From 60abb16c6db024a734c61123e156960f6680f5e2 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sun, 7 Apr 2024 11:46:32 -0700 Subject: [PATCH] UI Experiment: Optional Layout for ED_workspace_status_text Experiment in allowing current uses of ED_workspace_status_text, which draws simple text to the status bar, to give a callback to allow complex layout features. --- source/blender/blenkernel/intern/workspace.cc | 2 + source/blender/editors/include/ED_screen.hh | 5 ++ .../regions/interface_region_menu_popup.cc | 48 ++++++++++++++--- .../templates/interface_templates.cc | 5 +- source/blender/editors/screen/area.cc | 52 +++++++++++++++---- source/blender/makesdna/DNA_workspace_types.h | 4 ++ 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/intern/workspace.cc b/source/blender/blenkernel/intern/workspace.cc index 50847042600..214f4d03968 100644 --- a/source/blender/blenkernel/intern/workspace.cc +++ b/source/blender/blenkernel/intern/workspace.cc @@ -116,6 +116,8 @@ static void workspace_blend_read_data(BlendDataReader *reader, ID *id) } workspace->status_text = nullptr; + workspace->status_cb = nullptr; + workspace->status_cb_data = nullptr; /* Do not keep the scene reference when appending a workspace. Setting a scene for a workspace is * a convenience feature, but the workspace should never truly depend on scene data. */ diff --git a/source/blender/editors/include/ED_screen.hh b/source/blender/editors/include/ED_screen.hh index d36ca708c85..3f46adfdcd1 100644 --- a/source/blender/editors/include/ED_screen.hh +++ b/source/blender/editors/include/ED_screen.hh @@ -449,6 +449,11 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol bool ED_workspace_layout_cycle(WorkSpace *workspace, short direction, bContext *C) ATTR_NONNULL(); void ED_workspace_status_text(bContext *C, const char *str); +void ED_workspace_status_text(bContext *C, + void (*status_cb)(const bContext *C, + uiLayout *layout, + void *user_data), + void *user_data); void ED_workspace_do_listen(bContext *C, const wmNotifier *note); diff --git a/source/blender/editors/interface/regions/interface_region_menu_popup.cc b/source/blender/editors/interface/regions/interface_region_menu_popup.cc index b1ca5e76c10..b92f2b8aaa8 100644 --- a/source/blender/editors/interface/regions/interface_region_menu_popup.cc +++ b/source/blender/editors/interface/regions/interface_region_menu_popup.cc @@ -385,6 +385,45 @@ static void ui_block_free_func_POPUP(void *arg_pup) MEM_delete(pup); } +static void ui_popup_menu_space_search_status_cb(const bContext *C, + uiLayout *layout, + void *user_data) +{ + MenuType *mt = static_cast(user_data); + const bool search_type = (mt && (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress))); + const bool search_space = (!mt || (!search_type && mt && mt->idname[0])); + + uiItemL(layout, "", UI_icon_from_event_type(LEFTMOUSE, KM_CLICK)); + uiItemL(layout, IFACE_("Select"), ICON_NONE); + uiItemL(layout, "", UI_icon_from_event_type(RIGHTMOUSE, KM_CLICK)); + uiItemL(layout, IFACE_("Options"), ICON_NONE); + uiItemS_ex(layout, 0.7f); + + if (search_space) { + uiItemL(layout, "", UI_icon_from_event_type(EVT_SPACEKEY, KM_ANY)); + uiItemS_ex(layout, 0.6f); + uiItemL(layout, IFACE_("Search"), ICON_NONE); + uiItemS_ex(layout, 0.7f); + } + else if (search_type) { + uiItemL(layout, "", UI_icon_from_event_type(EVT_AKEY, KM_ANY)); + uiItemL(layout, ("-"), ICON_NONE); + uiItemL(layout, "", UI_icon_from_event_type(EVT_ZKEY, KM_ANY)); + uiItemS_ex(layout, 0.6f); + uiItemL(layout, IFACE_("Search"), ICON_NONE); + uiItemS_ex(layout, 0.7f); + } + + uiItemL(layout, "", UI_icon_from_event_type(EVT_UPARROWKEY, KM_ANY)); + uiItemL(layout, "", UI_icon_from_event_type(EVT_DOWNARROWKEY, KM_ANY)); + uiItemL(layout, "", UI_icon_from_event_type(EVT_LEFTARROWKEY, KM_ANY)); + uiItemL(layout, "", UI_icon_from_event_type(EVT_RIGHTARROWKEY, KM_ANY)); + uiItemL(layout, "", UI_icon_from_event_type(EVT_RETKEY, KM_ANY)); + uiItemL(layout, "", UI_icon_from_event_type(EVT_ESCKEY, KM_ANY)); + uiItemS_ex(layout, 0.6f); + uiItemL(layout, IFACE_("Keyboard Navigation"), ICON_NONE); +} + static uiPopupBlockHandle *ui_popup_menu_create( bContext *C, ARegion *butregion, @@ -403,7 +442,7 @@ static uiPopupBlockHandle *ui_popup_menu_create( pup->but = but; if (but->type == UI_BTYPE_PULLDOWN) { - ED_workspace_status_text(C, IFACE_("Press spacebar to search...")); + ED_workspace_status_text(C, ui_popup_menu_space_search_status_cb, nullptr); } } @@ -610,12 +649,7 @@ static void ui_popup_menu_create_from_menutype(bContext *C, STRNCPY(handle->menu_idname, mt->idname); handle->can_refresh = true; - if (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) { - ED_workspace_status_text(C, IFACE_("Type to search...")); - } - else if (mt->idname[0]) { - ED_workspace_status_text(C, IFACE_("Press spacebar to search...")); - } + ED_workspace_status_text(C, ui_popup_menu_space_search_status_cb, mt); } int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports) diff --git a/source/blender/editors/interface/templates/interface_templates.cc b/source/blender/editors/interface/templates/interface_templates.cc index 2047a435dfc..b2392353c14 100644 --- a/source/blender/editors/interface/templates/interface_templates.cc +++ b/source/blender/editors/interface/templates/interface_templates.cc @@ -6154,8 +6154,9 @@ void uiTemplateInputStatus(uiLayout *layout, bContext *C) WorkSpace *workspace = CTX_wm_workspace(C); /* Workspace status text has priority. */ - if (workspace->status_text) { - uiItemL(layout, workspace->status_text, ICON_NONE); + if (workspace->status_cb) { + uiLayout *row = uiLayoutRow(layout, true); + workspace->status_cb(C, row, workspace->status_cb_data); return; } diff --git a/source/blender/editors/screen/area.cc b/source/blender/editors/screen/area.cc index 805b4f9942a..d10fea41c95 100644 --- a/source/blender/editors/screen/area.cc +++ b/source/blender/editors/screen/area.cc @@ -834,7 +834,18 @@ void ED_area_status_text(ScrArea *area, const char *str) } } -void ED_workspace_status_text(bContext *C, const char *str) +static void ed_workspace_simple_text_status_cb(const bContext *C, + uiLayout *layout, + void *user_data) +{ + uiItemL(layout, static_cast(user_data), ICON_NONE); +} + +void ED_workspace_status_text(bContext *C, + void (*status_cb)(const bContext *C, + uiLayout *layout, + void *user_data), + void *user_data) { wmWindow *win = CTX_wm_window(C); WorkSpace *workspace = CTX_wm_workspace(C); @@ -844,22 +855,43 @@ void ED_workspace_status_text(bContext *C, const char *str) return; } + if (status_cb) { + workspace->status_cb = status_cb; + workspace->status_cb_data = user_data; + } + else { + workspace->status_cb = nullptr; + workspace->status_cb_data = nullptr; + MEM_SAFE_FREE(workspace->status_text); + } + + /* Redraw status bar. */ + LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) { + if (area->spacetype == SPACE_STATUSBAR) { + ED_area_tag_redraw(area); + break; + } + } +} + +void ED_workspace_status_text(bContext *C, const char *str) +{ + WorkSpace *workspace = CTX_wm_workspace(C); + + /* Can be nullptr when running operators in background mode. */ + if (workspace == nullptr) { + return; + } + if (str) { if (workspace->status_text == nullptr) { workspace->status_text = static_cast(MEM_mallocN(UI_MAX_DRAW_STR, "headerprint")); } BLI_strncpy(workspace->status_text, str, UI_MAX_DRAW_STR); + ED_workspace_status_text(C, ed_workspace_simple_text_status_cb, workspace->status_text); } else { - MEM_SAFE_FREE(workspace->status_text); - } - - /* Redraw status bar. */ - LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) { - if (area->spacetype == SPACE_STATUSBAR) { - ED_area_tag_redraw(area); - break; - } + ED_workspace_status_text(C, nullptr, nullptr); } } diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index 78f2f8dcba7..7b9359535b7 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -149,6 +149,10 @@ typedef struct WorkSpace { * spreadsheet and viewport do this). */ ViewerPath viewer_path; + + void (*status_cb)(const struct bContext *C, struct uiLayout *layout, void *user_data); + void *status_cb_data; + } WorkSpace; /** -- 2.30.2