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