diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-07-05 13:09:17 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-07-05 13:27:15 +0300 |
commit | 397d088611b857e536bea08003eeba1b50678ec2 (patch) | |
tree | 25c7564fd7a65fb0c500b58f907e6831f338820b /source/blender/windowmanager | |
parent | 1517fa43097a3925b5fd1d4b8738fd56fde17bc8 (diff) |
UI: show modal operator keymaps in the status bar
This is work in progress, transform keymap especially
needs some filtering on it's keymap.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 80 |
2 files changed, 82 insertions, 3 deletions
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; +} + +/** \} */ |