]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Interaction/BaseInteractorStyle.h
Code cleaning
[cpPlugins.git] / lib / cpExtensions / Interaction / BaseInteractorStyle.h
1 #ifndef __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__
2 #define __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__
3
4 #include <cpExtensions/Config.h>
5
6 #include <chrono>
7 #include <map>
8 #include <utility>
9
10 #include <vtkInteractorStyle.h>
11
12 /* =========================================================================
13  * Double click algorithm inspired from:
14  * http://www.autohotkey.com/board/topic/56493-easiest-way-to-detect-double-clicks/
15  * =========================================================================
16  */
17
18 // -------------------------------------------------------------------------
19 #define cpExtensions_BaseInteractorStyle_Commands( C )                  \
20   protected:                                                            \
21   std::map< T##C##Command, void* > m_##C##Commands;                     \
22 public:                                                                 \
23   inline void Add##C##Command( T##C##Command c, void* d )               \
24   {                                                                     \
25     if( c != NULL )                                                     \
26     {                                                                   \
27       this->m_##C##Commands[ c ] = d;                                   \
28       this->Modified( );                                                \
29     }                                                                   \
30   }                                                                     \
31   inline void Remove##C##Command( T##C##Command c )                     \
32   {                                                                     \
33     std::map< T##C##Command, void* >::iterator i =                      \
34       this->m_##C##Commands.find( c );                                  \
35     if( i != this->m_##C##Commands.end( ) )                             \
36     {                                                                   \
37       this->m_##C##Commands.erase( i );                                 \
38       this->Modified( );                                                \
39     }                                                                   \
40   }
41
42 // -------------------------------------------------------------------------
43 #define BaseInteractorStyle_DIFF_TIME                           \
44   std::chrono::duration_cast< std::chrono::milliseconds >(      \
45     std::chrono::system_clock::now( ).time_since_epoch( )       \
46     ).count( )
47
48 namespace cpExtensions
49 {
50   namespace Interaction
51   {
52     /**
53      */
54     class cpExtensions_EXPORT BaseInteractorStyle
55       : public vtkInteractorStyle
56     {
57     public:
58       typedef BaseInteractorStyle Self;
59       vtkTypeMacro( BaseInteractorStyle, vtkInteractorStyle );
60
61       enum ButtonID
62       {
63         ButtonID_None = 0,
64         ButtonID_Left,
65         ButtonID_Middle,
66         ButtonID_Right
67       };
68
69       // Callbacks types
70       typedef void ( *TMouseCommand )(
71         void*, const ButtonID&, int*, double*, bool, bool, bool
72         );
73       typedef void ( *TMouseWheelCommand )( void*, const int&, bool, bool, bool );
74       typedef void ( *TKeyCommand )( void*, const char& );
75       typedef void ( *TVoidCommand )( void* );
76       typedef TMouseCommand TMouseMoveCommand;
77       typedef TMouseCommand TMouseClickCommand;
78       typedef TMouseCommand TMouseDoubleClickCommand;
79       typedef TVoidCommand  TExposeCommand;
80       typedef TVoidCommand  TConfigureCommand;
81       typedef TVoidCommand  TEnterCommand;
82       typedef TVoidCommand  TLeaveCommand;
83
84       // Associate callbacks for each event
85       cpExtensions_BaseInteractorStyle_Commands( MouseMove );
86       cpExtensions_BaseInteractorStyle_Commands( MouseClick );
87       cpExtensions_BaseInteractorStyle_Commands( MouseDoubleClick );
88       cpExtensions_BaseInteractorStyle_Commands( MouseWheel );
89       cpExtensions_BaseInteractorStyle_Commands( Key );
90       cpExtensions_BaseInteractorStyle_Commands( Expose );
91       cpExtensions_BaseInteractorStyle_Commands( Configure );
92       cpExtensions_BaseInteractorStyle_Commands( Enter );
93       cpExtensions_BaseInteractorStyle_Commands( Leave );
94
95     public:
96       vtkObject* GetAssociatedObject( );
97       const vtkObject* GetAssociatedObject( ) const;
98       void SetAssociatedObject( vtkObject* obj );
99
100       static void SetSetDoubleClickDelay( long delay );
101       void DelegateTDxEvent( unsigned long event, void* calldata );
102
103       // Possible mouse motion events
104       virtual void OnMouseMove( );
105       virtual void OnMouseWheelForward( );
106       virtual void OnMouseWheelBackward( );
107
108       // Possible mouse click-related events
109       inline ButtonID GetButtonID( ) const
110       {
111         return( this->m_ActiveButton );
112       }
113
114       virtual void OnLeftButtonDown( );
115       virtual void OnLeftButtonUp( );
116       virtual void OnMiddleButtonDown( );
117       virtual void OnMiddleButtonUp( );
118       virtual void OnRightButtonDown( );
119       virtual void OnRightButtonUp( );
120
121       virtual void OnLeftClick( );
122       virtual void OnLeftDoubleClick( );
123       virtual void OnMiddleClick( );
124       virtual void OnMiddleDoubleClick( );
125       virtual void OnRightClick( );
126       virtual void OnRightDoubleClick( );
127
128       // Keyboard-related events
129       virtual void OnChar( );
130       virtual void OnKeyDown( )    { }
131       virtual void OnKeyUp( )      { }
132       virtual void OnKeyPress( )   { }
133       virtual void OnKeyRelease( ) { }
134
135       // Other events
136       virtual void OnExpose( );
137       virtual void OnConfigure( );
138       virtual void OnEnter( );
139       virtual void OnLeave( );
140
141       virtual void Dolly( );
142       virtual void Pan( );
143
144     protected:
145       BaseInteractorStyle( );
146       virtual ~BaseInteractorStyle( );
147
148       virtual void _Dolly( double factor );
149
150       // Extension interface
151       virtual bool _PickPosition( int idx[ 2 ], double pos[ 3 ] ) = 0;
152
153       // Main event callback
154       static void _ProcessEvents(
155         vtkObject* object,
156         unsigned long event,
157         void* clientdata,
158         void* calldata
159         );
160
161     private:
162       // Purposely not implemented
163       BaseInteractorStyle( const Self& );
164       Self& operator=( const Self& );
165
166     protected:
167       vtkObject* m_AssociatedObject;
168       double m_MotionFactor;
169
170       /**
171        * Button events
172        */
173       struct _TMouseButtonEvent
174       {
175         static long MaxDoubleClick;
176         long m_LastButtonUp;
177         long m_LastButtonHeld;
178         long m_LastButtonDown;
179
180         inline _TMouseButtonEvent( )
181           { this->Reset( ); }
182         inline void Reset( )
183           {
184             this->m_LastButtonUp = 0;
185             this->m_LastButtonHeld = 0;
186             this->m_LastButtonDown = -1;
187           }
188         inline void Release( )
189           {
190             long c = BaseInteractorStyle_DIFF_TIME;
191             this->m_LastButtonUp = c;
192             this->m_LastButtonHeld = c - this->m_LastButtonDown;
193             this->m_LastButtonDown = -1;
194           }
195         inline unsigned char Clicks( )
196           {
197             unsigned char n = 0;
198             long c = BaseInteractorStyle_DIFF_TIME;
199             if(
200               this->m_LastButtonHeld < MaxDoubleClick &&
201               ( c - this->m_LastButtonUp ) < MaxDoubleClick
202               )
203             {
204               this->Reset( );
205               n = 2;
206             }
207             else
208               n = 1;
209             if( this->m_LastButtonDown < 0 )
210               this->m_LastButtonDown = c;
211             return( n );
212           }
213       };
214       _TMouseButtonEvent m_LeftButtonEvent;
215       _TMouseButtonEvent m_MiddleButtonEvent;
216       _TMouseButtonEvent m_RightButtonEvent;
217       ButtonID           m_ActiveButton;
218     };
219
220   } // ecapseman
221
222 } // ecapseman
223
224 #endif // __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__
225
226 // eof - $RCSfile$