Fix on_drag_start handler not getting ID when dragging from Outliner
We would first invoke the dragging, and then set the drag data (like the ID or the dragged modifier), so the `wmDropBox.on_drag_start()` handler wouldn't be able to access this. This broke dragging some IDs from the Outliner, noticed in D15333. It's now possible to first create/request drag data, extend it, and then invoke the actual dragging. The normal function to start dragging returns `void` now instead of `wmDrag *`, so the drag data can't easily be modified after starting anymore.
This commit is contained in:
@@ -122,7 +122,7 @@ bool ui_but_drag_is_draggable(const uiBut *but)
|
||||
|
||||
void ui_but_drag_start(bContext *C, uiBut *but)
|
||||
{
|
||||
wmDrag *drag = WM_event_start_drag(C,
|
||||
wmDrag *drag = WM_drag_data_create(C,
|
||||
but->icon,
|
||||
but->dragtype,
|
||||
but->dragpoin,
|
||||
@@ -136,6 +136,8 @@ void ui_but_drag_start(bContext *C, uiBut *but)
|
||||
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)) {
|
||||
|
||||
@@ -1455,7 +1455,7 @@ static int outliner_item_drag_drop_invoke(bContext *C,
|
||||
TSE_GPENCIL_EFFECT_BASE);
|
||||
|
||||
const int wm_drag_type = use_datastack_drag ? WM_DRAG_DATASTACK : WM_DRAG_ID;
|
||||
wmDrag *drag = WM_event_start_drag(C, data.icon, wm_drag_type, nullptr, 0.0, WM_DRAG_NOP);
|
||||
wmDrag *drag = WM_drag_data_create(C, data.icon, wm_drag_type, nullptr, 0.0, WM_DRAG_NOP);
|
||||
|
||||
if (use_datastack_drag) {
|
||||
TreeElement *te_bone = nullptr;
|
||||
@@ -1545,6 +1545,8 @@ static int outliner_item_drag_drop_invoke(bContext *C,
|
||||
WM_drag_add_local_ID(drag, data.drag_id, data.drag_parent);
|
||||
}
|
||||
|
||||
WM_event_start_prepared_drag(C, drag);
|
||||
|
||||
ED_outliner_select_sync_from_outliner(C, space_outliner);
|
||||
|
||||
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
|
||||
|
||||
@@ -1214,10 +1214,24 @@ int WM_operator_flag_only_pass_through_on_press(int retval, const struct wmEvent
|
||||
/* Drag and drop. */
|
||||
|
||||
/**
|
||||
* Note that the pointer should be valid allocated and not on stack.
|
||||
* Start dragging immediately with the given data.
|
||||
* Note that \a poin should be valid allocated and not on stack.
|
||||
*/
|
||||
struct wmDrag *WM_event_start_drag(
|
||||
void WM_event_start_drag(
|
||||
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
|
||||
/**
|
||||
* Create and fill the dragging data, but don't start dragging just yet (unlike
|
||||
* #WM_event_start_drag()). Must be followed up by #WM_event_start_prepared_drag(), otherwise the
|
||||
* returned pointer will leak memory.
|
||||
*
|
||||
* Note that \a poin should be valid allocated and not on stack.
|
||||
*/
|
||||
wmDrag *WM_drag_data_create(
|
||||
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
|
||||
/**
|
||||
* Invoke dragging using the given \a drag data.
|
||||
*/
|
||||
void WM_event_start_prepared_drag(struct bContext *C, wmDrag *drag);
|
||||
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale);
|
||||
void WM_drag_free(struct wmDrag *drag);
|
||||
void WM_drag_data_free(int dragtype, void *poin);
|
||||
|
||||
@@ -175,16 +175,14 @@ static void wm_dropbox_invoke(bContext *C, wmDrag *drag)
|
||||
}
|
||||
}
|
||||
|
||||
wmDrag *WM_event_start_drag(
|
||||
wmDrag *WM_drag_data_create(
|
||||
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
|
||||
|
||||
/* Keep track of future multi-touch drag too, add a mouse-pointer id or so. */
|
||||
/* if multiple drags are added, they're drawn as list */
|
||||
|
||||
BLI_addtail(&wm->drags, drag);
|
||||
drag->flags = flags;
|
||||
drag->icon = icon;
|
||||
drag->type = type;
|
||||
@@ -226,11 +224,24 @@ wmDrag *WM_event_start_drag(
|
||||
}
|
||||
drag->value = value;
|
||||
|
||||
wm_dropbox_invoke(C, drag);
|
||||
|
||||
return drag;
|
||||
}
|
||||
|
||||
void WM_event_start_prepared_drag(bContext *C, wmDrag *drag)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
BLI_addtail(&wm->drags, drag);
|
||||
wm_dropbox_invoke(C, drag);
|
||||
}
|
||||
|
||||
void WM_event_start_drag(
|
||||
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
|
||||
{
|
||||
wmDrag *drag = WM_drag_data_create(C, icon, type, poin, value, flags);
|
||||
WM_event_start_prepared_drag(C, drag);
|
||||
}
|
||||
|
||||
void wm_drags_exit(wmWindowManager *wm, wmWindow *win)
|
||||
{
|
||||
bool any_active = false;
|
||||
|
||||
Reference in New Issue
Block a user