wrap the mouse within the region while grabbing so on release the current view never...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 17 Oct 2009 19:32:28 +0000 (19:32 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 17 Oct 2009 19:32:28 +0000 (19:32 +0000)
14 files changed:
intern/ghost/GHOST_C-api.h
intern/ghost/GHOST_IWindow.h
intern/ghost/intern/GHOST_C-api.cpp
intern/ghost/intern/GHOST_SystemX11.cpp
intern/ghost/intern/GHOST_Window.cpp
intern/ghost/intern/GHOST_Window.h
intern/ghost/intern/GHOST_WindowX11.cpp
source/blender/editors/animation/anim_filter.c
source/blender/editors/interface/interface_handlers.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/intern/rna_wm.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_cursors.c
source/blender/windowmanager/intern/wm_event_system.c

index 93bd12437ab80521d405bb8c731d51c65003a4ac..bd812177f17d6633a028dc3b21fc36c1e59d6c94 100644 (file)
@@ -372,11 +372,13 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
  * events when the mouse is outside the window. X11 only, others
  * do this automatically.
  * @param windowhandle The handle to the window
- * @param      grab The new grab state of the cursor.
+ * @param      mode The new grab state of the cursor.
+ * @param      bounds The grab ragion (optional) - left,top,right,bottom
  * @return     Indication of success.
  */
 extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
-                                                                                               GHOST_TGrabCursorMode mode);
+                                                                                               GHOST_TGrabCursorMode mode,
+                                                                                               int* bounds);
 
 /***************************************************************************************
  ** Access to mouse button and keyboard states.
index 3ab9bef2bfa20f49d28522efcc935d0485a15835..512fad877cb1d2cc6a3842537cddcf70236d9f95 100644 (file)
@@ -271,7 +271,7 @@ public:
         * @param       grab The new grab state of the cursor.
         * @return      Indication of success.
         */
-       virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; };
+       virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; };
 
 };
 
index 5563e0d1aa8a9100286519c0139db61256774699..0160df552cc10df5f04bf3b841ab383bc2a5d057 100644 (file)
@@ -355,11 +355,21 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
 
 
 GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
-                                                                               GHOST_TGrabCursorMode mode)
+                                                                               GHOST_TGrabCursorMode mode,
+                                                                               int *bounds)
 {
        GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+       GHOST_Rect bounds_rect, bounds_win;
+
+       if(bounds) {
+               /* if this is X11 specific we need a function that converts */
+               window->getClientBounds(bounds_win);
+               window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t);
+               window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b);
+
+       }
        
-       return window->setCursorGrab(mode);
+       return window->setCursorGrab(mode, bounds ? &bounds_rect:NULL);
 }
 
 
index 122e6c55241de5a03c51846ee4e6c9654aa3bd68..774fd025b854ef25f35db3ac25fb1c65d90a8110 100644 (file)
@@ -395,7 +395,9 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                                GHOST_TInt32 x_accum, y_accum;
                                GHOST_Rect bounds;
 
-                               window->getClientBounds(bounds);
+                               /* fallback to window bounds */
+                               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  */
index cda6bfa06eed8ab0563c89539c1da9ba1c5a3b3d..33484284d7c64d1314fa2b62074b2b90566ba3c9 100644 (file)
@@ -97,12 +97,18 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
        }
 }
 
-GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode)
+GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds)
 {
        if(m_cursorGrab == mode)
                return GHOST_kSuccess;
 
        if (setWindowCursorGrab(mode)) {
+
+               if(mode==GHOST_kGrabDisable)
+                       m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1;
+               else if (bounds) {
+                       m_cursorGrabBounds= *bounds;
+               }
                m_cursorGrab = mode;
                return GHOST_kSuccess;
        }
@@ -111,6 +117,12 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode)
        }
 }
 
+GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds)
+{
+       bounds= m_cursorGrabBounds;
+       return (bounds.m_l==-1 && bounds.m_r==-1) ? GHOST_kFailure : GHOST_kSuccess;
+}
+
 GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
 {
        if (setWindowCursorShape(cursorShape)) {
index e66a3c2fd36c90e0cbf17ecac2cd1fd3fce87742..0986fc5743058b6b64ad755c6fa2fb5d473ddf5d 100644 (file)
@@ -171,10 +171,16 @@ public:
 
        /**
         * Sets the cursor grab.
-        * @param       grab The new grab state of the cursor.
+        * @param       mode The new grab state of the cursor.
         * @return      Indication of success.
         */
-       virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode);
+       virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds);
+
+       /**
+        * Gets the cursor grab region, if unset the window is used.
+        * reset when grab is disabled.
+        */
+       virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
 
        /**
         * Sets the window "modified" status, indicating unsaved changes
@@ -281,6 +287,9 @@ protected:
        /** Accumulated offset from m_cursorGrabInitPos. */
        GHOST_TInt32 m_cursorGrabAccumPos[2];
 
+       /** Wrap the cursor within this region. */
+       GHOST_Rect m_cursorGrabBounds;
+
        /** The current shape of the cursor */
        GHOST_TStandardCursor m_cursorShape;
     
index 9914bad23c8039e96ed86cc03c55bdc39d9fc8df..dba1be1b86275b8521e73bfcfc236e3557f74794 100644 (file)
@@ -1421,6 +1421,7 @@ setWindowCursorGrab(
 
                /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
                setCursorGrabAccum(0, 0);
+               m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
                XUngrabPointer(m_display, CurrentTime);
        }
 
index aa1bc108176ec504215387a3187c292fb4a3c218..96bdb9aa848309111f1db80cc3c110e5682734d4 100644 (file)
@@ -78,6 +78,7 @@
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
+#include "BKE_fcurve.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_key.h"
@@ -669,7 +670,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
                                                 * then free the MEM_alloc'd string
                                                 */
                                                if (rna_path) {
-                                                       ale->key_data= list_find_fcurve(&act->curves, rna_path, 0);
+                                                       ale->key_data= (void *)list_find_fcurve(&act->curves, rna_path, 0);
                                                        MEM_freeN(rna_path);
                                                }
                                        }
index 018098b539bf0178609d124c5b4f11eabb5c452a..29d840765330a4804ee83b3479dc416229bb0872 100644 (file)
@@ -3750,7 +3750,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
        /* number editing */
        if(state == BUTTON_STATE_NUM_EDITING) {
                if(ui_is_a_warp_but(but))
-                       WM_cursor_grab(CTX_wm_window(C), TRUE, TRUE);
+                       WM_cursor_grab(CTX_wm_window(C), TRUE, TRUE, NULL);
                ui_numedit_begin(but, data);
        } else if(data->state == BUTTON_STATE_NUM_EDITING) {
                ui_numedit_end(but, data);
index 722b686218b0cb5c11e2bbae5c967d3c9755e523..1acf3c8effa81eec1aab323dd21fff4c75c30b94 100644 (file)
@@ -52,6 +52,7 @@ static void rna_userdef_update(bContext *C, PointerRNA *ptr)
        WM_event_add_notifier(C, NC_WINDOW, NULL);
 }
 
+#if 0
 static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value)
 {
        UserDef *userdef = (UserDef*)ptr->data;
@@ -64,7 +65,6 @@ static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value)
                userdef->flag &= ~USER_LMOUSESELECT;
 }
 
-#if 0
 static void rna_userdef_rmb_select_set(PointerRNA *ptr,int value)
 {
        rna_userdef_lmb_select_set(ptr, !value);
index 82b244fa7025ad94727e9557919815ca477cf200..2189412783ac203399f11ae67201ece6f815147d 100644 (file)
@@ -680,8 +680,9 @@ static void rna_def_windowmanager(BlenderRNA *brna)
 static void rna_def_keyconfig(BlenderRNA *brna)
 {
        StructRNA *srna;
-       FunctionRNA *func;
-       PropertyRNA *prop, *parm;
+       // FunctionRNA *func;
+       // PropertyRNA *parm;
+       PropertyRNA *prop;
 
        static EnumPropertyItem map_type_items[] = {
                {KMI_TYPE_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""},
index d90d812d0bb5fb5c8ec85b490e13b063f2c9a7b2..59f3bcd4edcab16ae2b5d984fea74be9bf1ee692 100644 (file)
@@ -76,7 +76,7 @@ void          WM_cursor_set           (struct wmWindow *win, int curs);
 void           WM_cursor_modal         (struct wmWindow *win, int curs);
 void           WM_cursor_restore       (struct wmWindow *win);
 void           WM_cursor_wait          (int val);
-void           WM_cursor_grab(struct wmWindow *win, int wrap, int hide);
+void           WM_cursor_grab(struct wmWindow *win, int wrap, int hide, int *bounds);
 void           WM_cursor_ungrab(struct wmWindow *win);
 void           WM_timecursor           (struct wmWindow *win, int nr);
 
index 1d5b10f2583c0c08658d68fff2f6e706737b0aee..5fe62157979f51b4746114229f44b8b0d4e48972 100644 (file)
@@ -163,26 +163,27 @@ void WM_cursor_wait(int val)
        }
 }
 
-void WM_cursor_grab(wmWindow *win, int wrap, int hide)
+void WM_cursor_grab(wmWindow *win, int wrap, int hide, int *bounds)
 {
        /* Only grab cursor when not running debug.
         * It helps not to get a stuck WM when hitting a breakpoint  
         * */
        GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
+       int bounds_arr[4] = {-1, -1, -1, -1}; /* l/t/r/b */
 
        if(hide)                mode = GHOST_kGrabHide;
        else if(wrap)   mode = GHOST_kGrabWrap;
 
        if ((G.f & G_DEBUG) == 0)
                if(win)
-                       GHOST_SetCursorGrab(win->ghostwin, mode);
+                       GHOST_SetCursorGrab(win->ghostwin, mode, bounds);
 }
 
 void WM_cursor_ungrab(wmWindow *win)
 {
        if ((G.f & G_DEBUG) == 0)
                if(win)
-                       GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable);
+                       GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL);
 }
 
 /* afer this you can call restore too */
index 9e5f982880e011f490fa2575e7f42ff07187d799..8eca0a1b416ba5ac93c586d0a9e7ad726e3fbcc0 100644 (file)
@@ -463,8 +463,20 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
                else if(retval & OPERATOR_RUNNING_MODAL) {
                        /* grab cursor during blocking modal ops (X11) */
                        if(ot->flag & OPTYPE_BLOCKING) {
-                               int warp = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER));
-                               WM_cursor_grab(CTX_wm_window(C), warp, FALSE);
+                               int bounds[4] = {-1,-1,-1,-1};
+                               int wrap = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER));
+
+                               if(wrap) {
+                                       ARegion *ar= CTX_wm_region(C);
+                                       if(ar) {
+                                               bounds[0]= ar->winrct.xmin;
+                                               bounds[1]= ar->winrct.ymax;
+                                               bounds[2]= ar->winrct.xmax;
+                                               bounds[3]= ar->winrct.ymin;
+                                       }
+                               }
+
+                               WM_cursor_grab(CTX_wm_window(C), wrap, FALSE, bounds);
                        }
                }
                else