UI: New UI list layout type for big preview tiles

This new layout type is meant for the upcoming asset view UI template.
With it it is possible to show big asset previews with their names in a
responsive grid layout.

Notes:
* The layout is only available for C defined UI lists. We could expose
  it to Python, but I think there are still some scrolling issues to be
  fixed first. (The asset view template doesn't use scrolling for the UI
  list.)
* I'd consider this a more usable version of the existing `GRID` layout
  type. We may remove that in favor of the new one in future.
This commit is contained in:
2021-07-14 16:23:02 +02:00
committed by Sybren A. Stüvel
parent 788d380460
commit 00c7ea68a8
2 changed files with 95 additions and 0 deletions

View File

@@ -6527,6 +6527,100 @@ static void ui_template_list_layout_draw(bContext *C,
}
break;
}
case UILST_LAYOUT_BIG_PREVIEW_GRID:
box = uiLayoutListBox(layout, ui_list, &input_data->active_dataptr, input_data->activeprop);
/* For grip button. */
glob = uiLayoutColumn(box, true);
/* For scrollbar. */
row = uiLayoutRow(glob, false);
/* TODO ED_fileselect_init_layout(). Share somehow? */
float size_x = (96.0f / 20.0f) * UI_UNIT_X;
float size_y = (96.0f / 20.0f) * UI_UNIT_Y;
const int cols_per_row = MAX2((uiLayoutGetWidth(box) - V2D_SCROLL_WIDTH) / size_x, 1);
uiLayout *grid = uiLayoutGridFlow(row, true, cols_per_row, true, true, true);
TemplateListLayoutDrawData adjusted_layout_data = *layout_data;
adjusted_layout_data.columns = cols_per_row;
uilist_prepare(ui_list, items, &adjusted_layout_data, &visual_info);
if (input_data->dataptr.data && input_data->prop) {
/* create list items */
for (int 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;
overlap = uiLayoutOverlap(grid);
col = uiLayoutColumn(overlap, false);
uiBlock *subblock = uiLayoutGetBlock(col);
UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
but = uiDefButR_prop(subblock,
UI_BTYPE_LISTROW,
0,
"",
0,
0,
size_x,
size_y,
&input_data->active_dataptr,
input_data->activeprop,
0,
0,
org_i,
0,
0,
NULL);
UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
col = uiLayoutColumn(overlap, false);
icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
layout_data->draw_item(ui_list,
C,
col,
&input_data->dataptr,
itemptr,
icon,
&input_data->active_dataptr,
active_propname,
org_i,
flt_flag);
/* Items should be able to set context pointers for the layout. But the list-row button
* swallows events, so it needs the context storage too for handlers to see it. */
but->context = uiLayoutGetContextStore(col);
/* If we are "drawing" active item, set all labels as active. */
if (i == items->active_item_idx) {
ui_layout_list_set_labels_active(col);
}
UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
}
}
if (items->tot_items > visual_info.visual_items) {
/* col = */ uiLayoutColumn(row, false);
uiDefButI(block,
UI_BTYPE_SCROLL,
0,
"",
0,
0,
V2D_SCROLL_WIDTH,
size_y * dyn_data->visual_height,
&ui_list->list_scroll,
0,
dyn_data->height - dyn_data->visual_height,
dyn_data->visual_height,
0,
"");
}
break;
}
if (glob) {

View File

@@ -596,6 +596,7 @@ enum {
UILST_LAYOUT_DEFAULT = 0,
UILST_LAYOUT_COMPACT = 1,
UILST_LAYOUT_GRID = 2,
UILST_LAYOUT_BIG_PREVIEW_GRID = 3,
};
/** #uiList.flag */