diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-10-17 18:08:01 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-10-17 18:08:01 +0400 |
commit | 91d89c1ff7c215744e46957a1e7cc40adb7ac066 (patch) | |
tree | a811c95542f7fd40ff13cf592dfff1077a34f7d4 /intern | |
parent | 53624a53d9054a91688a1a988c6f3515ab601923 (diff) |
Adjustments to continuous grab
- Use an enum for grab modes rather then boolean options.
-- GHOST_kGrabNormal: continuous grab userpref disabled
-- GHOST_kGrabWrap: wrap the mouse at the screen bounds *
-- GHOST_kGrabHide: hide the mouse while grabbing and restore the mouse where it was initially pressed *
GrabWrap is nice for transform and tools where you want some idea where the cursor is, previously I found both restoring the mouse at its original location and restoring at a clamped location was confusing with operators like transform, wrapping is not ideal but IMHO the best of a bad bunch of options.
GrabHide is for numbuts, where restoring the mouse at the initial location isnt so confusing.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/GHOST_C-api.h | 2 | ||||
-rw-r--r-- | intern/ghost/GHOST_IWindow.h | 2 | ||||
-rw-r--r-- | intern/ghost/GHOST_Rect.h | 22 | ||||
-rw-r--r-- | intern/ghost/GHOST_Types.h | 6 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_C-api.cpp | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 51 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.cpp | 15 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.h | 57 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowCocoa.h | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 46 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.h | 5 |
11 files changed, 102 insertions, 110 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 00d2cdb1e3b..93bd12437ab 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -376,7 +376,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * @return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp, int restore); + GHOST_TGrabCursorMode mode); /*************************************************************************************** ** Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 993b41a4d4f..3ab9bef2bfa 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -271,7 +271,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; }; }; diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index 6271ecad408..98169ad2aa4 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -127,6 +127,13 @@ public: virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y); /** + * Grows the rectangle to included a point. + * @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); + + /** * Returns whether the point is inside this rectangle. * Point on the boundary is considered inside. * @param x x-coordinate of point to test. @@ -222,6 +229,21 @@ 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) +{ + GHOST_TInt32 w= getWidth(); + GHOST_TInt32 h= getHeight(); + + /* highly unlikely but avoid eternal loop */ + if(w-ofs <= 0 || h-ofs <= 0) + return; + + while(x-ofs < m_l) x+= w; + while(y-ofs < m_t) y+= h; + while(x+ofs > m_r) x-= w; + while(y+ofs > m_b) y-= h; +} + inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const { return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b); diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 14e3c4bb5f7..e98e58740ad 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -341,6 +341,12 @@ typedef enum { GHOST_kKeyF24 } GHOST_TKey; +typedef enum { + GHOST_kGrabDisable = 0, /* grab not set */ + GHOST_kGrabNormal, /* no cursor adjustments */ + GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */ + GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */ +} GHOST_TGrabCursorMode; typedef void* GHOST_TEventDataPtr; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index e225ad4fd90..5563e0d1aa8 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -355,11 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp, int restore) + GHOST_TGrabCursorMode mode) { GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; - return window->setCursorGrab(grab?true:false, warp?true:false, restore?true:false); + return window->setCursorGrab(mode); } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 8c87abf16bc..abf0b612f9a 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -388,31 +388,36 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XMotionEvent &xme = xe->xmotion; - if(window->getCursorWarp()) { - /* Calculate offscreen location and re-center the mouse */ - GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum; - - window->getCursorWarpPos(x_warp, y_warp); - getCursorPosition(x_new, y_new); - - if(x_warp != x_new || y_warp != y_new) { - window->getCursorWarpAccum(x_accum, y_accum); - x_accum += x_new - x_warp; - y_accum += y_new - y_warp; - - window->setCursorWarpAccum(x_accum, y_accum); - setCursorPosition(x_warp, y_warp); /* reset */ - - g_event = new - GHOST_EventCursor( - getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_warp + x_accum, - y_warp + y_accum - ); + if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) + { + GHOST_TInt32 x_new= xme.x_root; + GHOST_TInt32 y_new= xme.y_root; + GHOST_TInt32 x_accum, y_accum; + GHOST_Rect bounds; + + 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, 1); /* offset of one incase blender is at screen bounds */ + window->getCursorGrabAccum(x_accum, y_accum); + + if(x_new != xme.x_root || y_new != xme.y_root) { + setCursorPosition(x_new, y_new); /* wrap */ + window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new)); } + + g_event = new + GHOST_EventCursor( + getMilliSeconds(), + GHOST_kEventCursorMove, + window, + xme.x_root + x_accum, + xme.y_root + y_accum + ); + } else { g_event = new diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 94feb83e003..cda6bfa06ee 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -48,15 +48,14 @@ GHOST_Window::GHOST_Window( : m_drawingContextType(type), m_cursorVisible(true), - m_cursorGrabbed(false), - m_cursorWarp(false), + m_cursorGrab(GHOST_kGrabDisable), m_cursorShape(GHOST_kStandardCursorDefault), m_stereoVisual(stereoVisual) { m_isUnsavedChanges = false; - m_cursorWarpAccumPos[0] = 0; - m_cursorWarpAccumPos[1] = 0; + m_cursorGrabAccumPos[0] = 0; + m_cursorGrabAccumPos[1] = 0; m_fullScreen = state == GHOST_kWindowStateFullScreen; if (m_fullScreen) { @@ -98,13 +97,13 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore) +GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode) { - if(m_cursorGrabbed == grab) + if(m_cursorGrab == mode) return GHOST_kSuccess; - if (setWindowCursorGrab(grab, warp, restore)) { - m_cursorGrabbed = grab; + if (setWindowCursorGrab(mode)) { + m_cursorGrab = mode; return GHOST_kSuccess; } else { diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 786918716c5..e66a3c2fd36 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -158,10 +158,9 @@ public: * @return The visibility state of the cursor. */ inline virtual bool getCursorVisibility() const; - inline virtual bool getCursorWarp() const; - inline virtual bool getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline virtual bool getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); + inline virtual GHOST_TGrabCursorMode getCursorGrabMode() const; + inline virtual void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline virtual void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); /** * Shows or hides the cursor. @@ -175,7 +174,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore); + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode); /** * Sets the window "modified" status, indicating unsaved changes @@ -247,7 +246,7 @@ protected: * Sets the cursor grab on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; }; /** * Sets the cursor shape on the window using @@ -274,16 +273,13 @@ protected: bool m_cursorVisible; /** The current grabbed state of the cursor */ - bool m_cursorGrabbed; - - /** The current warped state of the cursor */ - bool m_cursorWarp; + GHOST_TGrabCursorMode m_cursorGrab; /** Initial grab location. */ - GHOST_TInt32 m_cursorWarpInitPos[2]; + GHOST_TInt32 m_cursorGrabInitPos[2]; - /** Accumulated offset from m_cursorWarpInitPos. */ - GHOST_TInt32 m_cursorWarpAccumPos[2]; + /** Accumulated offset from m_cursorGrabInitPos. */ + GHOST_TInt32 m_cursorGrabAccumPos[2]; /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; @@ -317,40 +313,21 @@ inline bool GHOST_Window::getCursorVisibility() const return m_cursorVisible; } -inline bool GHOST_Window::getCursorWarp() const -{ - return m_cursorWarp; -} - -inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const { - if(m_cursorWarp==false) - return GHOST_kFailure; - - x= m_cursorWarpInitPos[0]; - y= m_cursorWarpInitPos[1]; - return GHOST_kSuccess; + return m_cursorGrab; } -inline bool GHOST_Window::getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - if(m_cursorWarp==false) - return GHOST_kFailure; - - x= m_cursorWarpAccumPos[0]; - y= m_cursorWarpAccumPos[1]; - return GHOST_kSuccess; + x= m_cursorGrabAccumPos[0]; + y= m_cursorGrabAccumPos[1]; } -inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y) +inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y) { - if(m_cursorWarp==false) - return GHOST_kFailure; - - m_cursorWarpAccumPos[0]= x; - m_cursorWarpAccumPos[1]= y; - - return GHOST_kSuccess; + m_cursorGrabAccumPos[0]= x; + m_cursorGrabAccumPos[1]= y; } inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index d6c154535a9..e5fff75c66e 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -239,7 +239,7 @@ protected: /** * Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero */ - inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); + inline virtual bool setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); /** * Sets the cursor grab on the window using diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index d197b534352..9914bad23c8 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1400,47 +1400,27 @@ setWindowCursorVisibility( GHOST_TSuccess GHOST_WindowX11:: setWindowCursorGrab( - bool grab, bool warp, bool restore + GHOST_TGrabCursorMode mode ){ - if(grab) { - if(warp) { - m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + if(mode != GHOST_kGrabDisable) { + if(mode != GHOST_kGrabNormal) { + m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setCursorGrabAccum(0, 0); + + if(mode == GHOST_kGrabHide) + setWindowCursorVisibility(false); - setCursorWarpAccum(0, 0); - setWindowCursorVisibility(false); - m_cursorWarp= true; } XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } else { - if(m_cursorWarp) { /* are we exiting warp */ + if (m_cursorGrab==GHOST_kGrabHide) { + m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setWindowCursorVisibility(true); - /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - if(restore) { - GHOST_Rect bounds; - GHOST_TInt32 x_new, y_new, x_rel, y_rel; - - getClientBounds(bounds); - - x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0]; - y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1]; - - screenToClient(x_new, y_new, x_rel, y_rel); - - if(x_rel < 0) x_new = (x_new-x_rel) + 2; - if(y_rel < 0) y_new = (y_new-y_rel) + 2; - if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2; - if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2; - m_system->setCursorPosition(x_new, y_new); - - } - else { - m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); - } - - setCursorWarpAccum(0, 0); - m_cursorWarp= false; } + + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); XUngrabPointer(m_display, CurrentTime); } diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index eb0689ab410..0dba1776553 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -256,9 +256,12 @@ protected: */ GHOST_TSuccess setWindowCursorGrab( - bool grab, bool warp, bool restore + GHOST_TGrabCursorMode mode ); + GHOST_TGrabCursorMode + getWindowCursorGrab() const; + /** * Sets the cursor shape on the window using * native window system calls. |