UI: show modal operator keymaps in the status bar

This is work in progress, transform keymap especially
needs some filtering on it's keymap.
This commit is contained in:
2018-07-05 12:09:17 +02:00
parent 1517fa4309
commit 397d088611
3 changed files with 86 additions and 3 deletions

View File

@@ -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);

View File

@@ -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 *);

View File

@@ -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;
}
/** \} */