[Bf-blender-cvs] [3c858246cd8] master: UI: Support array properties for UILayout.prop_decorator()

Julian Eisel noreply at git.blender.org
Mon Apr 27 15:03:08 CEST 2020


Commit: 3c858246cd8f1859d06c72def727a64d70dd0460
Author: Julian Eisel
Date:   Mon Apr 27 13:50:16 2020 +0200
Branches: master
https://developer.blender.org/rB3c858246cd8f1859d06c72def727a64d70dd0460

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).

===================================================================

M	source/blender/editors/interface/interface_layout.c

===================================================================

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);
 }



More information about the Bf-blender-cvs mailing list