diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-05-28 17:48:48 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-05-28 17:52:43 +0300 |
commit | e4ac8ab212769b569334d0cd15d4bf04f42cbc89 (patch) | |
tree | 62cc58acd12f6f1bf974ff810900fa231d918354 /intern/ghost | |
parent | a7ebb4b7d96b129d3ac1950ee415754b282bfbc4 (diff) |
WM: support X/Y axis cursor wrapping
Operator flags to wrap on a single axis.
D4865 by @Gvgeo with updates.
Resolves T64585
Diffstat (limited to 'intern/ghost')
-rw-r--r-- | intern/ghost/GHOST_C-api.h | 1 | ||||
-rw-r--r-- | intern/ghost/GHOST_IWindow.h | 1 | ||||
-rw-r--r-- | intern/ghost/GHOST_Rect.h | 31 | ||||
-rw-r--r-- | intern/ghost/GHOST_Types.h | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_C-api.cpp | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemSDL.cpp | 6 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.cpp | 5 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.h | 10 |
11 files changed, 59 insertions, 23 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index fa783c17e8c..3238be8fd87 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -410,6 +410,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, + GHOST_TAxisFlag warp_axis, int bounds[4], const int mouse_ungrab_xy[2]); diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 6a9e0b9588a..8042244c536 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -314,6 +314,7 @@ class GHOST_IWindow { * \return Indication of success. */ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/, + GHOST_TAxisFlag /*wrap_axis*/, GHOST_Rect * /*bounds*/, GHOST_TInt32 /*mouse_ungrab_xy*/[2]) { diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index 831d3ef1445..88053f83fb9 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -125,7 +125,10 @@ class GHOST_Rect { * \param x The x-coordinate of the point. * \param y The y-coordinate of the point. */ - virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs); + virtual inline void wrapPoint(GHOST_TInt32 &x, + GHOST_TInt32 &y, + GHOST_TInt32 ofs, + GHOST_TAxisFlag axis); /** * Returns whether the point is inside this rectangle. @@ -236,7 +239,11 @@ inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y) if (y > m_b) m_b = y; } -inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs) + +inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, + GHOST_TInt32 &y, + GHOST_TInt32 ofs, + GHOST_TAxisFlag axis) { GHOST_TInt32 w = getWidth(); GHOST_TInt32 h = getHeight(); @@ -246,14 +253,18 @@ inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 return; } - while (x - ofs < m_l) - x += w - (ofs * 2); - while (y - ofs < m_t) - y += h - (ofs * 2); - while (x + ofs > m_r) - x -= w - (ofs * 2); - while (y + ofs > m_b) - y -= h - (ofs * 2); + if (axis & GHOST_kAxisX) { + while (x - ofs < m_l) + x += w - (ofs * 2); + while (x + ofs > m_r) + x -= w - (ofs * 2); + } + if (axis & GHOST_kGrabAxisY) { + while (y - ofs < m_t) + y += h - (ofs * 2); + while (y + ofs > m_b) + y -= h - (ofs * 2); + } } inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index f38154cbf94..68516c3ecf8 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -374,6 +374,13 @@ typedef enum { GHOST_kGrabHide, } GHOST_TGrabCursorMode; +typedef enum { + /** Axis that cursor grab will wrap. */ + GHOST_kGrabAxisNone = 0, + GHOST_kAxisX = (1 << 0), + GHOST_kGrabAxisY = (1 << 1), +} GHOST_TAxisFlag; + typedef void *GHOST_TEventDataPtr; typedef struct { diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index c8ee2e44efe..38ddf9819f9 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -324,6 +324,7 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, + GHOST_TAxisFlag wrap_axis, int bounds[4], const int mouse_ungrab_xy[2]) { @@ -340,7 +341,7 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, } return window->setCursorGrab( - mode, bounds ? &bounds_rect : NULL, mouse_ungrab_xy ? mouse_xy : NULL); + mode, wrap_axis, bounds ? &bounds_rect : NULL, mouse_ungrab_xy ? mouse_xy : NULL); } GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index f13c9d470a5..eb54ed20fe1 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1590,7 +1590,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) // Warp mouse cursor if needed GHOST_TInt32 warped_x_mouse = x_mouse; GHOST_TInt32 warped_y_mouse = y_mouse; - correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4); + + correctedBounds.wrapPoint( + warped_x_mouse, warped_y_mouse, 4, window->getCursorGrabAxis()); // Set new cursor position if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) { diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 8fc7046565d..520c62719f8 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -369,9 +369,9 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) window->getClientBounds(bounds); - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ + /* Could also clamp to screen bounds wrap with a window outside the view will fail atm. + * Use offset of 8 in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis()); window->getCursorGrabAccum(x_accum, y_accum); // cant use setCursorPosition because the mouse may have no focus! diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9f7b6f75e41..0cc1b36f369 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -934,10 +934,9 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, window->getClientBounds(bounds); } - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - - bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */ + /* Could also clamp to screen bounds wrap with a window outside the view will fail atm. + * Use offset of 8 in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis()); window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index b95e5fe3846..31411c823ae 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -868,9 +868,10 @@ void GHOST_SystemX11::processEvent(XEvent *xe) if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) window->getClientBounds(bounds); - /* could also clamp to screen bounds - * wrap with a window outside the view will fail atm */ - bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ + /* Could also clamp to screen bounds wrap with a window outside the view will fail atm. + * Use offset of 8 in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis()); + window->getCursorGrabAccum(x_accum, y_accum); if (x_new != xme.x_root || y_new != xme.y_root) { diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 85283a34d2e..5649386063d 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -136,6 +136,7 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, + GHOST_TAxisFlag wrap_axis, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) { @@ -151,8 +152,9 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, if (setWindowCursorGrab(mode)) { - if (mode == GHOST_kGrabDisable) + if (mode == GHOST_kGrabDisable) { m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; + } else if (bounds) { m_cursorGrabBounds = *bounds; } @@ -160,6 +162,7 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, getClientBounds(m_cursorGrabBounds); } m_cursorGrab = mode; + m_cursorGrabAxis = wrap_axis; return GHOST_kSuccess; } else { diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index b5399ec803e..acd0c93ff87 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -145,6 +145,7 @@ class GHOST_Window : public GHOST_IWindow { inline bool getCursorVisibility() const; inline GHOST_TGrabCursorMode getCursorGrabMode() const; inline bool getCursorGrabModeIsWarp() const; + inline GHOST_TAxisFlag getCursorGrabAxis() const; inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); @@ -162,6 +163,7 @@ class GHOST_Window : public GHOST_IWindow { * \return Indication of success. */ GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, + GHOST_TAxisFlag wrap_axis, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]); @@ -367,6 +369,9 @@ class GHOST_Window : public GHOST_IWindow { /** The current grabbed state of the cursor */ GHOST_TGrabCursorMode m_cursorGrab; + /** Grab cursor axis.*/ + GHOST_TAxisFlag m_cursorGrabAxis; + /** Initial grab location. */ GHOST_TInt32 m_cursorGrabInitPos[2]; @@ -426,6 +431,11 @@ inline bool GHOST_Window::getCursorGrabModeIsWarp() const return (m_cursorGrab == GHOST_kGrabWrap) || (m_cursorGrab == GHOST_kGrabHide); } +inline GHOST_TAxisFlag GHOST_Window::getCursorGrabAxis() const +{ + return m_cursorGrabAxis; +} + inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const { x = m_cursorGrabInitPos[0]; |