Fix fine-grid cursor movement using arrow keys

Fixes: lp:1497976
* https://bugs.launchpad.net/kicad/+bug/1497976
This commit is contained in:
Maciej Suminski 2017-08-22 15:13:25 +02:00
parent d4fddf1929
commit 31ef52a365
5 changed files with 43 additions and 59 deletions

View File

@ -36,7 +36,8 @@ using namespace KIGFX;
const wxEventType WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE = wxNewEventType();
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxScrolledCanvas* aParentPanel ) :
VIEW_CONTROLS( aView ), m_state( IDLE ), m_parentPanel( aParentPanel ), m_scrollScale( 1.0, 1.0 )
VIEW_CONTROLS( aView ), m_state( IDLE ), m_parentPanel( aParentPanel ),
m_scrollScale( 1.0, 1.0 ), m_cursorPos( 0, 0 ), m_updateCursor( true )
{
m_parentPanel->Connect( wxEVT_MOTION,
wxMouseEventHandler( WX_VIEW_CONTROLS::onMotion ), NULL, this );
@ -72,6 +73,7 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxScrolledCanvas* aParentPanel
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
bool isAutoPanning = false;
VECTOR2D mousePos( aEvent.GetX(), aEvent.GetY() );
if( m_settings.m_autoPanEnabled )
isAutoPanning = handleAutoPanning( aEvent );
@ -80,7 +82,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
if( m_state == DRAG_PANNING )
{
VECTOR2D d = m_dragStartPoint - VECTOR2D( aEvent.GetX(), aEvent.GetY() );
VECTOR2D d = m_dragStartPoint - mousePos;
VECTOR2D delta = m_view->ToWorld( d, false );
m_view->SetCenter( m_lookStartPoint + delta );
@ -88,6 +90,11 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
}
}
if( m_updateCursor ) // do not update the cursor position if it was explicitly set
m_cursorPos = m_view->ToWorld( mousePos );
else
m_updateCursor = true;
aEvent.Skip();
}
@ -355,8 +362,8 @@ void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
VECTOR2D WX_VIEW_CONTROLS::GetMousePosition( bool aWorldCoordinates ) const
{
wxPoint msp = wxGetMousePosition();
wxPoint winp = m_parentPanel->GetScreenPosition();
VECTOR2D screenPos( msp.x - winp.x, msp.y - winp.y );
m_parentPanel->ScreenToClient( &msp.x, &msp.y );
VECTOR2D screenPos( msp.x, msp.y );
return aWorldCoordinates ? m_view->ToWorld( screenPos ) : screenPos;
}
@ -370,16 +377,22 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition( bool aEnableSnapping ) const
}
else
{
VECTOR2D mousePosition = GetMousePosition();
if( aEnableSnapping )
return m_view->GetGAL()->GetGridPoint( mousePosition );
return m_view->GetGAL()->GetGridPoint( m_cursorPos );
else
return mousePosition;
return m_cursorPos;
}
}
void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition )
{
m_updateCursor = false;
WarpCursor( aPosition, true, true );
m_cursorPos = aPosition;
}
void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates,
bool aWarpView ) const
{

View File

@ -199,6 +199,14 @@ public:
m_settings.m_forcedPosition = aPosition;
}
/**
* Moves cursor to the requested position expressed in world coordinates. The position is not
* forced and will be overridden with the next mouse motion event. Mouse cursor follows the
* world cursor.
* @param aPosition is the requested cursor position in the world coordinates.
*/
virtual void SetCursorPosition( const VECTOR2D& aPosition ) = 0;
/**
* Function ForcedCursorPosition()
* Returns true if the current cursor position is forced to a specific location, ignoring

View File

@ -78,6 +78,8 @@ public:
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
VECTOR2D GetCursorPosition( bool aSnappingEnabled ) const override;
void SetCursorPosition( const VECTOR2D& aPosition ) override;
/// @copydoc VIEW_CONTROLS::CursorWarp()
void WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false,
bool aWarpView = false ) const override;
@ -137,6 +139,12 @@ private:
/// Current scrollbar position
VECTOR2I m_scrollPos;
/// Current cursor position (world coordinates)
VECTOR2D m_cursorPos;
/// Flag deciding whether the cursor position should be calculated using the mouse position
bool m_updateCursor;
};
} // namespace KIGFX

View File

@ -432,8 +432,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
m_cursor = grid.Align( m_cursor );
}
controls->ForceCursorPosition( true, m_cursor );
controls->WarpCursor( m_cursor, true );
controls->SetCursorPosition( m_cursor );
VECTOR2I o = VECTOR2I( curr_item->GetPosition() );
m_offset.x = o.x - m_cursor.x;

View File

@ -492,7 +492,6 @@ int PCBNEW_CONTROL::CursorControl( const TOOL_EVENT& aEvent )
GRID_HELPER gridHelper( m_frame );
VECTOR2D cursor = getViewControls()->GetCursorPosition();
VECTOR2I gridSize = gridHelper.GetGrid();
VECTOR2D newCursor = gridHelper.Align( cursor );
if( fastMove )
gridSize = gridSize * 10;
@ -500,19 +499,19 @@ int PCBNEW_CONTROL::CursorControl( const TOOL_EVENT& aEvent )
switch( type )
{
case PCB_ACTIONS::CURSOR_UP:
newCursor -= VECTOR2D( 0, gridSize.y );
cursor -= VECTOR2D( 0, gridSize.y );
break;
case PCB_ACTIONS::CURSOR_DOWN:
newCursor += VECTOR2D( 0, gridSize.y );
cursor += VECTOR2D( 0, gridSize.y );
break;
case PCB_ACTIONS::CURSOR_LEFT:
newCursor -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
cursor -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
break;
case PCB_ACTIONS::CURSOR_RIGHT:
newCursor += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
cursor += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
break;
case PCB_ACTIONS::CURSOR_CLICK: // fall through
@ -541,50 +540,7 @@ int PCBNEW_CONTROL::CursorControl( const TOOL_EVENT& aEvent )
break;
}
// Handler cursor movement
KIGFX::VIEW* view = getView();
newCursor = view->ToScreen( newCursor );
newCursor.x = KiROUND( newCursor.x );
newCursor.y = KiROUND( newCursor.y );
// Pan the screen if required
const VECTOR2I& screenSize = view->GetGAL()->GetScreenPixelSize();
BOX2I screenBox( VECTOR2I( 0, 0 ), screenSize );
if( !screenBox.Contains( newCursor ) )
{
VECTOR2D delta( 0, 0 );
if( newCursor.x < screenBox.GetLeft() )
{
delta.x = newCursor.x - screenBox.GetLeft();
newCursor.x = screenBox.GetLeft();
}
else if( newCursor.x > screenBox.GetRight() )
{
delta.x = newCursor.x - screenBox.GetRight();
// -1 is to keep the cursor within the drawing area,
// so the cursor coordinates are still updated
newCursor.x = screenBox.GetRight() - 1;
}
if( newCursor.y < screenBox.GetTop() )
{
delta.y = newCursor.y - screenBox.GetTop();
newCursor.y = screenBox.GetTop();
}
else if( newCursor.y > screenBox.GetBottom() )
{
delta.y = newCursor.y - screenBox.GetBottom();
// -1 is to keep the cursor within the drawing area,
// so the cursor coordinates are still updated
newCursor.y = screenBox.GetBottom() - 1;
}
view->SetCenter( view->GetCenter() + view->ToWorld( delta, false ) );
}
m_frame->GetGalCanvas()->WarpPointer( newCursor.x, newCursor.y );
getViewControls()->SetCursorPosition( cursor );
return 0;
}