Page MenuHome

UI: Better split layout support for checkboxes

Authored by Julian Eisel (Severin) on Apr 14 2020, 6:25 PM.
"Love" token, awarded by ez."Love" token, awarded by billreynish."Love" token, awarded by TakingFire."Love" token, awarded by Schiette."Love" token, awarded by brilliant_ape."Love" token, awarded by Tetone.



UI: Better split layout support for checkboxes

Makes the following layout changes possible:

Best test this in the temp-checkbox-layout-tweaks branch which contains
layout tweaks all over to make good use of the changes here. These will be
submitted separately.

Main changes:

  • Add support for row and column headers (i.e. uiLayout.column(heading="Foo"), uiLayout.row(heading="Bar")). If the first property added to this layout doesn't insert anything into the label split column, the heading is inserted there. Otherwise, it's inserted as own item.
  • Add support for manually inserting decorators for an existing item (uiLayout.prop_decorator()). That way layout creators can manually insert this, which was the only way I saw to support these layouts:
  • Autogenerated layouts for operator properties look bad if there are only checkboxes (which only use half the region width). So before creating the layout, we iterate over visible properties and disable split layout if all are booleans. I think this is fine, if needed we could also add layout hints to operators.
  • uiTemplateOperatorPropertyButs() now handles macros itself, the caller used to be responsible for this. Code that didn't handle these so far never used macros I think, so this change should be visible.
  • Remove manual property split layout from autogenerated operator properties layout.
  • Padding of checkboxes is tweaked to make their label visually more connected to the checkboxes.
  • Support split layout for menus (should work for, .operator_menu_enum(), .prop_menu_enum(), maybe more)

Diff Detail

rB Blender

Event Timeline

Julian Eisel (Severin) requested review of this revision.Apr 14 2020, 6:25 PM
Julian Eisel (Severin) edited the summary of this revision. (Show Details)Apr 14 2020, 6:39 PM

This is used in the modifier-panels-ui branch as flag for uiItemR(), so that code doesn't have to do workarounds when inserting multiple items to a split row. See rB513de8eaf6d8.
If useful we could expose this in .py too.

This revision is now accepted and ready to land.Apr 14 2020, 8:42 PM
Campbell Barton (campbellbarton) added inline comments.

The docs should note that this needs to be added immediately after the previous button (the order in the list matters, or it wont work properly).

Or it may be better to make this a boolean option for existing property buttons.

Brecht Van Lommel (brecht) requested changes to this revision.Apr 15 2020, 10:16 PM

Padding of checkboxes is tweaked to make their label visually more connected to the checkboxes.

I think the checkbox and text are too close together now, it's less than the width of a space between words (3 pixels vs. 6 pixels here). Should be at least the width of a space I think.

Other than that this looks reasonable, but I haven't read through all the changes yet.

This revision now requires changes to proceed.Apr 15 2020, 10:16 PM

@Brecht Van Lommel (brecht) let me give you a better explanation of the changes to the checkbox-distance-to-text change:

Before, the text in Blender was very far away from the checkbox compared to other apps I could find:

The fact that the text was as far or further away from the checkbox as the next checkbox, meant that the visual grouping wasn't optimal:

Compare it to this - the text is much closer to the checkbox it belongs to, compared to the distance to the next one, making it easier to see that the text belongs to one specific checkbox:

The other reason, is that when using headings, it works much better with this change. Let's look at a before/after:

This version looks like a checkbox in the middle, with some text flying around on either side:

Compare to this. The text clearly belongs to each checkbox and the heading is nicely different, separated:

This information should have been added to the design task or the patch description above. But, perhaps this gives you a better idea of the rationale behind this particular change.

I don't know. Most of the apps I've checked here do have checkboxes maybe a bit closer, but not anywhere near as crammed together as Mac OS, such as:

Photoshop 2020:


Visual Studio:

Windows Explorer:


Quixel Mixer:

BMD Fusion:

@William Reynish (billreynish) I think it's just an issue with smaller UI scales, which doesn't show when it's 2.0 as on macOS retina displays.

Fix for excessive rounding:

diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 0aed84f..38c9a24 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -4146,7 +4146,7 @@ static void widget_optionbut(uiWidgetColors *wcol,
   uiWidgetBase wtb;
   rcti recttemp = *rect;
   float rad;
-  int delta;
+  float delta;
@@ -4159,7 +4159,7 @@ static void widget_optionbut(uiWidgetColors *wcol,
   /* smaller */
-  delta = 1 + BLI_rcti_size_y(&recttemp) / 8;
+  delta = 1 + BLI_rcti_size_y(&recttemp) / 8.0f;
       &recttemp, BLI_rcti_size_x(&recttemp) - delta * 2, BLI_rcti_size_y(&recttemp) - delta * 2);
   /* Keep one edge in place. */

Before and after with UI scale 1.44:

@Brecht Van Lommel (brecht) I tried this change before, but issue is that it scales down checkboxes by 2px I think. That in itself I wouldn't mind, but it breaks vertical alignment with panel headers, e.g. at 1.0 DPI:

Now this can be tweaked too, but I didn't get it to work just right with different DPI scales. I already did quite some experimenting with this earlier, but I can have a quick look again, to at least make it look fine on 1.0 DPI with your changes.


Note to myself: This should check if but_iter == but_decorate.
(Although currently, ui_but_rna_equals_ex() would fail on self because RNA data is stored differently, but I don't want to rely on such obscure conditions.)


This is actually not true anymore, the decorator can be placed anywhere in the block. It's still fastest to place it immediately after, although not doing that shouldn't make any notable difference really.

See ui_but_anim_decorate_find_attached_button()

  • Fix expanded enums using columns within split layout
  • Fix inconsistent checkbox text padding with different DPIs
  • Don't compare decorator button against itself

@Brecht Van Lommel (brecht) turns out the issue was that DPI and zoom got basically applied twice in the padding calculations, so I guess rounding errors added up. Once by using the rectangle height for the text rectangle changes in widget_optionbut(), once by the regular widget_draw_text_icon() text padding. Now widget_optionbut() has full control over the padding.

This revision is now accepted and ready to land.Apr 17 2020, 4:03 PM