Support displaying collections in outliner
Adds a new outliner display mode "Collections" which draws the active collection. We might want to rename it to "Active Collection" if we don't plan to support showing other collections there. Also added the buttons for restricting visibility and selectability. @dfelinto, code in restrictbutton_collection_hide_cb and restrictbutton_collection_hide_select_cb is duplicated from rna_LayerCollection_hide_update and rna_LayerCollection_hide_select_update, maybe utility functions would be handy for this?
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
@@ -247,6 +248,34 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void restrictbutton_collection_hide_cb(bContext *C, void *poin, void *poin2)
|
||||
{
|
||||
Scene *scene = poin;
|
||||
LayerCollection *collection = poin2;
|
||||
SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, collection);
|
||||
|
||||
/* hide and deselect bases that are directly influenced by this LayerCollection */
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
BKE_scene_layer_engine_settings_collection_recalculate(sl, collection);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL);
|
||||
}
|
||||
|
||||
static void restrictbutton_collection_hide_select_cb(bContext *C, void *poin, void *poin2)
|
||||
{
|
||||
Scene *scene = poin;
|
||||
LayerCollection *collection = poin2;
|
||||
|
||||
if ((collection->flag & COLLECTION_SELECTABLE) == 0) {
|
||||
SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, collection);
|
||||
|
||||
/* deselect bases that are directly influenced by this LayerCollection */
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
|
||||
}
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL);
|
||||
}
|
||||
|
||||
static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
|
||||
{
|
||||
ID *id = (ID *)poin;
|
||||
@@ -537,6 +566,27 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
|
||||
|
||||
/* TODO: visibility in renders */
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS);
|
||||
}
|
||||
else if (tselem->type == TSE_COLLECTION) {
|
||||
LayerCollection *collection = te->directdata;
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
|
||||
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_VISIBLE, 0, ICON_RESTRICT_VIEW_OFF,
|
||||
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
|
||||
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
|
||||
TIP_("Restrict/Allow 3D View visibility of objects in the collection"));
|
||||
UI_but_func_set(bt, restrictbutton_collection_hide_cb, scene, collection);
|
||||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||
|
||||
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
|
||||
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
|
||||
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
|
||||
TIP_("Restrict/Allow 3D View selection of objects in the collection"));
|
||||
UI_but_func_set(bt, restrictbutton_collection_hide_select_cb, scene, collection);
|
||||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -904,8 +904,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
||||
id = TREESTORE(parent)->id;
|
||||
}
|
||||
|
||||
/* One exception */
|
||||
if (type == TSE_ID_BASE) {
|
||||
/* exceptions */
|
||||
if (ELEM(type, TSE_ID_BASE, TSE_COLLECTION)) {
|
||||
/* pass */
|
||||
}
|
||||
else if (id == NULL) {
|
||||
@@ -942,6 +942,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
||||
else if (type == TSE_GP_LAYER) {
|
||||
/* pass */
|
||||
}
|
||||
else if (type == TSE_COLLECTION) {
|
||||
/* pass */
|
||||
}
|
||||
else if (type == TSE_ID_BASE) {
|
||||
/* pass */
|
||||
}
|
||||
@@ -1371,6 +1374,24 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
|
||||
}
|
||||
}
|
||||
|
||||
static void outliner_add_collections_recursive(SpaceOops *soops, ListBase *tree, ListBase *layer_collections,
|
||||
TreeElement *parent_ten)
|
||||
{
|
||||
for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) {
|
||||
TreeElement *ten = outliner_add_element(soops, tree, NULL, parent_ten, TSE_COLLECTION, 0);
|
||||
|
||||
ten->name = collection->scene_collection->name;
|
||||
ten->directdata = collection;
|
||||
|
||||
outliner_add_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten);
|
||||
}
|
||||
}
|
||||
|
||||
static void outliner_add_collections(SpaceOops *soops, SceneLayer *layer)
|
||||
{
|
||||
outliner_add_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL);
|
||||
}
|
||||
|
||||
/* ======================================================= */
|
||||
/* Generic Tree Building helpers - order these are called is top to bottom */
|
||||
|
||||
@@ -1832,6 +1853,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops
|
||||
else if (soops->outlinevis == SO_ID_ORPHANS) {
|
||||
outliner_add_orphaned_datablocks(mainvar, soops);
|
||||
}
|
||||
else if (soops->outlinevis == SO_COLLECTIONS) {
|
||||
outliner_add_collections(soops, BLI_findlink(&scene->render_layers, scene->active_layer));
|
||||
}
|
||||
else {
|
||||
ten = outliner_add_element(soops, &soops->tree, OBACT_NEW, NULL, 0, 0);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ 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 */
|
||||
|
||||
|
||||
/* Check whether given TreeStoreElem should have a real ID in its ->id member. */
|
||||
|
||||
@@ -274,21 +274,22 @@ typedef enum eSpaceOutliner_Flag {
|
||||
|
||||
/* SpaceOops->outlinevis */
|
||||
typedef enum eSpaceOutliner_Mode {
|
||||
SO_ALL_SCENES = 0,
|
||||
SO_CUR_SCENE = 1,
|
||||
SO_VISIBLE = 2,
|
||||
SO_SELECTED = 3,
|
||||
SO_ACTIVE = 4,
|
||||
SO_SAME_TYPE = 5,
|
||||
SO_GROUPS = 6,
|
||||
SO_LIBRARIES = 7,
|
||||
/* SO_VERSE_SESSION = 8, */ /* deprecated! */
|
||||
/* SO_VERSE_MS = 9, */ /* deprecated! */
|
||||
SO_SEQUENCE = 10,
|
||||
SO_DATABLOCKS = 11,
|
||||
SO_USERDEF = 12,
|
||||
/* SO_KEYMAP = 13, */ /* deprecated! */
|
||||
SO_ID_ORPHANS = 14,
|
||||
SO_ALL_SCENES = 0,
|
||||
SO_CUR_SCENE = 1,
|
||||
SO_VISIBLE = 2,
|
||||
SO_SELECTED = 3,
|
||||
SO_ACTIVE = 4,
|
||||
SO_SAME_TYPE = 5,
|
||||
SO_GROUPS = 6,
|
||||
SO_LIBRARIES = 7,
|
||||
/* SO_VERSE_SESSION = 8, */ /* deprecated! */
|
||||
/* SO_VERSE_MS = 9, */ /* deprecated! */
|
||||
SO_SEQUENCE = 10,
|
||||
SO_DATABLOCKS = 11,
|
||||
SO_USERDEF = 12,
|
||||
/* SO_KEYMAP = 13, */ /* deprecated! */
|
||||
SO_ID_ORPHANS = 14,
|
||||
SO_COLLECTIONS = 15,
|
||||
} eSpaceOutliner_Mode;
|
||||
|
||||
/* SpaceOops->storeflag */
|
||||
|
||||
@@ -2108,6 +2108,7 @@ static void rna_def_space_outliner(BlenderRNA *brna)
|
||||
{SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display user preference data"},
|
||||
{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_COLLECTIONS, "COLLECTIONS", 0, "Collections", "Display the collections of the active render layer"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user