#ifndef __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__ #define __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__ #include #include #include #include #include /* ========================================================================= * Double click algorithm inspired from: * http://www.autohotkey.com/board/topic/56493-easiest-way-to-detect-double-clicks/ * ========================================================================= */ // ------------------------------------------------------------------------- #define cpExtensions_BaseInteractorStyle_Commands( C ) \ protected: \ std::map< T##C##Command, void* > m_##C##Commands; \ public: \ inline void Add##C##Command( T##C##Command c, void* d ) \ { \ if( c != NULL ) \ { \ this->m_##C##Commands[ c ] = d; \ this->Modified( ); \ } \ } \ inline void Remove##C##Command( T##C##Command c ) \ { \ std::map< T##C##Command, void* >::iterator i = \ this->m_##C##Commands.find( c ); \ if( i != this->m_##C##Commands.end( ) ) \ { \ this->m_##C##Commands.erase( i ); \ this->Modified( ); \ } \ } // ------------------------------------------------------------------------- #define BaseInteractorStyle_DIFF_TIME \ std::chrono::duration_cast< std::chrono::milliseconds >( \ std::chrono::system_clock::now( ).time_since_epoch( ) \ ).count( ) namespace cpExtensions { namespace Interaction { /** */ class cpExtensions_EXPORT BaseInteractorStyle : public vtkInteractorStyle { public: typedef BaseInteractorStyle Self; vtkTypeMacro( BaseInteractorStyle, vtkInteractorStyle ); enum ButtonID { ButtonID_None = 0, ButtonID_Left, ButtonID_Middle, ButtonID_Right }; // Callbacks types typedef void ( *TMouseCommand )( void*, const ButtonID&, int*, double*, bool, bool, bool ); typedef void ( *TMouseWheelCommand )( void*, const int&, bool, bool, bool ); typedef void ( *TKeyCommand )( void*, const char& ); typedef void ( *TVoidCommand )( void* ); typedef TMouseCommand TMouseMoveCommand; typedef TMouseCommand TMouseClickCommand; typedef TMouseCommand TMouseDoubleClickCommand; typedef TVoidCommand TExposeCommand; typedef TVoidCommand TConfigureCommand; typedef TVoidCommand TEnterCommand; typedef TVoidCommand TLeaveCommand; // Associate callbacks for each event cpExtensions_BaseInteractorStyle_Commands( MouseMove ); cpExtensions_BaseInteractorStyle_Commands( MouseClick ); cpExtensions_BaseInteractorStyle_Commands( MouseDoubleClick ); cpExtensions_BaseInteractorStyle_Commands( MouseWheel ); cpExtensions_BaseInteractorStyle_Commands( Key ); cpExtensions_BaseInteractorStyle_Commands( Expose ); cpExtensions_BaseInteractorStyle_Commands( Configure ); cpExtensions_BaseInteractorStyle_Commands( Enter ); cpExtensions_BaseInteractorStyle_Commands( Leave ); public: vtkObject* GetAssociatedObject( ); const vtkObject* GetAssociatedObject( ) const; void SetAssociatedObject( vtkObject* obj ); static void SetSetDoubleClickDelay( long delay ); void DelegateTDxEvent( unsigned long event, void* calldata ); // Possible mouse motion events virtual void OnMouseMove( ); virtual void OnMouseWheelForward( ); virtual void OnMouseWheelBackward( ); // Possible mouse click-related events inline ButtonID GetButtonID( ) const { return( this->m_ActiveButton ); } virtual void OnLeftButtonDown( ); virtual void OnLeftButtonUp( ); virtual void OnMiddleButtonDown( ); virtual void OnMiddleButtonUp( ); virtual void OnRightButtonDown( ); virtual void OnRightButtonUp( ); virtual void OnLeftClick( ); virtual void OnLeftDoubleClick( ); virtual void OnMiddleClick( ); virtual void OnMiddleDoubleClick( ); virtual void OnRightClick( ); virtual void OnRightDoubleClick( ); // Keyboard-related events virtual void OnChar( ); virtual void OnKeyDown( ) { } virtual void OnKeyUp( ) { } virtual void OnKeyPress( ) { } virtual void OnKeyRelease( ) { } // Other events virtual void OnExpose( ); virtual void OnConfigure( ); virtual void OnEnter( ); virtual void OnLeave( ); virtual void Dolly( ); virtual void Pan( ); protected: BaseInteractorStyle( ); virtual ~BaseInteractorStyle( ); virtual void _Dolly( double factor ); // Extension interface virtual bool _PickPosition( int idx[ 2 ], double pos[ 3 ] ) = 0; // Main event callback static void _ProcessEvents( vtkObject* object, unsigned long event, void* clientdata, void* calldata ); private: // Purposely not implemented BaseInteractorStyle( const Self& ); Self& operator=( const Self& ); protected: vtkObject* m_AssociatedObject; double m_MotionFactor; /** * Button events */ struct _TMouseButtonEvent { static long MaxDoubleClick; long m_LastButtonUp; long m_LastButtonHeld; long m_LastButtonDown; inline _TMouseButtonEvent( ) { this->Reset( ); } inline void Reset( ) { this->m_LastButtonUp = 0; this->m_LastButtonHeld = 0; this->m_LastButtonDown = -1; } inline void Release( ) { long c = BaseInteractorStyle_DIFF_TIME; this->m_LastButtonUp = c; this->m_LastButtonHeld = c - this->m_LastButtonDown; this->m_LastButtonDown = -1; } inline unsigned char Clicks( ) { unsigned char n = 0; long c = BaseInteractorStyle_DIFF_TIME; if( this->m_LastButtonHeld < MaxDoubleClick && ( c - this->m_LastButtonUp ) < MaxDoubleClick ) { this->Reset( ); n = 2; } else n = 1; if( this->m_LastButtonDown < 0 ) this->m_LastButtonDown = c; return( n ); } }; _TMouseButtonEvent m_LeftButtonEvent; _TMouseButtonEvent m_MiddleButtonEvent; _TMouseButtonEvent m_RightButtonEvent; ButtonID m_ActiveButton; }; } // ecapseman } // ecapseman #endif // __CPEXTENSIONS__INTERACTION__BASEINTERACTORSTYLE__H__ // eof - $RCSfile$