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/window.h>
|
||||
|
||||
#include <view/view.h>
|
||||
#include <view/wx_view_controls.h>
|
||||
|
@ -33,9 +32,11 @@ using namespace KiGfx;
|
|||
|
||||
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
|
||||
VIEW_CONTROLS( aView ),
|
||||
m_state( IDLE ),
|
||||
m_autoPanEnabled( false ),
|
||||
m_grabMouse( false ),
|
||||
m_autoPanMargin( 0.1 ),
|
||||
m_autoPanSpeed( 0.15 ),
|
||||
m_autoPanCornerRatio( 0.1 ),
|
||||
m_parentPanel( aParentPanel )
|
||||
{
|
||||
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(
|
||||
WX_VIEW_CONTROLS::onEnter ), NULL, this );
|
||||
#endif
|
||||
|
||||
m_panTimer.SetOwner( this );
|
||||
this->Connect( wxEVT_TIMER, wxTimerEventHandler(
|
||||
WX_VIEW_CONTROLS::onTimer ), NULL, this );
|
||||
}
|
||||
|
||||
|
||||
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
if( aEvent.Dragging() && m_isDragPanning )
|
||||
{
|
||||
VECTOR2D mousePoint( aEvent.GetX(), aEvent.GetY() );
|
||||
|
||||
if( aEvent.Dragging() )
|
||||
{
|
||||
if( m_state == DRAG_PANNING )
|
||||
{
|
||||
VECTOR2D d = m_dragStartPoint - mousePoint;
|
||||
VECTOR2D delta = m_view->ToWorld( d, false );
|
||||
|
||||
m_view->SetCenter( m_lookStartPoint + delta );
|
||||
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 )
|
||||
{
|
||||
switch( m_state )
|
||||
{
|
||||
case IDLE:
|
||||
case AUTO_PANNING:
|
||||
if( aEvent.MiddleDown() )
|
||||
{
|
||||
m_isDragPanning = true;
|
||||
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
|
||||
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();
|
||||
}
|
||||
|
@ -141,3 +169,90 @@ void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent )
|
|||
{
|
||||
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
|
||||
{
|
||||
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 ) {};
|
||||
virtual ~VIEW_CONTROLS() {};
|
||||
|
||||
|
@ -89,13 +79,6 @@ public:
|
|||
*/
|
||||
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
|
||||
* 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() {};
|
||||
|
||||
/// Handler functions
|
||||
void onWheel( wxMouseEvent& aEvent );
|
||||
void onMotion( wxMouseEvent& aEvent );
|
||||
void onButton( 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:
|
||||
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
|
||||
bool m_isDragPanning;
|
||||
bool m_isAutoPanning;
|
||||
bool m_autoPanEnabled;
|
||||
bool m_needRedraw;
|
||||
bool m_grabMouse;
|
||||
|
||||
/// Distance from cursor to VIEW edge when panning is active.
|
||||
double m_autoPanMargin;
|
||||
float m_autoPanMargin;
|
||||
/// How fast is panning when in auto mode.
|
||||
double m_autoPanSpeed;
|
||||
float m_autoPanSpeed;
|
||||
/// TODO
|
||||
double m_autoPanCornerRatio;
|
||||
float m_autoPanAcceleration;
|
||||
|
||||
/// Panel that is affected by VIEW_CONTROLS
|
||||
wxWindow* m_parentPanel;
|
||||
|
@ -80,10 +108,11 @@ private:
|
|||
/// Stores information about point where event started.
|
||||
VECTOR2D m_dragStartPoint;
|
||||
VECTOR2D m_lookStartPoint;
|
||||
VECTOR2D m_panDirection;
|
||||
|
||||
/// Used for determining time intervals between events.
|
||||
wxLongLong m_timeStamp;
|
||||
TOOL_DISPATCHER* m_eventDispatcher;
|
||||
wxTimer m_panTimer;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
|
|
Loading…
Reference in New Issue