From 25e5ec245c17c95480acbc231600d581a53702c0 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 31 May 2018 14:34:16 +0200 Subject: Support Move / Link to collection in the outliner as well --- source/blender/editors/include/ED_outliner.h | 2 + source/blender/editors/object/object_edit.c | 45 ++++++++++++++-------- .../editors/space_outliner/outliner_collections.c | 19 +++++++++ .../blender/editors/space_outliner/outliner_ops.c | 3 ++ 4 files changed, 54 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/blender/editors/include/ED_outliner.h b/source/blender/editors/include/ED_outliner.h index bb4730fab52..c1b3c3e9e1c 100644 --- a/source/blender/editors/include/ED_outliner.h +++ b/source/blender/editors/include/ED_outliner.h @@ -32,4 +32,6 @@ struct ListBase; int ED_outliner_collections_editor_poll(struct bContext *C); +void ED_outliner_selected_objects_get(const struct bContext *C, struct ListBase *objects); + #endif /* __ED_OUTLINER_H__ */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 85d62c0401f..a05b7111846 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -96,6 +96,7 @@ #include "ED_mball.h" #include "ED_lattice.h" #include "ED_object.h" +#include "ED_outliner.h" #include "ED_screen.h" #include "ED_undo.h" #include "ED_image.h" @@ -1537,6 +1538,16 @@ bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_onl #define COLLECTION_INVALID_INDEX -1 +static int move_to_collection_poll(bContext *C) +{ + if (CTX_wm_space_outliner(C) != NULL) { + return ED_outliner_collections_editor_poll(C); + } + else { + return ED_operator_object_active_editable(C); + } +} + static int move_to_collection_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -1545,6 +1556,7 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) const bool is_link = STREQ(op->idname, "OBJECT_OT_link_to_collection"); const bool is_new = RNA_boolean_get(op->ptr, "is_new"); Collection *collection; + ListBase objects = {NULL}; if (!RNA_property_is_set(op->ptr, prop)) { BKE_report(op->reports, RPT_ERROR, "No collection selected"); @@ -1558,18 +1570,16 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - Object *single_object = NULL; - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) - { - if (single_object != NULL) { - single_object = NULL; - break; - } - else { - single_object = ob; + if (CTX_wm_space_outliner(C) != NULL) { + ED_outliner_selected_objects_get(C, &objects); + } + else { + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + BLI_addtail(&objects, BLI_genericNodeN(ob)); } + CTX_DATA_END; } - CTX_DATA_END; if (is_new) { char new_collection_name[MAX_NAME]; @@ -1577,16 +1587,21 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) collection = BKE_collection_add(bmain, collection, new_collection_name); } + Object *single_object = BLI_listbase_is_single(&objects) ? + ((LinkData *)objects.first)->data : NULL; + if ((single_object != NULL) && is_link && BLI_findptr(&collection->gobject, single_object, offsetof(CollectionObject, ob))) { BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", single_object->id.name + 2, collection->id.name + 2); + BLI_freelistN(&objects); return OPERATOR_CANCELLED; } - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) - { + for (LinkData *link = objects.first; link; link = link->next) { + Object *ob = link->data; + if (!is_link) { BKE_collection_object_move(bmain, scene, collection, NULL, ob); } @@ -1594,7 +1609,7 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) BKE_collection_object_add(bmain, collection, ob); } } - CTX_DATA_END; + BLI_freelistN(&objects); BKE_reportf(op->reports, RPT_INFO, @@ -1801,7 +1816,7 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) /* api callbacks */ ot->exec = move_to_collection_exec; ot->invoke = move_to_collection_invoke; - ot->poll = ED_operator_object_active_editable; + ot->poll = move_to_collection_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1828,7 +1843,7 @@ void OBJECT_OT_link_to_collection(wmOperatorType *ot) /* api callbacks */ ot->exec = move_to_collection_exec; ot->invoke = move_to_collection_invoke; - ot->poll = ED_operator_object_active_editable; + ot->poll = move_to_collection_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index ff8868d87e7..909938ad606 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -42,6 +42,7 @@ #include "DEG_depsgraph_build.h" #include "ED_object.h" +#include "ED_outliner.h" #include "ED_screen.h" #include "WM_api.h" @@ -695,3 +696,21 @@ void OUTLINER_OT_collection_include_set(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/** + * Populates the \param objects ListBase with all the outliner selected objects + * We store it as (Object *)LinkData->data + * \param objects expected to be empty + */ +void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + struct ObjectsSelectedData data = {{NULL}}; + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); + LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + TreeElement *ten_selected = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(ten_selected)->id; + BLI_addtail(objects, BLI_genericNodeN(ob)); + } + BLI_freelistN(&data.objects_selected_array); +} diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 9c1b9bf2630..a5a7067cd8e 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -557,6 +557,9 @@ void outliner_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "OUTLINER_OT_collection_new", CKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "OUTLINER_OT_collection_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0); + outliner_item_drag_drop_modal_keymap(keyconf); } -- cgit v1.2.3