Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2021-10-04 00:58:20 +0300
committerJulian Eisel <julian@blender.org>2021-10-04 00:58:20 +0300
commitc4dca6522812670ab9782e4f90553c5054109f3d (patch)
tree24dc1e2c0eb55985e8e6543b131989da1ca4125e /source/blender
parent3b1a2430391a6c1e0ea2744cfce2cf0749c72c85 (diff)
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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_asset_catalog.hh6
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc16
-rw-r--r--source/blender/editors/interface/interface.c7
-rw-r--r--source/blender/editors/interface/interface_handlers.c6
-rw-r--r--source/blender/editors/space_file/asset_catalog_tree_view.cc83
-rw-r--r--source/blender/editors/space_file/file_intern.h1
-rw-r--r--source/blender/editors/space_file/file_panels.c2
-rw-r--r--source/blender/editors/space_file/filelist.c3
-rw-r--r--source/blender/editors/space_file/filelist.h1
-rw-r--r--source/blender/editors/space_file/space_file.c19
-rw-r--r--source/blender/windowmanager/WM_api.h11
-rw-r--r--source/blender/windowmanager/WM_types.h37
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c94
13 files changed, 259 insertions, 27 deletions
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(layout);
@@ -223,7 +297,8 @@ void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library
ui::AbstractTreeView *tree_view = UI_block_add_view(
*block,
"asset catalog tree view",
- std::make_unique<ed::asset_browser::AssetCatalogTreeView>(asset_library, params));
+ std::make_unique<ed::asset_browser::AssetCatalogTreeView>(
+ asset_library, params, *space_file));
ui::TreeViewBuilder builder(*block);
builder.build_tree_view(*tree_view);
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index d39aefff691..c8609f48adb 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -165,6 +165,7 @@ void file_path_to_ui_path(const char *path, char *r_pathi, int max_size);
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
struct uiLayout *layout,
+ struct SpaceFile *space_file,
struct FileAssetSelectParams *params);
#ifdef __cplusplus
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 95aad202f1a..b530f1d0aa7 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -238,7 +238,7 @@ static void file_panel_asset_catalog_buttons_draw(const bContext *C, Panel *pane
FileAssetSelectParams *params = ED_fileselect_get_asset_params(sfile);
BLI_assert(params != NULL);
- file_create_asset_catalog_tree_view_in_layout(asset_library, panel->layout, params);
+ file_create_asset_catalog_tree_view_in_layout(asset_library, panel->layout, sfile, params);
}
void file_tools_region_panels_register(ARegionType *art)
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 0cb587c3b19..b58a04d6d4f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -490,7 +490,6 @@ static void filelist_readjob_main_assets(struct FileListReadJob *job_params,
static int groupname_to_code(const char *group);
static uint64_t groupname_to_filter_id(const char *group);
-static void filelist_tag_needs_filtering(FileList *filelist);
static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size);
/* ********** Sort helpers ********** */
@@ -970,7 +969,7 @@ static bool is_filtered_main_assets(FileListInternEntry *file,
is_filtered_asset(file, filter);
}
-static void filelist_tag_needs_filtering(FileList *filelist)
+void filelist_tag_needs_filtering(FileList *filelist)
{
filelist->flags |= FL_NEED_FILTERING;
}
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index d1f37b5b365..c2c1211b81c 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -76,6 +76,7 @@ void filelist_set_asset_catalog_filter_options(
struct FileList *filelist,
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
const struct bUUID *catalog_id);
+void filelist_tag_needs_filtering(struct FileList *filelist);
void filelist_filter(struct FileList *filelist);
void filelist_setlibrary(struct FileList *filelist,
const struct AssetLibraryReference *asset_library_ref);
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index a563f24e24e..c8bca22c166 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -894,6 +894,7 @@ const char *file_context_dir[] = {
"active_file",
"selected_files",
"asset_library_ref",
+ "selected_asset_files",
"id",
NULL,
};
@@ -951,6 +952,24 @@ static int /*eContextResult*/ file_context(const bContext *C,
result, &screen->id, &RNA_AssetLibraryReference, &asset_params->asset_library_ref);
return CTX_RESULT_OK;
}
+ /** TODO temporary AssetHandle design: For now this returns the file entry. Would be better if it
+ * was `"selected_assets"` and returned the assets (e.g. as `AssetHandle`) directly. See comment
+ * for #AssetHandle for more info. */
+ if (CTX_data_equals(member, "selected_asset_files")) {
+ const int num_files_filtered = filelist_files_ensure(sfile->files);
+
+ for (int file_index = 0; file_index < num_files_filtered; file_index++) {
+ if (filelist_entry_is_selected(sfile->files, file_index)) {
+ FileDirEntry *entry = filelist_file(sfile->files, file_index);
+ if (entry->asset_data) {
+ CTX_data_list_add(result, &screen->id, &RNA_FileSelectEntry, entry);
+ }
+ }
+ }
+
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return CTX_RESULT_OK;
+ }
if (CTX_data_equals(member, "id")) {
const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
if (file == NULL) {
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 577561017c4..ebb0f803acf 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -41,6 +41,8 @@ extern "C" {
#endif
struct ARegion;
+struct AssetHandle;
+struct AssetLibraryReference;
struct GHashIterator;
struct GPUViewport;
struct ID;
@@ -741,6 +743,9 @@ struct ID *WM_drag_get_local_ID(const struct wmDrag *drag, short idcode);
struct ID *WM_drag_get_local_ID_from_event(const struct wmEvent *event, short idcode);
bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
+wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
+ const char *path,
+ int import_type);
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
struct ID *WM_drag_get_local_ID_or_import_from_asset(const struct wmDrag *drag, int idcode);
@@ -748,6 +753,12 @@ void WM_drag_free_imported_drag_ID(struct Main *bmain,
struct wmDrag *drag,
struct wmDropBox *drop);
+void WM_drag_add_asset_list_item(wmDrag *drag,
+ const struct bContext *C,
+ const struct AssetLibraryReference *asset_library_ref,
+ const struct AssetHandle *asset);
+const ListBase *WM_drag_asset_list_get(const wmDrag *drag);
+
const char *WM_drag_get_item_name(struct wmDrag *drag);
/* Set OpenGL viewport and scissor */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 588c895c742..7f52bef3203 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -915,12 +915,16 @@ typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata
#define WM_DRAG_ID 0
#define WM_DRAG_ASSET 1
-#define WM_DRAG_RNA 2
-#define WM_DRAG_PATH 3
-#define WM_DRAG_NAME 4
-#define WM_DRAG_VALUE 5
-#define WM_DRAG_COLOR 6
-#define WM_DRAG_DATASTACK 7
+/** The user is dragging multiple assets. This is only supported in few specific cases, proper
+ * multi-item support for dragging isn't supported well yet. Therefore this is kept separate from
+ * #WM_DRAG_ASSET. */
+#define WM_DRAG_ASSET_LIST 2
+#define WM_DRAG_RNA 3
+#define WM_DRAG_PATH 4
+#define WM_DRAG_NAME 5
+#define WM_DRAG_VALUE 6
+#define WM_DRAG_COLOR 7
+#define WM_DRAG_DATASTACK 8
typedef enum wmDragFlags {
WM_DRAG_NOP = 0,
@@ -953,6 +957,25 @@ typedef struct wmDragAsset {
struct bContext *evil_C;
} wmDragAsset;
+/**
+ * For some specific cases we support dragging multiple assets (#WM_DRAG_ASSET_LIST). There is no
+ * proper support for dragging multiple items in the `wmDrag`/`wmDrop` API yet, so this is really
+ * just to enable specific features for assets.
+ *
+ * This struct basically contains a tagged union to either store a local ID pointer, or information
+ * about an externally stored asset.
+ */
+typedef struct wmDragAssetListItem {
+ struct wmDragAssetListItem *next, *prev;
+
+ union {
+ struct ID *local_id;
+ wmDragAsset *external_info;
+ } asset_data;
+
+ bool is_external;
+} wmDragAssetListItem;
+
typedef char *(*WMDropboxTooltipFunc)(struct bContext *,
struct wmDrag *,
const struct wmEvent *event,
@@ -979,6 +1002,8 @@ typedef struct wmDrag {
/** List of wmDragIDs, all are guaranteed to have the same ID type. */
ListBase ids;
+ /** List of `wmDragAssetListItem`s. */
+ ListBase asset_items;
} wmDrag;
/**
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index c5a89e3ad9f..b76b1672543 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -46,6 +46,8 @@
#include "BLO_readfile.h"
+#include "ED_asset.h"
+
#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_viewport.h"
@@ -66,6 +68,8 @@
static ListBase dropboxes = {NULL, NULL};
+static void wm_drag_free_asset_data(wmDragAsset **asset_data);
+
/* drop box maps are stored global for now */
/* these are part of blender's UI/space specs, and not like keymaps */
/* when editors become configurable, they can add own dropbox definitions */
@@ -176,6 +180,19 @@ wmDrag *WM_event_start_drag(
drag->poin = poin;
drag->flags |= WM_DRAG_FREE_DATA;
break;
+ /* The asset-list case is special: We get multiple assets from context and attach them to the
+ * drag item. */
+ case WM_DRAG_ASSET_LIST: {
+ const AssetLibraryReference *asset_library = CTX_wm_asset_library_ref(C);
+ ListBase asset_file_links = CTX_data_collection_get(C, "selected_asset_files");
+ LISTBASE_FOREACH (const CollectionPointerLink *, link, &asset_file_links) {
+ const FileDirEntry *asset_file = link->ptr.data;
+ const AssetHandle asset_handle = {asset_file};
+ WM_drag_add_asset_list_item(drag, C, asset_library, &asset_handle);
+ }
+ BLI_freelistN(&asset_file_links);
+ break;
+ }
default:
drag->poin = poin;
break;
@@ -202,10 +219,12 @@ void WM_drag_data_free(int dragtype, void *poin)
/* Not too nice, could become a callback. */
if (dragtype == WM_DRAG_ASSET) {
- wmDragAsset *asset_drag = poin;
- MEM_freeN((void *)asset_drag->path);
+ wmDragAsset *asset_data = poin;
+ wm_drag_free_asset_data(&asset_data);
+ }
+ else {
+ MEM_freeN(poin);
}
- MEM_freeN(poin);
}
void WM_drag_free(wmDrag *drag)
@@ -214,6 +233,12 @@ void WM_drag_free(wmDrag *drag)
WM_drag_data_free(drag->type, drag->poin);
}
BLI_freelistN(&drag->ids);
+ LISTBASE_FOREACH_MUTABLE (wmDragAssetListItem *, asset_item, &drag->asset_items) {
+ if (asset_item->is_external) {
+ wm_drag_free_asset_data(&asset_item->asset_data.external_info);
+ }
+ BLI_freelinkN(&drag->asset_items, asset_item);
+ }
MEM_freeN(drag);
}
@@ -378,6 +403,27 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
return WM_drag_get_local_ID(drag, idcode) || WM_drag_get_asset_data(drag, idcode);
}
+/**
+ * \note: Does not store \a asset in any way, so it's fine to pass a temporary.
+ */
+wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type)
+{
+ 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;
+
+ return asset_drag;
+}
+
+static void wm_drag_free_asset_data(wmDragAsset **asset_data)
+{
+ MEM_freeN((char *)(*asset_data)->path);
+ MEM_SAFE_FREE(*asset_data);
+}
+
wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
{
if (drag->type != WM_DRAG_ASSET) {
@@ -495,6 +541,48 @@ void WM_drag_free_imported_drag_ID(struct Main *bmain, wmDrag *drag, wmDropBox *
}
}
+/**
+ * \note: Does not store \a asset in any way, so it's fine to pass a temporary.
+ */
+void WM_drag_add_asset_list_item(
+ wmDrag *drag,
+ /* Context only needed for the hack in #ED_asset_handle_get_full_library_path(). */
+ const bContext *C,
+ const AssetLibraryReference *asset_library_ref,
+ const AssetHandle *asset)
+{
+ if (drag->type != WM_DRAG_ASSET_LIST) {
+ return;
+ }
+
+ /* No guarantee that the same asset isn't added twice. */
+
+ /* Add to list. */
+ wmDragAssetListItem *drag_asset = MEM_callocN(sizeof(*drag_asset), __func__);
+ ID *local_id = ED_asset_handle_get_local_id(asset);
+ if (local_id) {
+ drag_asset->is_external = false;
+ drag_asset->asset_data.local_id = local_id;
+ }
+ else {
+ char asset_blend_path[FILE_MAX_LIBEXTRA];
+ ED_asset_handle_get_full_library_path(C, asset_library_ref, asset, asset_blend_path);
+ drag_asset->is_external = true;
+ drag_asset->asset_data.external_info = WM_drag_create_asset_data(
+ asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
+ }
+ BLI_addtail(&drag->asset_items, drag_asset);
+}
+
+const ListBase *WM_drag_asset_list_get(const wmDrag *drag)
+{
+ if (drag->type != WM_DRAG_ASSET_LIST) {
+ return NULL;
+ }
+
+ return &drag->asset_items;
+}
+
/* ************** draw ***************** */
static void wm_drop_operator_draw(const char *name, int x, int y)