Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_dragdrop.c
| Show All 34 Lines | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_math_color.h" | #include "BLI_math_color.h" | ||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_idprop.h" | |||||
| #include "BKE_idtype.h" | #include "BKE_idtype.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BLO_readfile.h" | #include "BLO_readfile.h" | ||||
| #include "ED_asset.h" | #include "ED_asset.h" | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | wmDropBox *WM_dropbox_add(ListBase *lb, | ||||
| } | } | ||||
| WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname); | WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname); | ||||
| BLI_addtail(lb, drop); | BLI_addtail(lb, drop); | ||||
| return drop; | return drop; | ||||
| } | } | ||||
| void WM_dropbox_gizmogroup_set(wmDropBox *drop, | |||||
| const char gizmo_group[MAX_NAME], | |||||
| wmDropBoxCopyFn copy_gizmo_group) | |||||
| { | |||||
| BLI_strncpy(drop->gizmo_group, gizmo_group, sizeof(drop->gizmo_group)); | |||||
| drop->copy_gizmo_group = copy_gizmo_group; | |||||
| WM_gizmo_group_type_add(gizmo_group); | |||||
| } | |||||
| void wm_dropbox_free(void) | void wm_dropbox_free(void) | ||||
| { | { | ||||
| LISTBASE_FOREACH (wmDropBoxMap *, dm, &dropboxes) { | LISTBASE_FOREACH (wmDropBoxMap *, dm, &dropboxes) { | ||||
| LISTBASE_FOREACH (wmDropBox *, drop, &dm->dropboxes) { | LISTBASE_FOREACH (wmDropBox *, drop, &dm->dropboxes) { | ||||
| if (drop->ptr) { | if (drop->ptr) { | ||||
| WM_operator_properties_free(drop->ptr); | WM_operator_properties_free(drop->ptr); | ||||
| MEM_freeN(drop->ptr); | MEM_freeN(drop->ptr); | ||||
| ▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | |||||
| void WM_drag_free_list(struct ListBase *lb) | void WM_drag_free_list(struct ListBase *lb) | ||||
| { | { | ||||
| wmDrag *drag; | wmDrag *drag; | ||||
| while ((drag = BLI_pophead(lb))) { | while ((drag = BLI_pophead(lb))) { | ||||
| WM_drag_free(drag); | WM_drag_free(drag); | ||||
| } | } | ||||
| } | } | ||||
| struct wmDropboxActiveInfo { | |||||
| wmDropBox *drop; | |||||
| /* Some string the operator sets (operator name or some tooltip). */ | |||||
| const char *operator_string; | |||||
| const char *gizmo_group; | |||||
| }; | |||||
| static void wm_gizmogroup_properties_create(PointerRNA *ptr, const char *gz_group_name) | |||||
| { | |||||
| const wmGizmoGroupType *gz_grouptype = WM_gizmogrouptype_find(gz_group_name, false); | |||||
| if (gz_grouptype) { | |||||
| RNA_pointer_create(NULL, gz_grouptype->srna, NULL, ptr); | |||||
| } | |||||
| else { | |||||
| RNA_pointer_create(NULL, &RNA_GizmoGroupProperties, NULL, ptr); | |||||
| } | |||||
| } | |||||
| static char *dropbox_tooltip(bContext *C, wmDrag *drag, const wmEvent *event, wmDropBox *drop) | static char *dropbox_tooltip(bContext *C, wmDrag *drag, const wmEvent *event, wmDropBox *drop) | ||||
| { | { | ||||
| char *tooltip = NULL; | char *tooltip = NULL; | ||||
| if (drop->tooltip) { | if (drop->tooltip) { | ||||
| tooltip = drop->tooltip(C, drag, event, drop); | tooltip = drop->tooltip(C, drag, event, drop); | ||||
| } | } | ||||
| if (!tooltip) { | if (!tooltip) { | ||||
| tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr)); | tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr)); | ||||
| } | } | ||||
| /* XXX Doing translation here might not be ideal, but later we have no more | /* XXX Doing translation here might not be ideal, but later we have no more | ||||
| * access to ot (and hence op context)... */ | * access to ot (and hence op context)... */ | ||||
| return tooltip; | return tooltip; | ||||
| } | } | ||||
| static void wm_gizmogroup_properties_alloc(PointerRNA **ptr, | |||||
| IDProperty **properties, | |||||
| const char *gz_group_name) | |||||
| { | |||||
| if (*properties == NULL) { | |||||
| IDPropertyTemplate val = {0}; | |||||
| *properties = IDP_New(IDP_GROUP, &val, "wmGizmoGroupProp"); | |||||
| } | |||||
| if (*ptr == NULL) { | |||||
| *ptr = MEM_callocN(sizeof(PointerRNA), "wmGizmoGroupPtr"); | |||||
| wm_gizmogroup_properties_create(*ptr, gz_group_name); | |||||
| } | |||||
| (*ptr)->data = *properties; | |||||
| } | |||||
| static void dropbox_gizmo_activate(bContext *C, wmDrag *drag, wmDropBox *drop) | |||||
| { | |||||
| if (!STREQ(drag->gizmo_group, drop->gizmo_group)) { | |||||
| if (drop->gizmo_group[0]) { | |||||
| ARegion *region = CTX_wm_region(C); | |||||
| wmGizmoGroup *gzgroup = WM_gizmomap_group_find(region->gizmo_map, drop->gizmo_group); | |||||
| if (gzgroup) { | |||||
| wm_gizmogroup_properties_alloc(&gzgroup->ptr, &gzgroup->properties, drop->gizmo_group); | |||||
| WM_gizmo_properties_sanitize(gzgroup->ptr, 0); | |||||
| drop->gizmo_group_ptr = gzgroup->ptr; | |||||
| drop->copy_gizmo_group(drag, drop); | |||||
| } | |||||
| } | |||||
| } | |||||
| BLI_strncpy(drag->gizmo_group, drop->gizmo_group, sizeof(drag->gizmo_group)); | |||||
| } | |||||
| static wmDropBox *dropbox_active(bContext *C, | static wmDropBox *dropbox_active(bContext *C, | ||||
| ListBase *handlers, | ListBase *handlers, | ||||
| wmDrag *drag, | wmDrag *drag, | ||||
| const wmEvent *event) | const wmEvent *event) | ||||
| { | { | ||||
| LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { | LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { | ||||
| if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) { | if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) { | ||||
| wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base; | wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base; | ||||
| if (handler->dropboxes) { | if (handler->dropboxes) { | ||||
| LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) { | LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) { | ||||
| if (drop->poll(C, drag, event) && | if (drop->poll(C, drag, event) && | ||||
| WM_operator_poll_context(C, drop->ot, drop->opcontext)) { | WM_operator_poll_context(C, drop->ot, drop->opcontext)) { | ||||
| return drop; | return drop; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* return active operator tooltip/name when mouse is in box */ | /* return active operator name when mouse is in box */ | ||||
| static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event) | /** | ||||
| * \returns Pointer to static `wmDropboxActiveInfo` data, when the mouse is in a box with a | |||||
| * succeeding poll(). | |||||
| */ | |||||
| static struct wmDropboxActiveInfo *wm_dropbox_active(bContext *C, | |||||
| wmDrag *drag, | |||||
| const wmEvent *event) | |||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event); | wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event); | ||||
| if (!drop) { | if (!drop) { | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| drop = dropbox_active(C, &area->handlers, drag, event); | drop = dropbox_active(C, &area->handlers, drag, event); | ||||
| } | } | ||||
| if (!drop) { | if (!drop) { | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| drop = dropbox_active(C, ®ion->handlers, drag, event); | drop = dropbox_active(C, ®ion->handlers, drag, event); | ||||
| } | } | ||||
| if (drop) { | if (drop) { | ||||
| return dropbox_tooltip(C, drag, event, drop); | static struct wmDropboxActiveInfo active_info; | ||||
| active_info.drop = drop; | |||||
| active_info.gizmo_group = drop->gizmo_group; | |||||
| active_info.operator_string = dropbox_tooltip(C, drag, event, drop); | |||||
| return &active_info; | |||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *event) | static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *event) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| const int winsize_x = WM_window_pixels_x(win); | const int winsize_x = WM_window_pixels_x(win); | ||||
| const int winsize_y = WM_window_pixels_y(win); | const int winsize_y = WM_window_pixels_y(win); | ||||
| /* for multiwin drags, we only do this if mouse inside */ | /* 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) { | if (event->x < 0 || event->y < 0 || event->x > winsize_x || event->y > winsize_y) { | ||||
| return; | return; | ||||
| } | } | ||||
| drag->tooltip[0] = 0; | drag->tooltip[0] = 0; | ||||
| /* check buttons (XXX todo rna and value) */ | /* check buttons (XXX todo rna and value) */ | ||||
| if (UI_but_active_drop_name(C)) { | if (UI_but_active_drop_name(C)) { | ||||
| BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip)); | BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip)); | ||||
| drag->gizmo_group[0] = 0; | |||||
| } | } | ||||
| else { | else { | ||||
| char *tooltip = wm_dropbox_active(C, drag, event); | struct wmDropboxActiveInfo *active_info = wm_dropbox_active(C, drag, event); | ||||
| if (tooltip) { | if (active_info && active_info->operator_string) { | ||||
| BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip)); | BLI_strncpy(drag->tooltip, active_info->operator_string, sizeof(drag->tooltip)); | ||||
| MEM_freeN(tooltip); | MEM_freeN((char *)active_info->operator_string); | ||||
| // WM_cursor_modal_set(win, WM_CURSOR_COPY); | // WM_cursor_modal_set(win, WM_CURSOR_COPY); | ||||
| } | } | ||||
| if (active_info && active_info->gizmo_group) { | |||||
| dropbox_gizmo_activate(C, drag, active_info->drop); | |||||
| } | |||||
| else { | |||||
| drag->gizmo_group[0] = 0; | |||||
| } | |||||
| // else | // else | ||||
| // WM_cursor_modal_restore(win); | // WM_cursor_modal_restore(win); | ||||
| /* unsure about cursor type, feels to be too much */ | /* unsure about cursor type, feels to be too much */ | ||||
| } | } | ||||
| } | } | ||||
| /* called in inner handler loop, region context */ | /* called in inner handler loop, region context */ | ||||
| void wm_drags_check_ops(bContext *C, const wmEvent *event) | void wm_drags_check_ops(bContext *C, const wmEvent *event) | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode) | ||||
| if (drag->type != WM_DRAG_ASSET) { | if (drag->type != WM_DRAG_ASSET) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| wmDragAsset *asset_drag = drag->poin; | wmDragAsset *asset_drag = drag->poin; | ||||
| return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : NULL; | return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : NULL; | ||||
| } | } | ||||
| struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode) | |||||
| { | |||||
| wmDragAsset *drag_asset = WM_drag_get_asset_data(drag, idcode); | |||||
| if (drag_asset) { | |||||
| return drag_asset->metadata; | |||||
| } | |||||
| ID *local_id = WM_drag_get_local_ID(drag, idcode); | |||||
| if (local_id) { | |||||
| return local_id->asset_data; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag) | static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag) | ||||
| { | { | ||||
| const char *name = asset_drag->name; | const char *name = asset_drag->name; | ||||
| ID_Type idtype = asset_drag->id_type; | ID_Type idtype = asset_drag->id_type; | ||||
| /* FIXME: Link/Append should happens in the operator called at the end of drop process, not from | /* FIXME: Link/Append should happens in the operator called at the end of drop process, not from | ||||
| * here. */ | * here. */ | ||||
| ▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) | ||||
| /* Should we support multi-line drag draws? Maybe not, more types mixed won't work well. */ | /* Should we support multi-line drag draws? Maybe not, more types mixed won't work well. */ | ||||
| GPU_blend(GPU_BLEND_ALPHA); | GPU_blend(GPU_BLEND_ALPHA); | ||||
| LISTBASE_FOREACH (wmDrag *, drag, &wm->drags) { | LISTBASE_FOREACH (wmDrag *, drag, &wm->drags) { | ||||
| const uchar text_col[] = {255, 255, 255, 255}; | const uchar text_col[] = {255, 255, 255, 255}; | ||||
| int iconsize = UI_DPI_ICON_SIZE; | int iconsize = UI_DPI_ICON_SIZE; | ||||
| int padding = 4 * UI_DPI_FAC; | int padding = 4 * UI_DPI_FAC; | ||||
| /* image or icon */ | /* image or icon */ | ||||
| int x, y; | int x = cursorx - 2 * padding; | ||||
| if (drag->imb) { | int y = cursory - 2 * UI_DPI_FAC; | ||||
| if (drag->no_preview) { | |||||
| /* Pass. */ | |||||
| } | |||||
| else if (drag->imb) { | |||||
| x = cursorx - drag->sx / 2; | x = cursorx - drag->sx / 2; | ||||
| y = cursory - drag->sy / 2; | y = cursory - drag->sy / 2; | ||||
| if (rect) { | if (rect) { | ||||
| drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy); | drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy); | ||||
| } | } | ||||
| else { | else { | ||||
| float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */ | float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */ | ||||
| Show All 9 Lines | else if (drag->imb) { | ||||
| drag->scale, | drag->scale, | ||||
| drag->scale, | drag->scale, | ||||
| 1.0f, | 1.0f, | ||||
| 1.0f, | 1.0f, | ||||
| col); | col); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| x = cursorx - 2 * padding; | |||||
| y = cursory - 2 * UI_DPI_FAC; | |||||
| if (rect) { | if (rect) { | ||||
| drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize); | drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize); | ||||
| } | } | ||||
| else { | else { | ||||
| UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false); | UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false); | ||||
| } | } | ||||
| } | } | ||||
| /* item name */ | /* item name */ | ||||
| if (drag->imb) { | if (!drag->no_preview && drag->imb) { | ||||
| x = cursorx - drag->sx / 2; | x = cursorx - drag->sx / 2; | ||||
| y = cursory - drag->sy / 2 - iconsize; | y = cursory - drag->sy / 2 - iconsize; | ||||
| } | } | ||||
| else { | else { | ||||
| x = cursorx + 10 * UI_DPI_FAC; | x = cursorx + 10 * UI_DPI_FAC; | ||||
| y = cursory + 1 * UI_DPI_FAC; | y = cursory + 1 * UI_DPI_FAC; | ||||
| } | } | ||||
| Show All 34 Lines | if (drag->tooltip[0]) { | ||||
| } | } | ||||
| else { | else { | ||||
| wm_drop_operator_draw(drag->tooltip, x, y); | wm_drop_operator_draw(drag->tooltip, x, y); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GPU_blend(GPU_BLEND_NONE); | GPU_blend(GPU_BLEND_NONE); | ||||
| } | } | ||||
| /* ************** Queries ***************** */ | |||||
| const wmDrag *WM_drag_with_gizmogroup_find(const wmWindowManager *wm, const char name[MAX_NAME]) | |||||
| { | |||||
| LISTBASE_FOREACH (const wmDrag *, drag, &wm->drags) { | |||||
| if (STREQ(drag->gizmo_group, name)) { | |||||
| return drag; | |||||
| } | |||||
| } | |||||
| return NULL; | |||||
| } | |||||