Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-04-27 14:50:16 +0300
committerJulian Eisel <julian@blender.org>2020-04-27 15:57:29 +0300
commit3c858246cd8f1859d06c72def727a64d70dd0460 (patch)
treea2561224b362b4cf32f8fbec3dd388c9a23cb8e0 /source/blender/editors/interface/interface_layout.c
parentf346fd32126f35fa8fd050bd8d81f1ec2493d178 (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.c77
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);
}