From 5138fe3c0a24d5890438eed90a70401d90423356 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 27 Feb 2017 22:17:19 +0100 Subject: Outliner: "All Collections" mode showing the master collection hierarchy Reordering is disabled for now. Link, unlink and override operators are only available while in "Active Layer" mode, not in "All Collections". --- release/scripts/startup/bl_ui/space_outliner.py | 9 ++-- .../blender/editors/space_outliner/outliner_draw.c | 2 +- .../blender/editors/space_outliner/outliner_edit.c | 21 ++++++++-- .../blender/editors/space_outliner/outliner_ops.c | 4 +- .../editors/space_outliner/outliner_select.c | 4 +- .../editors/space_outliner/outliner_tools.c | 2 +- .../blender/editors/space_outliner/outliner_tree.c | 48 ++++++++++++++++++---- source/blender/makesdna/DNA_outliner_types.h | 3 +- source/blender/makesdna/DNA_space_types.h | 1 + source/blender/makesrna/intern/rna_space.c | 2 + 10 files changed, 73 insertions(+), 23 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index a8ef0c1a8a8..6af522e59e2 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -60,13 +60,14 @@ class OUTLINER_HT_header(Header): elif space.display_mode == 'ORPHAN_DATA': layout.operator("outliner.orphans_purge") - elif space.display_mode == 'ACT_LAYER': + elif space.display_mode in {'ACT_LAYER', 'COLLECTIONS'}: row = layout.row(align=True) row.operator("outliner.collection_new", text="", icon='NEW') - row.operator("outliner.collection_override_new", text="", icon='LINK_AREA') - row.operator("outliner.collection_link", text="", icon='LINKED') - row.operator("outliner.collection_unlink", text="", icon='UNLINKED') + if space.display_mode == 'ACT_LAYER': + row.operator("outliner.collection_override_new", text="", icon='LINK_AREA') + row.operator("outliner.collection_link", text="", icon='LINKED') + row.operator("outliner.collection_unlink", text="", icon='UNLINKED') row.operator("outliner.collection_delete", text="", icon='X') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 83a7a1db850..b8a43357482 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -569,7 +569,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar UI_block_emboss_set(block, UI_EMBOSS); } - else if (tselem->type == TSE_COLLECTION) { + else if (tselem->type == TSE_LAYER_COLLECTION) { LayerCollection *collection = te->directdata; UI_block_emboss_set(block, UI_EMBOSS_NONE); diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 5f3931a4a77..7d801318c33 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -307,6 +307,8 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot) static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports) { + bool add_textbut = false; + /* can't rename rna datablocks entries or listbases */ if (ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) { /* do nothing */; @@ -319,10 +321,17 @@ static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, Tre else if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) { BKE_report(reports, RPT_WARNING, "Cannot edit sequence name"); } - else if ((tselem->type == TSE_COLLECTION) && - (((LayerCollection *)te->directdata)->scene_collection == BKE_collection_master(scene))) - { - BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection"); + else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) { + SceneCollection *master = BKE_collection_master(scene); + + if ((tselem->type == TSE_SCENE_COLLECTION && te->directdata == master) || + (((LayerCollection *)te->directdata)->scene_collection == master)) + { + BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection"); + } + else { + add_textbut = true; + } } else if (ID_IS_LINKED_DATABLOCK(tselem->id)) { BKE_report(reports, RPT_WARNING, "Cannot edit external libdata"); @@ -331,6 +340,10 @@ static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, Tre BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library"); } else { + add_textbut = true; + } + + if (add_textbut) { tselem->flag |= TSE_TEXTBUT; ED_region_tag_redraw(ar); } diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 8a2272bf69a..459095b830e 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -61,8 +61,8 @@ static int outliner_item_drag_drop_poll(bContext *C) { SpaceOops *soops = CTX_wm_space_outliner(C); return ED_operator_outliner_active(C) && - /* Only collection display mode supported for now. Others need more design work */ - ELEM(soops->outlinevis, SO_ACT_LAYER); + /* Only collection display modes supported for now. Others need more design work */ + ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS); } static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 85b4c33c3f1..0793ba50c32 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -848,7 +848,7 @@ eOLDrawState tree_element_type_active( case TSE_GP_LAYER: //return tree_element_active_gplayer(C, scene, s, te, tselem, set); break; - case TSE_COLLECTION: + case TSE_LAYER_COLLECTION: return tree_element_active_collection(C, te, tselem, set); } return OL_DRAWSEL_NONE; @@ -867,7 +867,7 @@ static void outliner_item_activate( /* always makes active object, except for some specific types. * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want * to switch out of edit mode (see T48328 for details). */ - if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_COLLECTION)) { + if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) { tree_element_set_active_object(C, scene, sl, soops, te, (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, recursive && tselem->type == 0); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 320e38e82be..c932cc1052a 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -2006,7 +2006,7 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop else if (datalevel == TSE_MODIFIER) { WM_operator_name_call(C, "OUTLINER_OT_modifier_operation", WM_OP_INVOKE_REGION_WIN, NULL); } - else if (datalevel == TSE_COLLECTION) { + else if (datalevel == TSE_LAYER_COLLECTION) { WM_operator_name_call(C, "OUTLINER_OT_collection_operation", WM_OP_INVOKE_REGION_WIN, NULL); } else { diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 81fda948bc4..b0b99692405 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -908,7 +908,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } /* exceptions */ - if (ELEM(type, TSE_ID_BASE, TSE_COLLECTION)) { + if (ELEM(type, TSE_ID_BASE, TSE_LAYER_COLLECTION)) { /* pass */ } else if (id == NULL) { @@ -945,7 +945,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if (type == TSE_GP_LAYER) { /* pass */ } - else if (type == TSE_COLLECTION) { + else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) { /* pass */ } else if (type == TSE_ID_BASE) { @@ -1386,11 +1386,11 @@ static void outliner_collections_reorder(const Scene *scene, TreeElement *insert BKE_layer_collection_reinsert_after(scene, sl, insert_coll, insert_after_coll); } -static void outliner_add_collections_recursive(SpaceOops *soops, ListBase *tree, Scene *scene, - ListBase *layer_collections, TreeElement *parent_ten) +static void outliner_add_layer_collections_recursive(SpaceOops *soops, ListBase *tree, Scene *scene, + ListBase *layer_collections, TreeElement *parent_ten) { for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) { - TreeElement *ten = outliner_add_element(soops, tree, scene, parent_ten, TSE_COLLECTION, 0); + TreeElement *ten = outliner_add_element(soops, tree, scene, parent_ten, TSE_LAYER_COLLECTION, 0); ten->name = collection->scene_collection->name; ten->directdata = collection; @@ -1401,13 +1401,42 @@ static void outliner_add_collections_recursive(SpaceOops *soops, ListBase *tree, } outliner_make_hierarchy(&ten->subtree); - outliner_add_collections_recursive(soops, &ten->subtree, scene, &collection->layer_collections, ten); + outliner_add_layer_collections_recursive(soops, &ten->subtree, scene, &collection->layer_collections, ten); } } - static void outliner_add_collections_act_layer(SpaceOops *soops, SceneLayer *layer, Scene *scene) { - outliner_add_collections_recursive(soops, &soops->tree, scene, &layer->layer_collections, NULL); + outliner_add_layer_collections_recursive(soops, &soops->tree, scene, &layer->layer_collections, NULL); +} + +static void outliner_add_scene_collection_init(TreeElement *te, SceneCollection *collection) +{ + te->name = collection->name; + te->directdata = collection; +} + +static void outliner_add_scene_collections_recursive(SpaceOops *soops, ListBase *tree, Scene *scene, + ListBase *scene_collections, TreeElement *parent_ten) +{ + for (SceneCollection *collection = scene_collections->first; collection; collection = collection->next) { + TreeElement *ten = outliner_add_element(soops, tree, scene, parent_ten, TSE_SCENE_COLLECTION, 0); + + outliner_add_scene_collection_init(ten, collection); + for (LinkData *link = collection->objects.first; link; link = link->next) { + outliner_add_element(soops, &ten->subtree, link->data, NULL, 0, 0); + } + outliner_make_hierarchy(&ten->subtree); + + outliner_add_scene_collections_recursive(soops, &ten->subtree, scene, &collection->scene_collections, ten); + } +} +static void outliner_add_collections_master(SpaceOops *soops, Scene *scene) +{ + SceneCollection *master = BKE_collection_master(scene); + TreeElement *ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_SCENE_COLLECTION, 0); + + outliner_add_scene_collection_init(ten, master); + outliner_add_scene_collections_recursive(soops, &ten->subtree, scene, &master->scene_collections, ten); } /* ======================================================= */ @@ -1866,6 +1895,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops else if (soops->outlinevis == SO_ACT_LAYER) { outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active(scene), scene); } + else if (soops->outlinevis == SO_COLLECTIONS) { + outliner_add_collections_master(soops, scene); + } else { ten = outliner_add_element(soops, &soops->tree, OBACT_NEW, NULL, 0, 0); } diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 8c9de0665c4..44844653f3b 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -99,7 +99,8 @@ enum { #define TSE_KEYMAP_ITEM 35 /* NO ID */ #define TSE_ID_BASE 36 /* NO ID */ #define TSE_GP_LAYER 37 /* NO ID */ -#define TSE_COLLECTION 38 /* NO ID */ +#define TSE_LAYER_COLLECTION 38 /* NO ID */ +#define TSE_SCENE_COLLECTION 39 /* NO ID */ /* Check whether given TreeStoreElem should have a real ID in its ->id member. */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ce908b94d8d..10f41408f48 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -290,6 +290,7 @@ typedef enum eSpaceOutliner_Mode { /* SO_KEYMAP = 13, */ /* deprecated! */ SO_ID_ORPHANS = 14, SO_ACT_LAYER = 15, + SO_COLLECTIONS = 16, } eSpaceOutliner_Mode; /* SpaceOops->storeflag */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 0192ed887bb..9805f933487 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2106,6 +2106,8 @@ static void rna_def_space_outliner(BlenderRNA *brna) {SO_ID_ORPHANS, "ORPHAN_DATA", 0, "Orphan Data", "Display data-blocks which are unused and/or will be lost when the file is reloaded"}, {SO_ACT_LAYER, "ACT_LAYER", 0, "Active Render Layer", "Display the collections of the active render layer"}, + {SO_COLLECTIONS, "COLLECTIONS", 0, "All Collections", "Display all collections based on the master " + "collection hierarchy"}, {0, NULL, 0, NULL, NULL} }; -- cgit v1.2.3