diff options
author | Ton Roosendaal <ton@blender.org> | 2009-07-26 16:52:39 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-07-26 16:52:39 +0400 |
commit | 9ac754eca5466d62abed6d207d1efdbbb7d77b18 (patch) | |
tree | 3b0d63d120c6b24de6f5c161774cc9a3d874ab08 | |
parent | 7084447c73bd5b2b5fb9aa12a4e3b2e983723c2f (diff) |
2.5
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?
-rw-r--r-- | source/blender/editors/animation/anim_markers.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 7 | ||||
-rw-r--r-- | source/blender/editors/interface/view2d_ops.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner.c | 309 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_header.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_intern.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_windowmanager_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_wm.c | 24 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 10 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 20 |
14 files changed, 377 insertions, 17 deletions
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 7de3acdacef..d33eece52c9 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -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) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 18634e21a36..ca3be250a92 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -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: diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1736cd1ef52..0987f0d2f2a 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 44b7f1d13da..ee2a50d12a9 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -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 */ diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 0df0cb46473..b1919391c8d 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -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); diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c index fe2f054899c..0743a447298 100644 --- a/source/blender/editors/space_outliner/outliner_header.c +++ b/source/blender/editors/space_outliner/outliner_header.c @@ -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 */ diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index d5986f3ebbd..65b0708d64b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -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 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 007ea6ef51f..c61935c106f 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index f6f0fc1a753..a7ad502d438 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 9c9c256e819..4a2154bc3cf 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -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", ""}, diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0a68d2c9053..ca60c6e7637 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -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); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 78c7f7a7383..2a1fc009baa 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -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; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 764b209d755..1d959665f40 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -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; +} + + diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5c484dfa322..6c90926d545 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -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; } |