diff options
author | Ton Roosendaal <ton@blender.org> | 2009-07-28 20:48:02 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-07-28 20:48:02 +0400 |
commit | 347a1f4376e08ef56d932175669402b3eeb99948 (patch) | |
tree | f73517c70b36dbe346b86ee79b7fee4e82ed64a7 /source/blender/editors | |
parent | aa44603146e87f29f08cee2abab7e0ddd89222c5 (diff) |
2.5
Keymap feature: RightMouse in pulldown menus allows to assign
a new hotkey.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 40 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 144 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner.c | 3 |
4 files changed, 185 insertions, 5 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 8dc766499bc..d818f298de7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -206,6 +206,8 @@ typedef struct uiLayout uiLayout; #define HSVCIRCLE (42<<9) #define LISTBOX (43<<9) #define LISTROW (44<<9) +#define HOTKEYEVT (45<<9) + #define BUTTYPE (63<<9) /* Drawing @@ -426,6 +428,7 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip); void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip); +uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip); uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index ca3be250a92..f6bf8f2cd31 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -739,6 +739,7 @@ static void ui_is_but_sel(uiBut *but) case BUT: push= 2; break; + case HOTKEYEVT: case KEYEVT: push= 2; break; @@ -1846,7 +1847,33 @@ void ui_check_but(uiBut *but) strcat(but->drawstr, WM_key_event_string((short) ui_get_but_val(but))); } break; - + + case HOTKEYEVT: + if (but->flag & UI_SELECT) { + short *sp= (short *)but->func_arg3; + + strcpy(but->drawstr, but->str); + + if(*sp) { + char *str= but->drawstr; + + if(*sp & KM_SHIFT) + str= strcat(str, "Shift "); + if(*sp & KM_CTRL) + str= strcat(str, "Ctrl "); + if(*sp & KM_ALT) + str= strcat(str, "Alt "); + if(*sp & KM_OSKEY) + str= strcat(str, "Cmd "); + } + else + strcat(but->drawstr, "Press a key "); + } else { + /* XXX todo, button currently only used temporarily */ + strcpy(but->drawstr, WM_key_event_string((short) ui_get_but_val(but))); + } + break; + case BUT_TOGDUAL: /* trying to get the dual-icon to left of text... not very nice */ if(but->str[0]) { @@ -2941,6 +2968,17 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, ui_check_but(but); } +/* short pointers hardcoded */ +/* modkeypoin will be set to KM_SHIFT, KM_ALT, KM_CTRL, KM_OSKEY bits */ +uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip) +{ + uiBut *but= ui_def_but(block, HOTKEYEVT|SHO, retval, str, x1, y1, x2, y2, keypoin, 0.0, 0.0, 0.0, 0.0, tip); + but->func_arg3= modkeypoin; /* XXX hrmf, abuse! */ + ui_check_but(but); + return but; +} + + /* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 0987f0d2f2a..5c3fc890144 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -840,6 +840,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut ui_apply_but_CHARTAB(C, but, data); break; #endif + case HOTKEYEVT: + ui_apply_but_BUT(C, but, data); + break; case LINK: case INLINK: ui_apply_but_LINK(C, but, data); @@ -1801,6 +1804,60 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEv return WM_UI_HANDLER_CONTINUE; } +static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + if(data->state == BUTTON_STATE_HIGHLIGHT) { + if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) { + but->drawstr[0]= 0; + button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); + return WM_UI_HANDLER_BREAK; + } + } + else if(data->state == BUTTON_STATE_WAIT_KEY_EVENT) { + short *sp= (short *)but->func_arg3; + + if(event->type == MOUSEMOVE) + return WM_UI_HANDLER_CONTINUE; + + if(ELEM(event->type, ESCKEY, LEFTMOUSE)) { + /* data->cancel doesnt work, this button opens immediate */ + ui_set_but_val(but, 0); + button_activate_state(C, but, BUTTON_STATE_EXIT); + return WM_UI_HANDLER_BREAK; + } + + /* always set */ + *sp= 0; + if(event->shift) + *sp |= KM_SHIFT; + if(event->alt) + *sp |= KM_ALT; + if(event->ctrl) + *sp |= KM_CTRL; + if(event->oskey) + *sp |= KM_OSKEY; + + ui_check_but(but); + ED_region_tag_redraw(data->region); + + if(event->val==KM_PRESS) { + if(ISHOTKEY(event->type)) { + + if(WM_key_event_string(event->type)[0]) + ui_set_but_val(but, event->type); + else + data->cancel= 1; + + button_activate_state(C, but, BUTTON_STATE_EXIT); + return WM_UI_HANDLER_BREAK; + } + } + } + + return WM_UI_HANDLER_CONTINUE; +} + + static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) { if(data->state == BUTTON_STATE_HIGHLIGHT) { @@ -3103,6 +3160,67 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmE return WM_UI_HANDLER_CONTINUE; } +/* callback for hotkey change button/menu */ +static void do_menu_change_hotkey(bContext *C, void *but_v, void *key_v) +{ + uiBut *but= but_v; + IDProperty *prop= (but->opptr)? but->opptr->data: NULL; + short *key= key_v; + char buf[512], *butstr, *cpoin; + + /* signal for escape */ + if(key[0]==0) return; + + WM_key_event_operator_change(C, but->optype->idname, but->opcontext, prop, key[0], key[1]); + + /* complex code to change name of button */ + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { + + butstr= MEM_mallocN(strlen(but->str)+strlen(buf)+2, "menu_block_set_keymaps"); + + /* XXX but->str changed... should not, remove the hotkey from it */ + cpoin= strchr(but->str, '|'); + if(cpoin) *cpoin= 0; + + strcpy(butstr, but->str); + strcat(butstr, "|"); + strcat(butstr, buf); + + but->str= but->strdata; + BLI_strncpy(but->str, butstr, sizeof(but->strdata)); + MEM_freeN(butstr); + + ui_check_but(but); + } + +} + + +static uiBlock *menu_change_hotkey(bContext *C, ARegion *ar, void *arg_but) +{ + uiBlock *block; + uiBut *but= arg_but; + wmOperatorType *ot= WM_operatortype_find(but->optype->idname, 1); + static short dummy[2]; + char buf[OP_MAX_TYPENAME+10]; + + dummy[0]= 0; + dummy[1]= 0; + + block= uiBeginBlock(C, ar, "_popup", UI_EMBOSSP); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_MOVEMOUSE_QUIT|UI_BLOCK_RET_1); + + BLI_strncpy(buf, ot->name, OP_MAX_TYPENAME); + strcat(buf, " |"); + + but= uiDefHotKeyevtButS(block, 0, buf, 0, 0, 200, 20, dummy, dummy+1, ""); + uiButSetFunc(but, do_menu_change_hotkey, arg_but, dummy); + + uiPopupBoundsBlock(block, 6.0f, 50, -10); + uiEndBlock(C, block); + + return block; +} static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) { @@ -3145,9 +3263,22 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) } /* handle menu */ else if(event->type == RIGHTMOUSE && event->val == KM_PRESS) { - button_timers_tooltip_remove(C, but); - ui_but_anim_menu(C, but); - return WM_UI_HANDLER_BREAK; + /* RMB has two options now */ + if(but->rnapoin.data && but->rnaprop) { + button_timers_tooltip_remove(C, but); + ui_but_anim_menu(C, but); + return WM_UI_HANDLER_BREAK; + } + else if((but->block->flag & UI_BLOCK_LOOP) && but->optype) { + IDProperty *prop= (but->opptr)? but->opptr->data: NULL; + char buf[512]; + + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { + + uiPupBlock(C, menu_change_hotkey, but); + + } + } } } @@ -3176,6 +3307,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case KEYEVT: retval= ui_do_but_KEYEVT(C, but, data, event); break; + case HOTKEYEVT: + retval= ui_do_but_HOTKEYEVT(C, but, data, event); + break; case TOGBUT: case TOG: case TOGR: @@ -3521,6 +3655,10 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA } button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); + /* activate right away */ + if(but->type==HOTKEYEVT) + button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); + if(type == BUTTON_ACTIVATE_OPEN) { button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 21ba9cfa707..b05d9637a69 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1132,8 +1132,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->name= km->nameid; if(!(tselem->flag & TSE_CLOSED)) { + a= 0; - for (kmi= km->keymap.first; kmi; kmi= kmi->next) { + for (kmi= km->keymap.first; kmi; kmi= kmi->next, a++) { const char *key= WM_key_event_string(kmi->type); if(key[0]) { |