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/windowmanager/intern/wm_dragdrop.c
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/windowmanager/intern/wm_dragdrop.c')
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c94
1 files changed, 91 insertions, 3 deletions
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)