#ifndef __cpExtensions__Interaction__BaseStyle__h__ #define __cpExtensions__Interaction__BaseStyle__h__ #include #include #include #include /* ========================================================================= * Double click algorithm inspired from: * http://www.autohotkey.com/board/topic/56493-easiest-way-to-detect-double-clicks/ * ========================================================================= */ // ------------------------------------------------------------------------- #define cpExtensions_BaseStyle_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( ); \ } \ } // ------------------------------------------------------------------------- namespace cpExtensions { namespace Interaction { /** */ class cpExtensions_EXPORT BaseStyle : public vtkInteractorStyle { public: typedef BaseStyle Self; vtkTypeMacro( BaseStyle, 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 TMouseCommand TMouseClickCommand; typedef TMouseCommand TMouseDoubleClickCommand; // Associate callbacks for each event cpExtensions_BaseStyle_Commands( MouseClick ); cpExtensions_BaseStyle_Commands( MouseDoubleClick ); public: static void SetSetDoubleClickDelay( long delay ); void DelegateTDxEvent( unsigned long event, void* calldata ); // Possible mouse motion events virtual void OnMouseMove( ) cpExtensions_OVERRIDE; virtual void OnMouseWheelForward( ) cpExtensions_OVERRIDE { } virtual void OnMouseWheelBackward( ) cpExtensions_OVERRIDE { } // Possible mouse click-related events inline ButtonID GetButtonID( ) const { return( this->m_ActiveButton ); } virtual void OnLeftButtonDown( ) cpExtensions_OVERRIDE; virtual void OnLeftButtonUp( ) cpExtensions_OVERRIDE; virtual void OnMiddleButtonDown( ) cpExtensions_OVERRIDE; virtual void OnMiddleButtonUp( ) cpExtensions_OVERRIDE; virtual void OnRightButtonDown( ) cpExtensions_OVERRIDE; virtual void OnRightButtonUp( ) cpExtensions_OVERRIDE; virtual void OnLeftClick( ); virtual void OnLeftDoubleClick( ); virtual void OnMiddleClick( ); virtual void OnMiddleDoubleClick( ); virtual void OnRightClick( ); virtual void OnRightDoubleClick( ); // Keyboard-related events virtual void OnChar( ) cpExtensions_OVERRIDE { } virtual void OnKeyDown( ) cpExtensions_OVERRIDE { } virtual void OnKeyUp( ) cpExtensions_OVERRIDE { } virtual void OnKeyPress( ) cpExtensions_OVERRIDE { } virtual void OnKeyRelease( ) cpExtensions_OVERRIDE { } // Other events virtual void OnExpose( ) cpExtensions_OVERRIDE { } virtual void OnConfigure( ) cpExtensions_OVERRIDE { } virtual void OnEnter( ) cpExtensions_OVERRIDE { } virtual void OnLeave( ) cpExtensions_OVERRIDE { } virtual void Dolly( ) cpExtensions_OVERRIDE; virtual void Pan( ) cpExtensions_OVERRIDE; protected: BaseStyle( ); virtual ~BaseStyle( ); 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 BaseStyle( const Self& ); Self& operator=( const Self& ); protected: 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 = cpExtensions_CHRONO; 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 = cpExtensions_CHRONO; 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__BaseStyle__h__ // eof - $RCSfile$