From 397d088611b857e536bea08003eeba1b50678ec2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jul 2018 12:09:17 +0200 Subject: UI: show modal operator keymaps in the status bar This is work in progress, transform keymap especially needs some filtering on it's keymap. --- .../editors/interface/interface_templates.c | 4 ++ source/blender/windowmanager/WM_api.h | 5 ++ .../blender/windowmanager/intern/wm_event_system.c | 80 +++++++++++++++++++++- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a14d12492ec..1c3ed3e3c75 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -4330,6 +4330,10 @@ void uiTemplateInputStatus(uiLayout *layout, struct bContext *C) return; } + if (WM_window_modal_keymap_status_draw(C, win, layout)) { + return; + } + /* Otherwise should cursor keymap status. */ for (int i = 0; i < 3; i++) { uiLayout *box = uiLayoutRow(layout, false); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e203a872d24..1f5e3aa2461 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -608,6 +608,11 @@ bool WM_event_is_ime_switch(const struct wmEvent *event); const char *WM_window_cursor_keymap_status_get(const struct wmWindow *win, int button_index, int type_index); void WM_window_cursor_keymap_status_refresh(struct bContext *C, struct wmWindow *win); +struct ScrArea *WM_window_find_area_status(struct wmWindow *win, struct bScreen *sc); +bool WM_window_modal_keymap_status_draw( + struct bContext *C, struct wmWindow *win, + struct uiLayout *layout); + /* wm_tooltip.c */ typedef struct ARegion *(*wmTooltipInitFn)(struct bContext *, struct ARegion *, bool *); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 91b924c1565..204bd62cfbe 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1960,6 +1960,15 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) { wm_operator_reports(C, op, retval, false); + + if (op->type->modalkeymap) { + wmWindow *win = CTX_wm_window(C); + bScreen *sc = WM_window_get_active_screen(win); + ScrArea *sa = WM_window_find_area_status(win, sc); + if (sa != NULL) { + ED_area_tag_redraw(sa); + } + } } else { /* not very common, but modal operators may report before finishing */ @@ -3191,6 +3200,14 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op) BLI_addhead(&win->modalhandlers, handler); + if (op->type->modalkeymap) { + bScreen *sc = WM_window_get_active_screen(win); + ScrArea *sa = WM_window_find_area_status(win, sc); + if (sa != NULL) { + ED_area_tag_redraw(sa); + } + } + return handler; } @@ -4321,11 +4338,14 @@ const char *WM_window_cursor_keymap_status_get(const wmWindow *win, int button_i return NULL; } -void WM_window_cursor_keymap_status_refresh(bContext *C, struct wmWindow *win) +/** + * Similar to #BKE_screen_area_map_find_area_xy and related functions, + * use here since the ara is stored in the window manager. + */ +ScrArea *WM_window_find_area_status(wmWindow *win, bScreen *screen) { - bScreen *screen = WM_window_get_active_screen(win); if (screen->state == SCREENFULL) { - return; + return NULL; } ScrArea *sa_statusbar = NULL; for (ScrArea *sa = win->global_areas.areabase.first; sa; sa = sa->next) { @@ -4334,6 +4354,13 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, struct wmWindow *win) break; } } + return sa_statusbar; +} + +void WM_window_cursor_keymap_status_refresh(bContext *C, wmWindow *win) +{ + bScreen *screen = WM_window_get_active_screen(win); + ScrArea *sa_statusbar = WM_window_find_area_status(win, screen); if (sa_statusbar == NULL) { return; } @@ -4476,3 +4503,50 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, struct wmWindow *win) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Modal Keymap Status + * + * \{ */ + +bool WM_window_modal_keymap_status_draw( + bContext *UNUSED(C), wmWindow *win, + uiLayout *layout) +{ + wmKeyMap *keymap = NULL; + wmOperatorType *ot = NULL; + for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) { + if (handler->op) { + /* 'handler->keymap' could be checked too, seems not to be used. */ + wmKeyMap *keymap_test = handler->op->type->modalkeymap; + if (keymap_test && keymap_test->modal_items) { + keymap = keymap_test; + ot = handler->op->type; + break; + } + } + } + if (keymap == NULL) { + return false; + } + const EnumPropertyItem *items = keymap->modal_items; + + uiLayout *row = uiLayoutRow(layout, true); + for (int i = 0; items[i].identifier; i++) { + if (!items[i].identifier[0]) { + continue; + } + char buf[UI_MAX_DRAW_STR]; + int available_len = sizeof(buf); + char *p = buf; + WM_modalkeymap_operator_items_to_string_buf(ot, items[i].value, true, UI_MAX_SHORTCUT_STR, &available_len, &p); + p -= 1; + if (p > buf) { + BLI_snprintf(p, available_len, ": %s", items[i].name); + uiItemL(row, buf, 0); + } + } + return true; +} + +/** \} */ -- cgit v1.2.3