[Bf-blender-cvs] [c4dca652281] master: Asset Browser: Support dragging assets into catalogs

Julian Eisel noreply at git.blender.org
Sun Oct 3 23:59:50 CEST 2021


Commit: c4dca6522812670ab9782e4f90553c5054109f3d
Author: Julian Eisel
Date:   Sun Oct 3 23:58:20 2021 +0200
Branches: master
https://developer.blender.org/rBc4dca6522812670ab9782e4f90553c5054109f3d

Asset Browser: Support dragging assets into catalogs

With this it is possible to select any number of assets in the Asset
Browser and drag them into catalogs. The assets will be moved to that
catalog then. However, this will only work in the "Current File" asset
library, since that is the only library that allows changing assets,
which is what's done here.

While dragging assets over the tree row, a tooltip is shown explaining
what's going to happen.

In preparation to this, the new UI tree-view API was already extended
with custom drop support, see 4ee2d9df428d.

----

Changes here to the `wmDrag` code were needed to support dragging multiple
assets. Some of it is considered temporary because a) a proper #AssetHandle
design should replace some ugly parts of this patch and b) the multi-item
support in `wmDrag` isn't that great yet. The entire API will have to be
written anyway (see D4071).

Maniphest Tasks: T91573

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

Reviewed by: Sybren Stüvel

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

M	doc/python_api/sphinx_doc_gen.py
M	source/blender/blenkernel/BKE_asset_catalog.hh
M	source/blender/blenkernel/intern/asset_catalog.cc
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/space_file/asset_catalog_tree_view.cc
M	source/blender/editors/space_file/file_intern.h
M	source/blender/editors/space_file/file_panels.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/space_file.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/intern/wm_dragdrop.c

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

diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index aa0f79646e6..ec636036f95 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1101,6 +1101,7 @@ context_type_map = {
     "scene": ("Scene", False),
     "sculpt_object": ("Object", False),
     "selectable_objects": ("Object", True),
+    "selected_asset_files": ("FileSelectEntry", True),
     "selected_bones": ("EditBone", True),
     "selected_editable_bones": ("EditBone", True),
     "selected_editable_fcurves": ("FCurve", True),
diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh
index 8afc4fe2ad2..b6b90cff5fd 100644
--- a/source/blender/blenkernel/BKE_asset_catalog.hh
+++ b/source/blender/blenkernel/BKE_asset_catalog.hh
@@ -181,10 +181,12 @@ class AssetCatalogTreeItem {
 
   AssetCatalogTreeItem(StringRef name,
                        CatalogID catalog_id,
+                       StringRef simple_name,
                        const AssetCatalogTreeItem *parent = nullptr);
 
   CatalogID get_catalog_id() const;
-  StringRef get_name() const;
+  StringRefNull get_simple_name() const;
+  StringRefNull get_name() const;
   /** Return the full catalog path, defined as the name of this catalog prefixed by the full
    * catalog path of its parent and a separator. */
   AssetCatalogPath catalog_path() const;
@@ -201,6 +203,8 @@ class AssetCatalogTreeItem {
   /** The user visible name of this component. */
   CatalogPathComponent name_;
   CatalogID catalog_id_;
+  /** Copy of #AssetCatalog::simple_name. */
+  std::string simple_name_;
 
   /** Pointer back to the parent item. Used to reconstruct the hierarchy from an item (e.g. to
    * build a path). */
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index 2c7cf28d60d..577d916288a 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -426,8 +426,9 @@ void AssetCatalogService::create_missing_catalogs()
 
 AssetCatalogTreeItem::AssetCatalogTreeItem(StringRef name,
                                            CatalogID catalog_id,
+                                           StringRef simple_name,
                                            const AssetCatalogTreeItem *parent)
-    : name_(name), catalog_id_(catalog_id), parent_(parent)
+    : name_(name), catalog_id_(catalog_id), simple_name_(simple_name), parent_(parent)
 {
 }
 
@@ -436,11 +437,16 @@ CatalogID AssetCatalogTreeItem::get_catalog_id() const
   return catalog_id_;
 }
 
-StringRef AssetCatalogTreeItem::get_name() const
+StringRefNull AssetCatalogTreeItem::get_name() const
 {
   return name_;
 }
 
+StringRefNull AssetCatalogTreeItem::get_simple_name() const
+{
+  return simple_name_;
+}
+
 AssetCatalogPath AssetCatalogTreeItem::catalog_path() const
 {
   AssetCatalogPath current_path = name_;
@@ -482,8 +488,10 @@ void AssetCatalogTree::insert_item(const AssetCatalog &catalog)
     /* Insert new tree element - if no matching one is there yet! */
     auto [key_and_item, was_inserted] = current_item_children->emplace(
         component_name,
-        AssetCatalogTreeItem(
-            component_name, is_last_component ? catalog.catalog_id : nil_id, parent));
+        AssetCatalogTreeItem(component_name,
+                             is_last_component ? catalog.catalog_id : nil_id,
+                             is_last_component ? catalog.simple_name : "",
+                             parent));
     AssetCatalogTreeItem &item = key_and_item->second;
 
     /* If full path of this catalog already exists as parent path of a previously read catalog,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c53bffca778..39ad88c3368 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -6226,12 +6226,7 @@ void UI_but_drag_set_asset(uiBut *but,
                            struct ImBuf *imb,
                            float scale)
 {
-  wmDragAsset *asset_drag = MEM_mallocN(sizeof(*asset_drag), "wmDragAsset");
-
-  BLI_strncpy(asset_drag->name, ED_asset_handle_get_name(asset), sizeof(asset_drag->name));
-  asset_drag->path = path;
-  asset_drag->id_type = ED_asset_handle_get_id_type(asset);
-  asset_drag->import_type = import_type;
+  wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, path, import_type);
 
   /* FIXME: This is temporary evil solution to get scene/viewlayer/etc in the copy callback of the
    * #wmDropBox.
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index aee66ec3a93..f0e3464a955 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2166,6 +2166,12 @@ static bool ui_but_drag_init(bContext *C,
                             BLI_rctf_size_x(&but->rect),
                             BLI_rctf_size_y(&but->rect));
       }
+
+      /* Special feature for assets: We add another drag item that supports multiple assets. It
+       * gets the assets from context. */
+      if (ELEM(but->dragtype, WM_DRAG_ASSET, WM_DRAG_ID)) {
+        WM_event_start_drag(C, ICON_NONE, WM_DRAG_ASSET_LIST, NULL, 0, WM_DRAG_NOP);
+      }
     }
     return true;
   }
diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc
index 7eea9af925b..92e4e668885 100644
--- a/source/blender/editors/space_file/asset_catalog_tree_view.cc
+++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc
@@ -25,6 +25,7 @@
 
 #include "DNA_space_types.h"
 
+#include "BKE_asset.h"
 #include "BKE_asset_catalog.hh"
 #include "BKE_asset_library.hh"
 
@@ -43,6 +44,7 @@
 #include "WM_types.h"
 
 #include "file_intern.h"
+#include "filelist.h"
 
 using namespace blender;
 using namespace blender::bke;
@@ -53,11 +55,14 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
   /** The asset catalog tree this tree-view represents. */
   bke::AssetCatalogTree *catalog_tree_;
   FileAssetSelectParams *params_;
+  SpaceFile &space_file_;
 
   friend class AssetCatalogTreeViewItem;
 
  public:
-  AssetCatalogTreeView(::AssetLibrary *library, FileAssetSelectParams *params);
+  AssetCatalogTreeView(::AssetLibrary *library,
+                       FileAssetSelectParams *params,
+                       SpaceFile &space_file);
 
   void build_tree() override;
 
@@ -117,6 +122,70 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
       RNA_string_set(props, "catalog_id", catalog_id_str_buffer);
     }
   }
+
+  bool has_droppable_item(const wmDrag &drag) const
+  {
+    const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+
+    /* There needs to be at least one asset from the current file. */
+    LISTBASE_FOREACH (const wmDragAssetListItem *, asset_item, asset_drags) {
+      if (!asset_item->is_external) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool can_drop(const wmDrag &drag) const override
+  {
+    if (drag.type != WM_DRAG_ASSET_LIST) {
+      return false;
+    }
+    return has_droppable_item(drag);
+  }
+
+  std::string drop_tooltip(const bContext & /*C*/,
+                           const wmDrag &drag,
+                           const wmEvent & /*event*/) const override
+  {
+    const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+    const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
+
+    /* Don't try to be smart by dynamically adding the 's' for the plural. Just makes translation
+     * harder, so use full literals. */
+    std::string basic_tip = is_multiple_assets ? TIP_("Move assets to catalog") :
+                                                 TIP_("Move asset to catalog");
+
+    return basic_tip + ": " + catalog_item_.get_name() + " (" +
+           catalog_item_.catalog_path().str() + ")";
+  }
+
+  bool on_drop(const wmDrag &drag) override
+  {
+    const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+    if (!asset_drags) {
+      return false;
+    }
+
+    const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
+        get_tree_view());
+
+    LISTBASE_FOREACH (wmDragAssetListItem *, asset_item, asset_drags) {
+      if (asset_item->is_external) {
+        /* Only internal assets can be modified! */
+        continue;
+      }
+      BKE_asset_metadata_catalog_id_set(asset_item->asset_data.local_id->asset_data,
+                                        catalog_item_.get_catalog_id(),
+                                        catalog_item_.get_simple_name().c_str());
+
+      /* Trigger re-run of filtering to update visible assets. */
+      filelist_tag_needs_filtering(tree_view.space_file_.files);
+      file_select_deselect_all(&tree_view.space_file_, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED);
+    }
+
+    return true;
+  }
 };
 
 /** Only reason this isn't just `BasicTreeViewItem` is to add a '+' icon for adding a root level
@@ -140,8 +209,12 @@ class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem {
   }
 };
 
-AssetCatalogTreeView::AssetCatalogTreeView(::AssetLibrary *library, FileAssetSelectParams *params)
-    : catalog_tree_(BKE_asset_library_get_catalog_tree(library)), params_(params)
+AssetCatalogTreeView::AssetCatalogTreeView(::AssetLibrary *library,
+                                           FileAssetSelectParams *params,
+                                           SpaceFile &space_file)
+    : catalog_tree_(BKE_asset_library_get_catalog_tree(library)),
+      params_(params),
+      space_file_(space_file)
 {
 }
 
@@ -216,6 +289,7 @@ bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
 
 void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
                                                    uiLayout *layout,
+                                                   SpaceFile *space_file,
                                                    FileAssetSelectParams *params)
 {
   uiBlock *block = uiLayoutGetBlock(layou

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list