diff options
author | Julian Eisel <julian@blender.org> | 2020-04-27 14:50:16 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-04-27 15:57:29 +0300 |
commit | 3c858246cd8f1859d06c72def727a64d70dd0460 (patch) | |
tree | a2561224b362b4cf32f8fbec3dd388c9a23cb8e0 /source/blender/editors/interface/interface_layout.c | |
parent | f346fd32126f35fa8fd050bd8d81f1ec2493d178 (diff) |
UI: Support array properties for UILayout.prop_decorator()
Previously `UILayout.prop_decorator()` (or `uiItemDecoratorR()` in C)
only worked for single items, not for arrays. The decorators are added
vertically, like `UILayout.prop()` adds them.
This will be needed for adding decorators to material properties, but
will likely have other use-cases as well.
Also, `None` (or `NULL`) can be passed for the data-pointer and property
now to create blank decorators (as already possible for
`uiItemDecoratorR_prop` in C).
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 80e248650e5..49ce1315e7f 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1874,6 +1874,15 @@ static void ui_item_rna_size(uiLayout *layout, *r_h = h; } +static bool ui_item_rna_is_expand(PropertyRNA *prop, int index, int item_flag) +{ + const bool is_array = RNA_property_array_check(prop); + const int subtype = RNA_property_subtype(prop); + return is_array && (index == RNA_NO_INDEX) && + ((item_flag & UI_ITEM_R_EXPAND) || + !ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA, PROP_DIRECTION)); +} + /** * Find first layout ancestor (or self) with a heading set. * @@ -2120,7 +2129,6 @@ void uiItemFullR(uiLayout *layout, } } else { - const PropertySubType subtype = RNA_property_subtype(prop); uiLayout *layout_split = uiLayoutSplit( layout_row ? layout_row : layout, UI_ITEM_PROP_SEP_DIVIDE, true); bool label_added = false; @@ -2131,8 +2139,7 @@ void uiItemFullR(uiLayout *layout, if (!use_prop_sep_split_label) { /* Pass */ } - else if ((index == RNA_NO_INDEX && is_array) && - ((!expand && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA, PROP_DIRECTION)) == 0)) { + else if (ui_item_rna_is_expand(prop, index, flag)) { char name_with_suffix[UI_MAX_DRAW_STR + 2]; char str[2] = {'\0'}; for (int a = 0; a < len; a++) { @@ -2934,20 +2941,19 @@ void uiItemMContents(uiLayout *layout, const char *menuname) void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index) { uiBlock *block = layout->root->block; - const bool is_anim = ptr && prop && RNA_property_animateable(ptr, prop); uiBut *but = NULL; - uiLayout *row; + uiLayout *col; UI_block_layout_set_current(block, layout); - row = uiLayoutRow(layout, false); - row->space = 0; - row->emboss = UI_EMBOSS_NONE; + col = uiLayoutColumn(layout, false); + col->space = 0; + col->emboss = UI_EMBOSS_NONE; - if (is_anim) { + if (ELEM(NULL, ptr, prop) || !RNA_property_animateable(ptr, prop)) { but = uiDefIconBut(block, UI_BTYPE_BUT, 0, - ICON_DOT, + ICON_BLANK1, 0, 0, UI_UNIT_X, @@ -2957,20 +2963,20 @@ void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, 0.0, 0.0, 0.0, - TIP_("Animate property")); - UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL); - but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK; - /* Reusing RNA search members, setting actual RNA data has many side-effects. */ - but->rnasearchpoin = *ptr; - but->rnasearchprop = prop; - but->custom_data = POINTER_FROM_INT(index); + ""); + but->flag |= UI_BUT_DISABLED; + return; } - else { - /* We may show other information here in future, for now use empty space. */ + + const bool is_expand = ui_item_rna_is_expand(prop, index, 0); + const bool is_array = RNA_property_array_check(prop); + + /* Loop for the array-case, but only do in case of an expanded array. */ + for (int i = 0; i < (is_expand ? RNA_property_array_length(ptr, prop) : 1); i++) { but = uiDefIconBut(block, UI_BTYPE_BUT, 0, - ICON_BLANK1, + ICON_DOT, 0, 0, UI_UNIT_X, @@ -2980,23 +2986,36 @@ void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, 0.0, 0.0, 0.0, - ""); - but->flag |= UI_BUT_DISABLED; + TIP_("Animate property")); + UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL); + but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK; + /* Reusing RNA search members, setting actual RNA data has many side-effects. */ + but->rnasearchpoin = *ptr; + but->rnasearchprop = prop; + /* ui_def_but_rna() sets non-array buttons to have a RNA index of 0. */ + but->custom_data = POINTER_FROM_INT((!is_array || is_expand) ? i : index); } } +/** + * Insert a decorator item for a button with the same property as \a prop. + * To force inserting a blank dummy element, NULL can be passed for \a ptr and \a propname. + */ void uiItemDecoratorR(uiLayout *layout, PointerRNA *ptr, const char *propname, int index) { - PropertyRNA *prop; + PropertyRNA *prop = NULL; - /* validate arguments */ - prop = RNA_struct_find_property(ptr, propname); - if (!prop) { - ui_item_disabled(layout, propname); - RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); - return; + if (ptr && propname) { + /* validate arguments */ + prop = RNA_struct_find_property(ptr, propname); + if (!prop) { + ui_item_disabled(layout, propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } } + /* ptr and prop are allowed to be NULL here. */ uiItemDecoratorR_prop(layout, ptr, prop, index); } |