[Bf-blender-cvs] [910b7dec8d] blender2.8: UI: Support drag & drop reordering of collections

Julian Eisel noreply at git.blender.org
Wed Feb 22 17:27:00 CET 2017


Commit: 910b7dec8dca25473d98c23f7c4fd8e44fafd47d
Author: Julian Eisel
Date:   Wed Feb 22 16:02:43 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB910b7dec8dca25473d98c23f7c4fd8e44fafd47d

UI: Support drag & drop reordering of collections

This adds initial support for reordering collections from the Outliner
using drag & drop.
Although drag & drop support is limited to collections for now, this
lays most foundations for general drag & drop reordering support in the
Outliner. There are some design questions to be answered though:
* Would reordering of other data types (like objects) be a purely visual change or would it affect the order in which they are stored? (Would that make a difference for the user?)
* Should/can we allow mixing of different data types? (e.g. mixing render layers with objects)
* How could we realize this technically?

Notes:
* "Sort Alphabetically" has to be disabled to use this ("View" menu).
* Reordering only works with collections on the same hierarchy level.
* Added some visual feedback that should work quite well, it's by far not a final design though: {F493806}
* Modified collection orders are stored in .blends.
* Reordering can be undone.
* Did minor cleanups here and there.

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

M	source/blender/blenkernel/BKE_collection.h
M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/layer.c
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c
M	source/blender/editors/space_outliner/outliner_tree.c

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

diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 4d5de723dc..644bcef622 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -44,7 +44,7 @@ struct Scene;
 
 struct SceneCollection *BKE_collection_add(struct Scene *scene, struct SceneCollection *sc_parent, const char *name);
 bool BKE_collection_remove(struct Scene *scene, struct SceneCollection *sc);
-struct SceneCollection *BKE_collection_master(struct Scene *scene);
+struct SceneCollection *BKE_collection_master(const struct Scene *scene);
 void BKE_collection_master_free(struct Scene *scene);
 void BKE_collection_object_add(struct Scene *scene, struct SceneCollection *sc, struct Object *object);
 void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 641cc969e7..d208cee5b4 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -54,7 +54,7 @@ struct Scene;
 struct SceneCollection;
 struct SceneLayer;
 
-struct SceneLayer *BKE_scene_layer_render_active(struct Scene *scene);
+struct SceneLayer *BKE_scene_layer_render_active(const struct Scene *scene);
 struct SceneLayer *BKE_scene_layer_context_active(struct Scene *scene);
 struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
 
@@ -84,6 +84,8 @@ struct LayerCollection *BKE_layer_collection_active(struct SceneLayer *sl);
 int BKE_layer_collection_count(struct SceneLayer *sl);
 
 int BKE_layer_collection_findindex(struct SceneLayer *sl, struct LayerCollection *lc);
+void BKE_layer_collection_reinsert_after(const struct Scene *scene, struct SceneLayer *sl,
+                                         struct LayerCollection *lc_reinsert, struct LayerCollection *lc_after);
 
 struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
 
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 100cbf2dd4..24f97c00af 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -44,6 +44,9 @@
 
 #include "MEM_guardedalloc.h"
 
+bool collection_remlink(SceneCollection *, SceneCollection *);
+bool collection_insert_after(SceneCollection *, SceneCollection *, SceneCollection *);
+
 /**
  * Add a collection to a collection ListBase and syncronize all render layers
  * The ListBase is NULL when the collection is to be added to the master collection
@@ -95,7 +98,7 @@ static void collection_free(SceneCollection *sc)
  * Unlink the collection recursively
  * return true if unlinked
  */
-static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
+bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
 {
 	for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next)
 	{
@@ -174,9 +177,35 @@ bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
 }
 
 /**
+ * Lookup the parent listbase of \a sc_insert_after and insert \a sc_insert after it.
+ * \param sc_after: If this is NULL, \a sc_insert will be inserted as first collection in \a parent.
+ */
+bool collection_insert_after(
+        SceneCollection *parent, SceneCollection *sc_insert, SceneCollection *sc_after)
+{
+	if (sc_after == NULL) {
+		BLI_addhead(&parent->scene_collections, sc_insert);
+		return true;
+	}
+
+	for (SceneCollection *sc = parent->scene_collections.first; sc; sc = sc->next) {
+		if (sc == sc_after) {
+			BLI_insertlinkafter(&parent->scene_collections, sc_after, sc_insert);
+			return true;
+		}
+
+		if (collection_insert_after(sc, sc_insert, sc_after)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
  * Returns the master collection
  */
-SceneCollection *BKE_collection_master(Scene *scene)
+SceneCollection *BKE_collection_master(const Scene *scene)
 {
 	return scene->collection;
 }
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 621ac51aba..3653a9ac65 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -66,7 +66,7 @@ static void object_bases_Iterator_next(Iterator *iter, const int flag);
  * Returns the SceneLayer to be used for rendering
  * Most of the time BKE_scene_layer_context_active should be used instead
  */
-SceneLayer *BKE_scene_layer_render_active(Scene *scene)
+SceneLayer *BKE_scene_layer_render_active(const Scene *scene)
 {
 	SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
 	BLI_assert(sl);
@@ -492,6 +492,71 @@ int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
 }
 
 /**
+ * \param lc_after: Can be NULL to insert \a lc_after as first collection in \a lb.
+ */
+static bool layer_collection_insert_after(ListBase *lb, LayerCollection *lc_insert, LayerCollection *lc_after)
+{
+	if (lc_after == NULL) {
+		BLI_addhead(lb, lc_insert);
+		return true;
+	}
+
+	for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+		if (lc == lc_after) {
+			BLI_insertlinkafter(lb, lc_after, lc_insert);
+			return true;
+		}
+
+		if (layer_collection_insert_after(&lc->layer_collections, lc_insert, lc_after)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool layer_collection_remlink(ListBase *lb, LayerCollection *lc)
+{
+	for (LayerCollection *lc_iter = lb->first; lc_iter; lc_iter = lc_iter->next) {
+		if (lc_iter == lc) {
+			BLI_remlink(lb, lc);
+			return true;
+		}
+
+		if (layer_collection_remlink(&lc_iter->layer_collections, lc)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * Move \a lc_reinsert so that it follows \a lc_after. After this, both \a lc_reinsert
+ * and \a lc_after should be stored in the same list.
+ *
+ * \param lc_after: Can be NULL to insert \a lc_after as first collection in \a sl.
+ */
+void BKE_layer_collection_reinsert_after(
+        const Scene *scene, SceneLayer *sl, LayerCollection *lc_reinsert, LayerCollection *lc_after)
+{
+	/* XXX maybe worth having a BKE internal header file for this? */
+	extern bool collection_remlink(SceneCollection *, SceneCollection *);
+	extern bool collection_insert_after(SceneCollection *, SceneCollection *, SceneCollection *);
+
+	SceneCollection *sc_master = BKE_collection_master(scene);
+
+	layer_collection_remlink(&sl->layer_collections, lc_reinsert);
+	collection_remlink(sc_master, lc_reinsert->scene_collection);
+
+	layer_collection_insert_after(&sl->layer_collections, lc_reinsert, lc_after);
+	collection_insert_after(sc_master, lc_reinsert->scene_collection, lc_after ? lc_after->scene_collection : NULL);
+
+	BKE_scene_layer_base_flag_recalculate(sl);
+	BKE_scene_layer_engine_settings_collection_recalculate(sl, lc_reinsert);
+}
+
+/**
  * Link a collection to a renderlayer
  * The collection needs to be created separately
  */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 945ac1b6db..cee68ed361 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -66,6 +66,7 @@ void UI_id_icon_render(
 int UI_preview_render_size(enum eIconSizes size);
 
 void UI_icon_draw(float x, float y, int icon_id);
+void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha);
 void UI_icon_draw_preview(float x, float y, int icon_id);
 void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect);
 void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, float alpha, int size);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index f61eb99a62..7d87527bda 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1432,6 +1432,11 @@ void UI_icon_draw(float x, float y, int icon_id)
 	UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f);
 }
 
+void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
+{
+	UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, alpha);
+}
+
 void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
 {
 	icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, ICON_SIZE_ICON, size, true, false);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index d15c3d67d4..48a2107560 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -663,6 +663,7 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
 	float miny = v2d->cur.ymin;
 	if (miny < v2d->tot.ymin) miny = v2d->tot.ymin;
 
+	glLineWidth(1.0f);
 	UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
 
 	/* draw column separator lines */
@@ -772,7 +773,7 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
 	/* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */
 	if (arg->x >= arg->xmax) {
 		glEnable(GL_BLEND);
-		UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha);
+		UI_icon_draw_alpha(arg->x, arg->y, icon, arg->alpha);
 		glDisable(GL_BLEND);
 	}
 	else {
@@ -835,189 +836,258 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
 	arg.xb = x;	/* for ui buttons */
 	arg.yb = y;
 	arg.alpha = alpha;
-	
+
 	/* placement of icons, copied from interface_widgets.c */
 	aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
 	arg.x = x = x + 4.0f * aspect;
 	arg.y = y = y + 0.1f * UI_UNIT_Y;
 
+#define ICON_DRAW(_icon) UI_icon_draw_alpha(x, y, _icon, alpha)
+
 	if (tselem->type) {
 		switch (tselem->type) {
 			case TSE_ANIM_DATA:
-				UI_icon_draw(x, y, ICON_ANIM_DATA); break; // xxx
+				ICON_DRAW(ICON_ANIM_DATA); /* XXX */
+				break;
 			case TSE_NLA:
-				UI_icon_draw(x, y, ICON_NLA); break;
+				ICON_DRAW(ICON_NLA);
+				break;
 			case TSE_NLA_TRACK:
-				UI_icon_draw(x, y, ICON_NLA); break; // XXX
+				ICON_DRAW(ICON_NLA); /* XXX */
+				break;
 			case

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list