diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_dragdrop.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 94 |
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) |