diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-08-07 11:57:09 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-08-10 18:53:00 +0300 |
commit | 86c363a02706b1a5d3cb18d17b4b37bd78461ded (patch) | |
tree | 3e10c488d7a10d2e84fa4a647ee7a211ff883427 /source/blender/windowmanager | |
parent | 74016d73dbebd8c8a0e1aed70295d1a09037d7eb (diff) |
WM: pass on wmDrag to drop operators, so they can get the data directly.
Currently drop operators work mostly by specifying the name of the datablock.
However there can be datablocks with the same name in different libraries, so
this gives wrong results in some cases.
Currently only outliner drop operators have been updated to use this mechanism.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 21 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 73 |
3 files changed, 65 insertions, 32 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 3521c4d1bd5..d175b11fe5c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -484,6 +484,9 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx void WM_drag_free(struct wmDrag *drag); void WM_drag_free_list(struct ListBase *lb); +struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode); +struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode); + struct wmDropBox *WM_dropbox_add( ListBase *lb, const char *idname, bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 0ae51cc922b..6b9a7fb5430 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -189,6 +189,27 @@ void WM_drag_free_list(struct ListBase *lb) } } + +ID *WM_drag_ID(const wmDrag *drag, short idcode) +{ + if (drag->type != WM_DRAG_ID) { + return NULL; + } + + ID *id = drag->poin; + return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; +} + +ID *WM_drag_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); +} + static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, const wmEvent *event) { wmEventHandler *handler = handlers->first; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5d343c5e0fe..0581d41ea04 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -98,7 +98,7 @@ static void wm_notifier_clear(wmNotifier *note); static void update_tablet_data(wmWindow *win, wmEvent *event); static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only); + const short context, const bool poll_only, wmEvent *event); /* ************ event management ************** */ @@ -638,7 +638,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot) /* sets up the new context and calls 'wm_operator_invoke()' with poll_only */ bool WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context) { - return wm_operator_call_internal(C, ot, NULL, NULL, context, true); + return wm_operator_call_internal(C, ot, NULL, NULL, context, true, NULL); } bool WM_operator_check_ui_empty(wmOperatorType *ot) @@ -1431,10 +1431,8 @@ static int wm_operator_invoke( */ static int wm_operator_call_internal( bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only) + const short context, const bool poll_only, wmEvent *event) { - wmEvent *event; - int retval; CTX_wm_operator_poll_msg_set(C, NULL); @@ -1443,27 +1441,29 @@ static int wm_operator_call_internal( if (ot) { wmWindow *window = CTX_wm_window(C); - switch (context) { - case WM_OP_INVOKE_DEFAULT: - case WM_OP_INVOKE_REGION_WIN: - case WM_OP_INVOKE_REGION_PREVIEW: - case WM_OP_INVOKE_REGION_CHANNELS: - case WM_OP_INVOKE_AREA: - case WM_OP_INVOKE_SCREEN: - /* window is needed for invoke, cancel operator */ - if (window == NULL) { - if (poll_only) { - CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + if (event == NULL) { + switch (context) { + case WM_OP_INVOKE_DEFAULT: + case WM_OP_INVOKE_REGION_WIN: + case WM_OP_INVOKE_REGION_PREVIEW: + case WM_OP_INVOKE_REGION_CHANNELS: + case WM_OP_INVOKE_AREA: + case WM_OP_INVOKE_SCREEN: + /* window is needed for invoke, cancel operator */ + if (window == NULL) { + if (poll_only) { + CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + } + return 0; } - return 0; - } - else { - event = window->eventstate; - } - break; - default: - event = NULL; - break; + else { + event = window->eventstate; + } + break; + default: + event = NULL; + break; + } } switch (context) { @@ -1561,7 +1561,7 @@ static int wm_operator_call_internal( int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties) { BLI_assert(ot == WM_operatortype_find(ot->idname, true)); - return wm_operator_call_internal(C, ot, properties, NULL, context, false); + return wm_operator_call_internal(C, ot, properties, NULL, context, false, NULL); } int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties) { @@ -1627,7 +1627,7 @@ int WM_operator_call_py( wmWindowManager *wm = CTX_wm_manager(C); if (!is_undo && wm) wm->op_undo_depth++; - retval = wm_operator_call_internal(C, ot, properties, reports, context, false); + retval = wm_operator_call_internal(C, ot, properties, reports, context, false, NULL); if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--; @@ -2370,17 +2370,26 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers for (drag = lb->first; drag; drag = drag->next) { const char *tooltip = NULL; if (drop->poll(C, drag, event, &tooltip)) { - drop->copy(drag, drop); + /* Optionally copy drag information to operator properties. */ + if (drop->copy) { + drop->copy(drag, drop); + } - /* free the drags before calling operator */ + /* Pass single matched wmDrag onto the operator. */ + BLI_remlink(lb, drag); + ListBase single_lb = {drag, drag}; + event->customdata = &single_lb; + + wm_operator_call_internal(C, drop->ot, drop->ptr, NULL, drop->opcontext, false, event); + action |= WM_HANDLER_BREAK; + + /* free the drags */ WM_drag_free_list(lb); + WM_drag_free_list(&single_lb); event->customdata = NULL; event->custom = 0; - WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr); - action |= WM_HANDLER_BREAK; - /* XXX fileread case */ if (CTX_wm_window(C) == NULL) return action; |