]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Interaction/BaseInteractorStyle.h
Merge branch 'master' of ssh://git.creatis.insa-lyon.fr/cpPlugins
[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 <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       static void SetSetDoubleClickDelay( long delay );
97       void DelegateTDxEvent( unsigned long event, void* calldata );
98
99       // Possible mouse motion events
100       virtual void OnMouseMove( );
101       virtual void OnMouseWheelForward( );
102       virtual void OnMouseWheelBackward( );
103
104       // Possible mouse click-related events
105       inline ButtonID GetButtonID( ) const
106       {
107         return( this->m_ActiveButton );
108       }
109
110       virtual void OnLeftButtonDown( );
111       virtual void OnLeftButtonUp( );
112       virtual void OnMiddleButtonDown( );
113       virtual void OnMiddleButtonUp( );
114       virtual void OnRightButtonDown( );
115       virtual void OnRightButtonUp( );
116
117       virtual void OnLeftClick( );
118       virtual void OnLeftDoubleClick( );
119       virtual void OnMiddleClick( );
120       virtual void OnMiddleDoubleClick( );
121       virtual void OnRightClick( );
122       virtual void OnRightDoubleClick( );
123
124       // Keyboard-related events
125       virtual void OnChar( );
126       virtual void OnKeyDown( )    { }
127       virtual void OnKeyUp( )      { }
128       virtual void OnKeyPress( )   { }
129       virtual void OnKeyRelease( ) { }
130
131       // Other events
132       virtual void OnExpose( );
133       virtual void OnConfigure( );
134       virtual void OnEnter( );
135       virtual void OnLeave( );
136
137       virtual void Dolly( );
138       virtual void Pan( );
139
140     protected:
141       BaseInteractorStyle( );
142       virtual ~BaseInteractorStyle( );
143
144       virtual void _Dolly( double factor );
145
146       // Extension interface
147       virtual bool _PickPosition( int idx[ 2 ], double pos[ 3 ] ) = 0;
148
149       // Main event callback
150       static void _ProcessEvents(
151         vtkObject* object,
152         unsigned long event,
153         void* clientdata,
154         void* calldata
155         );
156
157     private:
158       // Purposely not implemented
159       BaseInteractorStyle( const Self& );
160       Self& operator=( const Self& );
161
162     protected:
163       double m_MotionFactor;
164
165       /**
166        * Button events
167        */
168       struct _TMouseButtonEvent
169       {
170         static long MaxDoubleClick;
171         long m_LastButtonUp;
172         long m_LastButtonHeld;
173         long m_LastButtonDown;
174
175         inline _TMouseButtonEvent( )
176           { this->Reset( ); }
177         inline void Reset( )
178           {
179             this->m_LastButtonUp = 0;
180             this->m_LastButtonHeld = 0;
181             this->m_LastButtonDown = -1;
182           }
183         inline void Release( )
184           {
185             long c = BaseInteractorStyle_DIFF_TIME;
186             this->m_LastButtonUp = c;
187             this->m_LastButtonHeld = c - this->m_LastButtonDown;
188             this->m_LastButtonDown = -1;
189           }
190         inline unsigned char Clicks( )
191           {
192             unsigned char n = 0;
193             long c = BaseInteractorStyle_DIFF_TIME;
194             if(
195               this->m_LastButtonHeld < MaxDoubleClick &&
196               ( c - this->m_LastButtonUp ) < MaxDoubleClick
197               )
198             {
199               this->Reset( );
200               n = 2;
201             }
202             else
203               n = 1;
204             if( this->m_LastButtonDown < 0 )
205               this->m_LastButtonDown = c;
206             return( n );
207           }
208       };
209       _TMouseButtonEvent m_LeftButtonEvent;
210       _TMouseButtonEvent m_MiddleButtonEvent;
211       _TMouseButtonEvent m_RightButtonEvent;
212       ButtonID           m_ActiveButton;
213     };
214
215   } // ecapseman
216
217 } // ecapseman
218
219 #endif // __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__
220
221 // eof - $RCSfile$