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:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_dragdrop.c')
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c449
1 files changed, 308 insertions, 141 deletions
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 9af90355a79..b9f0e09d106 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -40,9 +40,13 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_screen.h"
+
+#include "GHOST_C-api.h"
#include "BLO_readfile.h"
@@ -63,6 +67,7 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
+#include "wm_window.h"
/* ****************************************************** */
@@ -176,6 +181,7 @@ wmDrag *WM_event_start_drag(
}
break;
case WM_DRAG_ASSET:
+ case WM_DRAG_ASSET_CATALOG:
/* Move ownership of poin to wmDrag. */
drag->poin = poin;
drag->flags |= WM_DRAG_FREE_DATA;
@@ -202,6 +208,31 @@ wmDrag *WM_event_start_drag(
return drag;
}
+/**
+ * Additional work to cleanly end dragging. Additional because this doesn't actually remove the
+ * drag items. Should be called whenever dragging is stopped (successful or not, also when
+ * canceled).
+ */
+void wm_drags_exit(wmWindowManager *wm, wmWindow *win)
+{
+ bool any_active = false;
+ LISTBASE_FOREACH (const wmDrag *, drag, &wm->drags) {
+ if (drag->active_dropbox) {
+ any_active = true;
+ break;
+ }
+ }
+
+ /* If there is no active drop-box #wm_drags_check_ops() set a stop-cursor, which needs to be
+ * restored. */
+ if (!any_active) {
+ WM_cursor_modal_restore(win);
+ /* Ensure the correct area cursor is restored. */
+ win->tag_cursor_refresh = true;
+ WM_event_add_mousemove(win);
+ }
+}
+
void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy)
{
drag->imb = imb;
@@ -229,9 +260,15 @@ void WM_drag_data_free(int dragtype, void *poin)
void WM_drag_free(wmDrag *drag)
{
+ if (drag->active_dropbox && drag->active_dropbox->draw_deactivate) {
+ drag->active_dropbox->draw_deactivate(drag->active_dropbox, drag);
+ }
if (drag->flags & WM_DRAG_FREE_DATA) {
WM_drag_data_free(drag->type, drag->poin);
}
+ if (drag->free_disabled_info) {
+ MEM_SAFE_FREE(drag->disabled_info);
+ }
BLI_freelistN(&drag->ids);
LISTBASE_FOREACH_MUTABLE (wmDragAssetListItem *, asset_item, &drag->asset_items) {
if (asset_item->is_external) {
@@ -250,11 +287,11 @@ void WM_drag_free_list(struct ListBase *lb)
}
}
-static char *dropbox_tooltip(bContext *C, wmDrag *drag, const wmEvent *event, wmDropBox *drop)
+static char *dropbox_tooltip(bContext *C, wmDrag *drag, const int xy[2], wmDropBox *drop)
{
char *tooltip = NULL;
if (drop->tooltip) {
- tooltip = drop->tooltip(C, drag, event, drop);
+ tooltip = drop->tooltip(C, drag, xy, drop);
}
if (!tooltip) {
tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr));
@@ -269,15 +306,35 @@ static wmDropBox *dropbox_active(bContext *C,
wmDrag *drag,
const wmEvent *event)
{
+ if (drag->free_disabled_info) {
+ MEM_SAFE_FREE(drag->disabled_info);
+ }
+ drag->disabled_info = NULL;
+
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
if (handler->dropboxes) {
LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) {
- if (drop->poll(C, drag, event) &&
- WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
+ if (!drop->poll(C, drag, event)) {
+ /* If the drop's poll fails, don't set the disabled-info. This would be too aggressive.
+ * Instead show it only if the drop box could be used in principle, but the operator
+ * can't be executed. */
+ continue;
+ }
+
+ if (WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
return drop;
}
+
+ /* Attempt to set the disabled hint when the poll fails. Will always be the last hint set
+ * when there are multiple failing polls (could allow multiple disabled-hints too). */
+ bool free_disabled_info = false;
+ const char *disabled_hint = CTX_wm_operator_poll_msg_get(C, &free_disabled_info);
+ if (disabled_hint) {
+ drag->disabled_info = disabled_hint;
+ drag->free_disabled_info = free_disabled_info;
+ }
}
}
}
@@ -286,7 +343,7 @@ static wmDropBox *dropbox_active(bContext *C,
}
/* return active operator tooltip/name when mouse is in box */
-static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
+static wmDropBox *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event);
@@ -298,13 +355,13 @@ static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
ARegion *region = CTX_wm_region(C);
drop = dropbox_active(C, &region->handlers, drag, event);
}
- if (drop) {
- return dropbox_tooltip(C, drag, event, drop);
- }
- return NULL;
+ return drop;
}
-static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *event)
+/**
+ * Update dropping information for the current mouse position in \a event.
+ */
+static void wm_drop_update_active(bContext *C, wmDrag *drag, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
const int winsize_x = WM_window_pixels_x(win);
@@ -316,24 +373,30 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e
return;
}
- drag->tooltip[0] = 0;
-
- /* check buttons (XXX todo rna and value) */
- if (UI_but_active_drop_name(C)) {
- BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip));
+ wmDropBox *drop_prev = drag->active_dropbox;
+ wmDropBox *drop = wm_dropbox_active(C, drag, event);
+ if (drop != drop_prev) {
+ if (drop_prev && drop_prev->draw_deactivate) {
+ drop_prev->draw_deactivate(drop_prev, drag);
+ BLI_assert(drop_prev->draw_data == NULL);
+ }
+ if (drop && drop->draw_activate) {
+ drop->draw_activate(drop, drag);
+ }
+ drag->active_dropbox = drop;
}
- else {
- char *tooltip = wm_dropbox_active(C, drag, event);
+}
- if (tooltip) {
- BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip));
- MEM_freeN(tooltip);
- // WM_cursor_modal_set(win, WM_CURSOR_COPY);
- }
- // else
- // WM_cursor_modal_restore(win);
- /* unsure about cursor type, feels to be too much */
+void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop)
+{
+ /* Optionally copy drag information to operator properties. Don't call it if the
+ * operator fails anyway, it might do more than just set properties (e.g.
+ * typically import an asset). */
+ if (drop->copy && WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
+ drop->copy(drag, drop);
}
+
+ wm_drags_exit(CTX_wm_manager(C), CTX_wm_window(C));
}
/* called in inner handler loop, region context */
@@ -341,8 +404,19 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
+ bool any_active = false;
LISTBASE_FOREACH (wmDrag *, drag, &wm->drags) {
- wm_drop_operator_options(C, drag, event);
+ wm_drop_update_active(C, drag, event);
+
+ if (drag->active_dropbox) {
+ any_active = true;
+ }
+ }
+
+ /* Change the cursor to display that dropping isn't possible here. But only if there is something
+ * being dragged actually. Cursor will be restored in #wm_drags_exit(). */
+ if (!BLI_listbase_is_empty(&wm->drags)) {
+ WM_cursor_modal_set(CTX_wm_window(C), any_active ? WM_CURSOR_DEFAULT : WM_CURSOR_STOP);
}
}
@@ -407,11 +481,15 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int 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 *WM_drag_create_asset_data(const AssetHandle *asset,
+ AssetMetaData *metadata,
+ 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->metadata = metadata;
asset_drag->path = path;
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
asset_drag->import_type = import_type;
@@ -435,8 +513,30 @@ wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : NULL;
}
-static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
+struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode)
+{
+ wmDragAsset *drag_asset = WM_drag_get_asset_data(drag, idcode);
+ if (drag_asset) {
+ return drag_asset->metadata;
+ }
+
+ ID *local_id = WM_drag_get_local_ID(drag, idcode);
+ if (local_id) {
+ return local_id->asset_data;
+ }
+
+ return NULL;
+}
+
+/**
+ * \param flag_extra: Additional linking flags (from #eFileSel_Params_Flag).
+ */
+ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
{
+ /* Only support passing in limited flags. */
+ BLI_assert(flag_extra == (flag_extra & FILE_AUTOSELECT));
+ eFileSel_Params_Flag flag = flag_extra | FILE_ACTIVE_COLLECTION;
+
const char *name = asset_drag->name;
ID_Type idtype = asset_drag->id_type;
@@ -450,14 +550,8 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
switch ((eFileAssetImportType)asset_drag->import_type) {
case FILE_ASSET_IMPORT_LINK:
- return WM_file_link_datablock(bmain,
- scene,
- view_layer,
- view3d,
- asset_drag->path,
- idtype,
- name,
- FILE_ACTIVE_COLLECTION);
+ return WM_file_link_datablock(
+ bmain, scene, view_layer, view3d, asset_drag->path, idtype, name, flag);
case FILE_ASSET_IMPORT_APPEND:
return WM_file_append_datablock(bmain,
scene,
@@ -466,7 +560,7 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
asset_drag->path,
idtype,
name,
- BLO_LIBLINK_APPEND_RECURSIVE | FILE_ACTIVE_COLLECTION |
+ flag | BLO_LIBLINK_APPEND_RECURSIVE |
BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR);
case FILE_ASSET_IMPORT_APPEND_REUSE:
return WM_file_append_datablock(G_MAIN,
@@ -476,7 +570,7 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
asset_drag->path,
idtype,
name,
- BLO_LIBLINK_APPEND_RECURSIVE | FILE_ACTIVE_COLLECTION |
+ flag | BLO_LIBLINK_APPEND_RECURSIVE |
BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR |
BLO_LIBLINK_APPEND_LOCAL_ID_REUSE);
}
@@ -485,12 +579,24 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
return NULL;
}
+bool WM_drag_asset_will_import_linked(const wmDrag *drag)
+{
+ if (drag->type != WM_DRAG_ASSET) {
+ return false;
+ }
+
+ const wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
+ return asset_drag->import_type == FILE_ASSET_IMPORT_LINK;
+}
+
/**
* 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).
*
* Use #WM_drag_free_imported_drag_ID() as cancel callback of the drop-box, so that the asset
* import is rolled back if the drop operator fails.
+ *
+ * \param flag: #eFileSel_Params_Flag passed to linking code.
*/
ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode)
{
@@ -508,7 +614,7 @@ ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode)
}
/* Link/append the asset. */
- return wm_drag_asset_id_import(asset_drag);
+ return WM_drag_asset_id_import(asset_drag, 0);
}
/**
@@ -544,6 +650,15 @@ void WM_drag_free_imported_drag_ID(struct Main *bmain, wmDrag *drag, wmDropBox *
}
}
+wmDragAssetCatalog *WM_drag_get_asset_catalog_data(const wmDrag *drag)
+{
+ if (drag->type != WM_DRAG_ASSET_CATALOG) {
+ return NULL;
+ }
+
+ return drag->poin;
+}
+
/**
* \note: Does not store \a asset in any way, so it's fine to pass a temporary.
*/
@@ -568,11 +683,12 @@ void WM_drag_add_asset_list_item(
drag_asset->asset_data.local_id = local_id;
}
else {
+ AssetMetaData *metadata = ED_asset_handle_get_metadata(asset);
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);
+ asset, metadata, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
}
BLI_addtail(&drag->asset_items, drag_asset);
}
@@ -603,6 +719,17 @@ static void wm_drop_operator_draw(const char *name, int x, int y)
UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
}
+static void wm_drop_redalert_draw(const char *redalert_str, int x, int y)
+{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
+ float col_fg[4];
+
+ UI_GetThemeColor4fv(TH_REDALERT, col_fg);
+
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, redalert_str, col_fg, col_bg);
+}
+
const char *WM_drag_get_item_name(wmDrag *drag)
{
switch (drag->type) {
@@ -629,132 +756,172 @@ const char *WM_drag_get_item_name(wmDrag *drag)
return "";
}
-static void drag_rect_minmax(rcti *rect, int x1, int y1, int x2, int y2)
+static void wm_drag_draw_icon(bContext *UNUSED(C),
+ wmWindow *UNUSED(win),
+ wmDrag *drag,
+ const int xy[2])
{
- if (rect->xmin > x1) {
- rect->xmin = x1;
- }
- if (rect->xmax < x2) {
- rect->xmax = x2;
+ int x, y;
+ if (drag->imb) {
+ x = xy[0] - drag->sx / 2;
+ y = xy[1] - drag->sy / 2;
+
+ float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTexScaled(&state,
+ x,
+ y,
+ drag->imb->x,
+ drag->imb->y,
+ GPU_RGBA8,
+ false,
+ drag->imb->rect,
+ drag->scale,
+ drag->scale,
+ 1.0f,
+ 1.0f,
+ col);
}
- if (rect->ymin > y1) {
- rect->ymin = y1;
- }
- if (rect->ymax < y2) {
- rect->ymax = y2;
+ else {
+ int padding = 4 * UI_DPI_FAC;
+ x = xy[0] - 2 * padding;
+ y = xy[1] - 2 * UI_DPI_FAC;
+
+ const uchar text_col[] = {255, 255, 255, 255};
+ UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false);
}
}
-/* called in wm_draw.c */
-/* if rect set, do not draw */
-void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
+static void wm_drag_draw_item_name(wmDrag *drag, const int x, const int y)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- wmWindowManager *wm = CTX_wm_manager(C);
- const int winsize_y = WM_window_pixels_y(win);
+ const uchar text_col[] = {255, 255, 255, 255};
+ UI_fontstyle_draw_simple(fstyle, x, y, WM_drag_get_item_name(drag), text_col);
+}
- int cursorx = win->eventstate->xy[0];
- int cursory = win->eventstate->xy[1];
- if (rect) {
- rect->xmin = rect->xmax = cursorx;
- rect->ymin = rect->ymax = cursory;
- }
+void WM_drag_draw_item_name_fn(bContext *UNUSED(C),
+ wmWindow *UNUSED(win),
+ wmDrag *drag,
+ const int xy[2])
+{
+ int x = xy[0] + 10 * UI_DPI_FAC;
+ int y = xy[1] + 1 * UI_DPI_FAC;
- /* Should we support multi-line drag draws? Maybe not, more types mixed won't work well. */
- GPU_blend(GPU_BLEND_ALPHA);
- LISTBASE_FOREACH (wmDrag *, drag, &wm->drags) {
- const uchar text_col[] = {255, 255, 255, 255};
- int iconsize = UI_DPI_ICON_SIZE;
- int padding = 4 * UI_DPI_FAC;
+ wm_drag_draw_item_name(drag, x, y);
+}
- /* image or icon */
- int x, y;
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
- y = cursory - drag->sy / 2;
+static void wm_drag_draw_tooltip(bContext *C, wmWindow *win, wmDrag *drag, const int xy[2])
+{
+ if (!CTX_wm_region(C)) {
+ /* Some callbacks require the region. */
+ return;
+ }
+ int iconsize = UI_DPI_ICON_SIZE;
+ int padding = 4 * UI_DPI_FAC;
- if (rect) {
- drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
- }
- else {
- float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTexScaled(&state,
- x,
- y,
- drag->imb->x,
- drag->imb->y,
- GPU_RGBA8,
- false,
- drag->imb->rect,
- drag->scale,
- drag->scale,
- 1.0f,
- 1.0f,
- col);
- }
- }
- else {
- x = cursorx - 2 * padding;
- y = cursory - 2 * UI_DPI_FAC;
+ char *tooltip = NULL;
+ if (drag->active_dropbox) {
+ tooltip = dropbox_tooltip(C, drag, xy, drag->active_dropbox);
+ }
- if (rect) {
- drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize);
- }
- else {
- UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false);
- }
- }
+ if (!tooltip && !drag->disabled_info) {
+ return;
+ }
+
+ const int winsize_y = WM_window_pixels_y(win);
+ int x, y;
+ if (drag->imb) {
+ x = xy[0] - drag->sx / 2;
- /* item name */
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
- y = cursory - drag->sy / 2 - iconsize;
+ if (xy[1] + drag->sy / 2 + padding + iconsize < winsize_y) {
+ y = xy[1] + drag->sy / 2 + padding;
}
else {
- x = cursorx + 10 * UI_DPI_FAC;
- y = cursory + 1 * UI_DPI_FAC;
+ y = xy[1] - drag->sy / 2 - padding - iconsize - padding - iconsize;
}
+ }
+ else {
+ x = xy[0] - 2 * padding;
- if (rect) {
- int w = UI_fontstyle_string_width(fstyle, WM_drag_get_item_name(drag));
- drag_rect_minmax(rect, x, y, x + w, y + iconsize);
+ if (xy[1] + iconsize + iconsize < winsize_y) {
+ y = (xy[1] + iconsize) + padding;
}
else {
- UI_fontstyle_draw_simple(fstyle, x, y, WM_drag_get_item_name(drag), text_col);
+ y = (xy[1] - iconsize) - padding;
}
+ }
- /* operator name with roundbox */
- if (drag->tooltip[0]) {
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
+ if (tooltip) {
+ wm_drop_operator_draw(tooltip, x, y);
+ MEM_freeN(tooltip);
+ }
+ else if (drag->disabled_info) {
+ wm_drop_redalert_draw(drag->disabled_info, x, y);
+ }
+}
- if (cursory + drag->sy / 2 + padding + iconsize < winsize_y) {
- y = cursory + drag->sy / 2 + padding;
- }
- else {
- y = cursory - drag->sy / 2 - padding - iconsize - padding - iconsize;
- }
- }
- else {
- x = cursorx - 2 * padding;
+static void wm_drag_draw_default(bContext *C, wmWindow *win, wmDrag *drag, const int xy[2])
+{
+ int xy_tmp[2] = {UNPACK2(xy)};
- if (cursory + iconsize + iconsize < winsize_y) {
- y = (cursory + iconsize) + padding;
- }
- else {
- y = (cursory - iconsize) - padding;
- }
- }
+ /* Image or icon. */
+ wm_drag_draw_icon(C, win, drag, xy_tmp);
- if (rect) {
- int w = UI_fontstyle_string_width(fstyle, WM_drag_get_item_name(drag));
- drag_rect_minmax(rect, x, y, x + w, y + iconsize);
- }
- else {
- wm_drop_operator_draw(drag->tooltip, x, y);
- }
+ /* Item name. */
+ if (drag->imb) {
+ int iconsize = UI_DPI_ICON_SIZE;
+ xy_tmp[0] = xy[0] - (drag->sx / 2);
+ xy_tmp[1] = xy[1] - (drag->sy / 2) - iconsize;
+ }
+ else {
+ xy_tmp[0] = xy[0] + 10 * UI_DPI_FAC;
+ xy_tmp[1] = xy[1] + 1 * UI_DPI_FAC;
+ }
+ wm_drag_draw_item_name(drag, UNPACK2(xy_tmp));
+
+ /* Operator name with roundbox. */
+ wm_drag_draw_tooltip(C, win, drag, xy);
+}
+
+void WM_drag_draw_default_fn(bContext *C, wmWindow *win, wmDrag *drag, const int xy[2])
+{
+ wm_drag_draw_default(C, win, drag, xy);
+}
+
+/* Called in #wm_draw_window_onscreen. */
+void wm_drags_draw(bContext *C, wmWindow *win)
+{
+ int xy[2];
+ if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
+ wm_cursor_position_get(win, &xy[0], &xy[1]);
+ }
+ else {
+ xy[0] = win->eventstate->xy[0];
+ xy[1] = win->eventstate->xy[1];
+ }
+
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, UNPACK2(xy));
+ ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, UNPACK2(xy));
+ if (region) {
+ BLI_assert(!CTX_wm_area(C) && !CTX_wm_region(C));
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ /* Should we support multi-line drag draws? Maybe not, more types mixed won't work well. */
+ GPU_blend(GPU_BLEND_ALPHA);
+ LISTBASE_FOREACH (wmDrag *, drag, &wm->drags) {
+ if (drag->active_dropbox && drag->active_dropbox->draw) {
+ drag->active_dropbox->draw(C, win, drag, xy);
+ continue;
}
+
+ wm_drag_draw_default(C, win, drag, xy);
}
GPU_blend(GPU_BLEND_NONE);
+ CTX_wm_area_set(C, NULL);
+ CTX_wm_region_set(C, NULL);
}