Files
test/source/blender/editors/interface/interface_drag.cc
Julian Eisel 92ff750bbf Refactor: Get rid of asset handle for drag & drop
`AssetHandle` is meant as temporary design and should be replaced by
`AssetRepresentation`. This moves us another step closer to that.

Rather than taking data from the volatile asset handle and storing that
in the drag data, store the (more persistent) asset representation there
and access data from it where needed.
2023-06-09 15:19:41 +02:00

136 lines
4.0 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edinterface
*/
#include "UI_interface.h"
#include "WM_api.h"
#include "interface_intern.hh"
void UI_but_drag_set_id(uiBut *but, ID *id)
{
but->dragtype = WM_DRAG_ID;
if (but->dragflag & UI_BUT_DRAGPOIN_FREE) {
WM_drag_data_free(but->dragtype, but->dragpoin);
but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
}
but->dragpoin = (void *)id;
}
void UI_but_drag_attach_image(uiBut *but, ImBuf *imb, const float scale)
{
but->imb = imb;
but->imb_scale = scale;
UI_but_dragflag_enable(but, UI_BUT_DRAG_FULL_BUT);
}
void UI_but_drag_set_asset(uiBut *but,
const AssetRepresentation *asset,
int import_type,
int icon,
ImBuf *imb,
float scale)
{
wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, import_type);
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
* #wmDropBox.
* TODO: Handle link/append in operator called at the end of the drop process, and NOT in its
* copy callback.
* */
asset_drag->evil_C = static_cast<bContext *>(but->block->evil_C);
but->dragtype = WM_DRAG_ASSET;
ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */
if (but->dragflag & UI_BUT_DRAGPOIN_FREE) {
WM_drag_data_free(but->dragtype, but->dragpoin);
}
but->dragpoin = asset_drag;
but->dragflag |= UI_BUT_DRAGPOIN_FREE;
UI_but_drag_attach_image(but, imb, scale);
}
void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr)
{
but->dragtype = WM_DRAG_RNA;
if (but->dragflag & UI_BUT_DRAGPOIN_FREE) {
WM_drag_data_free(but->dragtype, but->dragpoin);
but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
}
but->dragpoin = (void *)ptr;
}
void UI_but_drag_set_path(uiBut *but, const char *path)
{
but->dragtype = WM_DRAG_PATH;
if (but->dragflag & UI_BUT_DRAGPOIN_FREE) {
WM_drag_data_free(but->dragtype, but->dragpoin);
}
but->dragpoin = WM_drag_create_path_data(path);
but->dragflag |= UI_BUT_DRAGPOIN_FREE;
}
void UI_but_drag_set_name(uiBut *but, const char *name)
{
but->dragtype = WM_DRAG_NAME;
if (but->dragflag & UI_BUT_DRAGPOIN_FREE) {
WM_drag_data_free(but->dragtype, but->dragpoin);
but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
}
but->dragpoin = (void *)name;
}
void UI_but_drag_set_value(uiBut *but)
{
but->dragtype = WM_DRAG_VALUE;
}
void UI_but_drag_set_image(uiBut *but, const char *path, int icon, ImBuf *imb, float scale)
{
ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */
UI_but_drag_set_path(but, path);
UI_but_drag_attach_image(but, imb, scale);
}
void ui_but_drag_free(uiBut *but)
{
if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
WM_drag_data_free(but->dragtype, but->dragpoin);
}
}
bool ui_but_drag_is_draggable(const uiBut *but)
{
return but->dragpoin != nullptr;
}
void ui_but_drag_start(bContext *C, uiBut *but)
{
wmDrag *drag = WM_drag_data_create(C,
but->icon,
but->dragtype,
but->dragpoin,
ui_but_value_get(but),
(but->dragflag & UI_BUT_DRAGPOIN_FREE) ? WM_DRAG_FREE_DATA :
WM_DRAG_NOP);
/* wmDrag has ownership over dragpoin now, stop messing with it. */
but->dragpoin = nullptr;
if (but->imb) {
WM_event_drag_image(drag, but->imb, but->imb_scale);
}
WM_event_start_prepared_drag(C, drag);
/* 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, nullptr, 0, WM_DRAG_NOP);
}
}