2.5
authorTon Roosendaal <ton@blender.org>
Fri, 30 Jan 2009 18:18:41 +0000 (18:18 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 30 Jan 2009 18:18:41 +0000 (18:18 +0000)
- Edit mesh: Add ctrl+click add vertex or extrude.
  I've made it not move the 3d cursor in that case.

Also found out tweak events conflicted with existing
keymap definitions; on tweak failure (= no mousemove)
it now passes on the mouse event as 'mouse down' for
the remaining keymaps to check.
These then actually respond to mouse-up instead of down...

The location in the keymaps where tweaks get generated
remains important. Examples:

1 - 'select' mouse-handler, operator return pass-through
2 - tweak handler checks, and makes tweak event
3 - grabber responds to tweak event

1 - ctrl+mouse tweak handler checks, makes tweak event,
    or passes event on
2 - if tweak event, it runs lasso
3 - else when passed on, ctrl+click extrude happens

In the first case, select works on mouse-down, immediate.
In the second case, extrude happens on mouse-release, even
though the keymap defined mouse-press.

This will make designing nice balanced keymaps still not
simple; especially because you can't tell operators to
pass on the key... although we can add the convention that
select-mouse operators always pass on to enable tweaks.

Still a good reason to wait with custom keymaps
when this is fully settled!

17 files changed:
source/blender/editors/animation/anim_markers.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/mesh/mesh_intern.h
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_api.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

index 723a59e38f25ccdc5264ac43b717e570af1c0364..39ad92fd62e112668d1cfae93eb5f1e89e0a7d97 100644 (file)
@@ -857,10 +857,10 @@ void ED_marker_keymap(wmWindowManager *wm)
        ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
        
        WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
-       WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0);
+       WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
        WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0);
-       WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0);
+       WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect", SELECTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect_extend", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_verify_item(keymap, "MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
        WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
        WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
@@ -868,6 +868,6 @@ 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_verify_item(keymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
        
 }
index 54445f8715043d20116d976b79d766e79768cc85..ef648932eb45c1b6de76a3c8a8146ffcac2f5b14 100644 (file)
@@ -118,6 +118,8 @@ static short icoface[20][3] = {
        {10,9,11}
 };
 
+/* *************** add-click-mesh (extrude) operator ************** */
+
 static void get_view_aligned_coordinate(ViewContext *vc, float *fp, short mval[2])
 {
        float dvec[3];
@@ -136,15 +138,19 @@ static void get_view_aligned_coordinate(ViewContext *vc, float *fp, short mval[2
        }
 }
 
-void add_click_mesh(bContext *C)
+static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
 {
        ViewContext vc;
        EditVert *eve, *v1;
        float min[3], max[3];
        int done= 0;
+       short mval[2];
        
        em_setup_viewcontext(C, &vc);
        
+       mval[0]= event->x - vc.ar->winrct.xmin;
+       mval[1]= event->y - vc.ar->winrct.ymin;
+       
        INIT_MINMAX(min, max);
        
        for(v1= vc.em->verts.first;v1; v1=v1->next) {
@@ -159,7 +165,6 @@ void add_click_mesh(bContext *C)
                EditEdge *eed;
                float vec[3], cent[3], mat[3][3];
                float nor[3]= {0.0, 0.0, 0.0};
-               short mval[2];
                
                /* check for edges that are half selected, use for rotation */
                done= 0;
@@ -220,27 +225,45 @@ void add_click_mesh(bContext *C)
                float mat[3][3],imat[3][3];
                float *curs= give_cursor(vc.scene, vc.v3d);
                
+               VECCOPY(min, curs);
+               get_view_aligned_coordinate(&vc, min, mval);
+               
                eve= addvertlist(vc.em, 0, NULL);
 
                Mat3CpyMat4(mat, vc.obedit->obmat);
                Mat3Inv(imat, mat);
                
-               VECCOPY(eve->co, curs);
-               VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
-
+               VECCOPY(eve->co, min);
                Mat3MulVecfl(imat, eve->co);
+               VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
                
                eve->f= SELECT;
        }
        
        //retopo_do_all();
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); 
+       DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
        
-       BIF_undo_push("Add vertex/edge/face");
-       DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);   
-       
+       return OPERATOR_FINISHED;
+}
 
+void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Duplicate or Extrude at 3D Cursor";
+       ot->idname= "MESH_OT_dupli_extrude_cursor";
+       
+       /* api callbacks */
+       ot->invoke= dupli_extrude_cursor;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
 }
 
+
+/* ********************** */
+
 /* selected faces get hidden edges */
 static void make_fgon(EditMesh *em, int make)
 {
index a6d899e245185024cc44b9f35402025da15529de..44b1bf394461a4e16bc774eb543195a27dfcd662 100644 (file)
@@ -106,6 +106,7 @@ void MESH_OT_add_primitive_grid(struct wmOperatorType *ot);
 void MESH_OT_add_primitive_monkey(struct wmOperatorType *ot);
 void MESH_OT_add_primitive_uv_sphere(struct wmOperatorType *ot);
 void MESH_OT_add_primitive_ico_sphere(struct wmOperatorType *ot);
+void MESH_OT_dupli_extrude_cursor(struct wmOperatorType *ot);
 
 /* ******************* editmesh_lib.c */
 void EM_stats_update(EditMesh *em);
index 892db9e4dbce890b6a814b62b8edeb5c7a03ca58..4d25f0901c8685d79bea01e5234ec54dcd316529 100644 (file)
@@ -138,6 +138,7 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_extrude_mesh);
        WM_operatortype_append(MESH_OT_edit_faces);
        WM_operatortype_append(MESH_OT_separate);
+       WM_operatortype_append(MESH_OT_dupli_extrude_cursor);
        
 }
 
@@ -181,6 +182,7 @@ 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);
        
        
 }
index 87ee41c795adef455185370d9f789a93636dc9f7..acea4848a2af5f6f8d3f087118a9de0dc0b1c758 100644 (file)
@@ -140,7 +140,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
        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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
                
        /* transform system */
        transform_keymap_for_space(wm, keymap, SPACE_ACTION);
index 68ce0997906a53a713d5e8ba8ed229c4909656c3..4f62569f0215f849162d35475f93dc555e6ec6b6 100644 (file)
@@ -187,7 +187,7 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
        //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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
 
        /* transform system */
        transform_keymap_for_space(wm, keymap, SPACE_IPO);
index 55aa53e9821dc3f764cdfbd25f8b5579a447d78a..2bcb1a0eb7649e89215ed52bf53b192426fcdabb 100644 (file)
@@ -74,8 +74,8 @@ void node_keymap(struct wmWindowManager *wm)
        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_add_item(keymap, "WM_OT_tweak_gesture", ACTIONMOUSE, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       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 b97bfeb5ca84333e5b424099c14142e9af416180..2459131f2ee91eba1140866a418a34b2de98cdfb 100644 (file)
@@ -151,7 +151,7 @@ void sequencer_keymap(wmWindowManager *wm)
        
        WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
 
-       WM_keymap_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_tweak(keymap, SELECTMOUSE, KM_PRESS, 0, 0);
 
        transform_keymap_for_space(wm, keymap, SPACE_SEQ);
 }
index 049c65644297476d86295e1dab513a281231a099..81c87260af1c5aa7a52ad56dc702f05a7a6cd48e 100644 (file)
@@ -153,8 +153,8 @@ void view3d_keymap(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
        WM_keymap_add_item(keymap, "VIEW3D_OT_borderselect", BKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
        WM_keymap_add_item(keymap, "VIEW3D_OT_circle_select", CKEY, KM_PRESS, 0, 0);
        
        WM_keymap_add_item(keymap, "VIEW3D_OT_clipping", BKEY, KM_PRESS, KM_ALT, 0);
@@ -182,7 +182,9 @@ void view3d_keymap(wmWindowManager *wm)
        transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
 
        /* generates event, in end to make select work */
-       WM_keymap_verify_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       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 49d941f3d362010396c66fbd4e0bc6aa83c8408f..73ceb5c7fdb6dbfc37b9857e415f8447a430e5a8 100644 (file)
@@ -702,13 +702,16 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
        }
        RNA_END;
        
-       /* setup view context for argument to callbacks */
-       view3d_set_viewcontext(C, &vc);
-       
-       select= RNA_enum_is_equal(op->ptr, "type", "SELECT");
-       view3d_lasso_select(&vc, mcords, i, select);
-       
-       return OPERATOR_FINISHED;
+       if(i>1) {
+               /* setup view context for argument to callbacks */
+               view3d_set_viewcontext(C, &vc);
+               
+               select= RNA_enum_is_equal(op->ptr, "type", "SELECT");
+               view3d_lasso_select(&vc, mcords, i, select);
+               
+               return OPERATOR_FINISHED;
+       }
+       return OPERATOR_PASS_THROUGH;
 }
 
 void VIEW3D_OT_lasso_select(wmOperatorType *ot)
index 24b664daa1336ec92f180365d44153f598d4a85c..4f943a62065b2fd2f025b6397436cb31aacd28ff 100644 (file)
@@ -2569,7 +2569,7 @@ void ED_keymap_uvedit(wmWindowManager *wm)
        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_add_item(keymap, "WM_OT_tweak_gesture", SELECTMOUSE, KM_PRESS, 0, 0);
+       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);
index 5aeaf5d2743534b9572e425f71ddda9f53de02b4..670cc9e3b755f98c0fe6d4ae981e3fa129c660bb 100644 (file)
@@ -168,7 +168,7 @@ typedef struct wmKeymapItem {
        short shift, ctrl, alt, oskey;  /* oskey is apple or windowskey, value denotes order of pressed */
        short keymodifier;                              /* rawkey modifier */
        
-       short pad;
+       short is_tweak;                                 /* internal only, to handle tweak failure events properly */
 } wmKeymapItem;
 
 #define KMAP_MAX_NAME  64
index 940fd762f1005b2ab1c6345ff4faea5a49bb327c..4e04eabe09a51487fe621579c9405bb3aeded7c5 100644 (file)
@@ -71,12 +71,11 @@ void                *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct b
 void           WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
 
                        /* keymap */
-wmKeymapItem *WM_keymap_set_item       (ListBase *lb, char *idname, short type, 
-                                                                short val, int modifier, short keymodifier);
 wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, 
                                                                 short val, int modifier, short keymodifier);
-wmKeymapItem *WM_keymap_add_item       (ListBase *lb, char *idname, short type, 
+wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, 
                                                                 short val, int modifier, short keymodifier);
+wmKeymapItem *WM_keymap_tweak  (ListBase *lb, short type, short val, int modifier, short keymodifier);
 ListBase       *WM_keymap_listbase     (struct wmWindowManager *wm, const char *nameid, 
                                                                 int spaceid, int regionid);
 
index a9c31261aca921b407ef660b2e33d026a6dd4169..2b53121baf22c04e6a08420d9ebe300721fb6ec1 100644 (file)
@@ -61,13 +61,13 @@ enum {
 typedef struct wmEvent {
        struct wmEvent *next, *prev;
        
-       short type;             /* event code itself (short, is also in keymap) */
-       short val;              /* press, release, scrollvalue */
-       short x, y;                             /* mouse pointer position */
-       short prevx, prevy;             /* previous mouse pointer position */
-       short unicode;  /* future, ghost? */
-       char ascii;             /* from ghost */
-       char pad1;              
+       short type;                     /* event code itself (short, is also in keymap) */
+       short val;                      /* press, release, scrollvalue */
+       short x, y;                     /* mouse pointer position */
+       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 */
        
        /* modifier states */
        short shift, ctrl, alt, oskey;  /* oskey is apple or windowskey, value denotes order of pressed */
index 81efe5f8860e11c70eaad7a4cbfedd19d5136b8d..7df47ce346249bd9d0f1b000a2e80cfdebf2b573 100644 (file)
@@ -515,6 +515,9 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
        if(kmi->keymodifier)
                if(winevent->keymodifier!=kmi->keymodifier) return 0;
        
+       /* happens on tweak failure */
+       if(kmi->is_tweak)
+               if(winevent->no_tweak) return 0;
        
        return 1;
 }
@@ -545,7 +548,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                        
                        retval= ot->modal(C, op, event);
 
-                       /* putting back screen context */
+                       /* putting back screen context, reval can pass trough after modal failures! */
                        if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
                                CTX_wm_area_set(C, area);
                                CTX_wm_region_set(C, region);
@@ -581,7 +584,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                                MEM_freeN(handler);
                                
                                /* prevent silly errors from operator users */
-                               retval &= ~OPERATOR_PASS_THROUGH;
+                               //retval &= ~OPERATOR_PASS_THROUGH;
                        }
                        
                }
index 46a5c45a30d6807c2d9f339fcb6742f48eaed7c5..14cdf919ff977d7032426df1383265aa59a0b7c8 100644 (file)
@@ -111,25 +111,6 @@ wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, shor
        return kmi;
 }
 
-/* if item was added, then replace */
-wmKeymapItem *WM_keymap_set_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
-{
-       wmKeymapItem *kmi;
-       
-       for(kmi= lb->first; kmi; kmi= kmi->next)
-               if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0)
-                       break;
-       if(kmi==NULL) {
-               kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry");
-       
-               BLI_addtail(lb, kmi);
-               BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
-       }
-       keymap_event_set(kmi, type, val, modifier, keymodifier);
-       keymap_properties_set(kmi);
-       return kmi;
-}
-
 /* always add item */
 wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
 {
@@ -143,6 +124,15 @@ 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 */
+wmKeymapItem *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 827c7572788160fb7dab2252bf2aa2baa1bd4d46..9d59e71981e14c13df5593c075c1fe5bc586ab70 100644 (file)
@@ -764,9 +764,14 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
                case RIGHTMOUSE:
                case MIDDLEMOUSE:
                        if(gesture->event_type==event->type) {
-                               wm_gesture_evaluate(C, gesture);
                                wm_gesture_end(C, op);
-                               return OPERATOR_FINISHED;
+                               
+                               /* 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;
                        }
                        break;
        }