[Bf-blender-cvs] [61be5a0c067] temp-checkbox-layout-tweaks: UI: Better split layout support for checkboxes

Julian Eisel noreply at git.blender.org
Thu Apr 16 21:03:28 CEST 2020


Commit: 61be5a0c067161b3fd3486224b514c1c24b97abf
Author: Julian Eisel
Date:   Tue Apr 14 18:20:44 2020 +0200
Branches: temp-checkbox-layout-tweaks
https://developer.blender.org/rB61be5a0c067161b3fd3486224b514c1c24b97abf

UI: Better split layout support for checkboxes

Makes these kinds of layouts possible:

Best test this in the `temp-checkbox-changes` branch which contains layout
tweaks all over to make good use of the changes here. These will be submitted
separately.
Patch on top of D7409.

Main changes:
* Add support for row and column headers (i.e.
  `uiLayout.column(heading="Foo")`, `uiLayout.row(heading="Bar")). If the
  first property added to this layout doesn't insert anything into the label
  split column, the heading is inserted there. Otherwise, it's inserted as own
  item.
* Add support for manually inserting decorators for an existing item
  (`uiLayout.prop_decorator()`). That way layout creators can manually insert
  this, which was the only way I saw to support these layouts:
* Autogenerated layouts for operator properties look bad if there are only
  checkboxes (which only use half the region width). So before creating the
  layout, we iterate over visible properties and disable split layout if all
  are booleans. I think this is fine, if needed we could also add layout hints
  to operators.
* `uiTemplateOperatorPropertyButs()` now handles macros itself, the caller
  used to be responsible for this. Code that didn't handle these so far never
  used macros I think, so this change should be visible.
* Remove manual property split layout from autogenerated operator properties
  layout.
* Padding of checkboxes is tweaked to make their label visually more connected
  to the checkboxes.
* Support split layout for menus (should work for `uiLayout.menu()`,
  `.operator_menu_enum()`, `.prop_menu_enum()`, maybe more)
* Add `uiLayout.`

Maniphest Task: T65965

Reviewers: brecht pablovazquez billreynish

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_anim.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/interface/interface_utils.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/makesrna/intern/rna_ui_api.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 4716e7f0972..02f714f8520 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1774,6 +1774,8 @@ enum {
   UI_ITEM_O_DEPRESS = 1 << 10,
   UI_ITEM_R_COMPACT = 1 << 11,
   UI_ITEM_R_CHECKBOX_INVERT = 1 << 12,
+  /** Don't add a real decorator item, just blank space. */
+  UI_ITEM_R_FORCE_BLANK_DECORATE = 1 << 13,
 };
 
 #define UI_HEADER_OFFSET ((void)0, 0.4f * UI_UNIT_X)
@@ -1784,6 +1786,9 @@ enum {
   UI_TEMPLATE_OP_PROPS_SHOW_EMPTY = 1 << 1,
   UI_TEMPLATE_OP_PROPS_COMPACT = 1 << 2,
   UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED = 1 << 3,
+  /* Disable property split for the default layout (custom ui callbacks still have full control
+   * over the layout and can enable it). */
+  UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT = 1 << 4,
 };
 
 /* used for transp checkers */
@@ -1871,7 +1876,9 @@ 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);
 uiLayout *uiLayoutGridFlow(uiLayout *layout,
                            bool row_major,
@@ -2046,11 +2053,11 @@ void uiTemplateOperatorSearch(uiLayout *layout);
 void UI_but_func_menu_search(uiBut *but);
 void uiTemplateMenuSearch(uiLayout *layout);
 
-eAutoPropButsReturn uiTemplateOperatorPropertyButs(const struct bContext *C,
-                                                   uiLayout *layout,
-                                                   struct wmOperator *op,
-                                                   const eButLabelAlign label_align,
-                                                   const short flag);
+void uiTemplateOperatorPropertyButs(const struct bContext *C,
+                                    uiLayout *layout,
+                                    struct wmOperator *op,
+                                    eButLabelAlign label_align,
+                                    short flag);
 void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C);
 void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);
 void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
@@ -2311,6 +2318,9 @@ void uiItemM_ptr(uiLayout *layout, struct MenuType *mt, const char *name, int ic
 void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon);
 /* menu contents */
 void uiItemMContents(uiLayout *layout, const char *menuname);
+/* Decorators */
+void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index);
+void uiItemDecoratorR(uiLayout *layout, PointerRNA *ptr, const char *propname, int index);
 /* value */
 void uiItemV(uiLayout *layout, const char *name, int icon, int argval);
 /* separator */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c97f5ee8239..0e15405a06f 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -641,6 +641,26 @@ static int ui_but_calc_float_precision(uiBut *but, double value)
 
 /* ************** BLOCK ENDING FUNCTION ************* */
 
+bool ui_but_rna_equals(const uiBut *a, const uiBut *b)
+{
+  return ui_but_rna_equals_ex(a, &b->rnapoin, b->rnaprop, b->rnaindex);
+}
+
+bool ui_but_rna_equals_ex(const uiBut *but,
+                          const PointerRNA *ptr,
+                          const PropertyRNA *prop,
+                          int index)
+{
+  if (but->rnapoin.data != ptr->data) {
+    return false;
+  }
+  if (but->rnaprop != prop || but->rnaindex != index) {
+    return false;
+  }
+
+  return true;
+}
+
 /* NOTE: if but->poin is allocated memory for every defbut, things fail... */
 static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
 {
@@ -649,10 +669,7 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
   if (but->retval != oldbut->retval) {
     return false;
   }
-  if (but->rnapoin.data != oldbut->rnapoin.data) {
-    return false;
-  }
-  if (but->rnaprop != oldbut->rnaprop || but->rnaindex != oldbut->rnaindex) {
+  if (!ui_but_rna_equals(but, oldbut)) {
     return false;
   }
   if (but->func != oldbut->func) {
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 15fc23bc539..f04839d1a4d 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -28,6 +28,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 
+#include "BLI_listbase.h"
 #include "BLI_string.h"
 #include "BLI_string_utf8.h"
 #include "BLI_utildefines.h"
@@ -114,10 +115,38 @@ void ui_but_anim_flag(uiBut *but, float cfra)
   }
 }
 
+static uiBut *ui_but_anim_decorate_find_attached_button(uiBut *but_decorate)
+{
+  uiBut *but_iter = NULL;
+
+  BLI_assert(UI_but_is_decorator(but_decorate));
+  BLI_assert(but_decorate->rnasearchpoin.data && but_decorate->rnasearchprop);
+
+  LISTBASE_CIRCULAR_BACKWARD_BEGIN (&but_decorate->block->buttons, but_iter, but_decorate->prev) {
+    if (ui_but_rna_equals_ex(but_decorate,
+                             &but_iter->rnasearchpoin,
+                             but_iter->rnasearchprop,
+                             POINTER_AS_INT(but_iter->custom_data))) {
+      return but_iter;
+    }
+  }
+  LISTBASE_CIRCULAR_BACKWARD_END(&but_decorate->block->buttons, but_iter, but_decorate->prev);
+
+  return NULL;
+}
+
 void ui_but_anim_decorate_update_from_flag(uiBut *but)
 {
-  BLI_assert(UI_but_is_decorator(but) && but->prev);
-  int flag = but->prev->flag;
+  const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but);
+
+  if (!but_anim) {
+    printf("Could not find button with matching property to decorate (%s.%s)",
+           RNA_struct_identifier(but->rnapoin.type),
+           RNA_property_identifier(but->rnaprop));
+  }
+
+  int flag = but_anim->flag;
+
   if (flag & UI_BUT_DRIVEN) {
     but->icon = ICON_DECORATE_DRIVER;
   }
@@ -289,22 +318,26 @@ void ui_but_anim_paste_driver(bContext *C)
 void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
 {
   wmWindowManager *wm = CTX_wm_manager(C);
-  uiBut *but = arg_but;
-  but = but->prev;
+  uiBut *but_decorate = arg_but;
+  uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate);
+
+  if (!but_anim) {
+    return;
+  }
 
   /* FIXME(campbell), swapping active pointer is weak. */
-  SWAP(struct uiHandleButtonData *, but->active, but->next->active);
+  SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
   wm->op_undo_depth++;
 
-  if (but->flag & UI_BUT_DRIVEN) {
+  if (but_anim->flag & UI_BUT_DRIVEN) {
     /* pass */
     /* TODO: report? */
   }
-  else if (but->flag & UI_BUT_ANIMATED_KEY) {
+  else if (but_anim->flag & UI_BUT_ANIMATED_KEY) {
     PointerRNA props_ptr;
     wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_delete_button", false);
     WM_operator_properties_create_ptr(&props_ptr, ot);
-    RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
+    RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1);
     WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
     WM_operator_properties_free(&props_ptr);
   }
@@ -312,11 +345,11 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)
     PointerRNA props_ptr;
     wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_insert_button", false);
     WM_operator_properties_create_ptr(&props_ptr, ot);
-    RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
+    RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1);
     WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
     WM_operator_properties_free(&props_ptr);
   }
 
-  SWAP(struct uiHandleButtonData *, but->active, but->next->active);
+  SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
   wm->op_undo_depth--;
 }
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 51fe990bd02..6a489b49e20 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -790,6 +790,11 @@ float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
 
 void ui_but_add_shortcut(uiBut *but, const char *key_str, const bool do_strip);
 void ui_but_clipboard_free(void);
+bool ui_but_rna_equals(const uiBut *a, const uiBut *b);
+bool ui_but_rna_equals_ex(const uiBut *but,
+                          const PointerRNA *ptr,
+                          const PropertyRNA *prop,
+                          int index);
 uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new);
 uiBut *ui_but_find_new(uiBlock *block_old, const uiBut *but_new);
 
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index cbea32f179a..c4e492c9b54 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -135,10 +135,11 @@ enum {
 
   UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
   UI_ITEM_PROP_SEP = 1 << 3,
+  UI_ITEM_INSIDE_PROP_SEP = 1 << 4,
   /* Show an icon button next to each property (to set keyframes, show status).
    * Enabled by default, depends on 'UI_ITEM_PROP_SEP'. */
-  UI_ITEM_PROP_DECORATE = 1 << 4,
-  UI_ITEM_PROP_DECORATE_NO_PAD = 1 << 5,
+  UI_ITEM_PROP_DECORATE = 1 << 5,
+  UI_ITEM_PROP_DECORATE_NO_PAD = 1 << 6,
 };
 
 typedef struct uiButtonItem {
@@ -151,8 +152,11 @@ struct uiLayout {
 
   uiLayoutRoot *root;
   bContextStore *context;
+  uiLayout *parent;
   ListBase items;
 
+  char heading[UI_MAX_NAME_STR];
+
   /** Sub layout to add child items, if not the layout itself. */
   uiLayout *child

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list