[Bf-blender-cvs] [7714746e5cf] temp-checkbox-layout-tweaks: Support heading in row layouts too - `uiLayout.row(heading="FOO")`

Julian Eisel noreply at git.blender.org
Sat Apr 11 22:59:50 CEST 2020


Commit: 7714746e5cf99a54e338b1c957c9493965e90022
Author: Julian Eisel
Date:   Sat Apr 11 22:50:57 2020 +0200
Branches: temp-checkbox-layout-tweaks
https://developer.blender.org/rB7714746e5cf99a54e338b1c957c9493965e90022

Support heading in row layouts too - `uiLayout.row(heading="FOO")`

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/makesrna/intern/rna_ui_api.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index d6481a9564e..079527c4456 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1867,6 +1867,7 @@ bool uiLayoutGetPropDecorate(uiLayout *layout);
 
 /* layout specifiers */
 uiLayout *uiLayoutRow(uiLayout *layout, bool align);
+uiLayout *uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading);
 uiLayout *uiLayoutColumn(uiLayout *layout, bool align);
 uiLayout *uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading);
 uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, bool align);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index dcc138da8b3..6847d63c768 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1867,21 +1867,26 @@ static void ui_item_rna_size(uiLayout *layout,
 }
 
 /**
- * Returns a pointer to the heading string. It's non-const so it can be cleared to mark a heading
- * as "added".
+ * Find first layout ancestor (or self) with a heading set.
+ *
+ * \returns the layout to add the heading to as fallback (i.e. if it can't be placed in a split
+ *          layout). Its #uiLayout.heading member can be cleared to mark the heading as added (so
+ *          it's not added multiple times). Returns a pointer to the heading
  */
-static char *ui_layout_heading_find(uiLayout *cur_layout)
+static uiLayout *ui_layout_heading_find(uiLayout *cur_layout)
 {
   for (uiLayout *parent = cur_layout; parent; parent = parent->parent) {
     if (parent->heading[0]) {
-      return parent->heading;
+      return parent;
     }
   }
 
   return NULL;
 }
 
-static void ui_layout_heading_label_add(uiLayout *layout, char *heading, bool right_align)
+static void ui_layout_heading_label_add(uiLayout *layout,
+                                        uiLayout *heading_layout,
+                                        bool right_align)
 {
   const int prev_alignment = layout->alignment;
 
@@ -1889,10 +1894,10 @@ static void ui_layout_heading_label_add(uiLayout *layout, char *heading, bool ri
     uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_RIGHT);
   }
 
-  uiItemL(layout, heading, ICON_NONE);
+  uiItemL(layout, heading_layout->heading, ICON_NONE);
   /* After adding the heading label, we have to mark it somehow as added, so it's not added again
    * for other items in this layout. For now just clear it. */
-  heading[0] = '\0';
+  heading_layout->heading[0] = '\0';
 
   layout->alignment = prev_alignment;
 }
@@ -1934,7 +1939,7 @@ void uiItemFullR(uiLayout *layout,
   /* Columns can define a heading to insert. If the first item added to a split layout doesn't have
    * a label to display in the first column, the heading is inserted there. Otherwise it's inserted
    * as a new row before the first item. */
-  char *heading = ui_layout_heading_find(layout);
+  uiLayout *heading_layout = ui_layout_heading_find(layout);
   /* Although checkboxes use the split layout, they are an exception and should only place their
    * label in the second column, to not make that almost empty.
    *
@@ -2096,8 +2101,8 @@ void uiItemFullR(uiLayout *layout,
       /* Ensure we get a column when text is not set. */
       layout = uiLayoutColumn(layout_row ? layout_row : layout, true);
       layout->space = 0;
-      if (heading) {
-        ui_layout_heading_label_add(layout, heading, false);
+      if (heading_layout) {
+        ui_layout_heading_label_add(layout, heading_layout, false);
       }
     }
     else {
@@ -2157,8 +2162,8 @@ void uiItemFullR(uiLayout *layout,
         }
       }
 
-      if (!label_added && heading) {
-        ui_layout_heading_label_add(layout_sub, heading, true);
+      if (!label_added && heading_layout) {
+        ui_layout_heading_label_add(layout_sub, heading_layout, true);
       }
 
       layout_split = ui_item_prop_split_layout_hack(layout_parent, layout_split);
@@ -2198,9 +2203,10 @@ void uiItemFullR(uiLayout *layout,
 #endif /* UI_PROP_DECORATE */
   }
   /* End split. */
-  else if (heading) {
-    layout = uiLayoutColumn(layout_parent, true);
-    ui_layout_heading_label_add(layout, heading, false);
+  else if (heading_layout) {
+    /* Could not add heading to split layout, fallback to inserting it to the layout with the
+     * heading itself. */
+    ui_layout_heading_label_add(heading_layout, heading_layout, false);
   }
   else if (inside_prop_sep) {
     /* When placing further items in a split row, add them to a column so they match the column
@@ -4591,6 +4597,14 @@ static void ui_litem_init_from_parent(uiLayout *litem, uiLayout *layout, int ali
   }
 }
 
+static void ui_layout_heading_set(uiLayout *layout, const char *heading)
+{
+  BLI_assert(layout->heading[0] == '\0');
+  if (heading) {
+    STRNCPY(layout->heading, heading);
+  }
+}
+
 /* layout create functions */
 uiLayout *uiLayoutRow(uiLayout *layout, bool align)
 {
@@ -4607,6 +4621,16 @@ uiLayout *uiLayoutRow(uiLayout *layout, bool align)
   return litem;
 }
 
+/**
+ * See #uiLayoutColumnWithHeading().
+ */
+uiLayout *uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
+{
+  uiLayout *litem = uiLayoutRow(layout, align);
+  ui_layout_heading_set(litem, heading);
+  return litem;
+}
+
 uiLayout *uiLayoutColumn(uiLayout *layout, bool align)
 {
   uiLayout *litem;
@@ -4631,12 +4655,7 @@ uiLayout *uiLayoutColumn(uiLayout *layout, bool align)
 uiLayout *uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading)
 {
   uiLayout *litem = uiLayoutColumn(layout, align);
-
-  BLI_assert(litem->heading[0] == '\0');
-  if (heading) {
-    STRNCPY(litem->heading, heading);
-  }
-
+  ui_layout_heading_set(litem, heading);
   return litem;
 }
 
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index ef442f982f9..e29e3caf75b 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -693,7 +693,7 @@ void RNA_api_ui_layout(StructRNA *srna)
   static float node_socket_color_default[] = {0.0f, 0.0f, 0.0f, 1.0f};
 
   /* simple layout specifiers */
-  func = RNA_def_function(srna, "row", "uiLayoutRow");
+  func = RNA_def_function(srna, "row", "uiLayoutRowWithHeading");
   parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
   RNA_def_function_return(func, parm);
   RNA_def_function_ui_description(
@@ -701,6 +701,12 @@ void RNA_api_ui_layout(StructRNA *srna)
       "Sub-layout. Items placed in this sublayout are placed next to each other "
       "in a row");
   RNA_def_boolean(func, "align", false, "", "Align buttons to each other");
+  RNA_def_string(func,
+                 "heading",
+                 NULL,
+                 UI_MAX_NAME_STR,
+                 "Heading",
+                 "Label to insert into the layout for this row");
 
   func = RNA_def_function(srna, "column", "uiLayoutColumnWithHeading");
   parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");



More information about the Bf-blender-cvs mailing list