Added autopanning functionality to WX_VIEW_CONTROLS.
This commit is contained in:
parent
875c0f7062
commit
961a8c2eca
|
@ -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;
|
||||||
|
|
||||||
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 ) :
|
||||||
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() );
|
VECTOR2D mousePoint( aEvent.GetX(), aEvent.GetY() );
|
||||||
|
|
||||||
|
if( aEvent.Dragging() )
|
||||||
|
{
|
||||||
|
if( m_state == DRAG_PANNING )
|
||||||
|
{
|
||||||
VECTOR2D d = m_dragStartPoint - mousePoint;
|
VECTOR2D d = m_dragStartPoint - mousePoint;
|
||||||
VECTOR2D delta = m_view->ToWorld( d, false );
|
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 )
|
||||||
|
|
||||||
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
|
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
switch( m_state )
|
||||||
|
{
|
||||||
|
case IDLE:
|
||||||
|
case AUTO_PANNING:
|
||||||
if( aEvent.MiddleDown() )
|
if( aEvent.MiddleDown() )
|
||||||
{
|
{
|
||||||
m_isDragPanning = true;
|
|
||||||
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
|
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
|
||||||
m_lookStartPoint = m_view->GetCenter();
|
m_lookStartPoint = m_view->GetCenter();
|
||||||
|
m_state = DRAG_PANNING;
|
||||||
}
|
}
|
||||||
else if( aEvent.MiddleUp() )
|
break;
|
||||||
|
|
||||||
|
case DRAG_PANNING:
|
||||||
|
if( aEvent.MiddleUp() )
|
||||||
{
|
{
|
||||||
m_isDragPanning = false;
|
m_state = IDLE;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
aEvent.Skip();
|
aEvent.Skip();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
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:
|
||||||
*/
|
*/
|
||||||
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:
|
||||||
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:
|
||||||
/// 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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue