UI: Expand Enum Items Over Multiple Rows

Expanding enum items in a small area would render the names with
dots, what is a bad solution. When you use expand directly on a
`grid_flow` or `column_flow`, it will render the items on multiple
lines, giving more control to the developer.

Reviewers: campbellbarton, brecht, mont29

Differential Revision: https://developer.blender.org/D4698
This commit is contained in:
Jeroen Bakker 2019-04-17 15:02:30 +02:00
parent a05b6199fc
commit 2d171d873c
2 changed files with 76 additions and 57 deletions

View File

@ -4617,7 +4617,7 @@ class VIEW3D_PT_shading_color(Panel):
layout = self.layout
shading = VIEW3D_PT_shading.get_shading(context)
layout.row().prop(shading, "color_type", expand=True)
layout.grid_flow(columns=3, align=True).prop(shading, "color_type", expand=True)
if shading.color_type == 'SINGLE':
layout.row().prop(shading, "single_color", text="")

View File

@ -722,6 +722,71 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value);
}
}
static void ui_item_enum_expand_elem_exec(uiLayout *layout,
uiBlock *block,
PointerRNA *ptr,
PropertyRNA *prop,
const char *uiname,
int h,
int but_type,
bool icon_only,
const EnumPropertyItem *item,
bool is_first)
{
uiBut *but;
const char *name;
int itemw, icon, value;
name = (!uiname || uiname[0]) ? item->name : "";
icon = item->icon;
value = item->value;
itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
if (icon && name[0] && !icon_only) {
but = uiDefIconTextButR_prop(
block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
else if (icon) {
but = uiDefIconButR_prop(block,
but_type,
0,
icon,
0,
0,
(is_first) ? itemw : ceilf(itemw - U.pixelsize),
h,
ptr,
prop,
-1,
0,
value,
-1,
-1,
NULL);
}
else {
but = uiDefButR_prop(
block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* If this is set, assert since we're clobbering someone elses callback. */
BLI_assert(but->func == NULL);
UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value));
}
if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) {
but->drawflag |= UI_BUT_TEXT_LEFT;
}
/* Allow quick, inaccurate swipe motions to switch tabs
* (no need to keep cursor over them). */
if (but_type == UI_BTYPE_TAB) {
but->flag |= UI_BUT_DRAG_LOCK;
}
}
static void ui_item_enum_expand_exec(uiLayout *layout,
uiBlock *block,
PointerRNA *ptr,
@ -743,16 +808,13 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
* - mont29
*/
uiBut *but;
uiLayout *layout_radial = NULL;
const EnumPropertyItem *item, *item_array;
const char *name;
int itemw, icon, value;
bool free;
bool radial = (layout->root->type == UI_LAYOUT_PIEMENU);
BLI_assert(RNA_property_type(prop) == PROP_ENUM);
uiLayout *layout_radial = NULL;
bool radial = (layout->root->type == UI_LAYOUT_PIEMENU);
if (radial) {
RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free);
}
@ -773,11 +835,12 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
UI_block_layout_set_current(block, layout);
}
}
else if (layout->root->type != UI_LAYOUT_MENU) {
UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));
else if (ELEM(layout->item.type, ITEM_LAYOUT_GRID_FLOW, ITEM_LAYOUT_COLUMN_FLOW) ||
layout->root->type == UI_LAYOUT_MENU) {
UI_block_layout_set_current(block, layout);
}
else {
UI_block_layout_set_current(block, layout);
UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));
}
for (item = item_array; item->identifier; item++) {
@ -789,7 +852,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
/* Separate items, potentially with a label. */
if (next_item->identifier) {
/* Item without identifier but with name:
* Add group label for the following items. */
* Add group label for the following items. */
if (item->name) {
if (!is_first) {
uiItemS(block->curlayout);
@ -806,54 +869,10 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
continue;
}
name = (!uiname || uiname[0]) ? item->name : "";
icon = item->icon;
value = item->value;
itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
if (icon && name[0] && !icon_only) {
but = uiDefIconTextButR_prop(
block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
else if (icon) {
but = uiDefIconButR_prop(block,
but_type,
0,
icon,
0,
0,
(is_first) ? itemw : ceilf(itemw - U.pixelsize),
h,
ptr,
prop,
-1,
0,
value,
-1,
-1,
NULL);
}
else {
but = uiDefButR_prop(
block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* If this is set, assert since we're clobbering someone elses callback. */
BLI_assert(but->func == NULL);
UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value));
}
if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) {
but->drawflag |= UI_BUT_TEXT_LEFT;
}
/* Allow quick, inaccurate swipe motions to switch tabs
* (no need to keep cursor over them). */
if (but_type == UI_BTYPE_TAB) {
but->flag |= UI_BUT_DRAG_LOCK;
}
ui_item_enum_expand_elem_exec(
layout, block, ptr, prop, uiname, h, but_type, icon_only, item, is_first);
}
UI_block_layout_set_current(block, layout);
if (free) {