Commit 961a8c2e authored by Maciej Suminski's avatar Maciej Suminski

Added autopanning functionality to WX_VIEW_CONTROLS.

parent 875c0f70
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
*/ */
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/window.h>
#include <view/view.h> #include <view/view.h>
#include <view/wx_view_controls.h> #include <view/wx_view_controls.h>
...@@ -33,9 +32,11 @@ using namespace KiGfx; ...@@ -33,9 +32,11 @@ using namespace KiGfx;
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) : WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
VIEW_CONTROLS( aView ), VIEW_CONTROLS( aView ),
m_state( IDLE ),
m_autoPanEnabled( false ),
m_grabMouse( false ),
m_autoPanMargin( 0.1 ), m_autoPanMargin( 0.1 ),
m_autoPanSpeed( 0.15 ), m_autoPanSpeed( 0.15 ),
m_autoPanCornerRatio( 0.1 ),
m_parentPanel( aParentPanel ) m_parentPanel( aParentPanel )
{ {
m_parentPanel->Connect( wxEVT_MOTION, wxMouseEventHandler( m_parentPanel->Connect( wxEVT_MOTION, wxMouseEventHandler(
...@@ -50,22 +51,40 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) : ...@@ -50,22 +51,40 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
m_parentPanel->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( m_parentPanel->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler(
WX_VIEW_CONTROLS::onEnter ), NULL, this ); WX_VIEW_CONTROLS::onEnter ), NULL, this );
#endif #endif
m_panTimer.SetOwner( this );
this->Connect( wxEVT_TIMER, wxTimerEventHandler(
WX_VIEW_CONTROLS::onTimer ), NULL, this );
} }
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{ {
if( aEvent.Dragging() && m_isDragPanning ) VECTOR2D mousePoint( aEvent.GetX(), aEvent.GetY() );
if( aEvent.Dragging() )
{ {
VECTOR2D mousePoint( aEvent.GetX(), aEvent.GetY() ); if( m_state == DRAG_PANNING )
VECTOR2D d = m_dragStartPoint - mousePoint; {
VECTOR2D delta = m_view->ToWorld( d, false ); VECTOR2D d = m_dragStartPoint - mousePoint;
VECTOR2D delta = m_view->ToWorld( d, false );
m_view->SetCenter( m_lookStartPoint + delta ); m_view->SetCenter( m_lookStartPoint + delta );
m_parentPanel->Refresh(); m_parentPanel->Refresh();
aEvent.StopPropagation();
}
else
{
aEvent.Skip();
}
}
else
{
if( m_autoPanEnabled )
handleAutoPanning( aEvent );
} }
aEvent.Skip(); // DeletePendingEvents();
} }
...@@ -122,16 +141,25 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent ) ...@@ -122,16 +141,25 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent ) void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
{ {
if( aEvent.MiddleDown() ) switch( m_state )
{ {
m_isDragPanning = true; case IDLE:
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() ); case AUTO_PANNING:
m_lookStartPoint = m_view->GetCenter(); if( aEvent.MiddleDown() )
} {
else if( aEvent.MiddleUp() ) m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
{ m_lookStartPoint = m_view->GetCenter();
m_isDragPanning = false; m_state = DRAG_PANNING;
} }
break;
case DRAG_PANNING:
if( aEvent.MiddleUp() )
{
m_state = IDLE;
}
break;
};
aEvent.Skip(); aEvent.Skip();
} }
...@@ -141,3 +169,90 @@ void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent ) ...@@ -141,3 +169,90 @@ void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent )
{ {
m_parentPanel->SetFocus(); m_parentPanel->SetFocus();
} }
void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
{
switch( m_state )
{
case AUTO_PANNING:
{
double borderSize = std::min( m_autoPanMargin * m_view->GetScreenPixelSize().x,
m_autoPanMargin * m_view->GetScreenPixelSize().y );
VECTOR2D dir( m_panDirection );
if( dir.EuclideanNorm() > borderSize )
dir = dir.Resize( borderSize );
dir = m_view->ToWorld( dir, false );
// wxLogDebug( "AutoPanningTimer: dir %.4f %.4f sped %.4f", dir.x, dir.y, m_autoPanSpeed );
m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
wxPaintEvent redrawEvent;
wxPostEvent( m_parentPanel, redrawEvent );
}
break;
}
DeletePendingEvents();
m_panTimer.DeletePendingEvents();
}
void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
{
m_grabMouse = aEnabled;
if( aEnabled )
m_parentPanel->CaptureMouse();
else
m_parentPanel->ReleaseMouse();
}
void WX_VIEW_CONTROLS::handleAutoPanning( wxMouseEvent& aEvent )
{
VECTOR2D p( aEvent.GetX(), aEvent.GetY() );
// Compute areas where autopanning is active
double borderStart = std::min( m_autoPanMargin * m_view->GetScreenPixelSize().x,
m_autoPanMargin * m_view->GetScreenPixelSize().y );
double borderEndX = m_view->GetScreenPixelSize().x - borderStart;
double borderEndY = m_view->GetScreenPixelSize().y - borderStart;
m_panDirection = VECTOR2D();
if( p.x < borderStart )
m_panDirection.x = -( borderStart - p.x );
else if( p.x > borderEndX )
m_panDirection.x = ( p.x - borderEndX );
if( p.y < borderStart )
m_panDirection.y = -( borderStart - p.y );
else if( p.y > borderEndY )
m_panDirection.y = ( p.y - borderEndY );
bool borderHit = ( m_panDirection.x != 0 || m_panDirection.y != 0 );
switch( m_state )
{
case AUTO_PANNING:
if( !borderHit )
{
m_panTimer.Stop();
m_state = IDLE;
}
break;
case IDLE:
if( borderHit )
{
m_state = AUTO_PANNING;
m_panTimer.Start( (int) ( 1000.0 / 60.0 ) );
}
break;
}
}
...@@ -46,16 +46,6 @@ class VIEW; ...@@ -46,16 +46,6 @@ class VIEW;
class VIEW_CONTROLS class VIEW_CONTROLS
{ {
public: public:
/**
* Possible modes for panning (JUMP means that view is updated less often, resulting in
* not so responsive user interface).
*/
enum PanMode {
SMOOTH = 1,
JUMP = 2
};
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ) {}; VIEW_CONTROLS( VIEW* aView ) : m_view( aView ) {};
virtual ~VIEW_CONTROLS() {}; virtual ~VIEW_CONTROLS() {};
...@@ -89,13 +79,6 @@ public: ...@@ -89,13 +79,6 @@ public:
*/ */
virtual void SetPanSpeed( float aSpeed ) {}; virtual void SetPanSpeed( float aSpeed ) {};
/**
* Function SetPanMode
* Enables specified mode for panning.
* @param aMode is a new mode used for VIEW panning.
*/
virtual void SetPanMode( PanMode aMode ) {};
/** /**
* Function SetZoomSpeed * Function SetZoomSpeed
* Determines how much zoom factor should be affected on one zoom event (eg. mouse wheel). * Determines how much zoom factor should be affected on one zoom event (eg. mouse wheel).
......
...@@ -52,27 +52,55 @@ public: ...@@ -52,27 +52,55 @@ public:
WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ); WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel );
~WX_VIEW_CONTROLS() {}; ~WX_VIEW_CONTROLS() {};
/// Handler functions
void onWheel( wxMouseEvent& aEvent ); void onWheel( wxMouseEvent& aEvent );
void onMotion( wxMouseEvent& aEvent ); void onMotion( wxMouseEvent& aEvent );
void onButton( wxMouseEvent& aEvent ); void onButton( wxMouseEvent& aEvent );
void onEnter( wxMouseEvent& aEvent ); void onEnter( wxMouseEvent& aEvent );
void onTimer( wxTimerEvent& aEvent );
void SetEventDispatcher( TOOL_DISPATCHER *aEventDispatcher );
/**
* Function SetGrabMouse()
* Enables/disables mouse cursor grabbing (limits the movement field only to the panel area).
*
* @param aEnabled says whether the option should enabled or disabled.
*/
void SetGrabMouse( bool aEnabled );
/**
* Function SetAutoPan()
* Enables/disables autopanning (panning when mouse cursor reaches the panel border).
*
* @param aEnabled says whether the option should enabled or disabled.
*/
void SetAutoPan( bool aEnabled )
{
m_autoPanEnabled = true;
}
private: private:
enum State {
IDLE = 1,
DRAG_PANNING,
AUTO_PANNING,
};
void handleAutoPanning( wxMouseEvent& aEvent );
/// Current state of VIEW_CONTROLS
State m_state;
/// Options for WX_VIEW_CONTROLS /// Options for WX_VIEW_CONTROLS
bool m_isDragPanning;
bool m_isAutoPanning;
bool m_autoPanEnabled; bool m_autoPanEnabled;
bool m_needRedraw; bool m_needRedraw;
bool m_grabMouse;
/// Distance from cursor to VIEW edge when panning is active. /// Distance from cursor to VIEW edge when panning is active.
double m_autoPanMargin; float m_autoPanMargin;
/// How fast is panning when in auto mode. /// How fast is panning when in auto mode.
double m_autoPanSpeed; float m_autoPanSpeed;
/// TODO /// TODO
double m_autoPanCornerRatio; float m_autoPanAcceleration;
/// Panel that is affected by VIEW_CONTROLS /// Panel that is affected by VIEW_CONTROLS
wxWindow* m_parentPanel; wxWindow* m_parentPanel;
...@@ -80,10 +108,11 @@ private: ...@@ -80,10 +108,11 @@ private:
/// Stores information about point where event started. /// Stores information about point where event started.
VECTOR2D m_dragStartPoint; VECTOR2D m_dragStartPoint;
VECTOR2D m_lookStartPoint; VECTOR2D m_lookStartPoint;
VECTOR2D m_panDirection;
/// Used for determining time intervals between events. /// Used for determining time intervals between events.
wxLongLong m_timeStamp; wxLongLong m_timeStamp;
TOOL_DISPATCHER* m_eventDispatcher; wxTimer m_panTimer;
}; };
} // namespace KiGfx } // namespace KiGfx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment