UI: Support right aligned non-shortcut hints in widgets

Widget drawing code already supported drawing right-aligned, grayed out
shortcut strings. This patch generalizes things a bit so this can also
be used to draw other hints in the same way. There have been a few
instances in the past where this would've been useful, D11046 being the
latest one.

Note that besides some manual regression testing, I didn't check if this
works yet, as there is no code actually using it (other than the
shortcuts). Can be checked as part of further development for D11046.

A possible further improvement would be providing a way to define how
clipping should be done. E.g. sometimes the right-aligned text should be
clipped first (because it's just a hint), in other cases it should be
left untouched (like current code explicitly does it for shortcuts).

Removes the `UI_BUT_HAS_SHORTCUT` flag, which isn't needed anymore.
This commit is contained in:
2021-06-15 18:53:32 +02:00
parent fcc844f8fb
commit a4f840e15b
5 changed files with 31 additions and 34 deletions

View File

@@ -290,18 +290,14 @@ enum {
/** Active right part of number button */ /** Active right part of number button */
UI_BUT_ACTIVE_RIGHT = 1 << 22, UI_BUT_ACTIVE_RIGHT = 1 << 22,
/* (also used by search buttons to enforce shortcut display for their items). */
/** Button has shortcut text. */
UI_BUT_HAS_SHORTCUT = 1 << 23,
/** Reverse order of consecutive off/on icons */ /** Reverse order of consecutive off/on icons */
UI_BUT_ICON_REVERSE = 1 << 24, UI_BUT_ICON_REVERSE = 1 << 23,
/** Value is animated, but the current value differs from the animated one. */ /** Value is animated, but the current value differs from the animated one. */
UI_BUT_ANIMATED_CHANGED = 1 << 25, UI_BUT_ANIMATED_CHANGED = 1 << 24,
/* Draw the checkbox buttons inverted. */ /* Draw the checkbox buttons inverted. */
UI_BUT_CHECKBOX_INVERT = 1 << 26, UI_BUT_CHECKBOX_INVERT = 1 << 25,
}; };
/* scale fixed button widths by this to account for DPI */ /* scale fixed button widths by this to account for DPI */

View File

@@ -1160,7 +1160,6 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
MEM_freeN(butstr_orig); MEM_freeN(butstr_orig);
but->str = but->strdata; but->str = but->strdata;
but->flag |= UI_BUT_HAS_SEP_CHAR; but->flag |= UI_BUT_HAS_SEP_CHAR;
but->drawflag |= UI_BUT_HAS_SHORTCUT;
ui_but_update(but); ui_but_update(but);
} }

View File

@@ -1280,7 +1280,6 @@ void ui_popup_context_menu_for_panel(bContext *C, ARegion *region, Panel *panel)
uiBlock *block = uiLayoutGetBlock(layout); uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but = block->buttons.last; uiBut *but = block->buttons.last;
but->flag |= UI_BUT_HAS_SEP_CHAR; but->flag |= UI_BUT_HAS_SEP_CHAR;
but->drawflag |= UI_BUT_HAS_SHORTCUT;
} }
} }
UI_popup_menu_end(C, pup); UI_popup_menu_end(C, pup);

View File

@@ -95,7 +95,7 @@ typedef struct uiSearchboxData {
/** draw thumbnail previews, rather than list */ /** draw thumbnail previews, rather than list */
bool preview; 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; bool use_shortcut_sep;
int prv_rows, prv_cols; int prv_rows, prv_cols;
/** /**
* Show the active icon and text after the last instance of this string. * Show the active icon and text after the last instance of this string.
@@ -314,7 +314,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
data->items.name_prefix_offsets[data->active] : data->items.name_prefix_offsets[data->active] :
0); 0);
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL; const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen); BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
@@ -535,7 +535,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
/* Never include the prefix in the button. */ /* Never include the prefix in the button. */
(data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] : (data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
0); 0);
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL; const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) { if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
data->active = a; data->active = a;
break; break;
@@ -627,7 +627,7 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
char *name_sep_test = NULL; char *name_sep_test = NULL;
uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE; uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE;
if (data->use_sep) { if (data->use_shortcut_sep) {
separator_type = UI_MENU_ITEM_SEPARATOR_SHORTCUT; separator_type = UI_MENU_ITEM_SEPARATOR_SHORTCUT;
} }
/* Only set for displaying additional hint (e.g. library name of a linked data-block). */ /* Only set for displaying additional hint (e.g. library name of a linked data-block). */
@@ -719,7 +719,10 @@ static void ui_searchbox_region_free_cb(ARegion *region)
region->regiondata = NULL; region->regiondata = NULL;
} }
ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but) static ARegion *ui_searchbox_create_generic_ex(bContext *C,
ARegion *butregion,
uiButSearch *search_but,
const bool use_shortcut_sep)
{ {
wmWindow *win = CTX_wm_window(C); wmWindow *win = CTX_wm_window(C);
const uiStyle *style = UI_style_get(); const uiStyle *style = UI_style_get();
@@ -759,12 +762,8 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
data->prv_cols = but->a2; data->prv_cols = but->a2;
} }
/* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of if (but->optype != NULL || use_shortcut_sep) {
* buttons are about data without having that pointer defined, let's rather try with optype!). data->use_shortcut_sep = true;
* One can also enforce that behavior by setting
* UI_BUT_HAS_SHORTCUT drawflag of search button. */
if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
data->use_sep = true;
} }
data->sep_string = search_but->item_sep_string; data->sep_string = search_but->item_sep_string;
@@ -888,6 +887,11 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
return region; return region;
} }
ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
return ui_searchbox_create_generic_ex(C, butregion, search_but, false);
}
/** /**
* Similar to Python's `str.title` except... * Similar to Python's `str.title` except...
* *
@@ -973,8 +977,8 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
data->items.names[a], data->items.names[a],
0, 0,
state, state,
data->use_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT : data->use_shortcut_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT :
UI_MENU_ITEM_SEPARATOR_NONE, UI_MENU_ITEM_SEPARATOR_NONE,
NULL); NULL);
} }
} }
@@ -996,8 +1000,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but) ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but)
{ {
UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); ARegion *region = ui_searchbox_create_generic_ex(C, butregion, search_but, true);
ARegion *region = ui_searchbox_create_generic(C, butregion, search_but);
region->type->draw = ui_searchbox_region_draw_cb__operator; region->type->draw = ui_searchbox_region_draw_cb__operator;
@@ -1016,8 +1019,7 @@ static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion
ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but) ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
{ {
UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); ARegion *region = ui_searchbox_create_generic_ex(C, butregion, search_but, true);
ARegion *region = ui_searchbox_create_generic(C, butregion, search_but);
if (false) { if (false) {
region->type->draw = ui_searchbox_region_draw_cb__menu; region->type->draw = ui_searchbox_region_draw_cb__menu;

View File

@@ -2131,14 +2131,15 @@ static void widget_draw_text(const uiFontStyle *fstyle,
transopts = ui_translate_buttons(); transopts = ui_translate_buttons();
#endif #endif
bool use_drawstr_right_as_hint = false;
/* cut string in 2 parts - only for menu entries */ /* cut string in 2 parts - only for menu entries */
if ((but->drawflag & UI_BUT_HAS_SHORTCUT) && (but->editstr == NULL)) { if (but->flag & UI_BUT_HAS_SEP_CHAR && (but->editstr == NULL)) {
if (but->flag & UI_BUT_HAS_SEP_CHAR) { drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
drawstr_right = strrchr(drawstr, UI_SEP_CHAR); if (drawstr_right) {
if (drawstr_right) { use_drawstr_right_as_hint = true;
drawstr_left_len = (drawstr_right - drawstr); drawstr_left_len = (drawstr_right - drawstr);
drawstr_right++; drawstr_right++;
}
} }
} }
@@ -2243,7 +2244,7 @@ static void widget_draw_text(const uiFontStyle *fstyle,
if (drawstr_right) { if (drawstr_right) {
uchar col[4]; uchar col[4];
copy_v4_v4_uchar(col, wcol->text); copy_v4_v4_uchar(col, wcol->text);
if (but->drawflag & UI_BUT_HAS_SHORTCUT) { if (use_drawstr_right_as_hint) {
col[3] *= 0.5f; col[3] *= 0.5f;
} }