Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2017-03-02 19:11:09 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-03-02 19:15:30 +0300
commit0322700d875a1d518a730512531a881f1278124b (patch)
treeb668e69e366d6621256603c3ef7f8dc4219ab3af /source
parent146a88dd60aa20b526ecae2f3f4c2512e1f4d4f0 (diff)
Get UI ready for using drag & drop to nest a collection into another one
Nothing happen yet when it's supposed to insert the collection into another one, that part will be handled by @dfelinto. See gif for demo of how it works UI wise: {F500337} Also fixed off-by-one error in utility function.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_layer.h1
-rw-r--r--source/blender/blenkernel/intern/layer.c11
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h11
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c38
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c2
7 files changed, 81 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 863f33dea8d..aa1d537a28e 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -86,6 +86,7 @@ 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);
+void BKE_layer_collection_reinsert_into(struct LayerCollection *lc_reinsert, struct LayerCollection *lc_into);
struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 605705c483a..77501c4acce 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -536,6 +536,10 @@ static ListBase *scene_collection_listbase_find(ListBase *lb, SceneCollection *s
void BKE_layer_collection_reinsert_after(
const Scene *scene, SceneLayer *sl, LayerCollection *lc_reinsert, LayerCollection *lc_after)
{
+ /* TODO this function probably needs to be rewritten completely to support all cases
+ * (reinserting master collection, reinsert into different hierarchy levels, etc) */
+ TODO_LAYER_OPERATORS;
+
SceneCollection *sc_master = BKE_collection_master(scene);
SceneCollection *sc_reinsert = lc_reinsert->scene_collection;
ListBase *lc_reinsert_lb = layer_collection_listbase_find(&sl->layer_collections, lc_reinsert);
@@ -564,6 +568,13 @@ void BKE_layer_collection_reinsert_after(
BKE_scene_layer_engine_settings_collection_recalculate(sl, lc_reinsert);
}
+void BKE_layer_collection_reinsert_into(LayerCollection *lc_reinsert, LayerCollection *lc_into)
+{
+ /* TODO this is missing */
+ TODO_LAYER_OPERATORS;
+ UNUSED_VARS(lc_reinsert, lc_into);
+}
+
/**
* Link a collection to a renderlayer
* The collection needs to be created separately
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 990ad296bb9..816740b8769 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1540,7 +1540,7 @@ static int outliner_count_visible_childs(const SpaceOops *soops, const TreeEleme
static void outliner_draw_tree_element_floating(const SpaceOops *soops, const ARegion *ar,
const TreeElement *te_floating)
{
- const TreeElement *te_insert = te_floating->drag_data->insert_te;
+ const TreeElement *te_insert = te_floating->drag_data->insert_handle;
const ListBase *lb_parent = te_floating->parent ? &te_floating->parent->subtree : &soops->tree;
const TreeElement *te_insert_fallback = te_insert ? te_insert : lb_parent->first;
const int line_width = 2;
@@ -1560,14 +1560,30 @@ static void outliner_draw_tree_element_floating(const SpaceOops *soops, const AR
UI_GetThemeColorShade4ubv(TH_BACK, -40, col);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4ubv(col);
- glLineWidth(line_width);
+ glEnable(GL_BLEND);
+
+ if (!te_insert || (te_floating->drag_data->insert_type == TE_INSERT_AFTER)) {
+ immUniformColor4ubv(col);
+ glLineWidth(line_width);
- immBegin(PRIM_LINE_STRIP, 2);
- immVertex2f(pos, 0, coord_y);
- immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
- immEnd();
+ immBegin(PRIM_LINE_STRIP, 2);
+ immVertex2f(pos, 0, coord_y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
+ immEnd();
+ }
+ else {
+ BLI_assert(te_floating->drag_data->insert_type == TE_INSERT_INTO);
+ immUniformColor4ub(UNPACK3(col), col[3] * 0.5f);
+
+ immBegin(PRIM_QUADS, 4);
+ immVertex2f(pos, 0, coord_y);
+ immVertex2f(pos, 0, coord_y + UI_UNIT_Y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y + UI_UNIT_Y);
+ immVertex2f(pos, ar->v2d.cur.xmax, coord_y);
+ immEnd();
+ }
+ glDisable(GL_BLEND);
immUnbindProgram();
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 731b5041bd9..4cee0e44fca 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -49,6 +49,12 @@ struct EditBone;
struct wmKeyConfig;
+typedef enum TreeElementInsertType {
+ /* no INSERT_BEFORE needed for now */
+ TE_INSERT_AFTER,
+ TE_INSERT_INTO,
+} TreeElementInsertType;
+
typedef enum TreeTraversalAction {
/* Continue traversal regularly, don't skip children. */
TRAVERSE_CONTINUE = 0,
@@ -63,7 +69,7 @@ typedef enum TreeTraversalAction {
* Passing scene right now, may be better to allow some custom data.
*/
typedef void (*TreeElementReinsertFunc)(const struct Scene *scene, struct TreeElement *insert_element,
- struct TreeElement *insert_after);
+ struct TreeElement *insert_handle, TreeElementInsertType action);
typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
@@ -84,8 +90,9 @@ typedef struct TreeElement {
TreeElementReinsertFunc reinsert;
struct {
+ TreeElementInsertType insert_type;
/* the element after which we may insert the dragged one (NULL to insert at top) */
- struct TreeElement *insert_te;
+ struct TreeElement *insert_handle;
} *drag_data;
} TreeElement;
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 5187cc66f58..3db0b6ffa08 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -87,24 +87,40 @@ static void outliner_item_drag_end(OutlinerItemDrag *op_drag_data)
MEM_freeN(op_drag_data);
}
-static void outliner_item_drag_handle(OutlinerItemDrag *op_drag_data, ARegion *ar, const wmEvent *event)
+static void outliner_item_drag_handle(ARegion *ar, const wmEvent *event, OutlinerItemDrag *op_drag_data)
{
TreeElement *dragged_te = op_drag_data->dragged_te;
const int delta_mouse_y = event->y - op_drag_data->init_mouse_xy[1];
const int cmp_coord = (int)UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+ const float margin = UI_UNIT_Y * (1.0f / 3);
/* by default we don't change the item position */
- dragged_te->drag_data->insert_te = dragged_te;
+ dragged_te->drag_data->insert_handle = dragged_te;
if (delta_mouse_y > 0) {
- for (TreeElement *te = dragged_te->prev; te && (cmp_coord >= (te->ys + (UI_UNIT_Y * 0.5f))); te = te->prev) {
- /* will be NULL if we want to insert as first element */
- dragged_te->drag_data->insert_te = te->prev;
+ for (TreeElement *te = dragged_te->prev; te && (cmp_coord >= (te->ys + margin)); te = te->prev) {
+ if (cmp_coord > (te->ys + (2 * margin))) {
+ dragged_te->drag_data->insert_type = TE_INSERT_AFTER;
+ /* will be NULL if we want to insert as first element */
+ dragged_te->drag_data->insert_handle = te->prev;
+ }
+ else {
+ dragged_te->drag_data->insert_type = TE_INSERT_INTO;
+ dragged_te->drag_data->insert_handle = te;
+ }
}
}
else {
- for (TreeElement *te = dragged_te->next; te && (cmp_coord <= (te->ys + (UI_UNIT_Y * 0.5f))); te = te->next) {
- dragged_te->drag_data->insert_te = te;
+ for (TreeElement *te = dragged_te->next; te && (cmp_coord <= (te->ys + UI_UNIT_Y - margin)); te = te->next) {
+ if (cmp_coord < (te->ys + margin)) {
+ dragged_te->drag_data->insert_type = TE_INSERT_AFTER;
+ dragged_te->drag_data->insert_handle = te;
+ BLI_assert(te->prev != NULL);
+ }
+ else {
+ dragged_te->drag_data->insert_type = TE_INSERT_INTO;
+ dragged_te->drag_data->insert_handle = te;
+ }
}
}
}
@@ -112,7 +128,7 @@ static void outliner_item_drag_handle(OutlinerItemDrag *op_drag_data, ARegion *a
static bool outliner_item_drag_drop_apply(const Scene *scene, OutlinerItemDrag *op_drag_data)
{
TreeElement *dragged_te = op_drag_data->dragged_te;
- TreeElement *insert_after = dragged_te->drag_data->insert_te;
+ TreeElement *insert_after = dragged_te->drag_data->insert_handle;
if (insert_after == dragged_te) {
/* No need to do anything */
@@ -123,7 +139,7 @@ static bool outliner_item_drag_drop_apply(const Scene *scene, OutlinerItemDrag *
/* Not sure yet what the best way to handle reordering elements of different types
* (and stored in different lists). For collection display mode this is enough. */
if (!insert_after || (insert_after->reinsert == dragged_te->reinsert)) {
- dragged_te->reinsert(scene, dragged_te, insert_after);
+ dragged_te->reinsert(scene, dragged_te, insert_after, dragged_te->drag_data->insert_type);
}
}
@@ -157,7 +173,7 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
redraw = true;
break;
case MOUSEMOVE:
- outliner_item_drag_handle(op_drag_data, ar, event);
+ outliner_item_drag_handle(ar, event, op_drag_data);
redraw = true;
break;
}
@@ -186,7 +202,7 @@ static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmE
op->customdata = outliner_item_drag_data_create(te, &event->x);
te->drag_data = MEM_callocN(sizeof(*te->drag_data), __func__);
/* by default we don't change the item position */
- te->drag_data->insert_te = te;
+ te->drag_data->insert_handle = te;
/* unset highlighted tree element, dragged one will be highlighted instead */
outliner_set_flag(&soops->tree, TSE_HIGHLIGHTED, false);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 8a024e0cc82..0cf76a671a4 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1287,13 +1287,19 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
}
}
-static void outliner_collections_reorder(const Scene *scene, TreeElement *insert_element, TreeElement *insert_after)
+static void outliner_collections_reorder(const Scene *scene, TreeElement *insert_element, TreeElement *insert_handle,
+ TreeElementInsertType action)
{
SceneLayer *sl = BKE_scene_layer_render_active(scene);
LayerCollection *insert_coll = insert_element->directdata;
- LayerCollection *insert_after_coll = insert_after ? insert_after->directdata : NULL;
+ LayerCollection *insert_handle_coll = insert_handle ? insert_handle->directdata : NULL;
- BKE_layer_collection_reinsert_after(scene, sl, insert_coll, insert_after_coll);
+ if (action == TE_INSERT_AFTER) {
+ BKE_layer_collection_reinsert_after(scene, sl, insert_coll, insert_handle_coll);
+ }
+ else if (action == TE_INSERT_INTO) {
+ BKE_layer_collection_reinsert_into(insert_coll, insert_handle_coll);
+ }
}
static void outliner_add_layer_collections_recursive(SpaceOops *soops, ListBase *tree, Scene *scene,
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 0e3a4e89fdf..f123b240efc 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -49,7 +49,7 @@ TreeElement *outliner_find_item_at_y(const SpaceOops *soops, const ListBase *tre
{
for (TreeElement *te_iter = tree->first; te_iter; te_iter = te_iter->next) {
if (view_co_y < (te_iter->ys + UI_UNIT_Y)) {
- if (view_co_y > te_iter->ys) {
+ if (view_co_y >= te_iter->ys) {
/* co_y is inside this element */
return te_iter;
}