[Bf-blender-cvs] [482936fc338] temp-outliner-library-override-hierarchy: Outliner: Add icon column to toggle if library overrides are editable

Julian Eisel noreply at git.blender.org
Thu Apr 14 18:25:21 CEST 2022


Commit: 482936fc338ead59a296e1b13f03d9e04d9b4c0d
Author: Julian Eisel
Date:   Thu Apr 14 18:11:56 2022 +0200
Branches: temp-outliner-library-override-hierarchy
https://developer.blender.org/rB482936fc338ead59a296e1b13f03d9e04d9b4c0d

Outliner: Add icon column to toggle if library overrides are editable

Adds a column to the right in the Library Overrides Hierarchies view mode to
toggle editability of library overrides.

Part of T95802.

Differential Revision: https://developer.blender.org/D14653

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

M	source/blender/blenkernel/BKE_context.h
M	source/blender/blenkernel/intern/context.c
M	source/blender/blenlib/BLI_utildefines.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.cc
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_utils.cc
M	source/blender/editors/space_outliner/outliner_draw.cc
M	source/blender/editors/space_outliner/outliner_utils.cc
M	source/blender/editors/util/CMakeLists.txt
M	source/blender/editors/util/ed_util_ops.cc

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

diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 584568b4a5e..f441203d9d6 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -10,6 +10,8 @@
 /* XXX temporary, until AssetHandle is designed properly and queries can return a pointer to it. */
 #include "DNA_asset_types.h"
 
+#include "BLI_utildefines.h"
+
 #include "DNA_listBase.h"
 #include "DNA_object_enums.h"
 #include "RNA_types.h"
@@ -136,6 +138,9 @@ bContextStore *CTX_store_add(ListBase *contexts, const char *name, const Pointer
 bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context);
 bContextStore *CTX_store_get(bContext *C);
 void CTX_store_set(bContext *C, bContextStore *store);
+const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
+                                       const char *name,
+                                       const StructRNA *type CPP_ARG_DEFAULT(nullptr));
 bContextStore *CTX_store_copy(bContextStore *store);
 void CTX_store_free(bContextStore *store);
 void CTX_store_free_list(ListBase *contexts);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 63efbb99368..1f1a49ca030 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -190,6 +190,22 @@ void CTX_store_set(bContext *C, bContextStore *store)
   C->wm.store = store;
 }
 
+const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
+                                       const char *name,
+                                       const StructRNA *type)
+{
+  bContextStoreEntry *entry = BLI_rfindstring(
+      &store->entries, name, offsetof(bContextStoreEntry, name));
+  if (!entry) {
+    return NULL;
+  }
+
+  if (type && !RNA_struct_is_a(entry->ptr.type, type)) {
+    return NULL;
+  }
+  return &entry->ptr;
+}
+
 bContextStore *CTX_store_copy(bContextStore *store)
 {
   bContextStore *ctx = MEM_dupallocN(store);
@@ -324,11 +340,10 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData
   if (done != 1 && recursion < 1 && C->wm.store) {
     C->data.recursion = 1;
 
-    bContextStoreEntry *entry = BLI_rfindstring(
-        &C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
+    const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, NULL);
 
-    if (entry) {
-      result->ptr = entry->ptr;
+    if (ptr) {
+      result->ptr = *ptr;
       done = 1;
     }
   }
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 51f0d3f486a..b8407a5453f 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -812,6 +812,16 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
 #  define ENUM_OPERATORS(_type, _max)
 #endif
 
+/**
+ * Utility so function declarations in C headers can use C++ default arguments. The default is then
+ * available when included in a C++ file, otherwise the argument has to be set explicitly.
+ */
+#ifdef __cplusplus
+#  define CPP_ARG_DEFAULT(default_value) = default_value
+#else
+#  define CPP_ARG_DEFAULT(default_value)
+#endif
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 3f58aab3e53..1b817d06564 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -508,6 +508,10 @@ typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
 typedef void (*uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
 typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
 
+/** Function to compare the identity of two buttons over redraws, to check if they represent the
+ * same data, and thus should be considered the same button over redraws. */
+typedef bool (*uiButIdentityCompareFunc)(const uiBut *a, const uiBut *b);
+
 /* Search types. */
 typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
                                                struct ARegion *butregion,
@@ -1360,6 +1364,13 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block,
 /* for passing inputs to ButO buttons */
 struct PointerRNA *UI_but_operator_ptr_get(uiBut *but);
 
+void UI_but_context_ptr_set(uiBlock *block,
+                            uiBut *but,
+                            const char *name,
+                            const struct PointerRNA *ptr);
+const struct PointerRNA *UI_but_context_ptr_get(const uiBut *but,
+                                                const char *name,
+                                                const StructRNA *type CPP_ARG_DEFAULT(nullptr));
 struct bContextStore *UI_but_context_get(const uiBut *but);
 
 void UI_but_unit_type_set(uiBut *but, int unit_type);
@@ -1642,6 +1653,18 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
                                      eButLabelAlign label_align,
                                      bool compact);
 
+/**
+ * Callback to compare the identity of two buttons, used to identify buttons over redraws. If the
+ * callback returns true, the given buttons are considered to be matching and relevant state is
+ * preserved (copied from the old to the new button). If it returns false, it's considered
+ * non-matching and no further checks are done.
+ *
+ * If this is set, it is always executed instead of the default comparisons. However it is only
+ * executed for buttons that have the same type and the same callback. So callbacks can assume the
+ * button types match.
+ */
+void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn);
+
 /**
  * Public function exported for functions that use #UI_BTYPE_SEARCH_MENU.
  *
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index 0ecaead4194..b7098c26bcd 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -725,6 +725,19 @@ bool ui_but_rna_equals_ex(const uiBut *but,
 /* NOTE: if `but->poin` is allocated memory for every `uiDefBut*`, things fail. */
 static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
 {
+  if (but->identity_cmp_func) {
+    /* If the buttons have own identity comparator callbacks (and they match), use this to
+     * determine equality. */
+    if (but->identity_cmp_func && (but->type == oldbut->type) &&
+        (but->identity_cmp_func == oldbut->identity_cmp_func)) {
+      /* Test if the comparison is symmetrical (if a == b then b == a), may help catch some issues.
+       */
+      BLI_assert(but->identity_cmp_func(but, oldbut) == but->identity_cmp_func(oldbut, but));
+
+      return but->identity_cmp_func(but, oldbut);
+    }
+  }
+
   /* various properties are being compared here, hopefully sufficient
    * to catch all cases, but it is simple to add more checks later */
   if (but->retval != oldbut->retval) {
@@ -5951,6 +5964,17 @@ PointerRNA *UI_but_operator_ptr_get(uiBut *but)
   return but->opptr;
 }
 
+void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const PointerRNA *ptr)
+{
+  but->context = CTX_store_add(&block->contexts, name, ptr);
+  but->context->used = true;
+}
+
+const PointerRNA *UI_but_context_ptr_get(const uiBut *but, const char *name, const StructRNA *type)
+{
+  return CTX_store_ptr_lookup(but->context, name, type);
+}
+
 bContextStore *UI_but_context_get(const uiBut *but)
 {
   return but->context;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 05acdac3597..c09ff68bbca 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -183,6 +183,9 @@ struct uiBut {
 
   uchar col[4];
 
+  /** See \ref UI_but_func_identity_compare_set(). */
+  uiButIdentityCompareFunc identity_cmp_func;
+
   uiButHandleFunc func;
   void *func_arg1;
   void *func_arg2;
diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc
index c59863f462a..993ccdf92f7 100644
--- a/source/blender/editors/interface/interface_utils.cc
+++ b/source/blender/editors/interface/interface_utils.cc
@@ -452,6 +452,11 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
   return return_info;
 }
 
+void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn)
+{
+  but->identity_cmp_func = cmp_fn;
+}
+
 /* *** RNA collection search menu *** */
 
 struct CollItemSearch {
diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index 02afd182d0b..d898be4eb2c 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -34,6 +34,7 @@
 #include "BKE_idtype.h"
 #include "BKE_layer.h"
 #include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_modifier.h"
@@ -66,6 +67,7 @@
 #include "outliner_intern.hh"
 #include "tree/tree_display.hh"
 #include "tree/tree_element.hh"
+#include "tree/tree_element_id.hh"
 #include "tree/tree_element_overrides.hh"
 #include "tree/tree_element_rna.hh"
 
@@ -1835,6 +1837,69 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
   }
 }
 
+static bool outliner_but_identity_cmp_context_id_fn(const uiBut *a, const uiBut *b)
+{
+  const PointerRNA *idptr_a = UI_but_context_ptr_get(a, "id", &RNA_ID);
+  const PointerRNA *idptr_b = UI_but_context_ptr_get(b, "id", &RNA_ID);
+  if (!idptr_a || !idptr_b) {
+    return false;
+  }
+  const ID *id_a = (const ID *)idptr_a->data;
+  const ID *id_b = (const ID *)idptr_b->data;
+
+  /* Using session UUID to compare is safer than using the pointer. */
+  return id_a->session_uuid == id_b->session_uuid;
+}
+
+static void outliner_draw_overrides_restrictbuts(Main *bmain,
+                                                 uiBlock *block,
+                    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list