46#define USE_MOUSE_CAPTURE
49#ifdef KICAD_GAL_PROFILE
70 return std::make_unique<ACCELERATING_ZOOM_CONTROLLER>();
137#if defined USE_MOUSE_CAPTURE
143 if(
m_parentPanel->EnableTouchEvents( wxTOUCH_ZOOM_GESTURE | wxTOUCH_PAN_GESTURES ) )
160 m_settings.m_lastKeyboardCursorPositionValid =
false;
161 m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
168#if defined USE_MOUSE_CAPTURE
224#ifdef KICAD_GAL_PROFILE
225 latencyProbeRepaintToMotion.Checkpoint(
"motion-event");
226 wxLogTrace(
traceGalProfile,
"%s", latencyProbeRepaintToMotion.to_string() );
227 latencyProbeZoomToRender.Reset();
230 ( *m_MotionEventCounter )++;
235 bool isAutoPanning =
false;
249 if( screenPos != keyboardScreenPos )
251 m_settings.m_lastKeyboardCursorPositionValid =
false;
252 m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
280 if(
m_settings.m_motionPanModifier != WXK_NONE
281 && wxGetKeyState(
static_cast<wxKeyCode
>(
m_settings.m_motionPanModifier ) ) )
287 aEvent.StopPropagation();
295 aEvent.StopPropagation();
318 if( !isAutoPanning && aEvent.Dragging() )
322 static bool justWarped =
false;
329 warpX = parentSize.x;
331 else if( x >= parentSize.x )
333 warpX = -parentSize.x;
338 warpY = parentSize.y;
340 else if( y >= parentSize.y )
342 warpY = -parentSize.y;
350#ifdef KICAD_GAL_PROFILE
351 latencyProbeZoomToRender.Checkpoint(
"mouse-mb-pan");
354 aEvent.StopPropagation();
379 static bool justWarped =
false;
385 warpY = parentSize.y;
387 else if( y >= parentSize.y )
389 warpY = -parentSize.y;
402 aEvent.StopPropagation();
436 if(
m_view->GetGAL() &&
m_view->GetGAL()->HasRetainedScene() )
445 const double wheelPanSpeed = 0.001;
446 const int axis = aEvent.GetWheelAxis();
448#ifdef KICAD_GAL_PROFILE
449 latencyProbeZoomToRender.Reset();
454 if( axis == wxMOUSE_WHEEL_HORIZONTAL )
460 * ( (double) aEvent.GetWheelRotation() * wheelPanSpeed );
472 if( aEvent.ShiftDown() )
475 modifiers = WXK_SHIFT;
478 if( aEvent.ControlDown() )
481 modifiers = modifiers == 0 ? WXK_CONTROL : modifiers;
484 if( aEvent.AltDown() )
487 modifiers = modifiers == 0 ? WXK_ALT : modifiers;
496 if( modifiers ==
m_settings.m_scrollModifierZoom && axis == wxMOUSE_WHEEL_VERTICAL )
498 const int rotation = aEvent.GetWheelRotation() * (
m_settings.m_scrollReverseZoom ? -1 : 1 );
502 const int wheelDelta = 0;
504 const int wheelDelta = aEvent.GetWheelDelta();
507 const double zoomScale =
m_zoomController->GetScaleForRotation( rotation, wheelDelta );
510#ifdef KICAD_GAL_PROFILE
512 latencyProbeZoomToRender.Checkpoint(
"mouse-wheel-zoom");
535 * ( (double) aEvent.GetWheelRotation() * wheelPanSpeed );
536 double scrollX = 0.0;
537 double scrollY = 0.0;
538 bool hReverse =
m_settings.m_scrollReversePanH;
540 if( modifiers ==
m_settings.m_scrollModifierPanH )
542 scrollX = hReverse ? scrollVec.
x : -scrollVec.
x;
546 scrollY = -scrollVec.
y;
572 m_view->SetScale(
m_view->GetScale() * ( aEvent.GetMagnification() + 1.0f ),
anchor );
598#if defined USE_MOUSE_CAPTURE
610#if defined USE_MOUSE_CAPTURE
616 if( aEvent.LeftUp() )
623 if( aEvent.MiddleUp() || aEvent.LeftUp() || aEvent.RightUp() )
628#if defined USE_MOUSE_CAPTURE
651#if defined( _WIN32 ) || defined( __WXGTK__ )
671#if !defined USE_MOUSE_CAPTURE
718 double borderSize = std::min(
m_settings.m_autoPanMargin *
m_view->GetScreenPixelSize().x,
728 float accel = 0.5f + (
m_settings.m_autoPanAcceleration / 5.0f );
734 dir = dir.
Resize( borderSize * accel );
736 dir = dir.
Resize( borderSize );
738 dir =
m_view->ToWorld( dir,
false );
757 if( aEvent.IsGestureStart() )
763 VECTOR2D evtPos( aEvent.GetPosition().x, aEvent.GetPosition().y );
776 if( wxGetMouseState().LeftIsDown() )
782 VECTOR2I screenDelta( aEvent.GetDelta().x, aEvent.GetDelta().y );
795 if( std::isfinite( aZoomFactor ) && aZoomFactor > 0.0 && aZoomFactor != 1.0 )
804 const double linePanDelta = 0.05;
805 const double pagePanDelta = 0.5;
807 int type = aEvent.GetEventType();
808 int dir = aEvent.GetOrientation();
810 if( type == wxEVT_SCROLLWIN_THUMBTRACK )
813 const auto& boundary =
m_view->GetBoundary();
816 const double xstart = (
m_view->IsMirroredX() ? boundary.GetRight() : boundary.GetLeft() );
817 const double xdelta = (
m_view->IsMirroredX() ? -1 : 1 );
819 if( dir == wxHORIZONTAL )
826 else if( type == wxEVT_SCROLLWIN_THUMBRELEASE || type == wxEVT_SCROLLWIN_TOP || type == wxEVT_SCROLLWIN_BOTTOM )
835 if( type == wxEVT_SCROLLWIN_PAGEUP )
839 else if( type == wxEVT_SCROLLWIN_PAGEDOWN )
841 dist = -pagePanDelta;
843 else if( type == wxEVT_SCROLLWIN_LINEUP )
847 else if( type == wxEVT_SCROLLWIN_LINEDOWN )
849 dist = -linePanDelta;
853 wxCHECK_MSG(
false, , wxT(
"Unhandled event type" ) );
858 double scrollX = 0.0;
859 double scrollY = 0.0;
861 if( dir == wxHORIZONTAL )
877#if defined USE_MOUSE_CAPTURE
911#if defined USE_MOUSE_CAPTURE
965 if( aTriggeredByArrows )
967 m_settings.m_lastKeyboardCursorPositionValid =
true;
968 m_settings.m_lastKeyboardCursorPosition = clampedPosition;
969 m_settings.m_lastKeyboardCursorCommand = aArrowCommand;
974 m_settings.m_lastKeyboardCursorPositionValid =
false;
975 m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
991 const VECTOR2I& screenSize =
m_view->GetGAL()->GetScreenPixelSize();
995 if( aWarpView && !screen.
Contains( screenPos ) )
996 m_view->SetCenter( clampedPosition );
1004 if( aWorldCoordinates )
1006 const VECTOR2I& screenSize =
m_view->GetGAL()->GetScreenPixelSize();
1011 if( !screen.
Contains( screenPos ) )
1015 m_view->SetCenter( clampedPosition );
1037 const VECTOR2I& screenSize =
m_view->GetGAL()->GetScreenPixelSize();
1038 VECTOR2D screenCenter( screenSize / 2 );
1046 m_view->SetCenter( newCenter );
1055 int border = std::min(
m_settings.m_autoPanMargin *
m_view->GetScreenPixelSize().x,
1059 VECTOR2D topLeft( border, border );
1060 VECTOR2D botRight(
m_view->GetScreenPixelSize().x - border,
m_view->GetScreenPixelSize().y - border );
1062 topLeft =
m_view->ToWorld( topLeft );
1063 botRight =
m_view->ToWorld( botRight );
1067 if( pos.
x < topLeft.
x )
1069 else if( pos.
x > botRight.
x )
1072 if( pos.
y < topLeft.
y )
1074 else if( pos.
y > botRight.
y )
1079 if( aWarpMouseCursor )
1086 VECTOR2I p( aEvent.GetX(), aEvent.GetY() );
1103 int borderStart = std::min(
m_settings.m_autoPanMargin *
m_view->GetScreenPixelSize().x,
1105 borderStart = std::max( borderStart, 2 );
1106 int borderEndX =
m_view->GetScreenPixelSize().x - borderStart;
1107 int borderEndY =
m_view->GetScreenPixelSize().y - borderStart;
1109 if( p.
x < borderStart )
1111 else if( p.
x > borderEndX )
1116 if( p.
y < borderStart )
1118 else if( p.
y > borderEndY )
1142 m_panTimer.Start( (
int) ( 250.0 / 60.0 ),
true );
1153 wxCHECK_MSG(
false,
false, wxT(
"This line should never be reached" ) );
1171 else if( x >= parentSize.x )
1173 x = parentSize.x - 1;
1182 else if( y >= parentSize.y )
1184 y = parentSize.y - 1;
1199 moveEvent.SetX( msp.x );
1200 moveEvent.SetY( msp.y );
1205 moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
1206 moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
1207 moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
1239 if(
m_view->IsMirroredX() )
1245 || newRange.
y !=
m_parentPanel->GetScrollRange( wxSB_VERTICAL ) )
1247 m_parentPanel->SetScrollbars( 1, 1, newRange.
x, newRange.
y, newScroll.
x, newScroll.
y,
true );
1250#if !defined( __APPLE__ ) && !defined( WIN32 )
1265 m_settings.m_forcedPosition = clampedPosition;
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetRight() const
constexpr coord_type GetTop() const
The base class for create windows for drawing purpose.
static void NoteInput()
Count an input so the frame that answers it is never held back by the display-rate limit.
static constexpr double MAC_SCALE
A suitable (magic) scale factor for Mac systems.
static constexpr double MSW_SCALE
A suitable (magic) scale factor for Windows systems.
static constexpr double GTK3_SCALE
A suitable (magic) scale factor for GTK3 systems.
static constexpr double MANUAL_SCALE_FACTOR
Multiplier for manual scale ssetting.
Abstract interface for drawing on a 2D-surface.
VECTOR2D GetGridPoint(const VECTOR2D &aPoint) const
For a given point it returns the nearest point belonging to the grid in world coordinates.
bool GetGridSnapping() const
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
bool m_cursorWarped
Application warped the cursor, not the user (keyboard).
bool IsCursorWarpingEnabled() const
VC_SETTINGS m_settings
Current VIEW_CONTROLS settings.
VIEW * m_view
Pointer to controlled VIEW.
VIEW_CONTROLS(VIEW *aView)
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
bool m_updateCursor
Flag deciding whether the cursor position should be calculated using the mouse position.
bool m_infinitePanWorks
Flag to indicate if infinite panning works on this platform.
void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView) override
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
void ApplyPanAndZoomGesture(const VECTOR2D &aPanDelta, double aZoomFactor, const VECTOR2D &aZoomAnchor)
Apply a platform gesture expressed in canvas pixel coordinates.
void LoadSettings() override
Applies VIEW_CONTROLS settings from the program COMMON_SETTINGS.
void setState(STATE aNewState)
Set the interaction state, simply a internal setter to make it easier to debug changes.
STATE m_state
Current state of VIEW_CONTROLS.
void CaptureCursor(bool aEnabled) override
Force the cursor to stay within the drawing panel area.
VECTOR2D m_metaPanStart
Last mouse position when panning via the meta key.
bool m_metaPanning
True if we are panning via the meta key.
void onScroll(wxScrollWinEvent &aEvent)
wxTimer m_panTimer
Timer responsible for handling autopanning.
void CancelDrag()
End any mouse drag action still in progress.
void repaintRetained()
Repaint only when the canvas keeps a retained scene.
VECTOR2D m_gestureLastPos
void onButton(wxMouseEvent &aEvent)
double m_gestureLastZoomFactor
Used to track gesture events.
void onEnter(wxMouseEvent &WXUNUSED(aEvent))
void onWheel(wxMouseEvent &aEvent)
Handler functions.
VECTOR2I m_scrollPos
Current scrollbar position.
void refreshMouse(bool aSetModifiers)
Send an event to refresh mouse position.
WX_VIEW_CONTROLS(VIEW *aView, EDA_DRAW_PANEL_GAL *aParentPanel)
void onZoomGesture(wxZoomGestureEvent &aEvent)
void PinCursorInsideNonAutoscrollArea(bool aWarpMouseCursor) override
void SetCursorPosition(const VECTOR2D &aPosition, bool warpView, bool aTriggeredByArrows, long aArrowCommand) override
Move cursor to the requested position expressed in world coordinates.
VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const override
Return the current mouse pointer position.
void WarpMouseCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false) override
If enabled (.
void onMagnify(wxMouseEvent &aEvent)
VECTOR2D GetRawCursorPosition(bool aSnappingEnabled=true) const override
Return the current cursor position in world coordinates ignoring the cursorUp position force mode.
VECTOR2D m_scrollScale
Ratio used for scaling world coordinates to scrollbar position.
bool handleAutoPanning(const wxMouseEvent &aEvent)
Compute new viewport settings while in autopanning mode.
wxPoint getMouseScreenPosition() const
Get the cursor position in the screen coordinates.
void onPanGesture(wxPanGestureEvent &aEvent)
void onTimer(wxTimerEvent &WXUNUSED(aEvent))
std::unique_ptr< ZOOM_CONTROLLER > m_zoomController
A ZOOM_CONTROLLER that determines zoom steps. This is platform-specific.
STATE
Possible states for WX_VIEW_CONTROLS.
@ DRAG_PANNING
Panning with mouse button pressed.
@ AUTO_PANNING
Panning on approaching borders of the frame.
@ DRAG_ZOOMING
Zooming with mouse button pressed.
@ IDLE
Nothing is happening.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
void CenterOnCursor() override
Set the viewport center to the current cursor position and warps the cursor to the screen center.
virtual ~WX_VIEW_CONTROLS()
VECTOR2D m_cursorPos
Current cursor position (world coordinates).
void onCaptureLost(wxMouseEvent &WXUNUSED(aEvent))
void onMotion(wxMouseEvent &aEvent)
std::unique_ptr< PROF_COUNTER > m_MotionEventCounter
EDA_DRAW_PANEL_GAL * m_parentPanel
Panel that is affected by VIEW_CONTROLS.
void UpdateScrollbars()
Adjusts the scrollbars position to match the current viewport.
void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0)) override
Place the cursor immediately at a given point.
void handleCursorCapture(int x, int y)
Limit the cursor position to within the canvas by warping it.
void onLeave(wxMouseEvent &WXUNUSED(aEvent))
VECTOR2D m_zoomStartPoint
The mouse position when a drag zoom started.
static const wxEventType EVT_REFRESH_MOUSE
Event that forces mouse move event in the dispatcher (eg.
VECTOR2D m_panDirection
Current direction of panning (only autopanning mode).
VECTOR2D m_dragStartPoint
Store information about point where dragging has started.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
virtual COMMON_SETTINGS * GetCommonSettings() const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
a few functions useful in geometry calculations.
VECTOR2< ret_type > GetClampedCoords(const VECTOR2< in_type > &aCoords, pad_type aPadding=1u)
Clamp a vector to values that can be negated, respecting numeric limits of coordinates data type with...
const wxChar *const traceZoomScroll
Flag to enable debug output of zoom-scrolling calculations in KIGFX::ZOOM_CONTROLLER and derivatives.
const wxChar *const traceGalProfile
Flag to enable debug output of GAL performance profiling.
The Cairo implementation of the graphics abstraction layer.
KICOMMON_API bool IsInputControlFocused(wxWindow *aFocus=nullptr)
Check if a input control has focus.
KICOMMON_API bool IsModalDialogFocused()
PGM_BASE & Pgm()
The global program "get" accessor.
wxLogTrace helper definitions.
Functions to provide common constants and other functions to assist in making a consistent UI.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
static std::unique_ptr< ZOOM_CONTROLLER > GetZoomControllerForPlatform(bool aAcceleration)
WX_VIEW_CONTROLS class definition.
ZOOM_CONTROLLER class definition.