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')
-rw-r--r--source/blender/windowmanager/WM_api.h106
-rw-r--r--source/blender/windowmanager/WM_types.h127
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h1
-rw-r--r--source/blender/windowmanager/intern/wm.c2
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c733
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c229
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c1
-rw-r--r--source/blender/windowmanager/intern/wm_window.c43
-rw-r--r--source/blender/windowmanager/wm_event_system.h6
10 files changed, 668 insertions, 584 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 802780b37f1..a886d1440d9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -55,8 +55,6 @@ struct View3D;
struct ViewLayer;
struct bContext;
struct rcti;
-struct wmDrag;
-struct wmDropBox;
struct wmEvent;
struct wmEventHandler_Keymap;
struct wmEventHandler_UI;
@@ -67,6 +65,9 @@ struct wmOperator;
struct wmOperatorType;
struct wmPaintCursor;
struct wmTabletData;
+struct wmDragData;
+struct wmDropTarget;
+struct wmDropTargetFinder;
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
@@ -304,8 +305,7 @@ enum {
WM_HANDLER_DO_FREE = (1 << 7), /* handler tagged to be freed in wm_handlers_do() */
};
-struct wmEventHandler_Dropbox *WM_event_add_dropbox_handler(ListBase *handlers,
- ListBase *dropboxes);
+void WM_event_ensure_drop_handler(ListBase *handlers);
/* mouse */
void WM_event_add_mousemove(wmWindow *win);
@@ -654,23 +654,87 @@ void WM_event_fileselect_event(struct wmWindowManager *wm, void *ophandle, int e
void WM_operator_region_active_win_set(struct bContext *C);
/* drag and drop */
-struct wmDrag *WM_event_start_drag(
- struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
-void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
-void WM_drag_free(struct wmDrag *drag);
-void WM_drag_free_list(struct ListBase *lb);
-
-struct wmDropBox *WM_dropbox_add(
- ListBase *lb,
- const char *idname,
- bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **),
- void (*copy)(struct wmDrag *, struct wmDropBox *));
-ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
-
-/* ID drag and drop */
-void WM_drag_add_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent);
-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 wmDragData *WM_drag_start_id(struct bContext *C, ID *id);
+struct wmDragData *WM_drag_start_filepath(struct bContext *C, const char *filepath);
+struct wmDragData *WM_drag_start_filepaths(struct bContext *C, const char **filepaths, int amount);
+struct wmDragData *WM_drag_start_color(struct bContext *C, float color[3], bool gamma_corrected);
+struct wmDragData *WM_drag_start_value(struct bContext *C, double value);
+struct wmDragData *WM_drag_start_rna(struct bContext *C, struct PointerRNA *rna);
+struct wmDragData *WM_drag_start_name(struct bContext *C, const char *name);
+struct wmDragData *WM_drag_start_collection_children(struct bContext *C,
+ struct ListBase *collection_children);
+
+struct wmDragData *WM_drag_get_active(struct bContext *C);
+struct wmDragData *WM_drag_data_from_event(const struct wmEvent *event);
+void WM_drag_transfer_ownership_to_event(struct wmWindowManager *wm, struct wmEvent *event);
+struct wmDropTarget *WM_drag_find_current_target(struct bContext *C,
+ struct wmDragData *drag_data,
+ const struct wmEvent *event);
+
+void WM_drag_display_set_color(struct wmDragData *drag_data, float color[3]);
+void WM_drag_display_set_color_derived(struct wmDragData *drag_data);
+void WM_drag_display_set_icon(struct wmDragData *drag_data, int icon_id);
+void WM_drag_display_set_image(
+ struct wmDragData *drag_data, struct ImBuf *imb, float scale, int width, int height);
+
+void WM_drag_data_free(struct wmDragData *drag);
+void WM_drop_target_free(struct wmDropTarget *drop_target);
+void WM_drag_stop(wmWindowManager *wm);
+
+struct ID *WM_drag_query_single_id(struct wmDragData *drag_data);
+struct ID *WM_drag_query_single_id_of_type(struct wmDragData *drag_data, int idtype);
+struct Collection *WM_drag_query_single_collection(struct wmDragData *drag_data);
+struct Material *WM_drag_query_single_material(struct wmDragData *drag_data);
+struct Object *WM_drag_query_single_object(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_of_types(struct wmDragData *drag_data, int types);
+const char *WM_drag_query_single_path_text(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_maybe_text(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_image(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_movie(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_sound(struct wmDragData *drag_data);
+const char *WM_drag_query_single_path_image_or_movie(struct wmDragData *drag_data);
+struct ListBase *WM_drag_query_collection_children(struct wmDragData *drag_data);
+bool WM_drag_query_single_color(struct wmDragData *drag_data,
+ float *r_color,
+ bool *r_gamma_corrected);
+
+typedef void (*wmDropTargetSetProps)(struct wmDragData *, struct PointerRNA *);
+
+enum DropTargetSize {
+ DROP_TARGET_SIZE_BUT,
+ DROP_TARGET_SIZE_OUTLINER_ROW,
+ DROP_TARGET_SIZE_VISIBLE_OBJECT,
+ DROP_TARGET_SIZE_REGION,
+ DROP_TARGET_SIZE_AREA,
+ DROP_TARGET_SIZE_WINDOW,
+ DROP_TARGET_SIZE_MAX,
+};
+
+void WM_drop_target_propose(struct wmDropTargetFinder *finder, struct wmDropTarget *target);
+void WM_drop_target_propose__template_1(struct wmDropTargetFinder *finder,
+ enum DropTargetSize size,
+ const char *ot_idname,
+ const char *tooltip,
+ wmDropTargetSetProps set_properties);
+void WM_drop_target_propose__template_2(struct wmDropTargetFinder *finder,
+ enum DropTargetSize size,
+ const char *ot_idname,
+ const char *tooltip,
+ wmDropTargetSetProps set_properties,
+ short context);
+
+struct wmDropTarget *WM_drop_target_new(enum DropTargetSize size,
+ char *ot_idname,
+ char *tooltip,
+ wmDropTargetSetProps set_properties,
+ short context,
+ bool free,
+ bool free_idname,
+ bool free_tooltip);
+
+void WM_drop_init_single_filepath(struct wmDragData *drag_data, struct PointerRNA *ptr);
+void WM_drop_init_single_id_name(struct wmDragData *drag_data, struct PointerRNA *ptr);
/* Set OpenGL viewport and scissor */
void wmViewport(const struct rcti *rect);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 4acce793707..48bd9ed9638 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -814,70 +814,73 @@ typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata
#define WM_DRAG_VALUE 4
#define WM_DRAG_COLOR 5
-typedef enum wmDragFlags {
- WM_DRAG_NOP = 0,
- WM_DRAG_FREE_DATA = 1,
-} wmDragFlags;
-
-/* note: structs need not exported? */
+/* wmDragData.type */
+enum DragDataType {
+ DRAG_DATA_IDS,
+ DRAG_DATA_FILEPATHS,
+ DRAG_DATA_COLOR,
+ DRAG_DATA_VALUE,
+ DRAG_DATA_RNA,
+ DRAG_DATA_NAME,
+ DRAG_DATA_COLLECTION_CHILDREN,
+};
+/* wmDragData.display_type */
+enum DragDisplayType {
+ DRAG_DISPLAY_NONE = 0,
+ DRAG_DISPLAY_ICON,
+ DRAG_DISPLAY_IMAGE,
+ DRAG_DISPLAY_COLOR,
+};
-typedef struct wmDragID {
- struct wmDragID *next, *prev;
+typedef struct wmDragCollectionChild {
struct ID *id;
- struct ID *from_parent;
-} wmDragID;
-
-typedef struct wmDrag {
- struct wmDrag *next, *prev;
-
- int icon;
- /** See 'WM_DRAG_' defines above. */
- int type;
- void *poin;
- char path[1024]; /* FILE_MAX */
- double value;
-
- /** If no icon but imbuf should be drawn around cursor. */
- struct ImBuf *imb;
- float scale;
- int sx, sy;
-
- /** If set, draws operator name. */
- char opname[200];
- unsigned int flags;
-
- /** List of wmDragIDs, all are guaranteed to have the same ID type. */
- ListBase ids;
-} wmDrag;
-
-/**
- * Dropboxes are like keymaps, part of the screen/area/region definition.
- * Allocation and free is on startup and exit.
- */
-typedef struct wmDropBox {
- struct wmDropBox *next, *prev;
-
- /** Test if the dropbox is active, then can print optype name. */
- bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *, const char **);
-
- /** Before exec, this copies drag info to #wmDrop properties. */
- void (*copy)(struct wmDrag *, struct wmDropBox *);
-
- /**
- * If poll succeeds, operator is called.
- * Not saved in file, so can be pointer.
- */
- wmOperatorType *ot;
-
- /** Operator properties, assigned to ptr->data and can be written to a file. */
- struct IDProperty *properties;
- /** RNA pointer to access properties. */
- struct PointerRNA *ptr;
-
- /** Default invoke. */
- short opcontext;
-
-} wmDropBox;
+ struct Collection *parent;
+} wmDragCollectionChild;
+
+typedef struct wmDragData {
+ enum DragDataType type;
+ enum DragDisplayType display_type;
+ union {
+ ListBase *ids;
+ struct {
+ char **paths;
+ int amount;
+ } filepaths;
+ struct {
+ float color[3];
+ bool gamma_corrected;
+ } color;
+ double value;
+ struct PointerRNA *rna;
+ char *name;
+ ListBase *collection_children;
+ } data;
+ union {
+ struct {
+ struct ImBuf *imb;
+ float scale;
+ int width;
+ int height;
+ } image;
+ int icon_id;
+ float color[3];
+ } display;
+} wmDragData;
+
+typedef struct wmDropTarget {
+ char *ot_idname;
+ char *tooltip;
+ short context;
+ int size;
+ bool free;
+ bool free_idname;
+ bool free_tooltip;
+ void (*set_properties)(struct wmDragData *, struct PointerRNA *);
+} wmDropTarget;
+
+typedef struct wmDropTargetFinder {
+ wmDropTarget *current;
+} wmDropTargetFinder;
/**
* Struct to store tool-tip timer and possible creation if the time is reached.
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
index 00df6edef22..eb2f8b53d17 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
@@ -123,7 +123,6 @@ struct wmGizmoMap {
/**
* This is a container for all gizmo types that can be instantiated in a region.
- * (similar to dropboxes).
*
* \note There is only ever one of these for every (area, region) combination.
*/
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 0032a341610..6edf0f9edfd 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -434,7 +434,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
BLI_freelistN(&wm->paintcursors);
- WM_drag_free_list(&wm->drags);
+ WM_drag_stop(wm);
wm_reports_free(wm);
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index ad3fc7a1302..e4fd6c76bc6 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -27,17 +27,21 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_collection_types.h"
+#include "DNA_space_types.h"
#include "MEM_guardedalloc.h"
#include "BLT_translation.h"
#include "BLI_blenlib.h"
+#include "BLI_math_vector.h"
#include "BIF_glutil.h"
#include "BKE_context.h"
#include "BKE_idtype.h"
+#include "BKE_screen.h"
#include "GPU_glew.h"
#include "GPU_shader.h"
@@ -49,453 +53,512 @@
#include "UI_interface.h"
#include "UI_interface_icons.h"
+#include "ED_outliner.h"
+#include "ED_fileselect.h"
+
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
-/* ****************************************************** */
-
-static ListBase dropboxes = {NULL, NULL};
+/* ********************* Free Data ********************* */
-/* drop box maps are stored global for now */
-/* these are part of blender's UI/space specs, and not like keymaps */
-/* when editors become configurable, they can add own dropbox definitions */
+static void drag_data_free_filepaths(wmDragData *drag_data)
+{
+ for (int i = 0; i < drag_data->data.filepaths.amount; i++) {
+ MEM_freeN(drag_data->data.filepaths.paths[i]);
+ }
+ MEM_freeN(drag_data->data.filepaths.paths);
+}
-typedef struct wmDropBoxMap {
- struct wmDropBoxMap *next, *prev;
+static void drag_data_free_collection_children(wmDragData *drag_data)
+{
+ ListBase *list = drag_data->data.collection_children;
+ LISTBASE_FOREACH (LinkData *, link, list) {
+ MEM_freeN(link->data);
+ }
+ BLI_freelistN(list);
+ MEM_freeN(list);
+}
- ListBase dropboxes;
- short spaceid, regionid;
- char idname[KMAP_MAX_NAME];
+void WM_drag_data_free(wmDragData *drag_data)
+{
+ switch (drag_data->type) {
+ case DRAG_DATA_FILEPATHS:
+ drag_data_free_filepaths(drag_data);
+ break;
+ case DRAG_DATA_COLLECTION_CHILDREN:
+ drag_data_free_collection_children(drag_data);
+ break;
+ default:
+ break;
+ }
-} wmDropBoxMap;
+ MEM_freeN(drag_data);
+}
-/* spaceid/regionid is zero for window drop maps */
-ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
+void WM_drop_target_free(wmDropTarget *drop_target)
{
- wmDropBoxMap *dm;
+ if (drop_target->free_idname) {
+ MEM_freeN(drop_target->ot_idname);
+ }
+ if (drop_target->free_tooltip) {
+ MEM_freeN(drop_target->tooltip);
+ }
+ if (drop_target->free) {
+ MEM_freeN(drop_target);
+ }
+}
- for (dm = dropboxes.first; dm; dm = dm->next) {
- if (dm->spaceid == spaceid && dm->regionid == regionid) {
- if (STREQLEN(idname, dm->idname, KMAP_MAX_NAME)) {
- return &dm->dropboxes;
- }
- }
+void WM_drag_stop(wmWindowManager *wm)
+{
+ if (wm->drag.data) {
+ WM_drag_data_free(wm->drag.data);
}
+ if (wm->drag.target) {
+ WM_drop_target_free(wm->drag.target);
+ }
+ wm->drag.data = NULL;
+ wm->drag.target = NULL;
+}
+
+/* ********************* Start Dragging ********************* */
- dm = MEM_callocN(sizeof(struct wmDropBoxMap), "dropmap list");
- BLI_strncpy(dm->idname, idname, KMAP_MAX_NAME);
- dm->spaceid = spaceid;
- dm->regionid = regionid;
- BLI_addtail(&dropboxes, dm);
+static void start_dragging_data(struct bContext *C, wmDragData *drag_data)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ WM_drag_stop(wm);
+ wm->drag.data = drag_data;
+ wm->drag.target = NULL;
+}
- return &dm->dropboxes;
+static wmDragData *WM_drag_data_new(void)
+{
+ return MEM_callocN(sizeof(wmDragData), "drag data");
}
-wmDropBox *WM_dropbox_add(ListBase *lb,
- const char *idname,
- bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **),
- void (*copy)(wmDrag *, wmDropBox *))
+wmDragData *WM_drag_start_id(struct bContext *C, ID *id)
{
- wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_IDS;
+ drag_data->data.ids = MEM_callocN(sizeof(ListBase), __func__);
+ BLI_addtail(drag_data->data.ids, BLI_genericNodeN(id));
- drop->poll = poll;
- drop->copy = copy;
- drop->ot = WM_operatortype_find(idname, 0);
- drop->opcontext = WM_OP_INVOKE_DEFAULT;
+ start_dragging_data(C, drag_data);
+ return drag_data;
+}
- if (drop->ot == NULL) {
- MEM_freeN(drop);
- printf("Error: dropbox with unknown operator: %s\n", idname);
- return NULL;
+wmDragData *WM_drag_start_filepaths(struct bContext *C, const char **filepaths, int amount)
+{
+ BLI_assert(amount > 0);
+
+ char **paths = MEM_malloc_arrayN(amount, sizeof(char *), __func__);
+ for (int i = 0; i < amount; i++) {
+ paths[i] = BLI_strdup(filepaths[i]);
}
- WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname);
- BLI_addtail(lb, drop);
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_FILEPATHS;
+ drag_data->data.filepaths.amount = amount;
+ drag_data->data.filepaths.paths = paths;
- return drop;
+ start_dragging_data(C, drag_data);
+ return drag_data;
}
-void wm_dropbox_free(void)
+wmDragData *WM_drag_start_filepath(struct bContext *C, const char *filepath)
{
- wmDropBoxMap *dm;
-
- for (dm = dropboxes.first; dm; dm = dm->next) {
- wmDropBox *drop;
+ return WM_drag_start_filepaths(C, &filepath, 1);
+}
- for (drop = dm->dropboxes.first; drop; drop = drop->next) {
- if (drop->ptr) {
- WM_operator_properties_free(drop->ptr);
- MEM_freeN(drop->ptr);
- }
- }
- BLI_freelistN(&dm->dropboxes);
- }
+wmDragData *WM_drag_start_color(struct bContext *C, float color[3], bool gamma_corrected)
+{
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_COLOR;
+ copy_v3_v3(drag_data->data.color.color, color);
+ drag_data->data.color.gamma_corrected = gamma_corrected;
- BLI_freelistN(&dropboxes);
+ start_dragging_data(C, drag_data);
+ return drag_data;
}
-/* *********************************** */
-
-/* note that the pointer should be valid allocated and not on stack */
-wmDrag *WM_event_start_drag(
- struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
+wmDragData *WM_drag_start_value(struct bContext *C, double value)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_VALUE;
+ drag_data->data.value = value;
- /* keep track of future multitouch drag too, add a mousepointer id or so */
- /* if multiple drags are added, they're drawn as list */
+ start_dragging_data(C, drag_data);
+ return drag_data;
+}
- BLI_addtail(&wm->drags, 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;
- }
- drag->value = value;
+wmDragData *WM_drag_start_rna(struct bContext *C, struct PointerRNA *rna)
+{
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_RNA;
+ drag_data->data.rna = rna;
- return drag;
+ start_dragging_data(C, drag_data);
+ return drag_data;
}
-void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy)
+wmDragData *WM_drag_start_name(struct bContext *C, const char *name)
{
- drag->imb = imb;
- drag->scale = scale;
- drag->sx = sx;
- drag->sy = sy;
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_NAME;
+ drag_data->data.name = BLI_strdup(name);
+
+ start_dragging_data(C, drag_data);
+ return drag_data;
}
-void WM_drag_free(wmDrag *drag)
+wmDragData *WM_drag_start_collection_children(struct bContext *C, ListBase *collection_children)
{
- if ((drag->flags & WM_DRAG_FREE_DATA) && drag->poin) {
- MEM_freeN(drag->poin);
- }
+ wmDragData *drag_data = WM_drag_data_new();
+ drag_data->type = DRAG_DATA_COLLECTION_CHILDREN;
+ drag_data->data.collection_children = collection_children;
- BLI_freelistN(&drag->ids);
- MEM_freeN(drag);
+ start_dragging_data(C, drag_data);
+ return drag_data;
}
-void WM_drag_free_list(struct ListBase *lb)
+/* ********************* Set Display Options ********************* */
+
+void WM_drag_display_set_image(
+ wmDragData *drag_data, ImBuf *imb, float scale, int width, int height)
{
- wmDrag *drag;
- while ((drag = BLI_pophead(lb))) {
- WM_drag_free(drag);
- }
+ drag_data->display_type = DRAG_DISPLAY_IMAGE;
+ drag_data->display.image.imb = imb;
+ drag_data->display.image.scale = scale;
+ drag_data->display.image.width = width;
+ drag_data->display.image.height = height;
}
-static const char *dropbox_active(bContext *C,
- ListBase *handlers,
- wmDrag *drag,
- const wmEvent *event)
-{
- 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) {
- const char *tooltip = NULL;
- if (drop->poll(C, drag, event, &tooltip)) {
- /* XXX Doing translation here might not be ideal, but later we have no more
- * access to ot (and hence op context)... */
- return (tooltip) ? tooltip : WM_operatortype_name(drop->ot, drop->ptr);
- }
- }
- }
- }
- }
- return NULL;
+void WM_drag_display_set_icon(wmDragData *drag_data, int icon_id)
+{
+ drag_data->display_type = DRAG_DISPLAY_ICON;
+ drag_data->display.icon_id = icon_id;
}
-/* return active operator name when mouse is in box */
-static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
+void WM_drag_display_set_color(wmDragData *drag_data, float color[3])
{
- wmWindow *win = CTX_wm_window(C);
- ScrArea *area = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
- const char *name;
+ drag_data->display_type = DRAG_DISPLAY_COLOR;
+ copy_v3_v3(drag_data->display.color, color);
+}
- name = dropbox_active(C, &win->handlers, drag, event);
- if (name) {
- return name;
- }
+void WM_drag_display_set_color_derived(wmDragData *drag_data)
+{
+ BLI_assert(drag_data->type == DRAG_DATA_COLOR);
+ WM_drag_display_set_color(drag_data, drag_data->data.color.color);
+}
- name = dropbox_active(C, &area->handlers, drag, event);
- if (name) {
- return name;
- }
+/* ********************* Drop Target Creation ********************* */
- name = dropbox_active(C, &region->handlers, drag, event);
- if (name) {
- return name;
+void WM_drop_target_propose(wmDropTargetFinder *finder, wmDropTarget *target)
+{
+ if (target == NULL) {
+ return;
}
+ else if (finder->current == NULL) {
+ finder->current = target;
+ }
+ else if (target->size < finder->current->size) {
+ WM_drop_target_free(finder->current);
+ finder->current = target;
+ }
+ else {
+ WM_drop_target_free(target);
+ }
+}
- return NULL;
+static enum DropTargetSize drop_target_get_current_size(wmDropTargetFinder *finder)
+{
+ if (finder->current)
+ return finder->current->size;
+ else
+ return DROP_TARGET_SIZE_MAX;
}
-static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *event)
+void WM_drop_target_propose__template_1(wmDropTargetFinder *finder,
+ enum DropTargetSize size,
+ const char *ot_idname,
+ const char *tooltip,
+ wmDropTargetSetProps set_properties)
{
- wmWindow *win = CTX_wm_window(C);
- const int winsize_x = WM_window_pixels_x(win);
- const int winsize_y = WM_window_pixels_y(win);
+ WM_drop_target_propose__template_2(
+ finder, size, ot_idname, tooltip, set_properties, WM_OP_INVOKE_DEFAULT);
+}
- /* for multiwin drags, we only do this if mouse inside */
- if (event->x < 0 || event->y < 0 || event->x > winsize_x || event->y > winsize_y) {
+void WM_drop_target_propose__template_2(wmDropTargetFinder *finder,
+ enum DropTargetSize size,
+ const char *ot_idname,
+ const char *tooltip,
+ wmDropTargetSetProps set_properties,
+ short context)
+{
+ if (size >= drop_target_get_current_size(finder))
return;
- }
+ WM_drop_target_propose(
+ finder,
+ WM_drop_target_new(
+ size, (char *)ot_idname, (char *)tooltip, set_properties, context, true, false, false));
+}
- drag->opname[0] = 0;
+wmDropTarget *WM_drop_target_new(enum DropTargetSize size,
+ char *ot_idname,
+ char *tooltip,
+ wmDropTargetSetProps set_properties,
+ short context,
+ bool free,
+ bool free_idname,
+ bool free_tooltip)
+{
+ wmDropTarget *drop_target = MEM_callocN(sizeof(wmDropTarget), __func__);
+ drop_target->size = size;
+ drop_target->ot_idname = ot_idname;
+ drop_target->tooltip = tooltip;
+ drop_target->set_properties = set_properties;
+ drop_target->context = context;
+ drop_target->free = free;
+ drop_target->free_idname = free_idname;
+ drop_target->free_tooltip = free_tooltip;
+ return drop_target;
+}
- /* check buttons (XXX todo rna and value) */
- if (UI_but_active_drop_name(C)) {
- BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname));
- }
- else {
- const char *opname = wm_dropbox_active(C, drag, event);
+/* ********************* Query Drag Data ********************* */
- if (opname) {
- BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
- // WM_cursor_modal_set(win, WM_CURSOR_COPY);
+ID *WM_drag_query_single_id(wmDragData *drag_data)
+{
+ if (drag_data->type == DRAG_DATA_IDS) {
+ ListBase *list = drag_data->data.ids;
+ if (BLI_listbase_is_single(list)) {
+ return (ID *)list->first;
+ }
+ }
+ else if (drag_data->type == DRAG_DATA_COLLECTION_CHILDREN) {
+ ListBase *list = drag_data->data.collection_children;
+ if (BLI_listbase_is_single(list)) {
+ return (ID *)((wmDragCollectionChild *)((LinkData *)list->first)->data)->id;
}
- // else
- // WM_cursor_modal_restore(win);
- /* unsure about cursor type, feels to be too much */
}
+ return NULL;
}
-/* called in inner handler loop, region context */
-void wm_drags_check_ops(bContext *C, const wmEvent *event)
+ID *WM_drag_query_single_id_of_type(wmDragData *drag_data, int idtype)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmDrag *drag;
+ ID *id = WM_drag_query_single_id(drag_data);
+ if (id && GS(id->name) == idtype)
+ return id;
+ return NULL;
+}
- for (drag = wm->drags.first; drag; drag = drag->next) {
- wm_drop_operator_options(C, drag, event);
- }
+Collection *WM_drag_query_single_collection(wmDragData *drag_data)
+{
+ return (Collection *)WM_drag_query_single_id_of_type(drag_data, ID_GR);
+}
+
+Material *WM_drag_query_single_material(wmDragData *drag_data)
+{
+ return (Material *)WM_drag_query_single_id_of_type(drag_data, ID_MA);
}
-/* ************** IDs ***************** */
+Object *WM_drag_query_single_object(wmDragData *drag_data)
+{
+ return (Object *)WM_drag_query_single_id_of_type(drag_data, ID_OB);
+}
-void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)
+const char *WM_drag_query_single_path(wmDragData *drag_data)
{
- /* Don't drag the same ID twice. */
- LISTBASE_FOREACH (wmDragID *, drag_id, &drag->ids) {
- if (drag_id->id == id) {
- if (drag_id->from_parent == NULL) {
- drag_id->from_parent = from_parent;
- }
- return;
- }
- else if (GS(drag_id->id->name) != GS(id->name)) {
- BLI_assert(!"All dragged IDs must have the same type");
- return;
+ if (drag_data->type == DRAG_DATA_FILEPATHS) {
+ if (drag_data->data.filepaths.amount == 1) {
+ return drag_data->data.filepaths.paths[0];
}
}
-
- /* Add to list. */
- wmDragID *drag_id = MEM_callocN(sizeof(wmDragID), __func__);
- drag_id->id = id;
- drag_id->from_parent = from_parent;
- BLI_addtail(&drag->ids, drag_id);
+ return NULL;
}
-ID *WM_drag_ID(const wmDrag *drag, short idcode)
+const char *WM_drag_query_single_path_of_types(wmDragData *drag_data, int types)
{
- if (drag->type != WM_DRAG_ID) {
+ const char *path = WM_drag_query_single_path(drag_data);
+ if (!path)
return NULL;
- }
- wmDragID *drag_id = drag->ids.first;
- if (!drag_id) {
- return NULL;
+ if (ED_path_extension_type(path) & types) {
+ return path;
}
- ID *id = drag_id->id;
- return (idcode == 0 || GS(id->name) == idcode) ? id : NULL;
+ return NULL;
}
-ID *WM_drag_ID_from_event(const wmEvent *event, short idcode)
+const char *WM_drag_query_single_path_maybe_text(wmDragData *drag_data)
{
- if (event->custom != EVT_DATA_DRAGDROP) {
+ const char *path = WM_drag_query_single_path(drag_data);
+ if (!path)
return NULL;
+
+ int type = ED_path_extension_type(path);
+ if (type == 0 || ELEM(type, FILE_TYPE_PYSCRIPT, FILE_TYPE_TEXT)) {
+ return path;
}
- ListBase *lb = event->customdata;
- return WM_drag_ID(lb->first, idcode);
+ return NULL;
}
-/* ************** draw ***************** */
+const char *WM_drag_query_single_path_image(wmDragData *drag_data)
+{
+ return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_IMAGE);
+}
-static void wm_drop_operator_draw(const char *name, int x, int y)
+const char *WM_drag_query_single_path_movie(wmDragData *drag_data)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
+ return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_MOVIE);
+}
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
+const char *WM_drag_query_single_path_sound(wmDragData *drag_data)
+{
+ return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_SOUND);
}
-static const char *wm_drag_name(wmDrag *drag)
+const char *WM_drag_query_single_path_image_or_movie(wmDragData *drag_data)
{
- switch (drag->type) {
- case WM_DRAG_ID: {
- ID *id = WM_drag_ID(drag, 0);
- bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1);
+ return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_IMAGE | FILE_TYPE_MOVIE);
+}
- if (single) {
- return id->name + 2;
- }
- else if (id) {
- return BKE_idtype_idcode_to_name_plural(GS(id->name));
- }
- break;
- }
- case WM_DRAG_PATH:
- case WM_DRAG_NAME:
- return drag->path;
+ListBase *WM_drag_query_collection_children(wmDragData *drag_data)
+{
+ if (drag_data->type == DRAG_DATA_COLLECTION_CHILDREN) {
+ return drag_data->data.collection_children;
}
- return "";
+ return NULL;
}
-static void drag_rect_minmax(rcti *rect, int x1, int y1, int x2, int y2)
+bool WM_drag_query_single_color(wmDragData *drag_data, float *r_color, bool *r_gamma_corrected)
{
- if (rect->xmin > x1) {
- rect->xmin = x1;
+ if (drag_data->type == DRAG_DATA_COLOR) {
+ if (r_color)
+ memcpy(r_color, drag_data->data.color.color, sizeof(float) * 3);
+ if (r_gamma_corrected)
+ *r_gamma_corrected = drag_data->data.color.gamma_corrected;
+ return true;
}
- if (rect->xmax < x2) {
- rect->xmax = x2;
+ return false;
+}
+
+/* ********************* Draw ********************* */
+
+void WM_drag_draw(bContext *UNUSED(C), wmWindow *win, wmDragOperation *drag_operation)
+{
+ wmDragData *drag_data = drag_operation->data;
+ wmDropTarget *drop_target = drag_operation->target;
+
+ int cursorx = win->eventstate->x;
+ int cursory = win->eventstate->y;
+
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ const uchar text_col[] = {255, 255, 255, 255};
+
+ if (drop_target && drop_target->tooltip) {
+ UI_fontstyle_draw_simple(fstyle, cursorx, cursory, drop_target->tooltip, text_col);
}
- if (rect->ymin > y1) {
- rect->ymin = y1;
+
+ glEnable(GL_BLEND);
+
+ if (drag_data->display_type == DRAG_DISPLAY_ICON) {
+ UI_icon_draw(cursorx, cursory, drag_data->display.icon_id);
}
- if (rect->ymax < y2) {
- rect->ymax = y2;
+ else if (drag_data->display_type == DRAG_DISPLAY_COLOR) {
+ float color[4];
+ copy_v3_v3(color, drag_data->display.color);
+ color[3] = 1.0f;
+ UI_draw_roundbox_4fv(true, cursorx - 5, cursory - 5, cursorx + 5, cursory + 5, 2, color);
}
+
+ glDisable(GL_BLEND);
}
-/* called in wm_draw.c */
-/* if rect set, do not draw */
-void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
+/* ****************** Find Current Target ****************** */
+
+static void drop_files_init(wmDragData *drag_data, PointerRNA *ptr)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- wmWindowManager *wm = CTX_wm_manager(C);
- wmDrag *drag;
- const int winsize_y = WM_window_pixels_y(win);
- int cursorx, cursory, x, y;
-
- cursorx = win->eventstate->x;
- cursory = win->eventstate->y;
- if (rect) {
- rect->xmin = rect->xmax = cursorx;
- rect->ymin = rect->ymax = cursory;
+ for (int i = 0; i < drag_data->data.filepaths.amount; i++) {
+ char *path = drag_data->data.filepaths.paths[i];
+ PointerRNA itemptr;
+ RNA_collection_add(ptr, "filepaths", &itemptr);
+ RNA_string_set(&itemptr, "name", path);
}
+}
- /* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */
- GPU_blend(true);
- for (drag = wm->drags.first; drag; drag = drag->next) {
- const uchar text_col[] = {255, 255, 255, 255};
- int iconsize = UI_DPI_ICON_SIZE;
- int padding = 4 * UI_DPI_FAC;
-
- /* image or icon */
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
- y = cursory - drag->sy / 2;
-
- 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,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- drag->imb->rect,
- drag->scale,
- drag->scale,
- 1.0f,
- 1.0f,
- col);
- }
- }
- else {
- x = cursorx - 2 * padding;
- y = cursory - 2 * UI_DPI_FAC;
-
- 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);
- }
- }
+static void get_window_drop_target(bContext *C,
+ wmDropTargetFinder *finder,
+ wmDragData *drag_data,
+ const wmEvent *event)
+{
+ UI_drop_target_find(C, finder, drag_data, event);
- /* item name */
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
- y = cursory - drag->sy / 2 - iconsize;
- }
- else {
- x = cursorx + 10 * UI_DPI_FAC;
- y = cursory + 1 * UI_DPI_FAC;
- }
+ if (drag_data->type == DRAG_DATA_FILEPATHS) {
+ WM_drop_target_propose__template_1(
+ finder, DROP_TARGET_SIZE_WINDOW, "WM_OT_drop_files", "", drop_files_init);
+ }
+}
- if (rect) {
- int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
- drag_rect_minmax(rect, x, y, x + w, y + iconsize);
- }
- else {
- UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag), text_col);
- }
+wmDropTarget *WM_drag_find_current_target(bContext *C, wmDragData *drag_data, const wmEvent *event)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ if (!sa)
+ return NULL;
- /* operator name with roundbox */
- if (drag->opname[0]) {
- if (drag->imb) {
- x = cursorx - drag->sx / 2;
-
- 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;
-
- if (cursory + iconsize + iconsize < winsize_y) {
- y = (cursory + iconsize) + padding;
- }
- else {
- y = (cursory - iconsize) - padding;
- }
- }
-
- if (rect) {
- int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
- drag_rect_minmax(rect, x, y, x + w, y + iconsize);
- }
- else {
- wm_drop_operator_draw(drag->opname, x, y);
- }
- }
+ wmDropTargetFinder finder = {0};
+
+ SpaceType *st = sa->type;
+ wmDropTarget *drop_target = NULL;
+
+ if (!drop_target && st->drop_target_find) {
+ st->drop_target_find(C, &finder, drag_data, event);
+ }
+
+ if (!drop_target) {
+ get_window_drop_target(C, &finder, drag_data, event);
+ }
+
+ return finder.current;
+}
+
+/* ****************** Misc ****************** */
+
+void WM_drag_transfer_ownership_to_event(struct wmWindowManager *wm, struct wmEvent *event)
+{
+ if (wm->drag.target) {
+ WM_drop_target_free(wm->drag.target);
}
- GPU_blend(false);
+
+ event->custom = EVT_DATA_DRAGDROP;
+ event->customdata = wm->drag.data;
+ event->customdatafree = true;
+
+ wm->drag.data = NULL;
+ wm->drag.target = NULL;
+}
+
+wmDragData *WM_drag_get_active(bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ return wm->drag.data;
+}
+
+wmDragData *WM_drag_data_from_event(const wmEvent *event)
+{
+ if (event->custom != EVT_DATA_DRAGDROP)
+ return NULL;
+ return (wmDragData *)event->customdata;
+}
+
+void WM_drop_init_single_filepath(wmDragData *drag_data, PointerRNA *ptr)
+{
+ RNA_string_set(ptr, "filepath", WM_drag_query_single_path(drag_data));
+}
+
+void WM_drop_init_single_id_name(wmDragData *drag_data, PointerRNA *ptr)
+{
+ RNA_string_set(ptr, "name", WM_drag_query_single_id(drag_data)->name + 2);
}
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index fa12d6cf974..730c5b3b0c2 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -795,8 +795,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
}
/* needs pixel coords in screen */
- if (wm->drags.first) {
- wm_drags_draw(C, win, NULL);
+ if (wm->drag.data) {
+ WM_drag_draw(C, win, &wm->drag);
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 53d6df915d6..9a90e73af39 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -152,20 +152,25 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add)
return event;
}
-void wm_event_free(wmEvent *event)
+static void wm_event_free_customdata_if_necessary(wmEvent *event)
{
if (event->customdata) {
if (event->customdatafree) {
- /* note: pointer to listbase struct elsewhere */
if (event->custom == EVT_DATA_DRAGDROP) {
- ListBase *lb = event->customdata;
- WM_drag_free_list(lb);
+ WM_drag_data_free(event->customdata);
}
else {
MEM_freeN(event->customdata);
}
}
}
+ event->customdata = NULL;
+ event->customdatafree = false;
+}
+
+void wm_event_free(wmEvent *event)
+{
+ wm_event_free_customdata_if_necessary(event);
MEM_freeN(event);
}
@@ -2390,6 +2395,56 @@ static int wm_action_not_handled(int action)
return action == WM_HANDLER_CONTINUE || action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL);
}
+static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect)
+{
+ if (wm_event_always_pass(event)) {
+ return true;
+ }
+ if (BLI_rcti_isect_pt_v(rect, &event->x)) {
+ return true;
+ }
+ return false;
+}
+
+static bool wm_event_inside_region(const wmEvent *event, const ARegion *region)
+{
+ if (wm_event_always_pass(event)) {
+ return true;
+ }
+ return ED_region_contains_xy(region, &event->x);
+}
+
+static ScrArea *area_event_inside(bContext *C, const int xy[2])
+{
+ wmWindow *win = CTX_wm_window(C);
+ bScreen *screen = CTX_wm_screen(C);
+
+ if (screen) {
+ ED_screen_areas_iter (win, screen, area) {
+ if (BLI_rcti_isect_pt_v(&area->totrct, xy)) {
+ return area;
+ }
+ }
+ }
+ return NULL;
+}
+
+static ARegion *region_event_inside(bContext *C, const int xy[2])
+{
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region;
+
+ if (screen && area) {
+ for (region = area->regionbase.first; region; region = region->next) {
+ if (BLI_rcti_isect_pt_v(&region->winrct, xy)) {
+ return region;
+ }
+ }
+ }
+ return NULL;
+}
+
#define PRINT \
if (do_debug_handler) \
printf
@@ -2744,50 +2799,44 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
else if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
- wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
- if (!wm->is_interface_locked && event->type == EVT_DROP) {
- wmDropBox *drop = handler->dropboxes->first;
- for (; drop; drop = drop->next) {
- /* other drop custom types allowed */
- if (event->custom == EVT_DATA_DRAGDROP) {
- ListBase *lb = (ListBase *)event->customdata;
- wmDrag *drag;
-
- for (drag = lb->first; drag; drag = drag->next) {
- const char *tooltip = NULL;
- if (drop->poll(C, drag, event, &tooltip)) {
- /* Optionally copy drag information to operator properties. */
- if (drop->copy) {
- drop->copy(drag, drop);
- }
+ wmDragData *drag_data = WM_drag_data_from_event(event);
+ if (!wm->is_interface_locked && event->type == EVT_DROP && drag_data) {
+ ARegion *region_old = CTX_wm_region(C);
+ ARegion *region = region_event_inside(C, &event->x);
+ CTX_wm_region_set(C, region);
+ wm_region_mouse_co(C, event);
- /* Pass single matched wmDrag onto the operator. */
- BLI_remlink(lb, drag);
- ListBase single_lb = {drag, drag};
- event->customdata = &single_lb;
+ wmDropTarget *drop_target = WM_drag_find_current_target(C, drag_data, event);
- wm_operator_call_internal(
- C, drop->ot, drop->ptr, NULL, drop->opcontext, false, event);
- action |= WM_HANDLER_BREAK;
+ if (drop_target) {
+ wmOperatorType *ot = WM_operatortype_find(drop_target->ot_idname, false);
+ struct PointerRNA *ptr = NULL;
+ struct IDProperty *properties = NULL;
+ WM_operator_properties_alloc(&ptr, &properties, drop_target->ot_idname);
- /* free the drags */
- WM_drag_free_list(lb);
- WM_drag_free_list(&single_lb);
+ if (drop_target->set_properties) {
+ drop_target->set_properties(drag_data, ptr);
+ }
- event->customdata = NULL;
- event->custom = 0;
+ wm_operator_call_internal(C, ot, ptr, NULL, drop_target->context, false, event);
+ action |= WM_HANDLER_BREAK;
- /* XXX fileread case */
- if (CTX_wm_window(C) == NULL) {
- return action;
- }
+ WM_operator_properties_free(ptr);
+ WM_drop_target_free(drop_target);
- /* escape from drag loop, got freed */
- break;
- }
- }
+ if (CTX_wm_window(C) == NULL) {
+ return action;
}
}
+
+ CTX_wm_region_set(C, region_old);
+ wm_region_mouse_co(C, event);
+ }
+
+ if (drag_data) {
+ WM_drag_data_free(drag_data);
+ event->customdata = NULL;
+ event->custom = 0;
}
}
else if (handler_base->type == WM_HANDLER_TYPE_GIZMO) {
@@ -2990,56 +3039,6 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
* Utilities used by #wm_event_do_handlers.
* \{ */
-static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect)
-{
- if (wm_event_always_pass(event)) {
- return true;
- }
- if (BLI_rcti_isect_pt_v(rect, &event->x)) {
- return true;
- }
- return false;
-}
-
-static bool wm_event_inside_region(const wmEvent *event, const ARegion *region)
-{
- if (wm_event_always_pass(event)) {
- return true;
- }
- return ED_region_contains_xy(region, &event->x);
-}
-
-static ScrArea *area_event_inside(bContext *C, const int xy[2])
-{
- wmWindow *win = CTX_wm_window(C);
- bScreen *screen = CTX_wm_screen(C);
-
- if (screen) {
- ED_screen_areas_iter (win, screen, area) {
- if (BLI_rcti_isect_pt_v(&area->totrct, xy)) {
- return area;
- }
- }
- }
- return NULL;
-}
-
-static ARegion *region_event_inside(bContext *C, const int xy[2])
-{
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *area = CTX_wm_area(C);
- ARegion *region;
-
- if (screen && area) {
- for (region = area->regionbase.first; region; region = region->next) {
- if (BLI_rcti_isect_pt_v(&region->winrct, xy)) {
- return region;
- }
- }
- }
- return NULL;
-}
-
static void wm_paintcursor_tag(bContext *C, wmPaintCursor *pc, ARegion *region)
{
if (region) {
@@ -3082,39 +3081,25 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event)
static void wm_event_drag_and_drop_test(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
- bScreen *screen = WM_window_get_active_screen(win);
-
- if (BLI_listbase_is_empty(&wm->drags)) {
+ if (!wm->drag.data) {
return;
}
+ bScreen *screen = WM_window_get_active_screen(win);
+
if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) {
screen->do_draw_drag = true;
}
else if (event->type == EVT_ESCKEY) {
- WM_drag_free_list(&wm->drags);
-
+ WM_drag_stop(wm);
screen->do_draw_drag = true;
}
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ wm_event_free_customdata_if_necessary(event);
event->type = EVT_DROP;
+ WM_drag_transfer_ownership_to_event(wm, event);
- /* create customdata, first free existing */
- if (event->customdata) {
- if (event->customdatafree) {
- MEM_freeN(event->customdata);
- }
- }
-
- event->custom = EVT_DATA_DRAGDROP;
- event->customdata = &wm->drags;
- event->customdatafree = 1;
-
- /* clear drop icon */
screen->do_draw_drag = true;
-
- /* restore cursor (disabled, see wm_dragdrop.c) */
- // WM_cursor_modal_restore(win);
}
}
@@ -3297,7 +3282,7 @@ void wm_event_do_handlers(bContext *C)
}
}
- /* check dragging, creates new event or frees, adds draw tag */
+ /* may change the event into a drop event, adds draw tag */
wm_event_drag_and_drop_test(wm, win, event);
/* builtin tweak, if action is break it removes tweak */
@@ -3346,12 +3331,10 @@ void wm_event_do_handlers(bContext *C)
/* call even on non mouse events, since the */
wm_region_mouse_co(C, event);
- if (!BLI_listbase_is_empty(&wm->drags)) {
- /* does polls for drop regions and checks uibuts */
- /* need to be here to make sure region context is true */
- if (ELEM(event->type, MOUSEMOVE, EVT_DROP) || ISKEYMODIFIER(event->type)) {
- wm_drags_check_ops(C, event);
- }
+ if (wm->drag.data) {
+ if (wm->drag.target)
+ WM_drop_target_free(wm->drag.target);
+ wm->drag.target = WM_drag_find_current_target(C, wm->drag.data, event);
}
action |= wm_handlers_do(C, event, &region->handlers);
@@ -3906,26 +3889,18 @@ void WM_event_free_ui_handler_all(bContext *C,
}
}
-wmEventHandler_Dropbox *WM_event_add_dropbox_handler(ListBase *handlers, ListBase *dropboxes)
+void WM_event_ensure_drop_handler(ListBase *handlers)
{
/* only allow same dropbox once */
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
- wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
- if (handler->dropboxes == dropboxes) {
- return handler;
- }
+ return;
}
}
wmEventHandler_Dropbox *handler = MEM_callocN(sizeof(*handler), __func__);
handler->head.type = WM_HANDLER_TYPE_DROPBOX;
-
- /* dropbox stored static, no free or copy */
- handler->dropboxes = dropboxes;
BLI_addhead(handlers, handler);
-
- return handler;
}
/* XXX solution works, still better check the real cause (ton) */
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 001acc459c2..c4fccddc869 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -536,7 +536,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
wm_operatortype_free();
wm_surfaces_free();
- wm_dropbox_free();
WM_menutype_free();
WM_uilisttype_free();
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 1ba22652157..05a84f6acaa 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -721,11 +721,6 @@ static void wm_window_ghostwindow_ensure(wmWindowManager *wm, wmWindow *win, boo
keymap = WM_keymap_ensure(wm->defaultconf, "Screen Editing", 0, 0);
WM_event_add_keymap_handler(&win->modalhandlers, keymap);
- /* add drop boxes */
- {
- ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
- WM_event_add_dropbox_handler(&win->handlers, lb);
- }
wm_window_title(wm, win);
/* add topbar */
@@ -1480,36 +1475,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->active = 1;
- wm_event_add(win, &event);
-
- /* make blender drop event with custom data pointing to wm drags */
- event.type = EVT_DROP;
- event.val = KM_RELEASE;
- event.custom = EVT_DATA_DRAGDROP;
- event.customdata = &wm->drags;
- event.customdatafree = 1;
-
- wm_event_add(win, &event);
-
- /* printf("Drop detected\n"); */
-
- /* add drag data to wm for paths: */
-
+ /* first initialize the dragging */
if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
GHOST_TStringArray *stra = ddd->data;
- int a, icon;
-
- for (a = 0; a < stra->count; a++) {
- printf("drop file %s\n", stra->strings[a]);
- /* try to get icon type from extension */
- icon = ED_file_extension_icon((char *)stra->strings[a]);
-
- WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
- /* void poin should point to string, it makes a copy */
- break; /* only one drop element supported now */
+ if (stra->count > 0) {
+ WM_drag_start_filepaths(C, (const char **)stra->strings, stra->count);
}
}
+ /* then drop it immediatly */
+ event.type = EVT_DROP;
+ event.val = KM_RELEASE;
+ event.shift = query_qual(SHIFT) ? true : false;
+ event.ctrl = query_qual(CONTROL) ? true : false;
+ event.alt = query_qual(ALT) ? true : false;
+ event.oskey = query_qual(OS) ? true : false;
+ WM_drag_transfer_ownership_to_event(wm, &event);
+ wm_event_add(win, &event);
+
break;
}
case GHOST_kEventNativeResolutionChange: {
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index efcf40d03eb..b837cafd30a 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -160,9 +160,7 @@ void wm_tablet_data_from_ghost(const struct GHOST_TabletData *tablet_data, wmTab
/* wm_keymap.c */
-/* wm_dropbox.c */
-void wm_dropbox_free(void);
-void wm_drags_check_ops(bContext *C, const wmEvent *event);
-void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
+/* wm_dragdrop.c */
+void WM_drag_draw(bContext *C, wmWindow *win, struct wmDragOperation *drag_operation);
#endif /* __WM_EVENT_SYSTEM_H__ */