UI: Remove dead space between tree view items

Part of #107742.

There used to be a small margin between items since the layout feels a
bit crammed otherwise. But this meant the mouse could be between items,
with no item highlighted or reacting to interactions. This was
especially annoying when dragging over items for drag and drop: in
between items dropping wasn't possible, and the drag-tooltip would
disappear, causing notable flickering during motions over the tree view.

The view item is now slightly enlarged to keep a look that is not too
crammed, and still remove the space between items. Item highlights are
still drawn with a smaller height (matching the normal widget height),
since anything else looked odd to me.

This now feels quite consistent with similar UIs (e.g. File Browser list
view or the Outliner), even though we give the items a bit more space.
This commit is contained in:
Julian Eisel
2023-09-22 17:15:12 +02:00
parent b838c34afa
commit 427bdc8dcf
3 changed files with 35 additions and 5 deletions

View File

@@ -369,6 +369,10 @@ struct uiButProgress : public uiBut {
struct uiButViewItem : public uiBut {
/* C-Handle to the view item this button was created for. */
uiViewItemHandle *view_item = nullptr;
/* Some items want to have a fixed size for drawing, differing from the interaction rectangle
* (e.g. so highlights are drawn smaller). */
int draw_width = 0;
int draw_height = 0;
};
/** Derived struct for #UI_BTYPE_HSVCUBE. */

View File

@@ -4178,19 +4178,32 @@ static void widget_menu_radial_itembut(uiBut *but,
widgetbase_draw(&wtb, wcol);
}
static void widget_list_itembut(uiWidgetColors *wcol,
static void widget_list_itembut(uiBut *but,
uiWidgetColors *wcol,
rcti *rect,
const uiWidgetStateInfo *state,
int /*roundboxalign*/,
const float zoom)
{
rcti draw_rect = *rect;
if (but->type == UI_BTYPE_VIEW_ITEM) {
uiButViewItem *item_but = static_cast<uiButViewItem *>(but);
if (item_but->draw_width > 0) {
BLI_rcti_resize_x(&draw_rect, item_but->draw_width);
}
if (item_but->draw_height > 0) {
BLI_rcti_resize_y(&draw_rect, item_but->draw_height);
}
}
uiWidgetBase wtb;
widget_init(&wtb);
/* no outline */
wtb.draw_outline = false;
const float rad = widget_radius_from_zoom(zoom, wcol);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
round_box_edges(&wtb, UI_CNR_ALL, &draw_rect, rad);
if (state->but_flag & UI_ACTIVE && !(state->but_flag & UI_SELECT)) {
copy_v3_v3_uchar(wcol->inner, wcol->text);
@@ -4208,7 +4221,7 @@ static void widget_preview_tile(uiBut *but,
const float zoom)
{
if (!ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) {
widget_list_itembut(wcol, rect, state, roundboxalign, zoom);
widget_list_itembut(but, wcol, rect, state, roundboxalign, zoom);
}
/* When the button is not tagged as having a preview icon, do regular icon drawing with the
@@ -4666,7 +4679,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
case UI_WTYPE_LISTITEM:
case UI_WTYPE_VIEW_ITEM:
wt.wcol_theme = &btheme->tui.wcol_list_item;
wt.draw = widget_list_itembut;
wt.custom = widget_list_itembut;
break;
case UI_WTYPE_PROGRESS:

View File

@@ -26,6 +26,16 @@
namespace blender::ui {
static int unpadded_item_height()
{
return UI_UNIT_Y;
}
static int padded_item_height()
{
const uiStyle *style = UI_style_get_dpi();
return unpadded_item_height() + style->buttonspacey;
}
/* ---------------------------------------------------------------------- */
AbstractTreeViewItem &TreeViewItemContainer::add_tree_item(
@@ -300,6 +310,7 @@ void AbstractTreeViewItem::add_treerow_button(uiBlock &block)
&block, UI_BTYPE_VIEW_ITEM, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nullptr, 0, 0, 0, 0, "");
view_item_but_->view_item = reinterpret_cast<uiViewItemHandle *>(this);
view_item_but_->draw_height = unpadded_item_height();
UI_but_func_set(view_item_but_, tree_row_click_fn, view_item_but_, nullptr);
}
@@ -579,7 +590,7 @@ void TreeViewLayoutBuilder::build_from_tree(const AbstractTreeView &tree_view)
uiLayout &parent_layout = current_layout();
uiLayout *box = uiLayoutBox(&parent_layout);
uiLayoutColumn(box, false);
uiLayoutColumn(box, true);
tree_view.foreach_item([this](AbstractTreeViewItem &item) { build_row(item); },
AbstractTreeView::IterOptions::SkipCollapsed |
@@ -616,6 +627,8 @@ void TreeViewLayoutBuilder::build_row(AbstractTreeViewItem &item) const
if (!item.is_interactive_) {
uiLayoutSetActive(overlap, false);
}
/* Scale the layout for the padded height. Widgets will be vertically centered then. */
uiLayoutSetScaleY(overlap, float(padded_item_height()) / UI_UNIT_Y);
uiLayout *row = uiLayoutRow(overlap, false);
/* Enable emboss for mouse hover highlight. */