diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-10-07 11:11:10 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-10-07 11:11:10 +0400 |
commit | 77476b294f8a7a74ee6f19ff8bfcbb3fb26e3bda (patch) | |
tree | d96b292248acdac14880309c1b3fa8976853b596 /intern | |
parent | 828395744ae9c70d3f69c923cd761aaf2f45abb9 (diff) |
Experimental option to allow moving the mouse outside the view, "Continuous Grab" in the user-prefs.
- Useful for dragging buttons to the far right when theyd otherwise hit the screen edge.
- Useful for transform though probably NOT what you want when using the transform manipulator (should make an option).
- When enabled, number buttons use this as well as a different conversion of mouse movement
float numbuts: mouse 1px == 1-clickstep
int numbuts: 2px == 1 (tried 1:1 but its too jitter prone)
details...
- access as an option to GHOST_SetCursorGrab(grab, warp)
- Currently all operators that grab use this, could be made an operator flag
- only Ghost/X11 supported currently
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/intern/GHOST_C-api.cpp | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 48 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.cpp | 12 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.h | 53 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 23 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.h | 3 |
8 files changed, 123 insertions, 24 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 9460fb504a9..35391d3f4cf 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 grab, int warp); /*************************************************************************************** ** Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index ff1484909b0..44ddf9a7cfb 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) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; }; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index d14945d1bf8..b86c4703ea2 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 grab, int warp) { GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; - return window->setCursorGrab(grab?true:false); + return window->setCursorGrab(grab?true:false, warp?true:false); } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index cdbdce9c2ca..8c87abf16bc 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -374,12 +374,12 @@ GHOST_SystemX11::processEvent(XEvent *xe) // Only generate a single expose event // per read of the event queue. - g_event = new + g_event = new GHOST_Event( getMilliSeconds(), GHOST_kEventWindowUpdate, window - ); + ); } break; } @@ -388,14 +388,42 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XMotionEvent &xme = xe->xmotion; - g_event = new - GHOST_EventCursor( - getMilliSeconds(), - GHOST_kEventCursorMove, - window, - xme.x_root, - xme.y_root - ); + 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 + ); + + } + } + else { + g_event = new + GHOST_EventCursor( + getMilliSeconds(), + GHOST_kEventCursorMove, + window, + xme.x_root, + xme.y_root + ); + } break; } diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 34e9f519a07..531674607d1 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -48,12 +48,16 @@ GHOST_Window::GHOST_Window( : m_drawingContextType(type), m_cursorVisible(true), - m_cursorGrabbed(true), + m_cursorGrabbed(false), + m_cursorWarp(false), m_cursorShape(GHOST_kStandardCursorDefault), m_stereoVisual(stereoVisual) { m_isUnsavedChanges = false; + m_cursorWarpAccumPos[0] = 0; + m_cursorWarpAccumPos[1] = 0; + m_fullScreen = state == GHOST_kWindowStateFullScreen; if (m_fullScreen) { m_fullScreenWidth = width; @@ -94,12 +98,12 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab) +GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp) { if(m_cursorGrabbed == grab) return GHOST_kSuccess; - if (setWindowCursorGrab(grab)) { + if (setWindowCursorGrab(grab, warp)) { m_cursorGrabbed = grab; return GHOST_kSuccess; } @@ -150,4 +154,4 @@ GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges) bool GHOST_Window::getModifiedState() { return m_isUnsavedChanges; -}
\ No newline at end of file +} diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index a2d1675f6ab..36e4bac6dae 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -158,6 +158,10 @@ 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); /** * Shows or hides the cursor. @@ -171,7 +175,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab); + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp); /** * Sets the window "modified" status, indicating unsaved changes @@ -243,7 +247,7 @@ protected: * Sets the cursor grab on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; /** * Sets the cursor shape on the window using @@ -272,6 +276,15 @@ protected: /** The current grabbed state of the cursor */ bool m_cursorGrabbed; + /** The current warped state of the cursor */ + bool m_cursorWarp; + + /** Initial grab location. */ + GHOST_TInt32 m_cursorWarpInitPos[2]; + + /** Accumulated offset from m_cursorWarpInitPos. */ + GHOST_TInt32 m_cursorWarpAccumPos[2]; + /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; @@ -304,6 +317,42 @@ 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 +{ + if(m_cursorWarp==false) + return GHOST_kFailure; + + x= m_cursorWarpInitPos[0]; + y= m_cursorWarpInitPos[1]; + return GHOST_kSuccess; +} + +inline bool GHOST_Window::getCursorWarpAccum(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; +} + +inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y) +{ + if(m_cursorWarp==false) + return GHOST_kFailure; + + m_cursorWarpAccumPos[0]= x; + m_cursorWarpAccumPos[1]= y; + + return GHOST_kSuccess; +} + inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const { return m_cursorShape; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 060e9ca6f6c..c2dc1048ea0 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1400,12 +1400,29 @@ setWindowCursorVisibility( GHOST_TSuccess GHOST_WindowX11:: setWindowCursorGrab( - bool grab + bool grab, bool warp ){ - if(grab) + if(grab) { + if(warp) { + m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + + setCursorWarpAccum(0, 0); + setWindowCursorVisibility(false); + m_cursorWarp= true; + } XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - else + } + else { + if(m_cursorWarp) { /* are we exiting warp */ + setWindowCursorVisibility(true); + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + + setCursorWarpAccum(0, 0); + m_cursorWarp= false; + } XUngrabPointer(m_display, CurrentTime); + } XFlush(m_display); diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 6f8940bdcbb..08fba3e2be8 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -252,10 +252,11 @@ protected: /** * Sets the cursor grab on the window using * native window system calls. + * @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen. */ GHOST_TSuccess setWindowCursorGrab( - bool grab + bool grab, bool warp ); /** |