diff options
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 106 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 127 | ||||
-rw-r--r-- | source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 733 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 229 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 43 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 6 |
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, ®ion->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(®ion->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(®ion->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, ®ion->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__ */ |