UI: uiBut Indeterminate State #108210
|
@ -86,6 +86,11 @@ typedef struct uiViewItemHandle uiViewItemHandle;
|
|||
#define UI_SEP_CHAR '|'
|
||||
#define UI_SEP_CHAR_S "|"
|
||||
|
||||
/**
|
||||
* Character used when value is indeterminate (multiple, unknown, unset).
|
||||
*/
|
||||
#define UI_VALUE_INDETERMINATE_CHAR BLI_STR_UTF8_EM_DASH
|
||||
|
||||
/* Separator for text in search menus (right pointing arrow).
|
||||
* keep in sync with `string_search.cc`. */
|
||||
#define UI_MENU_ARROW_SEP BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE
|
||||
|
|
|
@ -3792,15 +3792,8 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
/* if something changed in the button */
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
double value = UI_BUT_VALUE_UNSET;
|
||||
Harley marked this conversation as resolved
Outdated
Julian Eisel
commented
Would put this in Would put this in `UI_interface.h`, together with other defines like `UI_SEP_CHAR_S`.
|
||||
|
||||
/* Use emdash in place of text when in indeterminate state. */
|
||||
const char *UI_VALUE_INDETERMINATE_CHAR = "\u2014";
|
||||
|
||||
ui_but_update_select_flag(but, &value);
|
||||
|
||||
if ((but->drawflag & UI_BUT_INDETERMINATE) && (but->flag & UI_SELECT)) {
|
||||
but->flag &= ~UI_SELECT;
|
||||
}
|
||||
|
||||
/* only update soft range while not editing */
|
||||
if (!ui_but_is_editing(but)) {
|
||||
Harley marked this conversation as resolved
Outdated
Julian Eisel
commented
I still can't see an explanation on why this is done, only what it does. Testing the patch, when I simply enable I guess this should only affect drawing (it's controlled by a draw flag after all), so this should probably be done in I still can't see an explanation on _why_ this is done, only what it does. Testing the patch, when I simply enable `UI_BUT_INDETERMINATE` for all buttons, I get a whole bunch of interaction issues/glitches. That is because `UI_SELECT` is supposed to impact the behavior, not just the drawing.
I guess this should only affect drawing (it's controlled by a draw flag after all), so this should probably be done in `ui_draw_but()`. At the end of that we already do similar things to safely manipulate flags for drawing.
|
||||
if ((but->rnaprop != nullptr) || (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) {
|
||||
|
@ -3872,13 +3865,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (but->drawflag & UI_BUT_INDETERMINATE) {
|
||||
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
|
||||
but->drawflag &= ~(UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT);
|
||||
}
|
||||
else {
|
||||
STRNCPY(but->drawstr, but->str);
|
||||
}
|
||||
STRNCPY(but->drawstr, but->str);
|
||||
}
|
||||
break;
|
||||
Harley marked this conversation as resolved
Outdated
Julian Eisel
commented
It's not clear what It's not clear what `\u2014` is, better make this a named constant.
|
||||
|
||||
|
@ -3888,11 +3875,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
break;
|
||||
}
|
||||
UI_GET_BUT_VALUE_INIT(but, value);
|
||||
if (but->drawflag & UI_BUT_INDETERMINATE) {
|
||||
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
|
||||
but->drawflag &= ~(UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT);
|
||||
}
|
||||
else if (ui_but_is_float(but)) {
|
||||
if (ui_but_is_float(but)) {
|
||||
ui_but_build_drawstr_float(but, value);
|
||||
}
|
||||
else {
|
||||
|
@ -3915,15 +3898,9 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
case UI_BTYPE_TEXT:
|
||||
case UI_BTYPE_SEARCH_MENU:
|
||||
if (!but->editstr) {
|
||||
if (but->drawflag & UI_BUT_INDETERMINATE) {
|
||||
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
|
||||
but->drawflag &= ~(UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT);
|
||||
}
|
||||
else {
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
ui_but_string_get(but, str, UI_MAX_DRAW_STR);
|
||||
SNPRINTF(but->drawstr, "%s%s", but->str, str);
|
||||
}
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
ui_but_string_get(but, str, UI_MAX_DRAW_STR);
|
||||
SNPRINTF(but->drawstr, "%s%s", but->str, str);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1937,6 +1937,19 @@ static void widget_draw_text(const uiFontStyle *fstyle,
|
|||
}
|
||||
}
|
||||
|
||||
/* If not editing and indeterminate, show dash.*/
|
||||
if (but->drawflag & UI_BUT_INDETERMINATE && !but->editstr &&
|
||||
ELEM(but->type,
|
||||
UI_BTYPE_MENU,
|
||||
UI_BTYPE_NUM,
|
||||
UI_BTYPE_NUM_SLIDER,
|
||||
UI_BTYPE_TEXT,
|
||||
UI_BTYPE_SEARCH_MENU))
|
||||
{
|
||||
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
|
||||
Harley marked this conversation as resolved
Julian Eisel
commented
Do not modify Do not modify `but->drawstr` here, the function shouldn't have such side effects. Modify the local `drawstr` instead.
|
||||
align = UI_STYLE_TEXT_CENTER;
|
||||
}
|
||||
Harley marked this conversation as resolved
Outdated
Julian Eisel
commented
This doesn't have any impact, I think a This doesn't have any impact, `use_right_only` is already false at this point, and may only be set to true later. Same for `drawstr_right`.
I think a `bool drawstr_overridden` makes sense. When true we don't draw right aligned text. This could also be set when `but->editstr` is true.
|
||||
|
||||
/* text button selection, cursor, composite underline */
|
||||
if (but->editstr && but->pos != -1) {
|
||||
int but_pos_ofs;
|
||||
|
@ -5054,6 +5067,21 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
|
|||
state.but_flag &= ~UI_BUT_OVERRIDDEN;
|
||||
}
|
||||
|
||||
if ((state.but_drawflag & UI_BUT_INDETERMINATE)) {
|
||||
if (state.but_flag & UI_SELECT) {
|
||||
state.but_flag &= ~UI_SELECT;
|
||||
}
|
||||
Harley marked this conversation as resolved
Julian Eisel
commented
I'd remove the I'd remove the ` && (state.but_flag & UI_SELECT)` part, just makes the logic look unnecessarily complex.
|
||||
if (ELEM(but->type,
|
||||
UI_BTYPE_MENU,
|
||||
UI_BTYPE_NUM,
|
||||
UI_BTYPE_NUM_SLIDER,
|
||||
UI_BTYPE_TEXT,
|
||||
UI_BTYPE_SEARCH_MENU))
|
||||
{
|
||||
state.but_drawflag &= ~(UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
const float zoom = 1.0f / but->block->aspect;
|
||||
wt->state(wt, &state, but->emboss);
|
||||
if (wt->custom) {
|
||||
|
|
emdash
isn't really useful either, this should be more descriptive. Would suggest something likeUI_VALUE_INDETERMINATE_CHAR
.