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/interface/interface_handlers.c | |
parent | aa44603146e87f29f08cee2abab7e0ddd89222c5 (diff) |
2.5
Keymap feature: RightMouse in pulldown menus allows to assign
a new hotkey.
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 144 |
1 files changed, 141 insertions, 3 deletions
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); |