diff options
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 102 |
1 files changed, 84 insertions, 18 deletions
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 373360c7b92..fe2e2d92127 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -37,6 +37,7 @@ #include "BIF_glutil.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_idtype.h" #include "GPU_shader.h" @@ -146,16 +147,23 @@ wmDrag *WM_event_start_drag( drag->flags = flags; drag->icon = icon; drag->type = type; - if (type == WM_DRAG_PATH) { - BLI_strncpy(drag->path, poin, FILE_MAX); - } - else if (type == WM_DRAG_ID) { - if (poin) { - WM_drag_add_ID(drag, poin, NULL); - } - } - else { - drag->poin = poin; + switch (type) { + case WM_DRAG_PATH: + BLI_strncpy(drag->path, poin, FILE_MAX); + break; + case WM_DRAG_ID: + if (poin) { + WM_drag_add_local_ID(drag, poin, NULL); + } + break; + case WM_DRAG_ASSET: + /* Move ownership of poin to wmDrag. */ + drag->poin = poin; + drag->flags |= WM_DRAG_FREE_DATA; + break; + default: + drag->poin = poin; + break; } drag->value = value; @@ -170,12 +178,26 @@ void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy) drag->sy = sy; } -void WM_drag_free(wmDrag *drag) +void WM_drag_data_free(int dragtype, void *poin) { - if ((drag->flags & WM_DRAG_FREE_DATA) && drag->poin) { - MEM_freeN(drag->poin); + /* Don't require all the callers to have a NULL-check, just allow passing NULL. */ + if (!poin) { + return; } + /* Not too nice, could become a callback. */ + if (dragtype == WM_DRAG_ASSET) { + wmDragAsset *asset_drag = poin; + MEM_freeN((void *)asset_drag->path); + } + MEM_freeN(poin); +} + +void WM_drag_free(wmDrag *drag) +{ + if (drag->flags & WM_DRAG_FREE_DATA) { + WM_drag_data_free(drag->type, drag->poin); + } BLI_freelistN(&drag->ids); MEM_freeN(drag); } @@ -279,7 +301,7 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event) /* ************** IDs ***************** */ -void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent) +void WM_drag_add_local_ID(wmDrag *drag, ID *id, ID *from_parent) { /* Don't drag the same ID twice. */ LISTBASE_FOREACH (wmDragID *, drag_id, &drag->ids) { @@ -302,7 +324,7 @@ void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent) BLI_addtail(&drag->ids, drag_id); } -ID *WM_drag_ID(const wmDrag *drag, short idcode) +ID *WM_drag_get_local_ID(const wmDrag *drag, short idcode) { if (drag->type != WM_DRAG_ID) { return NULL; @@ -317,14 +339,54 @@ ID *WM_drag_ID(const wmDrag *drag, short idcode) return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; } -ID *WM_drag_ID_from_event(const wmEvent *event, short idcode) +ID *WM_drag_get_local_ID_from_event(const wmEvent *event, short idcode) { if (event->custom != EVT_DATA_DRAGDROP) { return NULL; } ListBase *lb = event->customdata; - return WM_drag_ID(lb->first, idcode); + return WM_drag_get_local_ID(lb->first, idcode); +} + +wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode) +{ + if (drag->type != WM_DRAG_ASSET) { + return NULL; + } + + wmDragAsset *asset_drag = drag->poin; + return (idcode == 0 || asset_drag->id_type == idcode) ? asset_drag : NULL; +} + +static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag) +{ + /* Append only for now, wmDragAsset could have a `link` bool. */ + return WM_file_append_datablock( + G_MAIN, NULL, NULL, NULL, asset_drag->path, asset_drag->id_type, asset_drag->name); +} + +/** + * When dragging a local ID, return that. Otherwise, if dragging an asset-handle, link or append + * that depending on what was chosen by the drag-box (currently append only in fact). + */ +ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode) +{ + if (!ELEM(drag->type, WM_DRAG_ASSET, WM_DRAG_ID)) { + return NULL; + } + + if (drag->type == WM_DRAG_ID) { + return WM_drag_get_local_ID(drag, idcode); + } + + wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, idcode); + if (!asset_drag) { + return NULL; + } + + /* Link/append the asset. */ + return wm_drag_asset_id_import(asset_drag); } /* ************** draw ***************** */ @@ -342,7 +404,7 @@ static const char *wm_drag_name(wmDrag *drag) { switch (drag->type) { case WM_DRAG_ID: { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1); if (single) { @@ -353,6 +415,10 @@ static const char *wm_drag_name(wmDrag *drag) } break; } + case WM_DRAG_ASSET: { + const wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0); + return asset_drag->name; + } case WM_DRAG_PATH: case WM_DRAG_NAME: return drag->path; |