[Bf-blender-cvs] [9b937c8404e] blender2.8: Outliner: support dragging multiple collections, same as objects.

Brecht Van Lommel noreply at git.blender.org
Thu Aug 30 14:00:12 CEST 2018


Commit: 9b937c8404e10dab59c394bb9c838d4e8c5bf65b
Author: Brecht Van Lommel
Date:   Wed Aug 29 18:07:14 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB9b937c8404e10dab59c394bb9c838d4e8c5bf65b

Outliner: support dragging multiple collections, same as objects.

===================================================================

M	source/blender/editors/space_outliner/outliner_collections.c
M	source/blender/editors/space_outliner/outliner_dragdrop.c
M	source/blender/editors/space_outliner/outliner_intern.h

===================================================================

diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 64315120afd..34128942382 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -99,9 +99,26 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te)
 	return NULL;
 }
 
+TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata)
+{
+	struct IDsSelectedData *data = customdata;
+	TreeStoreElem *tselem = TREESTORE(te);
+
+	if (outliner_is_collection_tree_element(te)) {
+		BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
+		return TRAVERSE_CONTINUE;
+	}
+
+	if (tselem->type || (tselem->id && GS(tselem->id->name) != ID_GR)) {
+		return TRAVERSE_SKIP_CHILDS;
+	}
+
+	return TRAVERSE_CONTINUE;
+}
+
 TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
 {
-	struct ObjectsSelectedData *data = customdata;
+	struct IDsSelectedData *data = customdata;
 	TreeStoreElem *tselem = TREESTORE(te);
 
 	if (outliner_is_collection_tree_element(te)) {
@@ -112,7 +129,7 @@ TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *custom
 		return TRAVERSE_SKIP_CHILDS;
 	}
 
-	BLI_addtail(&data->objects_selected_array, BLI_genericNodeN(te));
+	BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
 
 	return TRAVERSE_CONTINUE;
 }
@@ -811,12 +828,12 @@ void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
 void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
 {
 	SpaceOops *soops = CTX_wm_space_outliner(C);
-	struct ObjectsSelectedData data = {{NULL}};
+	struct IDsSelectedData data = {{NULL}};
 	outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
-	LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
+	LISTBASE_FOREACH (LinkData *, link, &data.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);
+	BLI_freelistN(&data.selected_array);
 }
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 1c19bb4d3b8..60f02dd9529 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -883,26 +883,55 @@ static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), c
 
 	wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
 
-	if (GS(data.drag_id->name) == ID_OB) {
-		/* For objects we cheat and drag all selected objects. */
+	if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
+		/* For collections and objects we cheat and drag all selected. */
 		TREESTORE(te)->flag |= TSE_SELECTED;
 
-		struct ObjectsSelectedData selected = {
-			.objects_selected_array  = {NULL, NULL},
+		/* Gather all selected elements. */
+		struct IDsSelectedData selected = {
+			.selected_array  = {NULL, NULL},
 		};
 
-		outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected);
-		LISTBASE_FOREACH (LinkData *, link, &selected.objects_selected_array) {
-			TreeElement *ten_selected = (TreeElement *)link->data;
-			Object *ob = (Object *)TREESTORE(ten_selected)->id;
+		if (GS(data.drag_id->name) == ID_OB) {
+			outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected);
+		}
+		else {
+			outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_collections, &selected);
+		}
+
+		LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
+			TreeElement *te_selected = (TreeElement *)link->data;
+			ID *id;
+
+			if (GS(data.drag_id->name) == ID_OB) {
+				id = TREESTORE(te_selected)->id;
+			}
+			else {
+				/* Keep collection hierarchies intact when dragging. */
+				bool parent_selected = false;
+				for (TreeElement *te_parent = te_selected->parent; te_parent; te_parent = te_parent->parent) {
+					if (outliner_is_collection_tree_element(te_parent)) {
+						if (TREESTORE(te_parent)->flag & TSE_SELECTED) {
+							parent_selected = true;
+							break;
+						}
+					}
+				}
+
+				if (parent_selected) {
+					continue;
+				}
+
+				id = &outliner_collection_from_tree_element(te_selected)->id;
+			}
 
-			/* Find parent collection of object. */
+			/* Find parent collection. */
 			Collection *parent = NULL;
 
-			if (ten_selected->parent) {
-				for (TreeElement *te_ob_parent = ten_selected->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) {
-					if (outliner_is_collection_tree_element(te_ob_parent)) {
-						parent = outliner_collection_from_tree_element(te_ob_parent);
+			if (te_selected->parent) {
+				for (TreeElement *te_parent = te_selected->parent; te_parent; te_parent = te_parent->parent) {
+					if (outliner_is_collection_tree_element(te_parent)) {
+						parent = outliner_collection_from_tree_element(te_parent);
 						break;
 					}
 				}
@@ -912,10 +941,10 @@ static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), c
 				parent = BKE_collection_master(scene);
 			}
 
-			WM_drag_add_ID(drag, &ob->id, &parent->id);
+			WM_drag_add_ID(drag, id, &parent->id);
 		}
 
-		BLI_freelistN(&selected.objects_selected_array);
+		BLI_freelistN(&selected.selected_array);
 	}
 	else {
 		/* Add single ID. */
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index f8dc41b8d37..99411df3fda 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -176,10 +176,11 @@ void outliner_build_tree(
         struct Scene *scene, struct ViewLayer *view_layer,
         struct SpaceOops *soops, struct ARegion *ar);
 
-typedef struct ObjectsSelectedData {
-	struct ListBase objects_selected_array;
-} ObjectsSelectedData;
+typedef struct IDsSelectedData {
+	struct ListBase selected_array;
+} IDsSelectedData;
 
+TreeTraversalAction outliner_find_selected_collections(struct TreeElement *te, void *customdata);
 TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void *customdata);
 
 /* outliner_draw.c ---------------------------------------------- */



More information about the Bf-blender-cvs mailing list