UI: uiBut Indeterminate State #108210
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Code Documentation
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#108210
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "Harley/blender:Indeterminate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Setting a new uiBut drawflag shows items in an indeterminate state,
not indicating a specific value or state.
This is needed for the Asset Shelf, but also for multi-object property editing if we ever want to make that default behavior. Properties shared between multiple objects but with differing values would show this indeterminate state. This just adds a new but->drawflag of UI_BUT_INDETERMINATE that gives different behavior:
Better to show a dash instead of blank (cc @pablovazquez )
Dalai Felinto referenced this pull request2023-05-30 14:58:54 +02:00
Wider "emdash" looks okay where narrow hypen looked too inconsequential.
Fantastic, it looks much better Harley, thanks.
Could you please try to centralise the dashes everywhere? (object font, text on curve, rotation, and the drop-down)
I think it will look better (for the drop down you probably want to centralise considering the entire area, “ignoring” the arrow. Otherwise it won’t align well in the UI with the other elements.
It looks good enough for me 👍
The one thing I'm wondering is, should we modify the draw-string like done here, or should we handle this in widget drawing? I think using the draw string makes sense, and in testing it behaves nicely (e.g. clicking to edit text or copy/pasting still uses the actual value). @ideasman42 any concerns about that?
We also need to figure out how to set this flag properly, like, you wouldn't want to always have to set the flag manually (which involves additional checks). Probably
ui_but_is_pushed_ex()
should allow some 3-way state as well. But this can be done separately.@ -319,1 +319,4 @@
UI_BUT_CHECKBOX_INVERT = 1 << 25,
/* Drawn in a way that indicates that the state/value is unknown. */
UI_BUT_INDETERMINATE = 1 << 26,
Not sure if indeterminate is the right word. For example for the checkbox in the asset catalog selector the state is known (it's unchecked, we just want to indicate that it has checked children). Maybe
UI_BUT_INDICATE_MUTLIVALUE
?@ -3797,6 +3797,11 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
}
}
if (but->drawflag & UI_BUT_INDETERMINATE) {
I'd rather avoid flags that silently change other flags. Why exactly is this needed?
@ -3863,2 +3868,3 @@
}
STRNCPY(but->drawstr, but->str);
if (but->drawflag & UI_BUT_INDETERMINATE) {
STRNCPY(but->drawstr, "\u2014");
It's not clear what
\u2014
is, better make this a named constant.@ -4164,0 +4177,4 @@
/* Flush the widget cache so we can draw on top. */
GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
We should avoid flushing the widget cache, this can introduce slowdowns (there were significant slowdowns in widget drawing in early 2.8, before adding the cache). It should be trivial to draw a line in the widget shader, without immediate mode drawing. E.g. see
shape_preset_init_number_arrows()
.All other uses 3-state checkboxes I have found use that word, and these include usecases that fit yours exactly. The best example is the HTML DOM where you can do things like:
https://css-tricks.com/indeterminate-checkboxes/
I added some comments, but it is to center the text and to unselect toggles.
It certainly looks trivial but so far not finding it as such. Although that function sets a vert array and face array those seem to be ignored and everything is instead done in the shader. For example you can change that tria->type from ROUNDBOX_TRIA_ARROWS to ROUNDBOX_TRIA_CHECK and a checkmark will display without changing anything else. weird.
In the current patch the selected color is used with transparency. I think we should blend between the un-selected & selected color instead. Otherwise it would look weird if the region background is drastically different from the widget inner color.
I personally still don't really like that term, or at least would prefer what I suggested earlier. But fair enough, the commonality may be worthwhile.
AFAICS the new shape needs to be added both in the C code and in the shader. Maybe best if you ask @fclem for help.
@ -3789,2 +3789,4 @@
double value = UI_BUT_VALUE_UNSET;
/* Use emdash in place of text when in indeterminate state. */
const char *emdash = "\u2014";
emdash
isn't really useful either, this should be more descriptive. Would suggest something likeUI_VALUE_INDETERMINATE_CHAR
.@ -3798,2 +3801,4 @@
}
if (but->drawflag & UI_BUT_INDETERMINATE) {
/* Center text. */
These comments only explain what it does which is obvious from the code. But why does it do this? And for which button types?
@ -3789,2 +3790,4 @@
double value = UI_BUT_VALUE_UNSET;
/* Use emdash in place of text when in indeterminate state. */
const char *UI_VALUE_INDETERMINATE_CHAR = "\u2014";
Would put this in
UI_interface.h
, together with other defines likeUI_SEP_CHAR_S
.@ -3791,2 +3795,4 @@
ui_but_update_select_flag(but, &value);
if ((but->drawflag & UI_BUT_INDETERMINATE) && (but->flag & UI_SELECT)) {
but->flag &= ~UI_SELECT;
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 becauseUI_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.@ -3864,1 +3872,3 @@
STRNCPY(but->drawstr, but->str);
if (but->drawflag & UI_BUT_INDETERMINATE) {
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
but->drawflag &= ~(UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT);
Same here, not sure if we should permanently modify the drawing flags here. Can be done just before drawing.
Actually, let's not even override the draw-string here, and just do that in
widget_draw_text()
by settingdrawstr
toUI_VALUE_INDETERMINATE_CHAR
for specific button types.@ -5032,6 +5070,10 @@ 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) && (state.but_flag & UI_SELECT)) {
I'd remove the
&& (state.but_flag & UI_SELECT)
part, just makes the logic look unnecessarily complex.@ -1930,0 +1946,4 @@
UI_BTYPE_TEXT,
UI_BTYPE_SEARCH_MENU))
{
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
Do not modify
but->drawstr
here, the function shouldn't have such side effects. Modify the localdrawstr
instead.@ -1930,0 +1948,4 @@
{
STRNCPY(but->drawstr, UI_VALUE_INDETERMINATE_CHAR);
align = UI_STYLE_TEXT_CENTER;
use_right_only = false;
This doesn't have any impact,
use_right_only
is already false at this point, and may only be set to true later. Same fordrawstr_right
.I think a
bool drawstr_overridden
makes sense. When true we don't draw right aligned text. This could also be set whenbut->editstr
is true.