UI/BPY: Remove grid layout for UI lists

The grid layout for UI lists wasn't used in practice from all we can
tell. It was badly maintained for a long time (bugs went unnoticed). I
think it was added for an earlier version of the asset UI design.

This was planned for removal in 5.0, see blender/blender#110461.

Usages in bundled scripts were already removed in efa8d942b8.

Pull Request: https://projects.blender.org/blender/blender/pulls/146656
This commit is contained in:
Julian Eisel
2025-09-29 13:07:31 +02:00
committed by Julian Eisel
parent f1d0f79302
commit eef971e377
6 changed files with 22 additions and 136 deletions

View File

@@ -30,20 +30,14 @@ class MATERIAL_UL_matslots_example(bpy.types.UIList):
ob = data
slot = item
ma = slot.material
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", translate=False, icon_value=icon)
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
# Note "data" names should never be translated!
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
else:
layout.label(text="", translate=False, icon_value=icon)
# And now we can use this list everywhere in Blender. Here is a small example panel.

View File

@@ -66,24 +66,18 @@ class MESH_UL_vgroups_slow(bpy.types.UIList):
# assert(isinstance(item, bpy.types.VertexGroup)
vgroup = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
# Here we use one feature of new filtering feature: it can pass data to draw_item, through flt_flag
# parameter, which contains exactly what filter_items set in its filter list for this item!
# In this case, we show empty groups grayed out.
if flt_flag & self.VGROUP_EMPTY:
col = layout.column()
col.enabled = False
col.alignment = 'LEFT'
col.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
else:
layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
if flt_flag & self.VGROUP_EMPTY:
layout.enabled = False
layout.label(text="", icon_value=icon)
# Here we use one feature of new filtering feature: it can pass data to draw_item, through flt_flag
# parameter, which contains exactly what filter_items set in its filter list for this item!
# In this case, we show empty groups grayed out.
if flt_flag & self.VGROUP_EMPTY:
col = layout.column()
col.enabled = False
col.alignment = 'LEFT'
col.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
else:
layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
def draw_filter(self, context, layout):
# Nothing much to say here, it's usual UI code...

View File

@@ -9959,7 +9959,7 @@ static int ui_list_get_increment(const uiList *ui_list, const int type, const in
/* Handle column offsets for grid layouts. */
if (ELEM(type, EVT_UPARROWKEY, EVT_DOWNARROWKEY) &&
ELEM(ui_list->layout_type, UILST_LAYOUT_GRID, UILST_LAYOUT_BIG_PREVIEW_GRID))
ELEM(ui_list->layout_type, UILST_LAYOUT_BIG_PREVIEW_GRID))
{
increment = (type == EVT_UPARROWKEY) ? -columns : columns;
}

View File

@@ -104,9 +104,6 @@ static void uilist_draw_item_default(uiList *ui_list,
/* Simplest one! */
switch (ui_list->layout_type) {
case UILST_LAYOUT_GRID:
layout->label("", icon);
break;
case UILST_LAYOUT_DEFAULT:
case UILST_LAYOUT_COMPACT:
default:
@@ -703,7 +700,7 @@ static void ui_template_list_layout_draw(const bContext *C,
uiListDyn *dyn_data = ui_list->dyn_data;
const char *active_propname = RNA_property_identifier(input_data->activeprop);
uiLayout *glob = nullptr, *box, *row, *col, *subrow, *sub, *overlap;
uiLayout *glob = nullptr, *box, *row, *col, *sub, *overlap;
char numstr[32];
int rnaicon = ICON_NONE, icon = ICON_NONE;
uiBut *but;
@@ -882,103 +879,6 @@ static void ui_template_list_layout_draw(const bContext *C,
UI_but_flag_enable(but, UI_BUT_DISABLED);
}
break;
case UILST_LAYOUT_GRID: {
box = &layout->list_box(ui_list, &input_data->active_dataptr, input_data->activeprop);
glob = &box->column(true);
row = &glob->row(false);
col = &row->column(true);
subrow = nullptr; /* Quite gcc warning! */
uilist_prepare(ui_list, items, layout_data, &visual_info);
int i = 0;
if (input_data->dataptr.data && input_data->prop) {
/* create list items */
for (i = visual_info.start_idx; i < visual_info.end_idx; i++) {
PointerRNA *itemptr = &items->item_vec[i].item;
const int org_i = items->item_vec[i].org_idx;
const int flt_flag = items->item_vec[i].flt_flag;
/* create button */
if (!(i % layout_data->columns)) {
subrow = &col->row(false);
}
uiBlock *subblock = subrow->block();
overlap = &subrow->overlap();
UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
/* list item behind label & other buttons */
overlap->row(false);
but = uiDefButR_prop(subblock,
ButType::ListRow,
0,
"",
0,
0,
UI_UNIT_X * 10,
UI_UNIT_Y,
&input_data->active_dataptr,
input_data->activeprop,
0,
0,
org_i,
std::nullopt);
UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
sub = &overlap->row(false);
icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
layout_data->draw_item(ui_list,
C,
sub,
&input_data->dataptr,
itemptr,
icon,
&input_data->active_dataptr,
active_propname,
org_i,
flt_flag);
/* If we are "drawing" active item, set all labels as active. */
if (i == items->active_item_idx) {
ui_layout_list_set_labels_active(sub);
}
UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
}
}
/* add dummy buttons to fill space */
for (; i < visual_info.start_idx + visual_info.visual_items; i++) {
if (!(i % layout_data->columns)) {
subrow = &col->row(false);
}
subrow->label("", ICON_NONE);
}
/* Add scroll-bar. */
if (items->item_vec.size() > visual_info.visual_items) {
/* col = */ row->column(false);
but = uiDefButI(block,
ButType::Scroll,
0,
"",
0,
0,
V2D_SCROLL_WIDTH,
UI_UNIT_Y * dyn_data->visual_height,
&ui_list->list_scroll,
0,
dyn_data->height - dyn_data->visual_height,
"");
uiButScrollBar *but_scroll = reinterpret_cast<uiButScrollBar *>(but);
but_scroll->visual_height = dyn_data->visual_height;
}
break;
}
case UILST_LAYOUT_BIG_PREVIEW_GRID:
box = &layout->list_box(ui_list, &input_data->active_dataptr, input_data->activeprop);
/* For grip button. */

View File

@@ -648,7 +648,6 @@ enum {
enum {
UILST_LAYOUT_DEFAULT = 0,
UILST_LAYOUT_COMPACT = 1,
UILST_LAYOUT_GRID = 2,
UILST_LAYOUT_BIG_PREVIEW_GRID = 3,
};

View File

@@ -50,7 +50,6 @@ const EnumPropertyItem rna_enum_operator_context_items[] = {
const EnumPropertyItem rna_enum_uilist_layout_type_items[] = {
{UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout", "Use the default, multi-rows layout"},
{UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout", "Use the compact, single-row layout"},
{UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout", "Use the grid-based layout"},
{0, nullptr, 0, nullptr, nullptr},
};