[Bf-blender-cvs] [994da7077d4] master: Outliner: Add icon column to toggle if library overrides are editable

Julian Eisel noreply at git.blender.org
Tue Apr 26 22:31:24 CEST 2022


Commit: 994da7077d4a683a122f40ad0c3b0585d4968fcc
Author: Julian Eisel
Date:   Tue Apr 26 22:30:33 2022 +0200
Branches: master
https://developer.blender.org/rB994da7077d4a683a122f40ad0c3b0585d4968fcc

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.

Note that making a library override non-editable currently involves
clearing all overridden properties. This is an arguable design choice,
we should probably at least warn the user before doing this.

Part of T95802.

Reviewed by: Bastien Montagne

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

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

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/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,
+                                                 const ARegion *region,
+                                                 const SpaceOutliner *space_outliner,
+                                                 const ListBase *lb,
+                                                 const int x)
+{
+  LISTBASE_FOREACH (const TreeElement *, te, lb) {
+    const TreeStoreElem *tselem = TREESTORE(te);
+    if (TSELEM_OPEN(tselem, space_outliner)) {
+      outliner_draw_overrides_restrictbuts(bmain, block, region, space_outliner, &te->subtree, x);
+    }
+
+    if (!outliner_is_element_in_view(te, &region->v2d)) {
+      continue;
+    }
+    TreeElementID *te_id = tree_element_cast<TreeElementID>(te);
+    if (!te_id) {
+      continue;
+    }
+
+    ID &id = te_id->get_ID();
+    BLI_assert(ID_IS_OVERRIDE_LIBRARY(&id));
+
+    if (ID_IS_LINKED(&id)) {
+      continue;
+    }
+
+    const bool is_system_override = BKE_lib_override_library_is_system_defined(bmain, &id);
+    const BIFIconID icon = is_system_override ? ICON_LIBRARY_DATA_OVERRIDE_NONEDITABLE :
+                                                ICON_LIBRARY_DATA_OVERRIDE;
+    uiBut *but = uiDefIconButO(block,
+                               UI_BTYPE_BUT,
+                               "ED_OT_lib_id_override_editable_toggle",
+                               WM_OP_EXEC_DEFAULT,
+                               icon,
+                               x,
+                               te->ys,
+                               UI_UNIT_X,
+                               UI_UNIT_Y,
+                               "");
+    PointerRNA idptr;
+    RNA_id_pointer_create(&id, &idptr);
+    UI_but_context_ptr_set(block, but, "id", &idptr);
+    UI_but_func_identity_compare_set(but, outliner_but_identity_cmp_context_id_fn);
+    UI_but_flag_enable(but, UI_BUT_DRAG_LOCK);
+  }
+}
+
 static bool outliner_draw_overrides_warning_buts(uiBlock *block,
                                                  ARegion *region,
                                                  SpaceOutliner *space_outliner,
@@ -3899,12 +3964,6 @@ void draw_outliner(const bContext *C)
   /* Default to no emboss for outliner UI. */
   UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
 
-  if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
-    /* Draw overrides status columns. */
-    outliner_draw_overrides_warning_buts(
-        block, region, space_outliner, &space_outliner->tree, true);
-  }
-
   if (space_outliner->outlinevis == SO_DATA_API) {
     int buttons_start_x = outliner_data_api_buttons_start_x(tree_width);
     /* draw rna buttons */
@@ -3919,14 +3978,23 @@ void draw_outliner(const bContext *C)
     /* draw user toggle columns */
     outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree);
   }
-  else if ((space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) &&
-           (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES)) {
-    UI_block_emboss_set(block, UI_EMBOSS);
-    UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
+  else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
+    /* Draw overrides status columns. */
+    outliner_draw_overrides_warning_buts(
+        block, region, space_outliner, &space_outliner->tree, true);
+
     const int x = region->v2d.cur.xmax - right_column_width;
     outliner_draw_separator(region, x);
-    outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
-    UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
+    if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
+      UI_block_emboss_set(block, UI_EMBOSS);
+      UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
+      outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
+      UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
+    }
+    else if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_HIERARCHIES) {
+      outliner_draw_overrides_restrictbuts(
+          mainvar, block, region, space_outliner, &space_outliner->tree, x);
+    }
   }
   else if (right_column_width > 0.0f) {
     /* draw restriction columns */
diff --git a/source/blender/editors/space_outliner/outliner_utils.cc b/source/blender/editors/space_outliner/outliner_utils.cc
index 7526cc7ef5c..4b947154864 100644
--- a/source/blender/editors/space_outliner/outliner_utils.cc
+++ b/source/blender/editors/space_outliner/outliner_utils.cc
@@ -324,10 +324,14 @@ float outliner_right_columns_width(const SpaceOutliner *space_outliner)
     case SO_LIBRARIES:
       return 0.0f;
     case SO_OVERRIDES_LIBRARY:
-      if (space_outliner->lib_override_view_mode != SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
-        return 0.0f;
+      switch ((eSpaceOutliner_LibOverrideViewMode)space_outliner->lib_override_view_mode) {
+        case SO_LIB_OVERRIDE_VIEW_PROPERTIES:
+          num_columns = OL_RNA_COL_SIZEX / UI_UNIT_X;
+          break;
+        case SO_LIB_OVERRIDE_VIEW_HIERARCHIES:
+          num_columns = 1;
+          break;
       }
-      num_columns = OL_RNA_COL_SIZEX / UI_UNIT_X;
       break;
     case SO_ID_ORPHANS:
       num_columns = 3;
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 7b4551fdb0c..89d80d582f8 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -18,6 +18,8 @@ set(INC
   ../../../../intern/clog
   ../../../../intern/glew-mx
   ../../../../intern/guardedalloc
+  # RNA_prototypes.h
+  ${CMAKE_BINARY_DIR}/source/blender/makesrna
 )
 
 
@@ -110,3 +112,6 @@ if(WITH_PYTHON)
 endif()
 
 blender_add_lib(bf_editor_util "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+# RNA_prototypes.h
+add_dependencies(bf_editor_util bf_rna)
diff --git a/source/blender/editors/util/ed_util_ops.cc b/source/blender/editors/util/ed_util_ops.cc
index ccc28353518..803e65590a0 100644
--- a/source/blender/editors/util/ed_util_ops.cc
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -17,6 +17,7 @@
 #include "BKE_context.h"
 #include "BKE_icons.h"
 #include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
 #include "BKE_main.h"
 #include "BKE_report.h"
 
@@ -28,6 +29,7 @@
 #include "ED_util.h"
 
 #include "RNA_access.h"
+#include "RNA_prototypes.h"
 
 #include "UI_interface.h"
 
@@ -294,6 +296,50 @@ static void ED_OT_lib_id_unlink(wmOperatorType *ot)
   ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
 }
 
+static bool lib_id_override_editable_toggle_poll(bContext *C)
+{
+  const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
+  const ID *id = static_cast<ID *>(id_ptr.data);
+
+  return id && ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id);
+}
+
+static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+{
+  Main *bmain = CTX_data_main(C);
+  const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
+  ID *id = static_cast<ID *>(id_ptr.data);
+
+  const bool is_system_override = BKE_lib_override_library_is_system_defined(bmain, id);
+  if (is_system_override) {
+    /* A system override is not editable. Make it an editable (non-system-defined) one. */
+    id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+  }
+  else {
+    /* Reset override, which makes it non-editable (i.e. a system define override). */
+    BKE_lib_override_library_id_reset(bmain, id, true);
+  }
+
+  WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr);
+
+  return OPERATOR_FINISHED;
+}
+
+static void ED_OT_lib_id_override_editable_toggle(wmOperatorType *ot)
+{
+  /* identifiers */
+  ot->name = "Toggle Library Override Editable";
+  ot->description = "Set if this library override data-block can be edited";
+  ot->idname = "ED_OT_lib_id_override_editable_toggle";
+
+  /* api callbacks */
+  ot->poll = lib_id_override_editable_toggle_poll;
+  ot->exec = lib_id_override_editable_toggle_exec;
+
+  /* flags */
+  ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -331,6 +377,7 @@ void ED_operatortypes_edutils()
 
   WM_operatortype_append(ED_OT_lib_id_fake_user_toggle);
   WM_operatortype_append(ED_OT_lib_id_unlink);
+  WM_operatortype_append(ED_OT_lib_id_override_editable_toggle);
 
   WM_operatortype_append(ED_OT_flush_edits);



More information about the Bf-blender-cvs mailing list