2.5
authorTon Roosendaal <ton@blender.org>
Mon, 2 Feb 2009 14:13:14 +0000 (14:13 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 2 Feb 2009 14:13:14 +0000 (14:13 +0000)
Sanitized the 'tweak' event.

Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.

Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:

- if Left/Middle/Rightmouse pressed
    if event wasn't handled by window queue (modal handlers)
       start checking mousepositions

- while mousepositions are checked
   - escape on any event other than mouse
   - on mouse events:
     - add tweak event if mousemove > 10 pixels
     - stop checking for tweak if mousebutton released

- Tweak events have a define indicating mousebutton used
  EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R

- In keymap definitions you can use _S or _A to map to
  action or select mouse userdef.

- Event value in keymap should be KM_ANY for all tweaks,
  or use one of the eight directions:
  EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE

- And of course you can add modifier checks in keymaps for it.

- Because tweaks are a result of mouse events, the handlers get
  both to evaluate. That means that RMB-select + tweak will work
  correctly.
  In case you don't want both to be handled, for example the
  CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
  need to set the first acting on a EVT_RELEASE, this event only
  gets passed on when tweak fails.

The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)

Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.

17 files changed:
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/space_action/action_ops.c
source/blender/editors/space_ipo/ipo_ops.c
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_sequencer/sequencer_ops.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/wm.h

index f53b6dad1736812701073b49c6a368946e5ec958..5dab59daef1c41ed2deb21c32fab31a9b65111f4 100644 (file)
@@ -3945,11 +3945,13 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
                win->ghostwin= NULL;
                win->eventstate= NULL;
                win->curswin= NULL;
-               
+               win->tweak= NULL;
+
                win->timers.first= win->timers.last= NULL;
                win->queue.first= win->queue.last= NULL;
                win->handlers.first= win->handlers.last= NULL;
                win->subwindows.first= win->subwindows.last= NULL;
+               win->gesture.first= win->gesture.last= NULL;
 
                win->drawdata= NULL;
                win->drawmethod= -1;
index 34d27675084635617e2ba89a7356f82a4756b8df..7817afc929c0d21aaefd89f4727813d4f0170e3d 100644 (file)
@@ -889,7 +889,4 @@ void ED_marker_keymap(wmWindowManager *wm)
        
        WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
        
-       /* generates event, needs to be after select to work */
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-       
 }
index 6d445245ae8be543925371619aa357acc248f5e5..bd708fde9e8770174bf8c17e69ec79abe920fbf7 100644 (file)
@@ -247,10 +247,9 @@ int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, s
        }
        else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
 
-       if(em_vertoffs==0) return 0;
-       
        buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
        if(buf==NULL) return 0;
+       if(em_vertoffs==0) return 0;
 
        dr = buf->rect;
 
@@ -260,6 +259,7 @@ int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, s
        glColor3ub(0, 0, 0);
        
        /* yah, opengl doesn't do concave... tsk! */
+       ED_region_pixelspace(vc->ar);
        draw_triangulated(mcords, tot); 
        
        glBegin(GL_LINE_LOOP);  /* for zero sized masks, lines */
@@ -301,11 +301,11 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
                else return 0;
        }
        else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
-       if(em_vertoffs==0) return 0;
        
        xmin= xs-rads; xmax= xs+rads;
        ymin= ys-rads; ymax= ys+rads;
        buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+       if(em_vertoffs==0) return 0;
        if(buf==NULL) return 0;
 
        dr = buf->rect;
index 07a73b0b401477f21c651dbf63994f6e34400967..47a98a457c69c7d472c020a6f9d0c21b4993b981 100644 (file)
@@ -206,9 +206,6 @@ void ED_keymap_mesh(wmWindowManager *wm)
        
        WM_keymap_add_item(keymap, "MESH_OT_selection_type", TABKEY, KM_PRESS, KM_CTRL, 0);
        
-       
-       /* transform keymap already defined, so no tweaks for select */
-       
        /* hide */
        WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "invert", 1);
@@ -236,7 +233,8 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+                                               /* use KM_RELEASE because same key is used for tweaks */
+       WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0);
        
        WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
        
index acea4848a2af5f6f8d3f087118a9de0dc0b1c758..a07e38c43619ef6539a87c8d03286bb815bce13a 100644 (file)
@@ -139,9 +139,6 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
        WM_keymap_add_item(keymap, "ACT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
        WM_keymap_add_item(keymap, "ACT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
        
-       /* generates event, needs to be after select to work */
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-               
        /* transform system */
        transform_keymap_for_space(wm, keymap, SPACE_ACTION);
 }
index 4f62569f0215f849162d35475f93dc555e6ec6b6..a829a8630ea34db02fe694631c265e1dc9a4e189 100644 (file)
@@ -186,9 +186,6 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
        //WM_keymap_add_item(keymap, "GRAPHEDIT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
        //WM_keymap_add_item(keymap, "GRAPHEDIT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
        
-       /* generates event, needs to be after select to work */
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-
        /* transform system */
        transform_keymap_for_space(wm, keymap, SPACE_IPO);
 }
index 2bcb1a0eb7649e89215ed52bf53b192426fcdabb..09a5d12bd3485ffc5f251bf567fe7dea7e33f38c 100644 (file)
@@ -73,9 +73,5 @@ void node_keymap(struct wmWindowManager *wm)
        WM_keymap_add_item(keymap, "NODE_OT_border_select", BKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "NODE_OT_delete_selection", XKEY, KM_PRESS, 0, 0);
        
-       /* generates event, needs to be after select to work */
-       WM_keymap_tweak(keymap, ACTIONMOUSE, KM_PRESS, 0, 0);
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-       
        transform_keymap_for_space(wm, keymap, SPACE_NODE);
 }
index 08d0c56c2608751d3d2ca0e1dc269c491272ac3d..f17efe19a21f947b5612b2a6b432a8b7ef51bf27 100644 (file)
@@ -155,8 +155,6 @@ void sequencer_keymap(wmWindowManager *wm)
        
        WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
 
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-
        transform_keymap_for_space(wm, keymap, SPACE_SEQ);
 }
 
index 65d668733b659f389535b8b16b44619e34eb308e..fe550724cc864abd81d87ec1856e8801979f48fd 100644 (file)
@@ -183,10 +183,5 @@ void view3d_keymap(wmWindowManager *wm)
 
        transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
 
-       /* generates event, in end to make select work */
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-       /* tweak event for border, lasso, etc */
-       WM_keymap_tweak(keymap, ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
-
 }
 
index 139668fe3a4db86e98a6deeeef60c1d39d644db1..9a94ca8624c86a1bacd3cecfd3ec799c3324c047 100644 (file)
@@ -703,6 +703,8 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
        RNA_END;
        
        if(i>1) {
+               view3d_operator_needs_opengl(C);
+               
                /* setup view context for argument to callbacks */
                view3d_set_viewcontext(C, &vc);
                
@@ -1754,6 +1756,8 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
                ViewContext vc;
                short mval[2], selecting;
                
+               view3d_operator_needs_opengl(C);
+               
                view3d_set_viewcontext(C, &vc);
                mval[0]= x;
                mval[1]= y;
index 4f943a62065b2fd2f025b6397436cb31aacd28ff..71e64886e34af8295a212a9ac2383874b17ea5f6 100644 (file)
@@ -2568,9 +2568,6 @@ void ED_keymap_uvedit(wmWindowManager *wm)
        // XXX not working?
        RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, KM_ALT)->ptr, "extend", 1);
 
-       /* generates event, needs to be after select to work */
-       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
-
        WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "UV_OT_unlink_selection", LKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "UV_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
index 670cc9e3b755f98c0fe6d4ae981e3fa129c660bb..822f081f9a8d416567d8658ae27780685512db20 100644 (file)
@@ -38,6 +38,7 @@ struct wmWindowManager;
 struct wmWindow;
 
 struct wmEvent;
+struct wmGesture;
 struct wmOperatorType;
 struct wmOperator;
 
@@ -102,6 +103,8 @@ typedef struct wmWindow {
        
        struct wmSubWindow *curswin;    /* internal for wm_subwindow.c only */
 
+       struct wmGesture *tweak;        /* internal for wm_operators.c */
+       
        int drawmethod, drawfail;       /* internal for wm_draw.c only */
        void *drawdata;                         /* internal for wm_draw.c only */
        
@@ -168,7 +171,7 @@ typedef struct wmKeymapItem {
        short shift, ctrl, alt, oskey;  /* oskey is apple or windowskey, value denotes order of pressed */
        short keymodifier;                              /* rawkey modifier */
        
-       short is_tweak;                                 /* internal only, to handle tweak failure events properly */
+       short pad;
 } wmKeymapItem;
 
 #define KMAP_MAX_NAME  64
index 6f5ad0a80b9ff09867ed97f156259e4a2db4a861..7554d25e77022d5a2d7f725a44eb7dcf5fe82483 100644 (file)
@@ -68,7 +68,7 @@ typedef struct wmEvent {
        short prevx, prevy;     /* previous mouse pointer position */
        short unicode;          /* future, ghost? */
        char ascii;                     /* from ghost */
-       char no_tweak;          /* set on tweak failure, to allow other events to try it */
+       char pad;
        
        /* modifier states */
        short shift, ctrl, alt, oskey;  /* oskey is apple or windowskey, value denotes order of pressed */
@@ -224,6 +224,7 @@ typedef struct wmNotifier {
 #define WM_GESTURE_CIRCLE              5
 
 /* wmGesture is registered to window listbase, handled by operator callbacks */
+/* tweak gesture is builtin feature */
 typedef struct wmGesture {
        struct wmGesture *next, *prev;
        int event_type; /* event->type */
index d8c1e8a58889bdcf43806cc10e4eba8b68a19b9e..6bcca9e2acfd9d39869902a77404efc6fa6976b2 100644 (file)
@@ -542,19 +542,6 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
        if(kmi->keymodifier)
                if(winevent->keymodifier!=kmi->keymodifier) return 0;
        
-       /* happens on tweak failure */
-       /* weak code, testing only now! (ton) */
-       if(kmi->is_tweak) {
-               /* only after tweak keymap we allow the hack */
-               if(winevent->no_tweak) {
-                       winevent->no_tweak= 2;
-                       return 0;
-               }
-       }
-       
-       if(winevent->no_tweak==1)
-               return 0;
-       
        return 1;
 }
 
@@ -850,15 +837,23 @@ void wm_event_do_handlers(bContext *C)
                                return;
                        }
                        
+                       /* builtin tweak, if action is break it removes tweak */
+                       if(!wm_event_always_pass(event))
+                               wm_tweakevent_test(C, event, action);
+                       
                        if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
                                ScrArea *sa;
                                ARegion *ar;
                                int doit= 0;
                                
                                /* XXX to solve, here screen handlers? */
-                               if(event->type==MOUSEMOVE) {
-                                       ED_screen_set_subwinactive(win, event); /* state variables in screen, cursors */
-                                       wm_paintcursor_test(C, event);
+                               if(!wm_event_always_pass(event)) {
+                                       if(event->type==MOUSEMOVE) {
+                                               /* state variables in screen, cursors */
+                                               ED_screen_set_subwinactive(win, event); 
+                                               /* for regions having custom cursors */
+                                               wm_paintcursor_test(C, event);
+                                       }
                                }
                                
                                for(sa= win->screen->areabase.first; sa; sa= sa->next) {
index 22189b1707ccfb5d37a29e200b680a4ad095394d..7528321c7c5baeb05dace1037969cfe7254cdbe0 100644 (file)
@@ -125,15 +125,6 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v
        return kmi;
 }
 
-/* enables tweak for mouse/modifier combo
-   on tweak fail, it passes on event with 'val=1', so other keymap items can test */
-void WM_keymap_tweak(ListBase *lb, short type, short val, int modifier, short keymodifier)
-{
-       wmKeymapItem *km= WM_keymap_add_item(lb, "WM_OT_tweak_gesture", type, val, modifier, keymodifier);
-       km->is_tweak= 1;
-}
-
-
 /* ****************** storage in WM ************ */
 
 /* name id's are for storing general or multiple keymaps, 
index 707cd5f2254b1e0407ac409663b927355cd8adec..098443d481ad05cbfce9c00036f26cf0c867e534 100644 (file)
@@ -729,22 +729,10 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
 
 /* **************** Tweak gesture *************** */
 
-static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
-       
-       /* add modal handler */
-       WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       return OPERATOR_RUNNING_MODAL;
-}
-
-static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+static void tweak_gesture_modal(bContext *C, wmEvent *event)
 {
        wmWindow *window= CTX_wm_window(C);
-       wmGesture *gesture= op->customdata;
+       wmGesture *gesture= window->tweak;
        rcti *rect= gesture->customdata;
        int sx, sy, val;
        
@@ -758,7 +746,7 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
                        
                        if((val= wm_gesture_evaluate(C, gesture))) {
                                wmEvent event;
-                                       
+
                                event= *(window->eventstate);
                                if(gesture->event_type==LEFTMOUSE)
                                        event.type= EVT_TWEAK_L;
@@ -770,11 +758,9 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
                                /* mouse coords! */
                                wm_event_add(window, &event);
                                
-                               wm_gesture_end(C, op);
-                               return OPERATOR_FINISHED;
+                               WM_gesture_end(C, gesture);     /* frees gesture itself, and unregisters from window */
+                               window->tweak= NULL;
                        }
-                       else
-                               wm_gesture_tag_redraw(C);
                        
                        break;
                        
@@ -782,29 +768,43 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
                case RIGHTMOUSE:
                case MIDDLEMOUSE:
                        if(gesture->event_type==event->type) {
-                               wm_gesture_end(C, op);
+                               WM_gesture_end(C, gesture);
+                               window->tweak= NULL;
                                
                                /* when tweak fails we should give the other keymap entries a chance
                                 * those then won't react to km_press, but km_release
                                 * it sets hidden event value where tweak maps fail on, to prevent loops */
-                               event->val= 1;
-                               event->no_tweak= 1;
-                               return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+                               //event->val= 1;
+                               //event->no_tweak= 1;
                        }
                        break;
+               default:
+                       WM_gesture_end(C, gesture);
+                       window->tweak= NULL;
        }
-       return OPERATOR_RUNNING_MODAL;
 }
 
-void WM_OT_tweak_gesture(wmOperatorType *ot)
+/* standard tweak, called after window handlers passed on event */
+void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
 {
-       ot->name= "Tweak Gesture";
-       ot->idname= "WM_OT_tweak_gesture";
+       wmWindow *win= CTX_wm_window(C);
        
-       ot->invoke= tweak_gesture_invoke;
-       ot->modal= tweak_gesture_modal;
-
-       ot->poll= WM_operator_winactive;
+       if(win->tweak==NULL) {
+               if(CTX_wm_region(C)) {
+                       if(event->val) { // pressed
+                               if( ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) )
+                                       win->tweak= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
+                       }
+               }
+       }
+       else {
+               if(action==WM_HANDLER_BREAK) {
+                       WM_gesture_end(C, win->tweak);
+                       win->tweak= NULL;
+               }
+               else
+                       tweak_gesture_modal(C, event);
+       }
 }
 
 /* *********************** lasso gesture ****************** */
@@ -1171,7 +1171,6 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_save_homefile);
        WM_operatortype_append(WM_OT_window_fullscreen_toggle);
        WM_operatortype_append(WM_OT_exit_blender);
-       WM_operatortype_append(WM_OT_tweak_gesture);
        WM_operatortype_append(WM_OT_open_recentfile);
        WM_operatortype_append(WM_OT_open_mainfile);
        WM_operatortype_append(WM_OT_jobs_timer);
index 556a3fadcfb34a3f6737c3c7efeb0404f2c0ff5d..fd5cbe3ff4f680ceee0f49e8ce67725221795eec 100644 (file)
@@ -55,6 +55,8 @@ void wm_operatortype_free(void);
 void wm_operatortype_init(void);
 void wm_window_keymap(wmWindowManager *wm);
 
+void wm_tweakevent_test(bContext *C, wmEvent *event, int action);
+
 /* wm_gesture.c */
 #define WM_LASSO_MAX_POINTS            1024
 void wm_gesture_draw(struct wmWindow *win);