diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-04-14 11:46:13 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-04-14 11:50:28 +0300 |
commit | e6d9d5dcc18f3ab55c31abc6bfb2010081538422 (patch) | |
tree | 99c6315d9612d81f4b9c34a72674bb702f64ceda | |
parent | 571646ebc175877225c26a3dcf8869691cf70ba7 (diff) |
UI: improve menu search with dimmed menu prefix
- Show dimmed text for the menu entries leading up to the menu item.
- Show icons between the menu text and menu item.
- Use unicode right pointing triangle instead of arrow.
10 files changed, 115 insertions, 35 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 1133f9e72c4..774cf8c509f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -49,6 +49,7 @@ struct PanelType; struct PointerRNA; struct PropertyRNA; struct ReportList; +struct ResultBLF; struct ScrArea; struct bContext; struct bContextStore; @@ -1576,6 +1577,7 @@ void UI_but_func_search_set(uiBut *but, void *arg, uiButSearchArgFreeFunc search_arg_free_func, uiButHandleFunc bfunc, + const char *search_sep_string, void *active); /* height in pixels, it's using hardcoded values still */ int UI_searchbox_size_y(void); @@ -2416,7 +2418,8 @@ void UI_fontstyle_draw_ex(const struct uiFontStyle *fs, const struct uiFontStyleDraw_Params *fs_params, size_t len, int *r_xofs, - int *r_yofs); + int *r_yofs, + struct ResultBLF *r_info); void UI_fontstyle_draw(const struct uiFontStyle *fs, const struct rcti *rect, const char *str, diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2b674686ffa..9ec660a9714 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -6332,7 +6332,9 @@ uiBut *uiDefSearchBut(uiBlock *block, /** * \param search_func, bfunc: both get it as \a arg. * \param arg: user value, - * \param active: when set, button opens with this item visible and selected. + * \param active: when set, button opens with this item visible and selected. + * \param separator_string: when not NULL, this string is used as a separator, + * showing the icon and highlighted text after the last instance of this string. */ void UI_but_func_search_set(uiBut *but, uiButSearchCreateFunc search_create_func, @@ -6340,6 +6342,7 @@ void UI_but_func_search_set(uiBut *but, void *arg, uiButSearchArgFreeFunc search_arg_free_func, uiButHandleFunc bfunc, + const char *search_sep_string, void *active) { /* needed since callers don't have access to internal functions @@ -6358,6 +6361,7 @@ void UI_but_func_search_set(uiBut *but, but->search_arg = arg; but->search_arg_free_func = search_arg_free_func; + but->search_sep_string = search_sep_string; if (bfunc) { #ifdef DEBUG @@ -6467,6 +6471,7 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, but, NULL, operator_enum_call_cb, + NULL, NULL); but->optype = ot; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 5573d9b2edb..9142aebd1ef 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -205,6 +205,7 @@ struct uiBut { uiButSearchFunc search_func; void *search_arg; uiButSearchArgFreeFunc search_arg_free_func; + const char *search_sep_string; uiButHandleRenameFunc rename_func; void *rename_arg1; @@ -851,7 +852,8 @@ void ui_draw_menu_item(const struct uiFontStyle *fstyle, const char *name, int iconid, int state, - bool use_sep); + bool use_sep, + int *r_name_width); void ui_draw_preview_item( const struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 92779c83d9a..cbea32f179a 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2633,6 +2633,7 @@ void ui_but_add_search( coll_search, ui_rna_collection_search_free_cb, NULL, + NULL, NULL); } else if (but->type == UI_BTYPE_SEARCH_MENU) { diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index 48779fd86dc..e2c87891169 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <string.h> +#include "DNA_ID.h" #include "MEM_guardedalloc.h" #include "DNA_userdef_types.h" @@ -89,9 +90,14 @@ typedef struct uiSearchboxData { bool noback; /** draw thumbnail previews, rather than list */ bool preview; - /** use the UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data) */ + /** Use the #UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data). */ bool use_sep; int prv_rows, prv_cols; + /** + * Show the active icon and text after the last instance of this string. + * Used so we can show leading text to menu items less prominently (not related to 'use_sep'). + */ + const char *sep_string; } uiSearchboxData; #define SEARCH_ITEMS 10 @@ -465,19 +471,50 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region) } } else { + const int search_sep_len = data->sep_string ? strlen(data->sep_string) : 0; /* draw items */ for (a = 0; a < data->items.totitem; a++) { const int state = ((a == data->active) ? UI_ACTIVE : 0) | data->items.states[a]; + char *name = data->items.names[a]; + int icon = data->items.icons[a]; + char *name_sep_test = NULL; ui_searchbox_butrect(&rect, data, a); /* widget itself */ - ui_draw_menu_item(&data->fstyle, - &rect, - data->items.names[a], - data->items.icons[a], - state, - data->use_sep); + if ((search_sep_len == 0) || + !(name_sep_test = strstr(data->items.names[a], data->sep_string))) { + + /* Simple menu item. */ + ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, data->use_sep, NULL); + } + else { + /* Split menu item, faded text before the separator. */ + char *name_sep = NULL; + do { + name_sep = name_sep_test; + name_sep_test = strstr(name_sep + search_sep_len, data->sep_string); + } while (name_sep_test != NULL); + + name_sep += search_sep_len; + const char name_sep_prev = *name_sep; + *name_sep = '\0'; + int name_width = 0; + ui_draw_menu_item( + &data->fstyle, &rect, name, 0, state | UI_BUT_INACTIVE, false, &name_width); + *name_sep = name_sep_prev; + rect.xmin += name_width; + rect.xmin += UI_UNIT_X / 4; + + if (icon == ICON_BLANK1) { + icon = ICON_NONE; + rect.xmin -= UI_DPI_ICON_SIZE / 4; + } + + /* The previous menu item draws the active selection. */ + ui_draw_menu_item( + &data->fstyle, &rect, name_sep, icon, state & ~UI_ACTIVE, data->use_sep, NULL); + } } /* indicate more */ if (data->items.more) { @@ -566,6 +603,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) { data->use_sep = true; } + data->sep_string = but->search_sep_string; /* compute position */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { @@ -762,9 +800,10 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre), data->items.icons[a], state, - false); + false, + NULL); ui_draw_menu_item( - &data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep); + &data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep, NULL); } } /* indicate more */ diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index a67d4f4ce83..d14c9e69e55 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -148,7 +148,8 @@ void UI_fontstyle_draw_ex(const uiFontStyle *fs, const struct uiFontStyleDraw_Params *fs_params, size_t len, int *r_xofs, - int *r_yofs) + int *r_yofs, + struct ResultBLF *r_info) { int xofs = 0, yofs; int font_flag = BLF_CLIPPING; @@ -196,7 +197,7 @@ void UI_fontstyle_draw_ex(const uiFontStyle *fs, BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); BLF_color4ubv(fs->uifont_id, col); - BLF_draw(fs->uifont_id, str, len); + BLF_draw_ex(fs->uifont_id, str, len, r_info); BLF_disable(fs->uifont_id, font_flag); @@ -212,7 +213,7 @@ void UI_fontstyle_draw(const uiFontStyle *fs, { int xofs, yofs; - UI_fontstyle_draw_ex(fs, rect, str, col, fs_params, BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs); + UI_fontstyle_draw_ex(fs, rect, str, col, fs_params, BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs, NULL); } /* drawn same as above, but at 90 degree angle */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 31417844347..f730e4c0e52 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -287,8 +287,14 @@ static uiBlock *template_common_search_menu(const bContext *C, 0, ""); } - UI_but_func_search_set( - but, ui_searchbox_create_generic, search_func, search_arg, NULL, handle_func, active_item); + UI_but_func_search_set(but, + ui_searchbox_create_generic, + search_func, + search_arg, + NULL, + handle_func, + NULL, + active_item); UI_block_bounds_set_normal(block, 0.3f * U.widget_unit); UI_block_direction_set(block, UI_DIR_DOWN); @@ -6660,8 +6666,14 @@ static void operator_search_cb(const bContext *C, void UI_but_func_operator_search(uiBut *but) { - UI_but_func_search_set( - but, ui_searchbox_create_operator, operator_search_cb, NULL, false, operator_call_cb, NULL); + UI_but_func_search_set(but, + ui_searchbox_create_operator, + operator_search_cb, + NULL, + false, + operator_call_cb, + NULL, + NULL); } void uiTemplateOperatorSearch(uiLayout *layout) @@ -6684,6 +6696,9 @@ void uiTemplateOperatorSearch(uiLayout *layout) /** \name Menu Search Template * \{ */ +/* Unicode arrow. */ +#define MENU_SEP "\xe2\x96\xb6" + struct MenuSearch_Parent { struct MenuSearch_Parent *parent; MenuType *parent_mt; @@ -7127,9 +7142,6 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, /* NOTE: currently this builds the full path for each menu item, * that could be moved into the parent menu. */ - /* Unicode arrow. */ -#define MENU_SEP "\xe2\x86\x92" - /* Set names as full paths. */ LISTBASE_FOREACH (struct MenuSearch_Item *, item, &data->items) { if (item->menu_parent != NULL) { @@ -7176,7 +7188,6 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, BLI_dynstr_clear(dyn_str); } BLI_dynstr_free(dyn_str); -#undef MENU_SEP /* Finally sort menu items. * @@ -7309,6 +7320,7 @@ void UI_but_func_menu_search(uiBut *but) data, menu_items_from_ui_destroy, menu_call_fn, + MENU_SEP, NULL); } @@ -7326,6 +7338,8 @@ void uiTemplateMenuSearch(uiLayout *layout) UI_but_func_menu_search(but); } +#undef MENU_SEP + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 88bc4c38fd3..86a5fd5dabb 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2315,7 +2315,8 @@ static void widget_draw_text(const uiFontStyle *fstyle, }, drawlen, &font_xofs, - &font_yofs); + &font_yofs, + NULL); if (but->menu_key != '\0') { char fixedbuf[128]; @@ -5267,8 +5268,13 @@ void ui_draw_tooltip_background(const uiStyle *UNUSED(style), uiBlock *UNUSED(bl /* helper call to draw a menu item without button */ /* state: UI_ACTIVE or 0 */ -void ui_draw_menu_item( - const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state, bool use_sep) +void ui_draw_menu_item(const uiFontStyle *fstyle, + rcti *rect, + const char *name, + int iconid, + int state, + bool use_sep, + int *r_name_width) { uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM); rcti _rect = *rect; @@ -5318,13 +5324,22 @@ void ui_draw_menu_item( UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0'); } - UI_fontstyle_draw(fstyle, - rect, - drawstr, - wt->wcol.text, - &(struct uiFontStyleDraw_Params){ - .align = UI_STYLE_TEXT_LEFT, - }); + int xofs = 0, yofs = 0; + struct ResultBLF info; + UI_fontstyle_draw_ex(fstyle, + rect, + drawstr, + wt->wcol.text, + &(struct uiFontStyleDraw_Params){ + .align = UI_STYLE_TEXT_LEFT, + }, + BLF_DRAW_STR_DUMMY_MAX, + &xofs, + &yofs, + &info); + if (r_name_width != NULL) { + *r_name_width = xofs + info.width; + } } /* part text right aligned */ diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 38ec855e845..50c32da4b5a 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -1179,7 +1179,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op) 0, 0, ""); - UI_but_func_search_set(but, NULL, node_find_cb, op->type, NULL, node_find_call_cb, NULL); + UI_but_func_search_set(but, NULL, node_find_cb, op->type, NULL, node_find_call_cb, NULL, NULL); UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT); /* fake button, it holds space for search items */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 34ca2267b7a..fe62272614f 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -590,7 +590,7 @@ static uiBlock *merged_element_search_menu(bContext *C, ARegion *region, void *d but = uiDefSearchBut( block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, menu_width, UI_UNIT_Y, 0, 0, ""); UI_but_func_search_set( - but, NULL, merged_element_search_cb, data, NULL, merged_element_search_call_cb, NULL); + but, NULL, merged_element_search_cb, data, NULL, merged_element_search_call_cb, NULL, NULL); UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT); /* Fake button to hold space for search items */ |