[Bf-blender-cvs] [734f7b1b4dd] temp-asset-browser-catalogs-ui: Support deleting catalogs from the UI

Julian Eisel noreply at git.blender.org
Thu Sep 23 12:25:40 CEST 2021


Commit: 734f7b1b4dd9ff47c42e629f0c4631c3b4d53709
Author: Julian Eisel
Date:   Thu Sep 23 11:59:39 2021 +0200
Branches: temp-asset-browser-catalogs-ui
https://developer.blender.org/rB734f7b1b4dd9ff47c42e629f0c4631c3b4d53709

Support deleting catalogs from the UI

Adds a 'x' icon to catalogs to delete them (including children, if any).

There's no undo/redo for editing catalogs yet (since they are not
stored in .blend files), so deleting a catalog is a destructive action.
Therefore we show a confirmation popup.

Only catalog tree-items in the UI that represent an actual catalog can
be deleted for now. With T91451 done, this will change (every item
visible will be an actual catalog, so you'll be able to delete each).

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

M	source/blender/blenkernel/intern/asset_catalog.cc
M	source/blender/editors/asset/ED_asset_catalog.hh
M	source/blender/editors/asset/intern/asset_catalog.cc
M	source/blender/editors/asset/intern/asset_ops.cc
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/include/UI_tree_view.hh
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/tree_view.cc
M	source/blender/editors/space_file/asset_catalog_tree_view.cc

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

diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index 9aa98424e4c..6a03bb25e05 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -476,6 +476,7 @@ void AssetCatalogTree::insert_item(AssetCatalog &catalog)
   BLI_assert_msg(!ELEM(catalog.path[0], '/', '\\'),
                  "Malformed catalog path: Path should be formatted like a relative path");
 
+  CatalogID unset_id = bke::UUID();
   const char *next_slash_ptr;
   /* Looks more complicated than it is, this just iterates over path components. E.g.
    * "just/some/path" iterates over "just", then "some" then "path". */
@@ -484,19 +485,28 @@ void AssetCatalogTree::insert_item(AssetCatalog &catalog)
        name_begin = next_slash_ptr ? next_slash_ptr + 1 : nullptr) {
     next_slash_ptr = BLI_path_slash_find(name_begin);
 
+    const bool is_last_component = next_slash_ptr == nullptr;
     /* Note that this won't be null terminated. */
-    StringRef component_name = next_slash_ptr ?
-                                   StringRef(name_begin, next_slash_ptr - name_begin) :
-                                   /* Last component in the path. */
-                                   name_begin;
+    StringRef component_name = is_last_component ?
+                                   name_begin :
+                                   StringRef(name_begin, next_slash_ptr - name_begin);
 
     /* Insert new tree element - if no matching one is there yet! */
-    auto [item, was_inserted] = insert_to_map->emplace(
-        component_name, AssetCatalogTreeItem(component_name, catalog.catalog_id, parent));
+    auto [key_and_item, was_inserted] = insert_to_map->emplace(
+        component_name,
+        AssetCatalogTreeItem(
+            component_name, is_last_component ? catalog.catalog_id : unset_id, parent));
+    AssetCatalogTreeItem &item = key_and_item->second;
+
+    /* If full path of this catalog already exists as parent path of a previously read catalog, we
+     * can ensure this tree item's UUID is set here. */
+    if (is_last_component && (item.catalog_id_ == unset_id)) {
+      item.catalog_id_ = catalog.catalog_id;
+    }
 
     /* Walk further into the path (no matter if a new item was created or not). */
-    parent = &item->second;
-    insert_to_map = &item->second.children_;
+    parent = &item;
+    insert_to_map = &item.children_;
   }
 }
 
diff --git a/source/blender/editors/asset/ED_asset_catalog.hh b/source/blender/editors/asset/ED_asset_catalog.hh
index 7ed12c76214..b65d8839ae5 100644
--- a/source/blender/editors/asset/ED_asset_catalog.hh
+++ b/source/blender/editors/asset/ED_asset_catalog.hh
@@ -30,3 +30,5 @@ struct AssetLibrary;
 blender::bke::AssetCatalog *ED_asset_catalog_add(blender::bke::AssetLibrary *library,
                                                  blender::StringRefNull name,
                                                  blender::StringRef parent_path = nullptr);
+void ED_asset_catalog_remove(blender::bke::AssetLibrary *library,
+                             const blender::bke::CatalogID &catalog_id);
diff --git a/source/blender/editors/asset/intern/asset_catalog.cc b/source/blender/editors/asset/intern/asset_catalog.cc
index b1a38e67e97..e4c73564946 100644
--- a/source/blender/editors/asset/intern/asset_catalog.cc
+++ b/source/blender/editors/asset/intern/asset_catalog.cc
@@ -81,3 +81,12 @@ AssetCatalog *ED_asset_catalog_add(blender::bke::AssetLibrary *library,
 
   return library->catalog_service->create_catalog(fullpath);
 }
+
+void ED_asset_catalog_remove(blender::bke::AssetLibrary *library, const CatalogID &catalog_id)
+{
+  if (!library || !library->catalog_service) {
+    return;
+  }
+
+  library->catalog_service->delete_catalog(catalog_id);
+}
diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc
index 9e6845797bb..584b4f297f7 100644
--- a/source/blender/editors/asset/intern/asset_ops.cc
+++ b/source/blender/editors/asset/intern/asset_ops.cc
@@ -303,7 +303,7 @@ static void ASSET_OT_list_refresh(struct wmOperatorType *ot)
 
 /* -------------------------------------------------------------------- */
 
-static bool asset_catalog_new_poll(bContext *C)
+static bool asset_catalog_operator_poll(bContext *C)
 {
   const SpaceFile *sfile = CTX_wm_space_file(C);
   return asset_operation_poll(C) && sfile && ED_fileselect_active_asset_library_get(sfile);
@@ -320,6 +320,8 @@ static int asset_catalog_new_exec(bContext *C, wmOperator *op)
 
   MEM_freeN(parent_path);
 
+  WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
+
   return OPERATOR_FINISHED;
 }
 
@@ -332,7 +334,7 @@ static void ASSET_OT_catalog_new(struct wmOperatorType *ot)
 
   /* api callbacks */
   ot->exec = asset_catalog_new_exec;
-  ot->poll = asset_catalog_new_poll;
+  ot->poll = asset_catalog_operator_poll;
 
   RNA_def_string(ot->srna,
                  "parent_path",
@@ -342,6 +344,43 @@ static void ASSET_OT_catalog_new(struct wmOperatorType *ot)
                  "Optional path defining the location to put the new catalog under");
 }
 
+static int asset_catalog_delete_exec(bContext *C, wmOperator *op)
+{
+  SpaceFile *sfile = CTX_wm_space_file(C);
+  struct AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
+  char *catalog_id_str = RNA_string_get_alloc(op->ptr, "catalog_id", nullptr, 0, nullptr);
+  bke::CatalogID catalog_id;
+  if (!BLI_uuid_parse_string(&catalog_id, catalog_id_str)) {
+    return OPERATOR_CANCELLED;
+  }
+
+  ED_asset_catalog_remove(reinterpret_cast<blender::bke::AssetLibrary *>(asset_library),
+                          catalog_id);
+
+  MEM_freeN(catalog_id_str);
+
+  WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
+
+  return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_catalog_delete(struct wmOperatorType *ot)
+{
+  /* identifiers */
+  ot->name = "Delete Asset Catalog";
+  ot->description =
+      "Remove an asset catalog from the asset library (contained assets will not be affected and "
+      "show up as unassigned)";
+  ot->idname = "ASSET_OT_catalog_delete";
+
+  /* api callbacks */
+  ot->exec = asset_catalog_delete_exec;
+  ot->invoke = WM_operator_confirm;
+  ot->poll = asset_catalog_operator_poll;
+
+  RNA_def_string(ot->srna, "catalog_id", nullptr, 0, "Catalog ID", "ID of the catalog to delete");
+}
+
 /* -------------------------------------------------------------------- */
 
 void ED_operatortypes_asset(void)
@@ -350,6 +389,7 @@ void ED_operatortypes_asset(void)
   WM_operatortype_append(ASSET_OT_clear);
 
   WM_operatortype_append(ASSET_OT_catalog_new);
+  WM_operatortype_append(ASSET_OT_catalog_delete);
 
   WM_operatortype_append(ASSET_OT_list_refresh);
 }
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 313e45bc0e5..b04e61e477e 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2761,7 +2761,8 @@ void UI_interface_tag_script_reload(void);
 /* Support click-drag motion which presses the button and closes a popover (like a menu). */
 #define USE_UI_POPOVER_ONCE
 
-bool UI_tree_view_item_is_active(uiTreeViewItemHandle *item_);
+bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item_);
+bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a_, const uiTreeViewItemHandle *b_);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 73c1245c18f..15568f8478b 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -186,6 +186,7 @@ class uiAbstractTreeViewItem : public uiTreeViewItemContainer {
    * last redraw to this item. If sub-classes introduce more advanced state they should override
    * this and make update their state accordingly. */
   virtual void update_from_old(uiAbstractTreeViewItem &old);
+  virtual bool matches(const uiAbstractTreeViewItem &other) const;
 
   const uiAbstractTreeView &get_tree_view() const;
   int count_parents() const;
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index beee622673c..c2ed903c9a7 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -743,6 +743,15 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
     return false;
   }
 
+  if ((but->type == UI_BTYPE_TREEROW) && (oldbut->type == UI_BTYPE_TREEROW)) {
+    uiButTreeRow *but_treerow = (uiButTreeRow *)but;
+    uiButTreeRow *oldbut_treerow = (uiButTreeRow *)oldbut;
+    if (!but_treerow->tree_item || !oldbut_treerow->tree_item ||
+        !UI_tree_view_item_matches(but_treerow->tree_item, oldbut_treerow->tree_item)) {
+      return false;
+    }
+  }
+
   return true;
 }
 
diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc
index 13601abb991..609252aef83 100644
--- a/source/blender/editors/interface/tree_view.cc
+++ b/source/blender/editors/interface/tree_view.cc
@@ -123,7 +123,7 @@ uiAbstractTreeViewItem *uiAbstractTreeView::find_matching_child(
     const uiAbstractTreeViewItem &lookup_item, const uiTreeViewItemContainer &items)
 {
   for (const auto &iter_item : items.children_) {
-    if (lookup_item.label_ == iter_item->label_) {
+    if (lookup_item.matches(*iter_item)) {
       /* We have a matching item! */
       return iter_item.get();
     }
@@ -145,6 +145,11 @@ void uiAbstractTreeViewItem::update_from_old(uiAbstractTreeViewItem &old)
   is_active_ = old.is_active_;
 }
 
+bool uiAbstractTreeViewItem::matches(const uiAbstractTreeViewItem &other) const
+{
+  return label_ == other.label_;
+}
+
 const uiAbstractTreeView &uiAbstractTreeViewItem::get_tree_view() const
 {
   return static_cast<uiAbstractTreeView &>(*root_);
@@ -309,8 +314,15 @@ uiBut *uiBasicTreeViewItem::button()
 
 using namespace blender::ui;
 
-bool UI_tree_view_item_is_active(uiTreeViewItemHandle *item_)
+bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list