diff options
-rw-r--r-- | source/blender/editors/space_console/space_console.c | 15 | ||||
-rw-r--r-- | source/blender/editors/space_node/space_node.c | 19 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_dragdrop.c | 642 | ||||
-rw-r--r-- | source/blender/editors/space_text/space_text.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 33 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 21 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 73 |
8 files changed, 324 insertions, 487 deletions
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index ce87ad3b177..3429d726349 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -172,29 +172,22 @@ static void console_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { -// SpaceConsole *sc = CTX_wm_space_console(C); - if (drag->type == WM_DRAG_ID) - return 1; - return 0; + return WM_drag_ID(drag, 0) != NULL; } static void id_drop_copy(wmDrag *drag, wmDropBox *drop) { - char *text; - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); /* copy drag path to properties */ - text = RNA_path_full_ID_py(id); + char *text = RNA_path_full_ID_py(id); RNA_string_set(drop->ptr, "text", text); MEM_freeN(text); } static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - // SpaceConsole *sc = CTX_wm_space_console(C); - if (drag->type == WM_DRAG_PATH) - return 1; - return 0; + return (drag->type == WM_DRAG_PATH); } static void path_drop_copy(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 74c036883e6..2b2e659d151 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -677,26 +677,17 @@ static void node_main_region_draw(const bContext *C, ARegion *ar) static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_IM) - return 1; + if (drag->type == WM_DRAG_PATH) { + return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */ } - else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ - return 1; + else { + return WM_drag_ID(drag, ID_IM) != NULL; } - return 0; } static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MSK) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_MSK) != NULL; } static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index c53a431a017..f9a4fda0c45 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -39,6 +39,7 @@ #include "DNA_space_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BLT_translation.h" @@ -105,64 +106,77 @@ static TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float f return NULL; } -/* ******************** Parent Drop Operator *********************** */ - -static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) +static TreeElement *outliner_drop_find(bContext *C, const wmEvent *event) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); float fmval[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + return outliner_dropzone_find(soops, fmval, true); +} - if (!te) { - /* pass */ - } - else if (te->idcode == ID_OB && tselem->type == 0) { - Scene *scene; - ID *te_id = tselem->id; - - /* check if dropping self or parent */ - if (te_id == id || (Object *)te_id == ((Object *)id)->parent) - return 0; - - /* check that parent/child are both in the same scene */ - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - - /* currently outliner organized in a way that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ - if (!scene) { - return 1; - } - else { - for (ViewLayer *view_layer = scene->view_layers.first; - view_layer; - view_layer = view_layer->next) - { - if (BKE_view_layer_base_find(view_layer, (Object *)id)) { - return 1; - } - } - } - } - } +static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode) +{ + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = (te) ? TREESTORE(te) : NULL; + + if (te && te->idcode == idcode && tselem->type == 0) { + return tselem->id; + } + else { + return NULL; } - return 0; } -static void parent_drop_copy(wmDrag *drag, wmDropBox *drop) +/* ******************** Parent Drop Operator *********************** */ + +static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ID *id = drag->poin; + SpaceOops *soops = CTX_wm_space_outliner(C); + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + if (!ob) { + return false; + } + + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + + if (!te) { + /* pass */ + } + else if (te->idcode == ID_OB && tselem->type == 0) { + Scene *scene; + ID *te_id = tselem->id; + + /* check if dropping self or parent */ + if (te_id == &ob->id || (Object *)te_id == ob->parent) + return false; + + /* check that parent/child are both in the same scene */ + scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + + /* currently outliner organized in a way that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + if (!scene) { + return true; + } + else { + for (ViewLayer *view_layer = scene->view_layers.first; + view_layer; + view_layer = view_layer->next) + { + if (BKE_view_layer_base_find(view_layer, ob)) { + return true; + } + } + } + } - RNA_string_set(drop->ptr, "child", id->name + 2); + return false; } static int parent_drop_exec(bContext *C, wmOperator *op) @@ -195,131 +209,121 @@ static int parent_drop_exec(bContext *C, wmOperator *op) static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Object *par = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - Scene *scene = NULL; - TreeElement *te = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + + if (!(te && te->idcode == ID_OB && tselem->type == 0)) { + return OPERATOR_CANCELLED; + } + + Object *par = (Object *)tselem->id; + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + + if (ELEM(NULL, ob, par)) { + return OPERATOR_CANCELLED; + } + if (ob == par) { + return OPERATOR_CANCELLED; + } + if (ID_IS_LINKED(ob)) { + BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); + return OPERATOR_CANCELLED; + } + char childname[MAX_ID_NAME]; char parname[MAX_ID_NAME]; - int partype = 0; - float fmval[2]; + STRNCPY(childname, ob->id.name); + STRNCPY(parname, par->id.name); + RNA_string_set(op->ptr, "child", childname); + RNA_string_set(op->ptr, "parent", parname); - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); + if (scene == NULL) { + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ - if (te) { - RNA_string_set(op->ptr, "parent", te->name); - /* Identify parent and child */ - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); - - if (ELEM(NULL, ob, par)) { - if (par == NULL) printf("par==NULL\n"); - return OPERATOR_CANCELLED; - } - if (ob == par) { - return OPERATOR_CANCELLED; - } - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; + scene = CTX_data_scene(C); + } + + if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { + int partype = 0; + if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); } + } + else { + /* Menu creation */ + wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); + PointerRNA ptr; + + /* Cannot use uiItemEnumO()... have multiple properties to set. */ + uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_OBJECT); + + /* par becomes parent, make the associated menus */ + if (par->type == OB_ARMATURE) { + uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE); - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - if (scene == NULL) { - /* currently outlier organized in a way, that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ + uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - scene = CTX_data_scene(C); - } + uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { - if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); - } + uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_BONE); } - else { - /* Menu creation */ - wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); - uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); - uiLayout *layout = UI_popup_menu_layout(pup); - PointerRNA ptr; - - /* Cannot use uiItemEnumO()... have multiple properties to set. */ - uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + else if (par->type == OB_CURVE) { + uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_OBJECT); - - /* par becomes parent, make the associated menus */ - if (par->type == OB_ARMATURE) { - uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - - uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_BONE); - } - else if (par->type == OB_CURVE) { - uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_CURVE); - - uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_FOLLOW); - - uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_PATH_CONST); - } - else if (par->type == OB_LATTICE) { - uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_LATTICE); - } + RNA_enum_set(&ptr, "type", PAR_CURVE); - UI_popup_menu_end(C, pup); + uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_FOLLOW); - return OPERATOR_INTERFACE; + uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_PATH_CONST); } - } - else { - return OPERATOR_CANCELLED; + else if (par->type == OB_LATTICE) { + uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_LATTICE); + } + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; } return OPERATOR_FINISHED; @@ -369,64 +373,42 @@ static bool parenting_poll(bContext *C) static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te = NULL; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) { return false; } - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - if (((Object *)id)->parent) { - if ((te = outliner_dropzone_find(soops, fmval, true))) { - TreeStoreElem *tselem = TREESTORE(te); - - switch (te->idcode) { - case ID_SCE: - return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); - case ID_OB: - return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); - /* Other codes to ignore? */ - } - } - return (te == NULL); - } - } + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + if (!(ob && ob->parent)) { + return false; } - return 0; -} - -static void parent_clear_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "dragged_obj", id->name + 2); - /* Set to simple parent clear type. Avoid menus for drag and drop if possible. - * If desired, user can toggle the different "Clear Parent" types in the operator - * menu on tool shelf. */ - RNA_enum_set(drop->ptr, "type", 0); + TreeElement *te = outliner_drop_find(C, event); + if (te) { + TreeStoreElem *tselem = TREESTORE(te); + + switch (te->idcode) { + case ID_SCE: + return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); + case ID_OB: + return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); + /* Other codes to ignore? */ + } + } + return (te == NULL); } -static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { Main *bmain = CTX_data_main(C); - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - char obname[MAX_ID_NAME]; + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); - RNA_string_get(op->ptr, "dragged_obj", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - /* search forwards to find the object */ - outliner_find_id(soops, &soops->tree, (ID *)ob); + if (ob == NULL) { + return OPERATOR_CANCELLED; + } - ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); + ED_object_parent_clear(ob, 0); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -448,97 +430,55 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); } /* ******************** Scene Drop Operator *********************** */ static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, false); - return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0); - } - } - return 0; -} - -static void scene_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "object", id->name + 2); + /* Ensure item under cursor is valid drop target */ + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL)); } -static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - Scene *scene = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - TreeElement *te = NULL; - char obname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, false); + Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE); + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); - if (te) { - RNA_string_set(op->ptr, "scene", te->name); - scene = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, te->name); - - RNA_string_get(op->ptr, "object", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { - return OPERATOR_CANCELLED; - } + if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { + return OPERATOR_CANCELLED; + } - if (BKE_scene_has_object(scene, ob)) { - return OPERATOR_CANCELLED; - } + if (BKE_scene_has_object(scene, ob)) { + return OPERATOR_CANCELLED; + } - Collection *collection; - if (scene != CTX_data_scene(C)) { - /* when linking to an inactive scene link to the master collection */ - collection = BKE_collection_master(scene); - } - else { - collection = CTX_data_collection(C); - } + Collection *collection; + if (scene != CTX_data_scene(C)) { + /* when linking to an inactive scene link to the master collection */ + collection = BKE_collection_master(scene); + } + else { + collection = CTX_data_collection(C); + } - BKE_collection_object_add(bmain, collection, ob); + BKE_collection_object_add(bmain, collection, ob); - for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { - Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base) { - ED_object_base_select(base, BA_SELECT); - } + for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base) { + ED_object_base_select(base, BA_SELECT); } + } - DEG_relations_tag_update(bmain); - - DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); - WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); + DEG_relations_tag_update(bmain); - return OPERATOR_FINISHED; - } + DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OUTLINER_OT_scene_drop(wmOperatorType *ot) @@ -555,75 +495,33 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene"); } /* ******************** Material Drop Operator *********************** */ static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MA) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0); - } - } - return 0; + /* Ensure item under cursor is valid drop target */ + Material *ma = (Material *)WM_drag_ID(drag, ID_MA); + return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL)); } -static void material_drop_copy(wmDrag *drag, wmDropBox *drop) +static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "material", id->name + 2); -} - -static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Material *ma = NULL; - Object *ob = NULL; Main *bmain = CTX_data_main(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - TreeElement *te = NULL; - char mat_name[MAX_ID_NAME - 2]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); - - if (te) { - RNA_string_set(op->ptr, "object", te->name); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, te->name); + Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB); + Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA); - RNA_string_get(op->ptr, "material", mat_name); - ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, mat_name); - - if (ELEM(NULL, ob, ma)) { - return OPERATOR_CANCELLED; - } - - assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); + if (ELEM(NULL, ob, ma)) { + return OPERATOR_CANCELLED; + } - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); + assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); - return OPERATOR_FINISHED; - } + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OUTLINER_OT_material_drop(wmOperatorType *ot) @@ -640,80 +538,28 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material"); } /* ******************** Collection Drop Operator *********************** */ static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + Collection *collection = (Collection *)WM_drag_ID(drag, ID_GR); - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (ELEM(GS(id->name), ID_OB, ID_GR)) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && outliner_is_collection_tree_element(te)); - } + if (ob || collection) { + TreeElement *te = outliner_drop_find(C, event); + return (te && outliner_is_collection_tree_element(te)); } - return 0; -} - -static void collection_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "child", id->name + 2); -} - -static int collection_drop_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) -{ - /* TODO: implement */ -#if 0 - Object *par = NULL, *ob = NULL; - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - int partype = -1; - char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; - - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(ID_OB, parname); - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(ID_OB, childname); - - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; + else { + return false; } - - ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); - - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); -#endif - - return OPERATOR_FINISHED; } -static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - char childname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); + TreeElement *te = outliner_drop_find(C, event); if (!te || !outliner_is_collection_tree_element(te)) { return OPERATOR_CANCELLED; @@ -724,9 +570,11 @@ static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *ev // TODO: don't use scene, makes no sense anymore // TODO: move rather than link, change hover text Scene *scene = BKE_scene_find_from_collection(bmain, collection); - BLI_assert(scene); - RNA_string_get(op->ptr, "child", childname); - Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + if (ELEM(NULL, ob, scene, collection)) { + return OPERATOR_CANCELLED; + } + BKE_collection_object_add(bmain, collection, ob); DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); @@ -745,16 +593,10 @@ void OUTLINER_OT_collection_drop(wmOperatorType *ot) /* api callbacks */ ot->invoke = collection_drop_invoke; - ot->exec = collection_drop_exec; - ot->poll = ED_operator_outliner_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_string(ot->srna, "parent", "Collection", MAX_ID_NAME, "Parent", "Parent Collection"); } /* ********************* Outliner Drag Operator ******************** */ @@ -1107,9 +949,9 @@ void outliner_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, parent_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, parent_clear_copy); - WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, scene_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, material_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, collection_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL); } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 53272ee9ed9..469e1b84c29 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -493,10 +493,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop) static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) - return true; - - return false; + return (drag->type == WM_DRAG_ID); } static void text_drop_paste(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 62adca6af6b..68ea59859da 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -556,46 +556,27 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar) static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_OB) != NULL; } static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_GR) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_GR) != NULL; } static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MA) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_MA) != NULL; } static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_IM) - return 1; + if (drag->type == WM_DRAG_PATH) { + return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */ } - else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ - return 1; + else { + return WM_drag_ID(drag, ID_IM) != NULL; } - return 0; } static bool view3d_ima_bg_is_camera_view(bContext *C) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 3521c4d1bd5..d175b11fe5c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -484,6 +484,9 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx void WM_drag_free(struct wmDrag *drag); void WM_drag_free_list(struct ListBase *lb); +struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode); +struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode); + struct wmDropBox *WM_dropbox_add( ListBase *lb, const char *idname, bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 0ae51cc922b..6b9a7fb5430 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -189,6 +189,27 @@ void WM_drag_free_list(struct ListBase *lb) } } + +ID *WM_drag_ID(const wmDrag *drag, short idcode) +{ + if (drag->type != WM_DRAG_ID) { + return NULL; + } + + ID *id = drag->poin; + return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; +} + +ID *WM_drag_ID_from_event(const wmEvent *event, short idcode) +{ + if (event->custom != EVT_DATA_DRAGDROP) { + return NULL; + } + + ListBase *lb = event->customdata; + return WM_drag_ID(lb->first, idcode); +} + static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, const wmEvent *event) { wmEventHandler *handler = handlers->first; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5d343c5e0fe..0581d41ea04 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -98,7 +98,7 @@ static void wm_notifier_clear(wmNotifier *note); static void update_tablet_data(wmWindow *win, wmEvent *event); static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only); + const short context, const bool poll_only, wmEvent *event); /* ************ event management ************** */ @@ -638,7 +638,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot) /* sets up the new context and calls 'wm_operator_invoke()' with poll_only */ bool WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context) { - return wm_operator_call_internal(C, ot, NULL, NULL, context, true); + return wm_operator_call_internal(C, ot, NULL, NULL, context, true, NULL); } bool WM_operator_check_ui_empty(wmOperatorType *ot) @@ -1431,10 +1431,8 @@ static int wm_operator_invoke( */ static int wm_operator_call_internal( bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only) + const short context, const bool poll_only, wmEvent *event) { - wmEvent *event; - int retval; CTX_wm_operator_poll_msg_set(C, NULL); @@ -1443,27 +1441,29 @@ static int wm_operator_call_internal( if (ot) { wmWindow *window = CTX_wm_window(C); - switch (context) { - case WM_OP_INVOKE_DEFAULT: - case WM_OP_INVOKE_REGION_WIN: - case WM_OP_INVOKE_REGION_PREVIEW: - case WM_OP_INVOKE_REGION_CHANNELS: - case WM_OP_INVOKE_AREA: - case WM_OP_INVOKE_SCREEN: - /* window is needed for invoke, cancel operator */ - if (window == NULL) { - if (poll_only) { - CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + if (event == NULL) { + switch (context) { + case WM_OP_INVOKE_DEFAULT: + case WM_OP_INVOKE_REGION_WIN: + case WM_OP_INVOKE_REGION_PREVIEW: + case WM_OP_INVOKE_REGION_CHANNELS: + case WM_OP_INVOKE_AREA: + case WM_OP_INVOKE_SCREEN: + /* window is needed for invoke, cancel operator */ + if (window == NULL) { + if (poll_only) { + CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + } + return 0; } - return 0; - } - else { - event = window->eventstate; - } - break; - default: - event = NULL; - break; + else { + event = window->eventstate; + } + break; + default: + event = NULL; + break; + } } switch (context) { @@ -1561,7 +1561,7 @@ static int wm_operator_call_internal( int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties) { BLI_assert(ot == WM_operatortype_find(ot->idname, true)); - return wm_operator_call_internal(C, ot, properties, NULL, context, false); + return wm_operator_call_internal(C, ot, properties, NULL, context, false, NULL); } int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties) { @@ -1627,7 +1627,7 @@ int WM_operator_call_py( wmWindowManager *wm = CTX_wm_manager(C); if (!is_undo && wm) wm->op_undo_depth++; - retval = wm_operator_call_internal(C, ot, properties, reports, context, false); + retval = wm_operator_call_internal(C, ot, properties, reports, context, false, NULL); if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--; @@ -2370,17 +2370,26 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers for (drag = lb->first; drag; drag = drag->next) { const char *tooltip = NULL; if (drop->poll(C, drag, event, &tooltip)) { - drop->copy(drag, drop); + /* Optionally copy drag information to operator properties. */ + if (drop->copy) { + drop->copy(drag, drop); + } - /* free the drags before calling operator */ + /* Pass single matched wmDrag onto the operator. */ + BLI_remlink(lb, drag); + ListBase single_lb = {drag, drag}; + event->customdata = &single_lb; + + wm_operator_call_internal(C, drop->ot, drop->ptr, NULL, drop->opcontext, false, event); + action |= WM_HANDLER_BREAK; + + /* free the drags */ WM_drag_free_list(lb); + WM_drag_free_list(&single_lb); event->customdata = NULL; event->custom = 0; - WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr); - action |= WM_HANDLER_BREAK; - /* XXX fileread case */ if (CTX_wm_window(C) == NULL) return action; |