2.5
authorTon Roosendaal <ton@blender.org>
Sun, 26 Jul 2009 12:52:39 +0000 (12:52 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 26 Jul 2009 12:52:39 +0000 (12:52 +0000)
First step towards keymap editor!
Before getting too excited:
- doesn't save yet
- no rna properties can be defined
- no insert/remove keymap options yet
- no option yet to set 'key press/release'

But what does work;
- Keymap list is in outliner, new category
  (Keymaps are listed in order as being created now)
- enable/disable a keymap entry: click on dot icon
- it displays python api names for ops
- browse new operator for keymap (menu button)
- set keymap to use other keys, mouse or tweak events
- four modifier key options

I first intent to test it all well, there are still
quite some modal map conflicts (like border select) and
there's problems assigning items to tweaks

Another issue is that a visual editor for keymaps might be
quite hard to use... the amount of data and options is just not
so fun for a buttons menu. There are ways to improve this though.
Maybe do this via a script?

14 files changed:
source/blender/editors/animation/anim_markers.c
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_outliner/outliner_header.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesrna/intern/rna_wm.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c

index 7de3acdacefab56a821c34f109be1c8412335062..d33eece52c9f7fe08369cf9407dc410829f8bdb7 100644 (file)
@@ -85,6 +85,7 @@ static ListBase *context_get_markers(const bContext *C)
 }
 
 /* Get the marker that is closest to this point */
+/* XXX for select, the min_dist should be small */
 TimeMarker *ED_markers_find_nearest_marker (ListBase *markers, float x) 
 {
        TimeMarker *marker, *nearest=NULL;
@@ -828,6 +829,7 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
        /* XXX marker context */
        for(marker= markers->first; marker; marker= marker->next) {
                if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
+                       /* XXX weak... */
                        switch (event_type) {
                                case LEFTMOUSE:
                                        if ((marker->flag & SELECT) == 0) 
index 18634e21a36871b7a20c148b644f7fb9b1ebfacb..ca3be250a923c4680b55e07362cd54edf99ed25d 100644 (file)
@@ -740,7 +740,7 @@ static void ui_is_but_sel(uiBut *but)
                        push= 2;
                        break;
                case KEYEVT:
-                       if (value==-1) push= 1;
+                       push= 2;
                        break;
                case TOGBUT:
                case TOG:
index 1736cd1ef529dc5cf116fdfb798a79f1500dca88..0987f0d2f2a8f6c47da5335f52194c622582c38f 100644 (file)
@@ -1805,7 +1805,10 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
 {
        if(data->state == BUTTON_STATE_HIGHLIGHT) {
                if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
-                       button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+                       short event= (short)ui_get_but_val(but);
+                       /* hardcoded prevention from editing or assigning ESC */
+                       if(event!=ESCKEY)
+                               button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
                        return WM_UI_HANDLER_BREAK;
                }
        }
@@ -1814,7 +1817,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
                        return WM_UI_HANDLER_CONTINUE;
 
                if(event->val==KM_PRESS) {
-                       if(WM_key_event_string(event->type)[0])
+                       if(event->type!=ESCKEY && WM_key_event_string(event->type)[0])
                                ui_set_but_val(but, event->type);
                        else
                                data->cancel= 1;
index 44b7f1d13da028aaee5333d586f4fa1065f29e3b..ee2a50d12a97ad11cb521d31b20bef9f5a69520c 100644 (file)
@@ -151,6 +151,12 @@ static void view_pan_apply(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(vpd->sa);
        UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
+       
+       /* exceptions */
+       if(vpd->sa->spacetype==SPACE_OUTLINER) {
+               SpaceOops *soops= vpd->sa->spacedata.first;
+               soops->storeflag |= SO_TREESTORE_REDRAW;
+       }
 }
 
 /* cleanup temp customdata  */
index 0df0cb46473aeb50c69083d1612d43a36421b709..b1919391c8d475a5a0a74fdee06cfc6bc0118b45 100644 (file)
@@ -1123,6 +1123,45 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        }
                }
        }
+       else if(type == TSE_KEYMAP) {
+               wmKeyMap *km= (wmKeyMap *)idv;
+               wmKeymapItem *kmi;
+               char opname[OP_MAX_TYPENAME];
+               
+               te->directdata= idv;
+               te->name= km->nameid;
+               
+               if(!(tselem->flag & TSE_CLOSED)) {
+                       
+                       for (kmi= km->keymap.first; kmi; kmi= kmi->next) {
+                               const char *key= WM_key_event_string(kmi->type);
+                               
+                               if(key[0]) {
+                                       wmOperatorType *ot= NULL;
+                                       
+                                       if(kmi->propvalue);
+                                       else ot= WM_operatortype_find(kmi->idname, 0);
+                                       
+                                       if(ot || kmi->propvalue) {
+                                               TreeElement *ten= outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
+                                               
+                                               ten->directdata= kmi;
+                                               
+                                               if(kmi->propvalue) {
+                                                       ten->name= "Modal map, not yet";
+                                               }
+                                               else {
+                                                       WM_operator_py_idname(opname, ot->idname);
+                                                       ten->name= BLI_strdup(opname);
+                                                       ten->flag |= TE_FREE_NAME;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               else 
+                       te->flag |= TE_LAZY_CLOSED;
+       }
 
        return te;
 }
@@ -1376,6 +1415,14 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
                        tselem->flag &= ~TSE_CLOSED;
                }
        }
+       else if(soops->outlinevis==SO_KEYMAP) {
+               wmWindowManager *wm= mainvar->wm.first;
+               wmKeyMap *km;
+               
+               for(km= wm->keymaps.first; km; km= km->next) {
+                       ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0);
+               }
+       }
        else {
                ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
                if(ten) ten->directdata= BASACT;
@@ -2193,6 +2240,21 @@ static int tree_element_active_sequence_dup(bContext *C, Scene *scene, TreeEleme
        return(0);
 }
 
+static int tree_element_active_keymap_item(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set)
+{
+       wmKeymapItem *kmi= te->directdata;
+       
+       if(set==0) {
+               if(kmi->inactive) return 0;
+               return 1;
+       }
+       else {
+               kmi->inactive= !kmi->inactive;
+       }
+       return 0;
+}
+
+
 /* generic call for non-id data to make/check active in UI */
 /* Context can be NULL when set==0 */
 static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set)
@@ -2213,10 +2275,8 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
                        break;
                case TSE_LINKED_PSYS:
                        return tree_element_active_psys(C, scene, te, tselem, set);
-                       break;
                case TSE_POSE_BASE:
                        return tree_element_active_pose(C, scene, te, tselem, set);
-                       break;
                case TSE_POSE_CHANNEL:
                        return tree_element_active_posechannel(C, scene, te, tselem, set);
                case TSE_CONSTRAINT:
@@ -2227,10 +2287,11 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
                        return tree_element_active_posegroup(C, scene, te, tselem, set);
                case TSE_SEQUENCE:
                        return tree_element_active_sequence(C, te, tselem, set);
-                       break;
                case TSE_SEQUENCE_DUP:
                        return tree_element_active_sequence_dup(C, scene, te, tselem, set);
-                       break;
+               case TSE_KEYMAP_ITEM:
+                       return tree_element_active_keymap_item(C, te, tselem, set);
+                       
        }
        return 0;
 }
@@ -4953,6 +5014,241 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
        }
 }
 
+static void operator_call_cb(struct bContext *C, void *arg_kmi, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       wmKeymapItem *kmi= arg_kmi;
+       
+       if(ot)
+               BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg_kmi, char *str, uiSearchItems *items)
+{
+       wmOperatorType *ot = WM_operatortype_first();
+       
+       for(; ot; ot= ot->next) {
+               
+               if(BLI_strcasestr(ot->idname, str)) {
+                       char name[OP_MAX_TYPENAME];
+                       
+                       /* display name for menu */
+                       WM_operator_py_idname(name, ot->idname);
+                       
+                       if(0==uiSearchItemAdd(items, name, ot, 0))
+                               break;
+               }
+       }
+}
+
+/* operator Search browse menu, open */
+static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
+{
+       static char search[OP_MAX_TYPENAME];
+       wmEvent event;
+       wmWindow *win= CTX_wm_window(C);
+       wmKeymapItem *kmi= arg_kmi;
+       wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0);
+       uiBlock *block;
+       uiBut *but;
+       
+       /* clear initial search string, then all items show */
+       search[0]= 0;
+       
+       block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+       uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+       
+       /* fake button, it holds space for search items */
+       uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+       
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+       uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
+       
+       uiBoundsBlock(block, 6);
+       uiBlockSetDirection(block, UI_DOWN);    
+       uiEndBlock(C, block);
+       
+       event= *(win->eventstate);      /* XXX huh huh? make api call */
+       event.type= EVT_BUT_OPEN;
+       event.val= KM_PRESS;
+       event.customdata= but;
+       event.customdatafree= FALSE;
+       wm_event_add(win, &event);
+       
+       return block;
+}
+
+#define OL_KM_KEYBOARD         0
+#define OL_KM_MOUSE                    1
+#define OL_KM_TWEAK                    2
+#define OL_KM_SPECIALS         3
+
+static short keymap_menu_type(short type)
+{
+       if(ISKEYBOARD(type)) return OL_KM_KEYBOARD;
+       if(WM_key_event_is_tweak(type)) return OL_KM_TWEAK;
+       if(type >= LEFTMOUSE && type <= WHEELOUTMOUSE) return OL_KM_MOUSE;
+//     return OL_KM_SPECIALS;
+       return 0;
+}
+
+static char *keymap_type_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Event Type %%t");
+       
+       str += sprintf(str, formatstr, "Keyboard", OL_KM_KEYBOARD);
+       str += sprintf(str, formatstr, "Mouse", OL_KM_MOUSE);
+       str += sprintf(str, formatstr, "Tweak", OL_KM_TWEAK);
+//     str += sprintf(str, formatstr, "Specials", OL_KM_SPECIALS);
+       
+       return string;
+}      
+
+static char *keymap_mouse_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Mouse Event %%t");
+       
+       str += sprintf(str, formatstr, "Left Mouse", LEFTMOUSE);
+       str += sprintf(str, formatstr, "Middle Mouse", MIDDLEMOUSE);
+       str += sprintf(str, formatstr, "Right Mouse", RIGHTMOUSE);
+       str += sprintf(str, formatstr, "Action Mouse", ACTIONMOUSE);
+       str += sprintf(str, formatstr, "Select Mouse", SELECTMOUSE);
+       str += sprintf(str, formatstr, "Mouse Move", MOUSEMOVE);
+       str += sprintf(str, formatstr, "Wheel Up", WHEELUPMOUSE);
+       str += sprintf(str, formatstr, "Wheel Down", WHEELDOWNMOUSE);
+       str += sprintf(str, formatstr, "Wheel In", WHEELINMOUSE);
+       str += sprintf(str, formatstr, "Wheel Out", WHEELOUTMOUSE);
+       
+       return string;
+}
+
+static char *keymap_tweak_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Tweak Event %%t");
+       
+       str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L);
+       str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M);
+       str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R);
+       str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A);
+       str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S);
+       
+       return string;
+}
+
+static void keymap_type_cb(bContext *C, void *kmi_v, void *unused_v)
+{
+       wmKeymapItem *kmi= kmi_v;
+       short maptype= keymap_menu_type(kmi->type);
+       
+       if(maptype!=kmi->maptype) {
+               switch(kmi->maptype) {
+                       case OL_KM_KEYBOARD:
+                               kmi->type= AKEY;
+                               kmi->val= KM_PRESS;
+                               break;
+                       case OL_KM_MOUSE:
+                               kmi->type= LEFTMOUSE;
+                               kmi->val= KM_PRESS;
+                               break;
+                       case OL_KM_TWEAK:
+                               kmi->type= EVT_TWEAK_L;
+                               kmi->val= KM_ANY;
+                               break;
+                       case OL_KM_SPECIALS:
+                               kmi->type= AKEY;
+                               kmi->val= KM_PRESS;
+               }
+               ED_region_tag_redraw(CTX_wm_region(C));
+       }
+}
+
+static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       uiBlockSetEmboss(block, UI_EMBOSST);
+       
+       for(te= lb->first; te; te= te->next) {
+               tselem= TREESTORE(te);
+               if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+                       uiBut *but;
+                       char *str;
+                       int xstart= 240;
+                       int butw1= 20; /* operator */
+                       int butw2= 90; /* event type, menus */
+                       int butw3= 43; /* modifiers */
+
+                       if(tselem->type == TSE_KEYMAP_ITEM) {
+                               wmKeymapItem *kmi= te->directdata;
+                               
+                               /* modal map? */
+                               if(kmi->propvalue);
+                               else {
+                                       uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator");
+                               }
+                               xstart+= butw1+10;
+                               
+                               /* map type button */
+                               kmi->maptype= keymap_menu_type(kmi->type);
+                               
+                               str= keymap_type_menu();
+                               but= uiDefButS(block, MENU, 0, str,     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+                               uiButSetFunc(but, keymap_type_cb, kmi, NULL);
+                               xstart+= butw2+5;
+                               
+                               /* edit actual event */
+                               switch(kmi->maptype) {
+                                       case OL_KM_KEYBOARD:
+                                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code");
+                                               xstart+= butw2+5;
+                                               break;
+                                       case OL_KM_MOUSE:
+                                               str= keymap_mouse_menu();
+                                               uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Mouse button");   
+                                               xstart+= butw2+5;
+                                               break;
+                                       case OL_KM_TWEAK:
+                                               str= keymap_tweak_menu();
+                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Tweak gesture"); 
+                                               xstart+= butw2+5;
+                                               break;
+                               }
+                               
+                               /* modifiers */
+                               uiBlockBeginAlign(block);
+                               uiDefButS(block, OPTION, 0, "Shift",    xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
+                               uiDefButS(block, OPTION, 0, "Ctrl",     xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Alt",      xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Cmd",      xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               xstart+= 5;
+                               uiBlockEndAlign(block);
+                               
+                               /* rna property */
+                               if(kmi->ptr && kmi->ptr->data)
+                                       uiDefBut(block, LABEL, 0, "(RNA property)",     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
+                                       
+                               
+                       }
+               }
+               
+               if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
+       }
+}
+
+
 static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
 {
        uiBut *bt;
@@ -5007,7 +5303,7 @@ void draw_outliner(const bContext *C)
        /* get extents of data */
        outliner_height(soops, &soops->tree, &sizey);
 
-       if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
+       if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) {
                /* RNA has two columns:
                 *      - column 1 is (max_width + OL_RNA_COL_SPACEX) or
                 *                               (OL_RNA_COL_X), whichever is wider...
@@ -5053,6 +5349,9 @@ void draw_outliner(const bContext *C)
                outliner_draw_rnacols(ar, soops, sizex_rna);
                outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree);
        }
+       else if(soops->outlinevis == SO_KEYMAP) {
+               outliner_draw_keymapbuts(block, ar, soops, &soops->tree);
+       }
        else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
                /* draw restriction columns */
                outliner_draw_restrictcols(ar, soops);
index fe2f054899c857d9205c610f19a9e488788a81b1..0743a447298ff12de2f6c3dd8ae821c4c3c2c0b3 100644 (file)
@@ -233,9 +233,9 @@ void outliner_header_buttons(const bContext *C, ARegion *ar)
        
        /* data selector*/
        if(G.main->library.first) 
-               uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12",     xco, yco, 120, 20,  &soutliner->outlinevis, 0, 0, 0, 0, "");
+               uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12||Key Maps %x13",      xco, yco, 120, 20,  &soutliner->outlinevis, 0, 0, 0, 0, "");
        else
-               uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12",   xco, yco, 120, 20,  &soutliner->outlinevis, 0, 0, 0, 0, "");   
+               uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12||Key Maps %x13",    xco, yco, 120, 20,  &soutliner->outlinevis, 0, 0, 0, 0, "");   
        xco += 120;
        
        /* KeyingSet editing buttons */
index d5986f3ebbddbe9d28ca93abc962aaa392effa76..65b0708d64b429ef76d1c9a27c5649ee298867c0 100644 (file)
@@ -95,6 +95,8 @@ typedef struct TreeElement {
 #define TSE_RNA_PROPERTY       31
 #define TSE_RNA_ARRAY_ELEM     32
 #define TSE_NLA_TRACK          33
+#define TSE_KEYMAP                     34
+#define TSE_KEYMAP_ITEM                35
 
 /* outliner search flags */
 #define OL_FIND                                        0
index 007ea6ef51f407e754aa9be4eedadfc0dd2d6d52..c61935c106f8ebf17a6969658c43eded67975e25 100644 (file)
@@ -749,6 +749,7 @@ enum {
 #define SO_SEQUENCE            10
 #define SO_DATABLOCKS  11
 #define SO_USERDEF             12
+#define SO_KEYMAP              13
 
 /* SpaceOops->storeflag */
 #define SO_TREESTORE_CLEANUP   1
index f6f0fc1a7539c6bb178f285f75c66ac0afea0ca8..a7ad502d43885f216d1a7ffb111d4a8e83bce632 100644 (file)
@@ -229,6 +229,10 @@ typedef struct wmKeymapItem {
        short keymodifier;                              /* rawkey modifier */
        
        short propvalue;                                /* if used, the item is from modal map */
+       
+       short inactive;                                 /* if set, deactivated item */
+       short maptype;                                          /* keymap editor */
+       short pad2, pad3;
 } wmKeymapItem;
 
 
index 9c9c256e819e3490ecd6c48ba6098467ec7a9252..4a2154bc3cf8f8afc3bfb75c806c6a5f93643d81 100644 (file)
@@ -40,8 +40,28 @@ EnumPropertyItem event_value_items[] = {
        {KM_RELEASE, "RELEASE", 0, "Release", ""},
        {0, NULL, 0, NULL, NULL}};
 
-/* not returned: CAPSLOCKKEY, UNKNOWNKEY, COMMANDKEY, GRLESSKEY */
+/* not returned: CAPSLOCKKEY, UNKNOWNKEY, GRLESSKEY */
 EnumPropertyItem event_type_items[] = {
+
+       {LEFTMOUSE, "LEFTMOUSE", 0, "Left Mouse", ""},
+       {MIDDLEMOUSE, "MIDDLEMOUSE", 0, "Middle Mouse", ""},
+       {RIGHTMOUSE, "RIGHTMOUSE", 0, "Right Mouse", ""},
+       {ACTIONMOUSE, "ACTIONMOUSE", 0, "Action Mouse", ""},
+       {SELECTMOUSE, "SELECTMOUSE", 0, "Select Mouse", ""},
+
+       {MOUSEMOVE, "MOUSEMOVE", 0, "Mouse Move", ""},
+
+       {WHEELUPMOUSE, "WHEELUPMOUSE", 0, "Wheel Up", ""},
+       {WHEELDOWNMOUSE, "WHEELDOWNMOUSE", 0, "Wheel Down", ""},
+       {WHEELINMOUSE, "WHEELINMOUSE", 0, "Wheel In", ""},
+       {WHEELOUTMOUSE, "WHEELOUTMOUSE", 0, "Wheel Out", ""},
+
+       {EVT_TWEAK_L, "EVT_TWEAK_L", 0, "Tweak Left", ""},
+       {EVT_TWEAK_M, "EVT_TWEAK_M", 0, "Tweak Middle", ""},
+       {EVT_TWEAK_R, "EVT_TWEAK_R", 0, "Tweak Right", ""},
+       {EVT_TWEAK_A, "EVT_TWEAK_A", 0, "Tweak Action", ""},
+       {EVT_TWEAK_S, "EVT_TWEAK_S", 0, "Tweak Select", ""},
+
        {AKEY, "A", 0, "A", ""},
        {BKEY, "B", 0, "B", ""},
        {CKEY, "C", 0, "C", ""},
@@ -86,6 +106,8 @@ EnumPropertyItem event_type_items[] = {
        {RIGHTALTKEY,   "RIGHT_ALT",    0, "Right Alt", ""},
        {RIGHTCTRLKEY,  "RIGHT_CTRL",   0, "Right Ctrl", ""},
        {RIGHTSHIFTKEY, "RIGHT_SHIFT",  0, "Right Shift", ""},
+
+       {COMMANDKEY,    "COMMAND",      0, "Command", ""},
        
        {ESCKEY, "ESC", 0, "Esc", ""},
        {TABKEY, "TAB", 0, "Tab", ""},
index 0a68d2c9053783814578e3fb11d19cf97d57e44d..ca60c6e7637bacd13b2bb06533276b0fc3cdd7e1 100644 (file)
@@ -96,6 +96,7 @@ wmKeyMap      *WM_modalkeymap_get(struct wmWindowManager *wm, const char *nameid);
 void           WM_modalkeymap_add_item(wmKeyMap *km, short type, short val, int modifier, short keymodifier, short value);
 void           WM_modalkeymap_assign(wmKeyMap *km, const char *opname);
 
+int                    WM_key_event_is_tweak(short type);
 
 const char     *WM_key_event_string(short type);
 char           *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
index 78c7f7a7383367cb36f454b6469e2842c81fa39c..2a1fc009baac6cfe701f4b4e9f309a5e108bdde5 100644 (file)
@@ -626,6 +626,8 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
 {
        int kmitype= wm_userdef_event_map(kmi->type);
 
+       if(kmi->inactive) return 0;
+       
        /* the matching rules */
        if(kmitype==KM_TEXTINPUT)
                if(ISKEYBOARD(winevent->type)) return 1;
index 764b209d7557dd07344513c14e602fb89803e1d0..1d959665f402270a742bb1d15704183eb3fbc9f9 100644 (file)
@@ -290,3 +290,13 @@ char *WM_key_event_operator_string(const bContext *C, const char *opname, int op
        return NULL;
 }
 
+/* ********************* */
+
+int WM_key_event_is_tweak(short type)
+{
+       if(type>=EVT_TWEAK_L && type<=EVT_GESTURE)
+               return 1;
+       return 0;
+}
+
+
index 5c484dfa322886d9971f71e193601164dfb67b7b..6c90926d545f7eb930d8950bae89515ff627683e 100644 (file)
@@ -906,7 +906,7 @@ void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
    It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
 */
 
-static int border_apply(bContext *C, wmOperator *op, int event_type)
+static int border_apply(bContext *C, wmOperator *op, int event_type, int event_orig)
 {
        wmGesture *gesture= op->customdata;
        rcti *rect= gesture->customdata;
@@ -924,9 +924,14 @@ static int border_apply(bContext *C, wmOperator *op, int event_type)
        RNA_int_set(op->ptr, "ymin", rect->ymin);
        RNA_int_set(op->ptr, "xmax", rect->xmax);
        RNA_int_set(op->ptr, "ymax", rect->ymax);
-       if( RNA_struct_find_property(op->ptr, "event_type") )
-               RNA_int_set(op->ptr, "event_type", event_type);
        
+       /* XXX weak; border should be configured for this without reading event types */
+       if( RNA_struct_find_property(op->ptr, "event_type") ) {
+               if(ELEM4(event_orig, EVT_TWEAK_L, EVT_TWEAK_R, EVT_TWEAK_A, EVT_TWEAK_S))
+                       event_type= LEFTMOUSE;
+               
+               RNA_int_set(op->ptr, "event_type", event_type);
+       }
        op->type->exec(C, op);
        
        return 1;
@@ -947,7 +952,10 @@ static void wm_gesture_end(bContext *C, wmOperator *op)
 
 int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
+       if(WM_key_event_is_tweak(event->type))
+               op->customdata= WM_gesture_new(C, event, WM_GESTURE_RECT);
+       else
+               op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
 
        /* add modal handler */
        WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
@@ -984,14 +992,14 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
                case LEFTMOUSE:
                case MIDDLEMOUSE:
                case RIGHTMOUSE:
-                       if(event->val==1) {
+                       if(event->val==KM_PRESS) {
                                if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) {
                                        gesture->mode= 1;
                                        wm_gesture_tag_redraw(C);
                                }
                        }
                        else {
-                               if(border_apply(C, op, event->type)) {
+                               if(border_apply(C, op, event->type, gesture->event_type)) {
                                        wm_gesture_end(C, op);
                                        return OPERATOR_FINISHED;
                                }