From 32f85c8322e872951c7029fece0dc7d9102ed2b5 Mon Sep 17 00:00:00 2001 From: Danrae Pray Date: Wed, 13 Dec 2017 09:49:34 -0200 Subject: Fix T51461: Outliner: Problems removing multiple collections in sequence We now select the LayerCollection at index 0 for the active ViewLayer after a collection deletion operation. Added some functions to query outliner tree data & get LayerCollection by index using a similar approach as we do for SceneCollection indexing. With warning and style cleanups by Dalai Felinto. Reviewers: dfelinto Tags: #bf_blender_2.8 Differential Revision: https://developer.blender.org/D2942 --- .../editors/space_outliner/outliner_collections.c | 51 ++++++++++++++++++++++ .../editors/space_outliner/outliner_intern.h | 4 ++ .../editors/space_outliner/outliner_select.c | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index d5c833a7b5f..b00f33ae37d 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -108,6 +108,46 @@ static SceneCollection *scene_collection_from_index(ListBase *lb, const int numb return NULL; } +typedef struct TreeElementFindData { + SceneCollection *sc; + TreeElement *te; +} TreeElementFindData; + +static TreeTraversalAction tree_element_find_by_scene_collection(TreeElement *te, void *customdata) +{ + TreeElementFindData *data = customdata; + + SceneCollection *current_element_sc = outliner_scene_collection_from_tree_element(te); + + if (current_element_sc == data->sc) { + data->te = te; + return TRAVERSE_BREAK; + } + + return TRAVERSE_CONTINUE; +} + +static TreeElement *outliner_tree_element_from_layer_collection(bContext *C) +{ + ViewLayer *view_layer = CTX_data_view_layer(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + + LayerCollection *lc = BKE_layer_collection_from_index(view_layer, 0); + + if (lc == NULL) { + return NULL; + } + + /* Find the tree element containing the LayerCollection's scene_collection. */ + TreeElementFindData data = { + .sc = lc->scene_collection, + .te = NULL, + }; + outliner_tree_traverse(soops, &soops->tree, 0, 0, tree_element_find_by_scene_collection, &data); + + return data.te; +} + static int collection_link_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -359,7 +399,9 @@ static TreeTraversalAction collection_find_data_to_delete(TreeElement *te, void static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); SpaceOops *soops = CTX_wm_space_outliner(C); struct CollectionDeleteData data = {.scene = scene, .soops = soops}; @@ -380,6 +422,15 @@ static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op)) BLI_gset_free(data.collections_to_delete, NULL); + /* Rebuild the outliner tree before we select the tree element */ + outliner_build_tree(bmain, scene, view_layer, soops); + + TreeElement *select_te = outliner_tree_element_from_layer_collection(C); + + if (select_te) { + outliner_item_select(soops, select_te, false, false); + } + DEG_relations_tag_update(CTX_data_main(C)); /* TODO(sergey): Use proper flag for tagging here. */ diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index f69eb9af1bf..9047512caad 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -203,6 +203,10 @@ int outliner_item_do_activate_from_cursor( struct bContext *C, const int mval[2], bool extend, bool recursive); +void outliner_item_select( + struct SpaceOops *soops, const struct TreeElement *te, + const bool extend, const bool toggle); + /* outliner_edit.c ---------------------------------------------- */ typedef void (*outliner_operation_cb)( struct bContext *C, struct ReportList *, struct Scene *scene, diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 08b5f337936..1806d52f1b3 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -973,7 +973,7 @@ static void do_outliner_item_activate_tree_element( * \param extend: Don't deselect other items, only modify \a te. * \param toggle: Select \a te when not selected, deselect when selected. */ -static void outliner_item_select(SpaceOops *soops, const TreeElement *te, const bool extend, const bool toggle) +void outliner_item_select(SpaceOops *soops, const TreeElement *te, const bool extend, const bool toggle) { TreeStoreElem *tselem = TREESTORE(te); const short new_flag = toggle ? (tselem->flag ^ TSE_SELECTED) : (tselem->flag | TSE_SELECTED); -- cgit v1.2.3