[Bf-blender-cvs] [3c39c51d021] soc-2020-outliner: Outliner: Object drop initial implementation
Nathan Craddock
noreply at git.blender.org
Thu Jul 9 21:42:35 CEST 2020
Commit: 3c39c51d0211210ea04c5e91a4d2f8181f1e5745
Author: Nathan Craddock
Date: Thu Jul 9 13:40:58 2020 -0600
Branches: soc-2020-outliner
https://developer.blender.org/rB3c39c51d0211210ea04c5e91a4d2f8181f1e5745
Outliner: Object drop initial implementation
Allow reordering objects in the outliner. Works for multiple selection.
The code has a few places that could be cleaned up.
Also, an issue exists where it isn't always clear where to move the
objects to. This applies to any outliner drag+drop so that will be
handled separately.
===================================================================
M source/blender/blenkernel/BKE_collection.h
M source/blender/blenkernel/intern/collection.c
M source/blender/editors/space_outliner/outliner_dragdrop.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 4cf33640ebd..bdb9ca7afa7 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -97,6 +97,9 @@ void BKE_collection_object_move(struct Main *bmain,
struct Collection *collection_dst,
struct Collection *collection_src,
struct Object *ob);
+void BKE_collection_object_move_after(struct Collection *collection,
+ struct Object *ob_relative,
+ struct Object *ob);
bool BKE_scene_collections_object_remove(struct Main *bmain,
struct Scene *scene,
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 7e22048379b..22c254684bb 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1084,6 +1084,33 @@ void BKE_collection_object_move(
}
}
+/**
+ * Move object within a collection after specified object.
+ *
+ * For outliner drag & drop.
+ */
+void BKE_collection_object_move_after(Collection *collection, Object *ob_relative, Object *ob)
+{
+ if (ELEM(NULL, collection, ob_relative, ob)) {
+ return;
+ }
+
+ CollectionObject *relative = BLI_findptr(
+ &collection->gobject, ob_relative, offsetof(CollectionObject, ob));
+ if (!relative) {
+ return;
+ }
+ int index_to = BLI_findindex(&collection->gobject, relative);
+
+ CollectionObject *object = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
+ if (!object) {
+ return;
+ }
+ int index_from = BLI_findindex(&collection->gobject, object);
+
+ BLI_listbase_move_index(&collection->gobject, index_from, index_to);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index aa5842fafc5..9d70cc13286 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -66,6 +66,8 @@
#include "outliner_intern.h"
+static Collection *collection_parent_from_ID(ID *id);
+
/* ******************** Drop Data Functions *********************** */
typedef struct OutlinerDropData {
@@ -297,11 +299,11 @@ static bool parent_drop_allowed(TreeElement *te, Object *potential_child)
static bool parent_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(r_tooltip))
+ const char **r_tooltip)
{
SpaceOutliner *soops = CTX_wm_space_outliner(C);
- bool changed = outliner_flag_set(&soops->tree, TSE_DRAG_ANY, false);
+ bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
if (changed) {
ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
}
@@ -311,18 +313,39 @@ static bool parent_drop_poll(bContext *C,
return false;
}
- TreeElement *te = outliner_drop_find(C, event);
+ TreeElementInsertType insert_type;
+ TreeElement *te = outliner_drop_insert_find(C, event, &insert_type);
if (!te) {
return false;
}
+ TreeStoreElem *tselem = TREESTORE(te);
- if (parent_drop_allowed(te, potential_child)) {
- TREESTORE(te)->flag |= TSE_DRAG_INTO;
- ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
- return true;
+ if (soops->sort_method != SO_SORT_FREE || soops->outlinevis != SO_VIEW_LAYER) {
+ insert_type = TE_INSERT_INTO;
}
- return false;
+ if (!parent_drop_allowed(te, potential_child)) {
+ return false;
+ }
+
+ switch (insert_type) {
+ case TE_INSERT_BEFORE:
+ tselem->flag |= TSE_DRAG_BEFORE;
+ *r_tooltip = TIP_("Reorder object");
+ break;
+ case TE_INSERT_AFTER:
+ tselem->flag |= TSE_DRAG_AFTER;
+ *r_tooltip = TIP_("Reorder object");
+ break;
+ case TE_INSERT_INTO:
+ tselem->flag |= TSE_DRAG_INTO;
+ break;
+ }
+
+ TREESTORE(te)->flag |= TSE_DRAG_INTO;
+ ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
+
+ return true;
}
static void parent_drop_set_parents(bContext *C,
@@ -378,9 +401,51 @@ static void parent_drop_set_parents(bContext *C,
}
}
+static void parent_drop_move_objects(bContext *C, wmDragID *drag, TreeElement *te)
+{
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ Scene *scene = (Scene *)outliner_search_back(te, ID_SCE);
+ if (scene == NULL) {
+ scene = CTX_data_scene(C);
+ }
+
+ Object *ob_drop = (Object *)TREESTORE(te)->id;
+ Collection *collection_to = collection_parent_from_ID(&ob_drop->id);
+ while (te) {
+ te = te->parent;
+ if (outliner_is_collection_tree_element(te)) {
+ collection_to = outliner_collection_from_tree_element(te);
+ break;
+ }
+ }
+
+ for (wmDragID *drag_id = drag; drag_id; drag_id = drag_id->next) {
+ if (GS(drag_id->id->name) == ID_OB) {
+ Object *object = (Object *)drag_id->id;
+
+ /* Do nothing to linked data */
+ if (ID_IS_LINKED(object)) {
+ continue;
+ }
+
+ Collection *from = collection_parent_from_ID(drag_id->from_parent);
+ BKE_collection_object_move(bmain, scene, collection_to, from, object);
+ BKE_collection_object_move_after(collection_to, ob_drop, object);
+ }
+ }
+
+ 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);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
+}
+
static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- TreeElement *te = outliner_drop_find(C, event);
+ TreeElementInsertType insert_type;
+ TreeElement *te = outliner_drop_insert_find(C, event, &insert_type);
TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
if (!(te && te->idcode == ID_OB && tselem->type == 0)) {
@@ -404,7 +469,17 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ListBase *lb = event->customdata;
wmDrag *drag = lb->first;
- parent_drop_set_parents(C, op->reports, drag->ids.first, par, PAR_OBJECT, event->alt);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ if (soops->sort_method != SO_SORT_FREE || soops->outlinevis != SO_VIEW_LAYER) {
+ insert_type = TE_INSERT_INTO;
+ }
+
+ if (insert_type == TE_INSERT_INTO) {
+ parent_drop_set_parents(C, op->reports, drag->ids.first, par, PAR_OBJECT, event->alt);
+ }
+ else {
+ parent_drop_move_objects(C, drag->ids.first, te);
+ }
return OPERATOR_FINISHED;
}
More information about the Bf-blender-cvs
mailing list