diff options
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 217 |
1 files changed, 141 insertions, 76 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 67b4f183c82..e802cf82b8e 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -720,7 +720,7 @@ void UI_context_active_but_prop_get_filebrowser( /** * Update a buttons tip with an enum's description if possible. */ -static void ui_but_tip_from_enum_item(uiBut *but, EnumPropertyItem *item) +static void ui_but_tip_from_enum_item(uiBut *but, const EnumPropertyItem *item) { if (but->tip == NULL || but->tip[0] == '\0') { if (item->description && item->description[0]) { @@ -883,6 +883,125 @@ void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int ico } +BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout) +{ + return (layout->item.type == ITEM_LAYOUT_RADIAL) || + ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU)); +} + +/** + * Create ui items for enum items in \a item_array. + * + * A version of #uiItemsFullEnumO that takes pre-calculated item array. + */ +void uiItemsFullEnumO_items( + uiLayout *layout, wmOperatorType *ot, PointerRNA ptr, PropertyRNA *prop, IDProperty *properties, + int context, int flag, + const EnumPropertyItem *item_array, int totitem) +{ + const char *propname = RNA_property_identifier(prop); + if (RNA_property_type(prop) != PROP_ENUM) { + RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname); + return; + } + + uiLayout *target, *split = NULL; + const EnumPropertyItem *item; + uiBlock *block = layout->root->block; + const bool radial = ui_layout_is_radial(layout); + + if (radial) { + target = uiLayoutRadial(layout); + } + else { + split = uiLayoutSplit(layout, 0.0f, false); + target = uiLayoutColumn(split, layout->align); + } + + + int i; + bool last_iter = false; + + for (i = 1, item = item_array; item->identifier && !last_iter; i++, item++) { + /* handle oversized pies */ + if (radial && (totitem > PIE_MAX_ITEMS) && (i >= PIE_MAX_ITEMS)) { + if (item->name) { /* only visible items */ + const EnumPropertyItem *tmp; + + /* Check if there are more visible items for the next level. If not, we don't + * add a new level and add the remaining item instead of the 'more' button. */ + for (tmp = item + 1; tmp->identifier; tmp++) + if (tmp->name) + break; + + if (tmp->identifier) { /* only true if loop above found item and did early-exit */ + ui_pie_menu_level_create(block, ot, propname, properties, item_array, totitem, context, flag); + /* break since rest of items is handled in new pie level */ + break; + } + else { + last_iter = true; + } + } + else { + continue; + } + } + + if (item->identifier[0]) { + PointerRNA tptr; + + WM_operator_properties_create_ptr(&tptr, ot); + if (properties) { + if (tptr.data) { + IDP_FreeProperty(tptr.data); + MEM_freeN(tptr.data); + } + tptr.data = IDP_CopyProperty(properties); + } + RNA_property_enum_set(&tptr, prop, item->value); + + uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag); + + ui_but_tip_from_enum_item(block->buttons.last, item); + } + else { + if (item->name) { + uiBut *but; + + if (item != item_array && !radial) { + target = uiLayoutColumn(split, layout->align); + + /* inconsistent, but menus with labels do not look good flipped */ + block->flag |= UI_BLOCK_NO_FLIP; + } + + if (item->icon || radial) { + uiItemL(target, item->name, item->icon); + + but = block->buttons.last; + } + else { + /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ + but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, + 0.0, 0.0, 0, 0, ""); + } + ui_but_tip_from_enum_item(but, item); + } + else { + if (radial) { + /* invisible dummy button to ensure all items are always at the same position */ + uiItemS(target); + } + else { + /* XXX bug here, colums draw bottom item badly */ + uiItemS(target); + } + } + } + } +} + void uiItemsFullEnumO( uiLayout *layout, const char *opname, const char *propname, IDProperty *properties, int context, int flag) @@ -892,8 +1011,6 @@ void uiItemsFullEnumO( PointerRNA ptr; PropertyRNA *prop; uiBlock *block = layout->root->block; - const bool radial = (layout->item.type == ITEM_LAYOUT_RADIAL) || - ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU)); if (!ot || !ot->srna) { ui_item_disabled(layout, opname); @@ -910,78 +1027,22 @@ void uiItemsFullEnumO( BLI_assert((prop == NULL) || (RNA_property_type(prop) == PROP_ENUM)); if (prop && RNA_property_type(prop) == PROP_ENUM) { - EnumPropertyItem *item, *item_array = NULL; + EnumPropertyItem *item_array = NULL; + int totitem; bool free; - uiLayout *split = NULL; - uiLayout *target; - if (radial) { - target = uiLayoutRadial(layout); + if (ui_layout_is_radial(layout)) { + RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free); } else { - split = uiLayoutSplit(layout, 0.0f, false); - target = uiLayoutColumn(split, layout->align); + RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free); } - if (radial) { - RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, NULL, &free); - } - else { - RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free); - } - - for (item = item_array; item->identifier; item++) { - if (item->identifier[0]) { - PointerRNA tptr; - - WM_operator_properties_create_ptr(&tptr, ot); - if (properties) { - if (tptr.data) { - IDP_FreeProperty(tptr.data); - MEM_freeN(tptr.data); - } - tptr.data = IDP_CopyProperty(properties); - } - RNA_property_enum_set(&tptr, prop, item->value); - - uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag); + /* add items */ + uiItemsFullEnumO_items( + layout, ot, ptr, prop, properties, context, flag, + item_array, totitem); - ui_but_tip_from_enum_item(block->buttons.last, item); - } - else { - if (item->name) { - uiBut *but; - - if (item != item_array && !radial) { - target = uiLayoutColumn(split, layout->align); - - /* inconsistent, but menus with labels do not look good flipped */ - block->flag |= UI_BLOCK_NO_FLIP; - } - - if (item->icon || radial) { - uiItemL(target, item->name, item->icon); - - but = block->buttons.last; - } - else { - /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ - but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, - 0.0, 0.0, 0, 0, ""); - } - ui_but_tip_from_enum_item(but, item); - } - else { - if (radial) { - uiItemS(target); - } - else { - /* XXX bug here, colums draw bottom item badly */ - uiItemS(target); - } - } - } - } if (free) { MEM_freeN(item_array); } @@ -1513,7 +1574,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s #if 0 /* this name is used for a string comparison and can't be modified, TODO */ /* if ever enabled, make name_ui be MAX_ID_NAME+1 */ - name_uiprefix_id(name_ui, id); + BKE_id_ui_prefix(name_ui, id); #else BLI_strncpy(name_ui, id->name + 2, sizeof(name_ui)); #endif @@ -1611,7 +1672,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->str[0] = 0; } - UI_but_func_search_set(but, rna_search_cb, but, NULL, NULL); + UI_but_func_search_set(but, ui_searchbox_create_generic, rna_search_cb, but, NULL, NULL); } } @@ -2167,9 +2228,9 @@ static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum) { RadialDirection dir; - if (itemnum >= 8) { - itemnum %= 8; - printf("Warning: Pie menus with more than 8 items are currently unsupported\n"); + if (itemnum >= PIE_MAX_ITEMS) { + itemnum %= PIE_MAX_ITEMS; + printf("Warning: Pie menus with more than %i items are currently unsupported\n", PIE_MAX_ITEMS); } dir = ui_radial_dir_order[itemnum]; @@ -2203,7 +2264,6 @@ static void ui_litem_layout_radial(uiLayout *litem) int itemnum = 0; int totitems = 0; - int minx, miny, maxx, maxy; /* For the radial layout we will use Matt Ebb's design * for radiation, see http://mattebb.com/weblog/radiation/ * also the old code at http://developer.blender.org/T5103 @@ -2214,7 +2274,7 @@ static void ui_litem_layout_radial(uiLayout *litem) x = litem->x; y = litem->y; - minx = x, miny = y, maxx = x, maxy = y; + int minx = x, miny = y, maxx = x, maxy = y; /* first count total items */ for (item = litem->items.first; item; item = item->next) @@ -3012,9 +3072,14 @@ static void ui_item_align(uiLayout *litem, short nr) for (item = litem->items.last; item; item = item->prev) { if (item->type == ITEM_BUTTON) { bitem = (uiButtonItem *)item; +#ifndef USE_UIBUT_SPATIAL_ALIGN if (ui_but_can_align(bitem->but)) - if (!bitem->but->alignnr) +#endif + { + if (!bitem->but->alignnr) { bitem->but->alignnr = nr; + } + } } else if (item->type == ITEM_LAYOUT_ABSOLUTE) { /* pass */ |