diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 32cd93a111..ad332b06f8 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -1063,7 +1063,7 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) gal->SetGridOrigin( VECTOR2D( GetGridOrigin() ) ); // Transfer EDA_DRAW_PANEL settings - GetGalCanvas()->GetViewControls()->SetEnableZoomNoCenter( m_canvas->GetEnableZoomNoCenter() ); + GetGalCanvas()->GetViewControls()->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); GetToolManager()->RunAction( "pcbnew.Control.switchCursor" ); } diff --git a/common/draw_panel.cpp b/common/draw_panel.cpp index 74b4e1bcb7..d624f26f17 100644 --- a/common/draw_panel.cpp +++ b/common/draw_panel.cpp @@ -644,7 +644,7 @@ void EDA_DRAW_PANEL::SetEnableZoomNoCenter( bool aEnable ) m_enableZoomNoCenter = aEnable; if( GetParent()->IsGalCanvasActive() ) - GetParent()->GetGalCanvas()->GetViewControls()->SetEnableZoomNoCenter( aEnable ); + GetParent()->GetGalCanvas()->GetViewControls()->EnableCursorWarping( !aEnable ); } diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 7bb333004a..91aea39d32 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -151,18 +151,18 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent ) zoomScale = ( rotation > 0 ) ? 1.05 : 0.95; } - if( GetEnableZoomNoCenter() ) - { - VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) ); - m_view->SetScale( m_view->GetScale() * zoomScale, anchor ); - } - else + if( IsCursorWarpingEnabled() ) { const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize(); m_view->SetCenter( GetCursorPosition() ); m_view->SetScale( m_view->GetScale() * zoomScale ); m_parentPanel->WarpPointer( screenSize.x / 2, screenSize.y / 2 ); } + else + { + VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) ); + m_view->SetScale( m_view->GetScale() * zoomScale, anchor ); + } } aEvent.Skip(); @@ -339,7 +339,9 @@ VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const { if( m_forceCursorPosition ) + { return m_forcedPosition; + } else { VECTOR2D mousePosition = GetMousePosition(); @@ -352,6 +354,35 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const } +void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates, + bool aWarpView ) const +{ + if( aWorldCoordinates ) + { + const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize(); + BOX2I screen( VECTOR2I( 0, 0 ), screenSize ); + VECTOR2D screenPos = m_view->ToScreen( aPosition ); + + if( !screen.Contains( screenPos ) ) + { + if( aWarpView ) + { + m_view->SetCenter( aPosition ); + m_parentPanel->WarpPointer( screenSize.x / 2, screenSize.y / 2 ); + } + } + else + { + m_parentPanel->WarpPointer( screenPos.x, screenPos.y ); + } + } + else + { + m_parentPanel->WarpPointer( aPosition.x, aPosition.y ); + } +} + + bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) { VECTOR2D p( aEvent.GetX(), aEvent.GetY() ); diff --git a/include/view/view_controls.h b/include/view/view_controls.h index f0ebe86a43..e49b644bb6 100644 --- a/include/view/view_controls.h +++ b/include/view/view_controls.h @@ -49,7 +49,7 @@ public: VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_forceCursorPosition( false ), m_cursorCaptured( false ), m_snappingEnabled( false ), m_grabMouse( false ), m_autoPanEnabled( false ), m_autoPanMargin( 0.1 ), - m_autoPanSpeed( 0.15 ), m_enableZoomNoCenter( false ) + m_autoPanSpeed( 0.15 ), m_warpCursor( false ) { } @@ -106,7 +106,7 @@ public: virtual void SetAutoPanMargin( float aMargin ) { m_autoPanMargin = aMargin; - }; + } /** * Function GetMousePosition() @@ -131,7 +131,7 @@ public: * Function ForceCursorPosition() * Places the cursor immediately at a given point. Mouse movement is ignored. * @param aEnabled enable forced cursor position - * @param aPosition the position + * @param aPosition the position (world coordinates). */ virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) ) { @@ -162,20 +162,35 @@ public: } /** - * Function SetEnableZoomNoCenter() - * Enables or Disables warping the cursor to the center of the drawing i - * panel area when zooming. - * @param aEnabled is true if the cursor should not be centered and false if - * the cursor should be centered. + * Function WarpCursor() + * If enabled (@see SetEnableCursorWarping(), warps the cursor to the specified position, + * expressed either in the screen coordinates or the world coordinates. + * @param aPosition is the position where the cursor should be warped. + * @param aWorldCoordinates if true treats aPosition as the world coordinates, otherwise it + * uses it as the screen coordinates. + * @param aWarpView determines if the view can be warped too (only matters if the position is + * specified in the world coordinates and its not visible in the current viewport). */ - virtual void SetEnableZoomNoCenter( bool aEnable ) + virtual void WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, + bool aWarpView = false ) const = 0; + + /** + * Function EnableCursorWarping() + * Enables or disables warping the cursor. + * @param aEnabled is true if the cursor is allowed to be warped. + */ + void EnableCursorWarping( bool aEnable ) { - m_enableZoomNoCenter = aEnable; + m_warpCursor = aEnable; } - virtual bool GetEnableZoomNoCenter() const + /** + * Function IsCursorWarpingEnabled() + * Returns the current setting for cursor warping. + */ + bool IsCursorWarpingEnabled() const { - return m_enableZoomNoCenter; + return m_warpCursor; } protected: @@ -209,8 +224,8 @@ protected: /// How fast is panning when in auto mode float m_autoPanSpeed; - /// If the cursor should be warped to the center of the view area when zooming - bool m_enableZoomNoCenter; + /// If the cursor is allowed to be warped + bool m_warpCursor; }; } // namespace KIGFX diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index 67ad9b4567..9a4c7ad1f1 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -91,6 +91,10 @@ public: /// @copydoc VIEW_CONTROLS::GetCursorPosition() VECTOR2D GetCursorPosition() const; + /// @copydoc VIEW_CONTROLS::CursorWarp() + void WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, + bool aWarpView = false ) const; + /// Adjusts the scrollbars position to match the current viewport. void UpdateScrollbars(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index a4a77baa9a..db6ef61c05 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -187,7 +187,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) if( m_dragging && evt->Category() == TC_MOUSE ) { m_cursor = grid.BestSnapAnchor( evt->Position(), item ); - getViewControls()->ForceCursorPosition( true, m_cursor ); + controls->ForceCursorPosition( true, m_cursor ); wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - item->GetPosition(); totalMovement += movement; @@ -222,7 +222,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); } - m_cursor = getViewControls()->GetCursorPosition(); + m_cursor = controls->GetCursorPosition(); if( selection.Size() == 1 ) { @@ -232,7 +232,9 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) grid.SetAuxAxes( true, m_cursor ); } - getViewControls()->ForceCursorPosition( true, m_cursor ); + controls->ForceCursorPosition( true, m_cursor ); + controls->WarpCursor( m_cursor, true ); + VECTOR2I o = VECTOR2I( item->GetPosition() ); m_offset.x = o.x - m_cursor.x; m_offset.y = o.y - m_cursor.y; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 9203ccc2ee..9fef98e209 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -84,7 +84,7 @@ int PCBNEW_CONTROL::ZoomInOut( const TOOL_EVENT& aEvent ) else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOut ) ) zoomScale = 0.7; - if( getViewControls()->GetEnableZoomNoCenter() ) + if( !getViewControls()->IsCursorWarpingEnabled() ) view->SetScale( view->GetScale() * zoomScale, getViewControls()->GetCursorPosition() ); else { @@ -119,7 +119,7 @@ int PCBNEW_CONTROL::ZoomCenter( const TOOL_EVENT& aEvent ) KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); view->SetCenter( getViewControls()->GetCursorPosition() ); - if( !getViewControls()->GetEnableZoomNoCenter() ) + if( getViewControls()->IsCursorWarpingEnabled() ) { const VECTOR2I& screenSize = view->GetGAL()->GetScreenPixelSize(); m_frame->GetGalCanvas()->WarpPointer( screenSize.x / 2, screenSize.y / 2 );