diff --git a/common/dialogs/panel_mouse_settings.cpp b/common/dialogs/panel_mouse_settings.cpp index 4df19092ce..af012e161b 100644 --- a/common/dialogs/panel_mouse_settings.cpp +++ b/common/dialogs/panel_mouse_settings.cpp @@ -111,6 +111,14 @@ bool PANEL_MOUSE_SETTINGS::TransferDataFromWindow() default: break; } + switch( m_choicePanMoveKey->GetSelection() ) + { + case 1: cfg->m_Input.motion_pan_modifier = WXK_ALT; break; + case 2: cfg->m_Input.motion_pan_modifier = WXK_CONTROL; break; + case 3: cfg->m_Input.motion_pan_modifier = WXK_SHIFT; break; + default: cfg->m_Input.motion_pan_modifier = 0; break; + } + cfg->m_Input.center_on_zoom = m_checkZoomCenter->GetValue(); cfg->m_Input.auto_pan = m_checkAutoPan->GetValue(); cfg->m_Input.auto_pan_acceleration = m_autoPanSpeed->GetValue(); @@ -178,6 +186,14 @@ void PANEL_MOUSE_SETTINGS::applySettingsToPanel( const COMMON_SETTINGS& aSetting default: break; } + switch( aSettings.m_Input.motion_pan_modifier ) + { + case WXK_ALT: m_choicePanMoveKey->SetSelection( 1 ); break; + case WXK_CONTROL: m_choicePanMoveKey->SetSelection( 2 ); break; + case WXK_SHIFT: m_choicePanMoveKey->SetSelection( 3 ); break; + default: m_choicePanMoveKey->SetSelection( 0 ); break; + } + m_currentScrollMod.zoom = aSettings.m_Input.scroll_modifier_zoom; m_currentScrollMod.panh = aSettings.m_Input.scroll_modifier_pan_h; m_currentScrollMod.panv = aSettings.m_Input.scroll_modifier_pan_v; diff --git a/common/dialogs/panel_mouse_settings_base.cpp b/common/dialogs/panel_mouse_settings_base.cpp index c281eb372b..20ffcda0e7 100644 --- a/common/dialogs/panel_mouse_settings_base.cpp +++ b/common/dialogs/panel_mouse_settings_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -156,6 +156,19 @@ PANEL_MOUSE_SETTINGS_BASE::PANEL_MOUSE_SETTINGS_BASE( wxWindow* parent, wxWindow fgSizer1->Add( m_choiceRightButtonDrag, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); + fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_panMoveKeyLabel = new wxStaticText( this, wxID_ANY, _("Pan on mouse movement with key:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_panMoveKeyLabel->Wrap( -1 ); + fgSizer1->Add( m_panMoveKeyLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 ); + + wxString m_choicePanMoveKeyChoices[] = { _("None"), _("Alt"), _("Ctrl"), _("Shift") }; + int m_choicePanMoveKeyNChoices = sizeof( m_choicePanMoveKeyChoices ) / sizeof( wxString ); + m_choicePanMoveKey = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePanMoveKeyNChoices, m_choicePanMoveKeyChoices, 0 ); + m_choicePanMoveKey->SetSelection( 0 ); + fgSizer1->Add( m_choicePanMoveKey, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); + + fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 ); diff --git a/common/dialogs/panel_mouse_settings_base.fbp b/common/dialogs/panel_mouse_settings_base.fbp index e16235dc3a..477bafecca 100644 --- a/common/dialogs/panel_mouse_settings_base.fbp +++ b/common/dialogs/panel_mouse_settings_base.fbp @@ -934,11 +934,11 @@ 0 - + 5 wxEXPAND|wxALL 1 - + 3 wxHORIZONTAL 2 @@ -1361,6 +1361,143 @@ 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Pan on mouse movement with key: + 0 + + 0 + + + 0 + + 1 + m_panMoveKeyLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + "None" "Alt" "Ctrl" "Shift" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_choicePanMoveKey + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + diff --git a/common/dialogs/panel_mouse_settings_base.h b/common/dialogs/panel_mouse_settings_base.h index c438c94df0..7f4a0fc5f7 100644 --- a/common/dialogs/panel_mouse_settings_base.h +++ b/common/dialogs/panel_mouse_settings_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -61,6 +61,8 @@ class PANEL_MOUSE_SETTINGS_BASE : public RESETTABLE_PANEL wxChoice* m_choiceMiddleButtonDrag; wxStaticText* m_staticText31; wxChoice* m_choiceRightButtonDrag; + wxStaticText* m_panMoveKeyLabel; + wxChoice* m_choicePanMoveKey; wxStaticText* m_scrollLabel; wxStaticLine* m_staticline2; wxStaticText* m_staticText21; diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 0ac9a79db9..924fd81f60 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -716,6 +716,7 @@ KIGFX::VC_SETTINGS EDA_DRAW_PANEL_GAL::GetVcSettings() vcSettings.m_scrollModifierZoom = cfg->m_Input.scroll_modifier_zoom; vcSettings.m_scrollModifierPanH = cfg->m_Input.scroll_modifier_pan_h; vcSettings.m_scrollModifierPanV = cfg->m_Input.scroll_modifier_pan_v; + vcSettings.m_motionPanModifier = cfg->m_Input.motion_pan_modifier; vcSettings.m_dragLeft = cfg->m_Input.drag_left; vcSettings.m_dragMiddle = cfg->m_Input.drag_middle; vcSettings.m_dragRight = cfg->m_Input.drag_right; diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp index 75b339f809..c86498e039 100644 --- a/common/settings/common_settings.cpp +++ b/common/settings/common_settings.cpp @@ -269,6 +269,9 @@ COMMON_SETTINGS::COMMON_SETTINGS() : m_params.emplace_back( new PARAM( "input.scroll_modifier_pan_v", &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) ); + m_params.emplace_back( new PARAM( "input.motion_pan_modifier", + &m_Input.motion_pan_modifier, 0 ) ); + m_params.emplace_back( new PARAM( "input.reverse_scroll_zoom", &m_Input.reverse_scroll_zoom, false ) ); diff --git a/common/view/view_controls.cpp b/common/view/view_controls.cpp index 5681614f0c..d7f133c191 100644 --- a/common/view/view_controls.cpp +++ b/common/view/view_controls.cpp @@ -76,6 +76,7 @@ void VC_SETTINGS::Reset() m_scrollModifierZoom = 0; m_scrollModifierPanH = WXK_CONTROL; m_scrollModifierPanV = WXK_SHIFT; + m_motionPanModifier = 0; m_dragLeft = MOUSE_DRAG_ACTION::NONE; m_dragMiddle = MOUSE_DRAG_ACTION::PAN; m_dragRight = MOUSE_DRAG_ACTION::PAN; diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index dc32008c85..705b01bbbd 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -35,7 +35,7 @@ #include #include #include -#include // for KiROUND +#include // for KiROUND #include #include #include @@ -45,7 +45,7 @@ #include #ifdef __WXMSW__ - #define USE_MOUSE_CAPTURE +#define USE_MOUSE_CAPTURE #endif using namespace KIGFX; @@ -73,9 +73,16 @@ static std::unique_ptr GetZoomControllerForPlatform( bool aAcce WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, EDA_DRAW_PANEL_GAL* aParentPanel ) : - VIEW_CONTROLS( aView ), m_state( IDLE ), m_parentPanel( aParentPanel ), - m_scrollScale( 1.0, 1.0 ), m_cursorPos( 0, 0 ), m_updateCursor( true ), - m_infinitePanWorks( false ), m_gestureLastZoomFactor( 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_metaPanning( false ), + m_metaPanStart( 0, 0 ), + m_infinitePanWorks( false ), + m_gestureLastZoomFactor( 1.0 ) { LoadSettings(); @@ -178,6 +185,7 @@ void WX_VIEW_CONTROLS::LoadSettings() m_settings.m_dragRight = cfg->m_Input.drag_right; m_settings.m_scrollReverseZoom = cfg->m_Input.reverse_scroll_zoom; m_settings.m_scrollReversePanH = cfg->m_Input.reverse_scroll_pan_h; + m_settings.m_motionPanModifier = cfg->m_Input.motion_pan_modifier; m_zoomController.reset(); @@ -238,6 +246,37 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) } } + if( m_settings.m_motionPanModifier != WXK_NONE + && wxGetKeyState( static_cast( m_settings.m_motionPanModifier ) ) ) + { + if( !m_metaPanning ) + { + m_metaPanning = true; + m_metaPanStart = mousePos; + aEvent.StopPropagation(); + } + else + { + VECTOR2D d = m_metaPanStart - mousePos; + m_metaPanStart = mousePos; + VECTOR2D delta = m_view->ToWorld( d, false ); + m_view->SetCenter( m_view->GetCenter() + delta ); + aEvent.StopPropagation(); + } + + if( m_updateCursor ) + m_cursorPos = GetClampedCoords( m_view->ToWorld( mousePos ) ); + else + m_updateCursor = true; + + aEvent.Skip(); + return; + } + else + { + m_metaPanning = false; + } + if( m_state != DRAG_PANNING && m_state != DRAG_ZOOMING ) handleCursorCapture( x, y ); @@ -249,15 +288,15 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) if( m_state == DRAG_PANNING ) { static bool justWarped = false; - int warpX = 0; - int warpY = 0; - wxSize parentSize = m_parentPanel->GetClientSize(); + int warpX = 0; + int warpY = 0; + wxSize parentSize = m_parentPanel->GetClientSize(); if( x < 0 ) { warpX = parentSize.x; } - else if(x >= parentSize.x ) + else if( x >= parentSize.x ) { warpX = -parentSize.x; } @@ -284,8 +323,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) { if( !justWarped ) { - if( m_infinitePanWorks - && KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) ) + if( m_infinitePanWorks && KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) ) { m_dragStartPoint += VECTOR2D( warpX, warpY ); justWarped = true; @@ -304,8 +342,8 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) else if( m_state == DRAG_ZOOMING ) { static bool justWarped = false; - int warpY = 0; - wxSize parentSize = m_parentPanel->GetClientSize(); + int warpY = 0; + wxSize parentSize = m_parentPanel->GetClientSize(); if( y < 0 ) { @@ -394,8 +432,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent ) // as vertical scroll events and confuse the user. if( modifiers == m_settings.m_scrollModifierZoom && axis == wxMOUSE_WHEEL_VERTICAL ) { - const int rotation = - aEvent.GetWheelRotation() * ( m_settings.m_scrollReverseZoom ? -1 : 1 ); + const int rotation = aEvent.GetWheelRotation() * ( m_settings.m_scrollReverseZoom ? -1 : 1 ); const double zoomScale = m_zoomController->GetScaleForRotation( rotation ); if( IsCursorWarpingEnabled() ) @@ -477,8 +514,8 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent ) { case IDLE: case AUTO_PANNING: - if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::PAN ) || - ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::PAN ) ) + if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::PAN ) + || ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::PAN ) ) { m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() ); setState( DRAG_PANNING ); @@ -489,10 +526,10 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent ) m_parentPanel->CaptureMouse(); #endif } - else if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::ZOOM ) || - ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::ZOOM ) ) + else if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::ZOOM ) + || ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::ZOOM ) ) { - m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() ); + m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() ); m_zoomStartPoint = m_dragStartPoint; setState( DRAG_ZOOMING ); @@ -503,7 +540,7 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent ) } if( aEvent.LeftUp() ) - setState( IDLE ); // Stop autopanning when user release left mouse button + setState( IDLE ); // Stop autopanning when user release left mouse button break; @@ -619,7 +656,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) // For a small mouse cursor dist to area, just use the distance. // But for a dist > borderSize / 2, use an accelerated pan value - if( dir.EuclideanNorm() >= borderSize ) // far from area limits + if( dir.EuclideanNorm() >= borderSize ) // far from area limits dir = dir.Resize( borderSize * accel ); else if( dir.EuclideanNorm() > borderSize / 2 ) // Near from area limits dir = dir.Resize( borderSize ); @@ -633,10 +670,9 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) } break; - case IDLE: // Just remove unnecessary warnings + case IDLE: // Just remove unnecessary warnings case DRAG_PANNING: - case DRAG_ZOOMING: - break; + case DRAG_ZOOMING: break; } } @@ -685,12 +721,11 @@ void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent ) if( type == wxEVT_SCROLLWIN_THUMBTRACK ) { - auto center = m_view->GetCenter(); + auto center = m_view->GetCenter(); const auto& boundary = m_view->GetBoundary(); // Flip scroll direction in flipped view - const double xstart = ( m_view->IsMirroredX() ? - boundary.GetRight() : boundary.GetLeft() ); + const double xstart = ( m_view->IsMirroredX() ? boundary.GetRight() : boundary.GetLeft() ); const double xdelta = ( m_view->IsMirroredX() ? -1 : 1 ); if( dir == wxHORIZONTAL ) @@ -700,9 +735,7 @@ void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent ) m_view->SetCenter( center ); } - else if( type == wxEVT_SCROLLWIN_THUMBRELEASE || - type == wxEVT_SCROLLWIN_TOP || - type == wxEVT_SCROLLWIN_BOTTOM ) + else if( type == wxEVT_SCROLLWIN_THUMBRELEASE || type == wxEVT_SCROLLWIN_TOP || type == wxEVT_SCROLLWIN_BOTTOM ) { // Do nothing on thumb release, we don't care about it. // We don't have a concept of top or bottom in our viewport, so ignore those events. @@ -737,7 +770,7 @@ void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent ) double scrollX = 0.0; double scrollY = 0.0; - if ( dir == wxHORIZONTAL ) + if( dir == wxHORIZONTAL ) scrollX = -scroll.x; else scrollY = -scroll.y; @@ -769,8 +802,7 @@ void WX_VIEW_CONTROLS::CaptureCursor( bool aEnabled ) // Calling it without calling ReleaseMouse() is not accepted by wxWidgets (MSW specific) m_parentPanel->m_MouseCapturedLost = false; } - else if( !aEnabled && m_parentPanel->HasCapture() - && m_state != DRAG_PANNING && m_state != DRAG_ZOOMING ) + else if( !aEnabled && m_parentPanel->HasCapture() && m_state != DRAG_PANNING && m_state != DRAG_ZOOMING ) { m_parentPanel->ReleaseMouse(); @@ -793,12 +825,14 @@ void WX_VIEW_CONTROLS::CancelDrag() m_parentPanel->ReleaseMouse(); #endif } + + m_metaPanning = false; } VECTOR2D WX_VIEW_CONTROLS::GetMousePosition( bool aWorldCoordinates ) const { - wxPoint msp = getMouseScreenPosition(); + wxPoint msp = getMouseScreenPosition(); VECTOR2D screenPos( msp.x, msp.y ); return aWorldCoordinates ? GetClampedCoords( m_view->ToWorld( screenPos ) ) : screenPos; @@ -833,8 +867,8 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition( bool aEnableSnapping ) const } -void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpView, - bool aTriggeredByArrows, long aArrowCommand ) +void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpView, bool aTriggeredByArrows, + long aArrowCommand ) { m_updateCursor = false; @@ -860,8 +894,7 @@ void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpV } -void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition, - bool aWarpView = true ) +void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition, bool aWarpView = true ) { m_updateCursor = false; @@ -878,8 +911,7 @@ void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition, } -void WX_VIEW_CONTROLS::WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCoordinates, - bool aWarpView ) +void WX_VIEW_CONTROLS::WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCoordinates, bool aWarpView ) { if( aWorldCoordinates ) { @@ -915,7 +947,7 @@ void WX_VIEW_CONTROLS::WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCo void WX_VIEW_CONTROLS::CenterOnCursor() { const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize(); - VECTOR2D screenCenter( screenSize / 2 ); + VECTOR2D screenCenter( screenSize / 2 ); if( GetMousePosition( false ) != screenCenter ) { @@ -937,8 +969,7 @@ void WX_VIEW_CONTROLS::PinCursorInsideNonAutoscrollArea( bool aWarpMouseCursor ) border += 2; VECTOR2D topLeft( border, border ); - VECTOR2D botRight( m_view->GetScreenPixelSize().x - border, - m_view->GetScreenPixelSize().y - border ); + VECTOR2D botRight( m_view->GetScreenPixelSize().x - border, m_view->GetScreenPixelSize().y - border ); topLeft = m_view->ToWorld( topLeft ); botRight = m_view->ToWorld( botRight ); @@ -965,7 +996,7 @@ void WX_VIEW_CONTROLS::PinCursorInsideNonAutoscrollArea( bool aWarpMouseCursor ) bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) { VECTOR2I p( aEvent.GetX(), aEvent.GetY() ); - VECTOR2I pKey( m_view->ToScreen(m_settings.m_lastKeyboardCursorPosition ) ); + VECTOR2I pKey( m_view->ToScreen( m_settings.m_lastKeyboardCursorPosition ) ); if( m_cursorWarped || ( m_settings.m_lastKeyboardCursorPositionValid && p == pKey ) ) { @@ -1028,8 +1059,7 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) return false; case DRAG_PANNING: - case DRAG_ZOOMING: - return false; + case DRAG_ZOOMING: return false; } wxCHECK_MSG( false, false, wxT( "This line should never be reached" ) ); @@ -1042,7 +1072,7 @@ void WX_VIEW_CONTROLS::handleCursorCapture( int x, int y ) { if( m_settings.m_cursorCaptured ) { - bool warp = false; + bool warp = false; wxSize parentSize = m_parentPanel->GetClientSize(); if( x < 0 ) @@ -1077,7 +1107,7 @@ void WX_VIEW_CONTROLS::refreshMouse( bool aSetModifiers ) { // Notify tools that the cursor position has changed in the world coordinates wxMouseEvent moveEvent( EVT_REFRESH_MOUSE ); - wxPoint msp = getMouseScreenPosition(); + wxPoint msp = getMouseScreenPosition(); moveEvent.SetX( msp.x ); moveEvent.SetY( msp.y ); @@ -1104,20 +1134,18 @@ wxPoint WX_VIEW_CONTROLS::getMouseScreenPosition() const void WX_VIEW_CONTROLS::UpdateScrollbars() { - const BOX2D viewport = m_view->GetViewport(); + const BOX2D viewport = m_view->GetViewport(); const BOX2D& boundary = m_view->GetBoundary(); - m_scrollScale.x = 2e3 / viewport.GetWidth(); // TODO it does not have to be updated so often + m_scrollScale.x = 2e3 / viewport.GetWidth(); // TODO it does not have to be updated so often m_scrollScale.y = 2e3 / viewport.GetHeight(); VECTOR2I newScroll( ( viewport.Centre().x - boundary.GetLeft() ) * m_scrollScale.x, ( viewport.Centre().y - boundary.GetTop() ) * m_scrollScale.y ); // We add the width of the scroll bar thumb to the range because the scroll range is given by // the full bar while the position is given by the left/top position of the thumb - VECTOR2I newRange( m_scrollScale.x * boundary.GetWidth() + - m_parentPanel->GetScrollThumb( wxSB_HORIZONTAL ), - m_scrollScale.y * boundary.GetHeight() + - m_parentPanel->GetScrollThumb( wxSB_VERTICAL ) ); + VECTOR2I newRange( m_scrollScale.x * boundary.GetWidth() + m_parentPanel->GetScrollThumb( wxSB_HORIZONTAL ), + m_scrollScale.y * boundary.GetHeight() + m_parentPanel->GetScrollThumb( wxSB_VERTICAL ) ); // Flip scroll direction in flipped view if( m_view->IsMirroredX() ) @@ -1126,10 +1154,9 @@ void WX_VIEW_CONTROLS::UpdateScrollbars() // Adjust scrollbars only if it is needed. Otherwise there are cases when canvas is continuously // refreshed (Windows) if( m_scrollPos != newScroll || newRange.x != m_parentPanel->GetScrollRange( wxSB_HORIZONTAL ) - || newRange.y != m_parentPanel->GetScrollRange( wxSB_VERTICAL ) ) + || newRange.y != m_parentPanel->GetScrollRange( wxSB_VERTICAL ) ) { - m_parentPanel->SetScrollbars( 1, 1, newRange.x, newRange.y, newScroll.x, newScroll.y, - true ); + m_parentPanel->SetScrollbars( 1, 1, newRange.x, newRange.y, newScroll.x, newScroll.y, true ); m_scrollPos = newScroll; #if !defined( __APPLE__ ) && !defined( WIN32 ) diff --git a/include/settings/common_settings.h b/include/settings/common_settings.h index a2b19e6ae0..7b5fd27184 100644 --- a/include/settings/common_settings.h +++ b/include/settings/common_settings.h @@ -96,6 +96,8 @@ public: int scroll_modifier_pan_h; int scroll_modifier_pan_v; + int motion_pan_modifier; + MOUSE_DRAG_ACTION drag_left; MOUSE_DRAG_ACTION drag_middle; MOUSE_DRAG_ACTION drag_right; diff --git a/include/view/view_controls.h b/include/view/view_controls.h index 96b44a83cf..cda852cad5 100644 --- a/include/view/view_controls.h +++ b/include/view/view_controls.h @@ -109,6 +109,9 @@ struct GAL_API VC_SETTINGS /// What modifier key to enable vertical with the (vertical) scroll wheel. int m_scrollModifierPanV; + /// What modifier key pans the view when the mouse moves with it held. + int m_motionPanModifier; + MOUSE_DRAG_ACTION m_dragLeft; MOUSE_DRAG_ACTION m_dragMiddle; MOUSE_DRAG_ACTION m_dragRight; diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index b20ca49e1c..e3163043ce 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -89,15 +89,14 @@ public: /// @copydoc VIEW_CONTROLS::GetRawCursorPosition() VECTOR2D GetRawCursorPosition( bool aSnappingEnabled = true ) const override; - void SetCursorPosition( const VECTOR2D& aPosition, bool warpView, - bool aTriggeredByArrows, long aArrowCommand ) override; + void SetCursorPosition( const VECTOR2D& aPosition, bool warpView, bool aTriggeredByArrows, + long aArrowCommand ) override; /// @copydoc VIEW_CONTROLS::SetCrossHairCursorPosition() void SetCrossHairCursorPosition( const VECTOR2D& aPosition, bool aWarpView ) override; /// @copydoc VIEW_CONTROLS::CursorWarp() - void WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, - bool aWarpView = false ) override; + void WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, bool aWarpView = false ) override; /// @copydoc VIEW_CONTROLS::CenterOnCursor() void CenterOnCursor() override; @@ -108,8 +107,7 @@ public: /// End any mouse drag action still in progress. void CancelDrag(); - void ForceCursorPosition( bool aEnabled, - const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) ) override; + void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) ) override; /// Applies VIEW_CONTROLS settings from the program #COMMON_SETTINGS. void LoadSettings() override; @@ -124,10 +122,10 @@ private: /// Possible states for WX_VIEW_CONTROLS. enum STATE { - IDLE = 1, ///< Nothing is happening. - DRAG_PANNING, ///< Panning with mouse button pressed. - AUTO_PANNING, ///< Panning on approaching borders of the frame. - DRAG_ZOOMING, ///< Zooming with mouse button pressed. + IDLE = 1, ///< Nothing is happening. + DRAG_PANNING, ///< Panning with mouse button pressed. + AUTO_PANNING, ///< Panning on approaching borders of the frame. + DRAG_ZOOMING, ///< Zooming with mouse button pressed. }; /** @@ -162,7 +160,7 @@ private: * @param aSetModifiers If false, don't change the modifiers (they were set using the * keyboard motion). */ - void refreshMouse( bool aSetModifiers); + void refreshMouse( bool aSetModifiers ); /** * Get the cursor position in the screen coordinates. @@ -170,34 +168,40 @@ private: wxPoint getMouseScreenPosition() const; /// Current state of VIEW_CONTROLS. - STATE m_state; + STATE m_state; /// Panel that is affected by VIEW_CONTROLS. EDA_DRAW_PANEL_GAL* m_parentPanel; /// Store information about point where dragging has started. - VECTOR2D m_dragStartPoint; + VECTOR2D m_dragStartPoint; /// Current direction of panning (only autopanning mode). - VECTOR2D m_panDirection; + VECTOR2D m_panDirection; /// Timer responsible for handling autopanning. - wxTimer m_panTimer; + wxTimer m_panTimer; /// Ratio used for scaling world coordinates to scrollbar position. - VECTOR2D m_scrollScale; + VECTOR2D m_scrollScale; /// Current scrollbar position. - VECTOR2I m_scrollPos; + VECTOR2I m_scrollPos; /// The mouse position when a drag zoom started. - VECTOR2D m_zoomStartPoint; + VECTOR2D m_zoomStartPoint; /// Current cursor position (world coordinates). - VECTOR2D m_cursorPos; + VECTOR2D m_cursorPos; /// Flag deciding whether the cursor position should be calculated using the mouse position. - bool m_updateCursor; + bool m_updateCursor; + + /// True if we are panning via the meta key. + bool m_metaPanning; + + /// Last mouse position when panning via the meta key. + VECTOR2D m_metaPanStart; /// Flag to indicate if infinite panning works on this platform. bool m_infinitePanWorks;