Compare commits
1 Commits
tmp-worben
...
temp-outli
Author | SHA1 | Date | |
---|---|---|---|
ee3d36f78a |
@@ -64,9 +64,9 @@ static TreeElement *outliner_dropzone_element(TreeElement *te,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Not it. Let's look at its children. */
|
/* Not it. Let's look at its children. */
|
||||||
if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) {
|
if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0) {
|
||||||
LISTBASE_FOREACH (TreeElement *, te_sub, &te->subtree) {
|
for (TreeElement &te_sub : te->child_elements) {
|
||||||
TreeElement *te_valid = outliner_dropzone_element(te_sub, fmval, children);
|
TreeElement *te_valid = outliner_dropzone_element(&te_sub, fmval, children);
|
||||||
if (te_valid) {
|
if (te_valid) {
|
||||||
return te_valid;
|
return te_valid;
|
||||||
}
|
}
|
||||||
@@ -139,14 +139,14 @@ static TreeElement *outliner_drop_insert_find(bContext *C,
|
|||||||
|
|
||||||
if (view_mval[1] < (te_hovered->ys + margin)) {
|
if (view_mval[1] < (te_hovered->ys + margin)) {
|
||||||
if (TSELEM_OPEN(TREESTORE(te_hovered), space_outliner) &&
|
if (TSELEM_OPEN(TREESTORE(te_hovered), space_outliner) &&
|
||||||
!BLI_listbase_is_empty(&te_hovered->subtree)) {
|
!te_hovered->child_elements.is_empty()) {
|
||||||
/* inserting after a open item means we insert into it, but as first child */
|
/* inserting after a open item means we insert into it, but as first child */
|
||||||
if (BLI_listbase_is_empty(&te_hovered->subtree)) {
|
if (te_hovered->child_elements.is_empty()) {
|
||||||
*r_insert_type = TE_INSERT_INTO;
|
*r_insert_type = TE_INSERT_INTO;
|
||||||
return te_hovered;
|
return te_hovered;
|
||||||
}
|
}
|
||||||
*r_insert_type = TE_INSERT_BEFORE;
|
*r_insert_type = TE_INSERT_BEFORE;
|
||||||
return static_cast<TreeElement *>(te_hovered->subtree.first);
|
return &*te_hovered->child_elements.begin();
|
||||||
}
|
}
|
||||||
*r_insert_type = TE_INSERT_AFTER;
|
*r_insert_type = TE_INSERT_AFTER;
|
||||||
return te_hovered;
|
return te_hovered;
|
||||||
|
@@ -81,22 +81,22 @@ namespace blender::ed::outliner {
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void outliner_tree_dimensions_impl(SpaceOutliner *space_outliner,
|
static void outliner_tree_dimensions_impl(SpaceOutliner *space_outliner,
|
||||||
ListBase *lb,
|
SubTree &subtree,
|
||||||
int *width,
|
int *width,
|
||||||
int *height)
|
int *height)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (TreeElement *, te, lb) {
|
for (TreeElement &te : subtree) {
|
||||||
*width = MAX2(*width, te->xend);
|
*width = MAX2(*width, te.xend);
|
||||||
if (height != nullptr) {
|
if (height != nullptr) {
|
||||||
*height += UI_UNIT_Y;
|
*height += UI_UNIT_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeStoreElem *tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
if (TSELEM_OPEN(tselem, space_outliner)) {
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
||||||
outliner_tree_dimensions_impl(space_outliner, &te->subtree, width, height);
|
outliner_tree_dimensions_impl(space_outliner, te.child_elements, width, height);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outliner_tree_dimensions_impl(space_outliner, &te->subtree, width, nullptr);
|
outliner_tree_dimensions_impl(space_outliner, te.child_elements, width, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,8 @@ void outliner_tree_dimensions(SpaceOutliner *space_outliner, int *r_width, int *
|
|||||||
{
|
{
|
||||||
*r_width = 0;
|
*r_width = 0;
|
||||||
*r_height = 0;
|
*r_height = 0;
|
||||||
outliner_tree_dimensions_impl(space_outliner, &space_outliner->tree, r_width, r_height);
|
outliner_tree_dimensions_impl(
|
||||||
|
space_outliner, space_outliner->runtime->root_elements, r_width, r_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1030,7 +1031,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
ViewLayer *view_layer,
|
ViewLayer *view_layer,
|
||||||
ARegion *region,
|
ARegion *region,
|
||||||
SpaceOutliner *space_outliner,
|
SpaceOutliner *space_outliner,
|
||||||
ListBase *lb,
|
SubTree &subtree,
|
||||||
RestrictPropertiesActive props_active_parent)
|
RestrictPropertiesActive props_active_parent)
|
||||||
{
|
{
|
||||||
/* Get RNA properties (once for speed). */
|
/* Get RNA properties (once for speed). */
|
||||||
@@ -1105,16 +1106,16 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
/* Create buttons. */
|
/* Create buttons. */
|
||||||
uiBut *bt;
|
uiBut *bt;
|
||||||
|
|
||||||
LISTBASE_FOREACH (TreeElement *, te, lb) {
|
for (TreeElement &te : subtree) {
|
||||||
TreeStoreElem *tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
RestrictPropertiesActive props_active = props_active_parent;
|
RestrictPropertiesActive props_active = props_active_parent;
|
||||||
|
|
||||||
if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
|
if (te.ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te.ys <= region->v2d.cur.ymax) {
|
||||||
if (tselem->type == TSE_R_LAYER &&
|
if (tselem->type == TSE_R_LAYER &&
|
||||||
ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
|
ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
|
||||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
|
if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
|
||||||
/* View layer render toggle. */
|
/* View layer render toggle. */
|
||||||
ViewLayer *layer = static_cast<ViewLayer *>(te->directdata);
|
ViewLayer *layer = static_cast<ViewLayer *>(te.directdata);
|
||||||
|
|
||||||
bt = uiDefIconButBitS(block,
|
bt = uiDefIconButBitS(block,
|
||||||
UI_BTYPE_ICON_TOGGLE_N,
|
UI_BTYPE_ICON_TOGGLE_N,
|
||||||
@@ -1122,7 +1123,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_RESTRICT_RENDER_OFF,
|
ICON_RESTRICT_RENDER_OFF,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&layer->flag,
|
&layer->flag,
|
||||||
@@ -1136,18 +1137,18 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
|
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) &&
|
else if (((tselem->type == TSE_SOME_ID) && (te.idcode == ID_OB)) &&
|
||||||
(te->flag & TE_CHILD_NOT_IN_COLLECTION)) {
|
(te.flag & TE_CHILD_NOT_IN_COLLECTION)) {
|
||||||
/* Don't show restrict columns for children that are not directly inside the collection. */
|
/* Don't show restrict columns for children that are not directly inside the collection. */
|
||||||
}
|
}
|
||||||
else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
|
else if ((tselem->type == TSE_SOME_ID) && (te.idcode == ID_OB)) {
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
Object *ob = (Object *)tselem->id;
|
Object *ob = (Object *)tselem->id;
|
||||||
RNA_id_pointer_create(&ob->id, &ptr);
|
RNA_id_pointer_create(&ob->id, &ptr);
|
||||||
|
|
||||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
|
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
|
||||||
Base *base = (te->directdata) ? (Base *)te->directdata :
|
Base *base = (te.directdata) ? (Base *)te.directdata :
|
||||||
BKE_view_layer_base_find(view_layer, ob);
|
BKE_view_layer_base_find(view_layer, ob);
|
||||||
if (base) {
|
if (base) {
|
||||||
PointerRNA base_ptr;
|
PointerRNA base_ptr;
|
||||||
RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, &base_ptr);
|
RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, &base_ptr);
|
||||||
@@ -1156,7 +1157,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&base_ptr,
|
&base_ptr,
|
||||||
@@ -1183,7 +1184,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1208,7 +1209,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1233,7 +1234,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1253,7 +1254,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tselem->type == TSE_CONSTRAINT) {
|
else if (tselem->type == TSE_CONSTRAINT) {
|
||||||
bConstraint *con = (bConstraint *)te->directdata;
|
bConstraint *con = (bConstraint *)te.directdata;
|
||||||
|
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
RNA_pointer_create(tselem->id, &RNA_Constraint, con, &ptr);
|
RNA_pointer_create(tselem->id, &RNA_Constraint, con, &ptr);
|
||||||
@@ -1264,7 +1265,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1282,7 +1283,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tselem->type == TSE_MODIFIER) {
|
else if (tselem->type == TSE_MODIFIER) {
|
||||||
ModifierData *md = (ModifierData *)te->directdata;
|
ModifierData *md = (ModifierData *)te.directdata;
|
||||||
|
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
|
RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
|
||||||
@@ -1293,7 +1294,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1316,7 +1317,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1335,7 +1336,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
else if (tselem->type == TSE_POSE_CHANNEL) {
|
else if (tselem->type == TSE_POSE_CHANNEL) {
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
|
bPoseChannel *pchan = (bPoseChannel *)te.directdata;
|
||||||
Bone *bone = pchan->bone;
|
Bone *bone = pchan->bone;
|
||||||
Object *ob = (Object *)tselem->id;
|
Object *ob = (Object *)tselem->id;
|
||||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||||
@@ -1348,7 +1349,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&ptr,
|
&ptr,
|
||||||
@@ -1372,7 +1373,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_RESTRICT_SELECT_OFF,
|
ICON_RESTRICT_SELECT_OFF,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&(bone->flag),
|
&(bone->flag),
|
||||||
@@ -1389,7 +1390,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
else if (tselem->type == TSE_EBONE) {
|
else if (tselem->type == TSE_EBONE) {
|
||||||
bArmature *arm = (bArmature *)tselem->id;
|
bArmature *arm = (bArmature *)tselem->id;
|
||||||
EditBone *ebone = (EditBone *)te->directdata;
|
EditBone *ebone = (EditBone *)te.directdata;
|
||||||
|
|
||||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
|
if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
|
||||||
bt = uiDefIconButBitI(block,
|
bt = uiDefIconButBitI(block,
|
||||||
@@ -1398,7 +1399,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_RESTRICT_VIEW_OFF,
|
ICON_RESTRICT_VIEW_OFF,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&(ebone->flag),
|
&(ebone->flag),
|
||||||
@@ -1420,7 +1421,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_RESTRICT_SELECT_OFF,
|
ICON_RESTRICT_SELECT_OFF,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&(ebone->flag),
|
&(ebone->flag),
|
||||||
@@ -1437,7 +1438,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
else if (tselem->type == TSE_GP_LAYER) {
|
else if (tselem->type == TSE_GP_LAYER) {
|
||||||
ID *id = tselem->id;
|
ID *id = tselem->id;
|
||||||
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
|
bGPDlayer *gpl = (bGPDlayer *)te.directdata;
|
||||||
|
|
||||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
|
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
|
||||||
bt = uiDefIconButBitS(block,
|
bt = uiDefIconButBitS(block,
|
||||||
@@ -1446,7 +1447,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_HIDE_OFF,
|
ICON_HIDE_OFF,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&gpl->flag,
|
&gpl->flag,
|
||||||
@@ -1467,7 +1468,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
ICON_UNLOCKED,
|
ICON_UNLOCKED,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&gpl->flag,
|
&gpl->flag,
|
||||||
@@ -1480,17 +1481,17 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (outliner_is_collection_tree_element(te)) {
|
else if (outliner_is_collection_tree_element(&te)) {
|
||||||
PointerRNA collection_ptr;
|
PointerRNA collection_ptr;
|
||||||
PointerRNA layer_collection_ptr;
|
PointerRNA layer_collection_ptr;
|
||||||
|
|
||||||
if (outliner_restrict_properties_collection_set(
|
if (outliner_restrict_properties_collection_set(
|
||||||
scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active)) {
|
scene, &te, &collection_ptr, &layer_collection_ptr, &props, &props_active)) {
|
||||||
|
|
||||||
LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
|
LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
|
||||||
static_cast<LayerCollection *>(te->directdata) :
|
static_cast<LayerCollection *>(te.directdata) :
|
||||||
nullptr;
|
nullptr;
|
||||||
Collection *collection = outliner_collection_from_tree_element(te);
|
Collection *collection = outliner_collection_from_tree_element(&te);
|
||||||
|
|
||||||
if (layer_collection != nullptr) {
|
if (layer_collection != nullptr) {
|
||||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_ENABLE) {
|
if (space_outliner->show_restrict_flags & SO_RESTRICT_ENABLE) {
|
||||||
@@ -1499,7 +1500,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax) - restrict_offsets.enable,
|
(int)(region->v2d.cur.xmax) - restrict_offsets.enable,
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&layer_collection_ptr,
|
&layer_collection_ptr,
|
||||||
@@ -1519,7 +1520,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
(int)(region->v2d.cur.xmax - restrict_offsets.hide),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&layer_collection_ptr,
|
&layer_collection_ptr,
|
||||||
@@ -1548,7 +1549,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.holdout),
|
(int)(region->v2d.cur.xmax - restrict_offsets.holdout),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&layer_collection_ptr,
|
&layer_collection_ptr,
|
||||||
@@ -1578,7 +1579,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.indirect_only),
|
(int)(region->v2d.cur.xmax - restrict_offsets.indirect_only),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&layer_collection_ptr,
|
&layer_collection_ptr,
|
||||||
@@ -1610,7 +1611,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
(int)(region->v2d.cur.xmax - restrict_offsets.viewport),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&collection_ptr,
|
&collection_ptr,
|
||||||
@@ -1647,7 +1648,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
(int)(region->v2d.cur.xmax - restrict_offsets.render),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&collection_ptr,
|
&collection_ptr,
|
||||||
@@ -1682,7 +1683,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
(int)(region->v2d.cur.xmax - restrict_offsets.select),
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
&collection_ptr,
|
&collection_ptr,
|
||||||
@@ -1713,16 +1714,16 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (outliner_is_collection_tree_element(te)) {
|
else if (outliner_is_collection_tree_element(&te)) {
|
||||||
PointerRNA collection_ptr;
|
PointerRNA collection_ptr;
|
||||||
PointerRNA layer_collection_ptr;
|
PointerRNA layer_collection_ptr;
|
||||||
outliner_restrict_properties_collection_set(
|
outliner_restrict_properties_collection_set(
|
||||||
scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active);
|
scene, &te, &collection_ptr, &layer_collection_ptr, &props, &props_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSELEM_OPEN(tselem, space_outliner)) {
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
||||||
outliner_draw_restrictbuts(
|
outliner_draw_restrictbuts(
|
||||||
block, scene, view_layer, region, space_outliner, &te->subtree, props_active);
|
block, scene, view_layer, region, space_outliner, te.child_elements, props_active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1797,7 +1798,7 @@ static void outliner_draw_userbuts(uiBlock *block,
|
|||||||
static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
||||||
const ARegion *region,
|
const ARegion *region,
|
||||||
const SpaceOutliner *space_outliner,
|
const SpaceOutliner *space_outliner,
|
||||||
const ListBase *lb,
|
const SubTree &subtree,
|
||||||
const int x)
|
const int x)
|
||||||
{
|
{
|
||||||
const float pad_x = 2.0f * UI_DPI_FAC;
|
const float pad_x = 2.0f * UI_DPI_FAC;
|
||||||
@@ -1805,17 +1806,17 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
const float item_max_width = round_fl_to_int(OL_RNA_COL_SIZEX - 2 * pad_x);
|
const float item_max_width = round_fl_to_int(OL_RNA_COL_SIZEX - 2 * pad_x);
|
||||||
const float item_height = round_fl_to_int(UI_UNIT_Y - 2.0f * pad_y);
|
const float item_height = round_fl_to_int(UI_UNIT_Y - 2.0f * pad_y);
|
||||||
|
|
||||||
LISTBASE_FOREACH (const TreeElement *, te, lb) {
|
for (const TreeElement &te : subtree) {
|
||||||
const TreeStoreElem *tselem = TREESTORE(te);
|
const TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
if (TSELEM_OPEN(tselem, space_outliner)) {
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
||||||
outliner_draw_overrides_rna_buts(block, region, space_outliner, &te->subtree, x);
|
outliner_draw_overrides_rna_buts(block, region, space_outliner, te.child_elements, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outliner_is_element_in_view(te, ®ion->v2d)) {
|
if (!outliner_is_element_in_view(&te, ®ion->v2d)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TreeElementOverridesProperty *override_elem = tree_element_cast<TreeElementOverridesProperty>(
|
TreeElementOverridesProperty *override_elem = tree_element_cast<TreeElementOverridesProperty>(
|
||||||
te);
|
&te);
|
||||||
if (!override_elem) {
|
if (!override_elem) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1826,7 +1827,7 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
0,
|
0,
|
||||||
override_elem->rna_path.c_str(),
|
override_elem->rna_path.c_str(),
|
||||||
x + pad_x,
|
x + pad_x,
|
||||||
te->ys + pad_y,
|
te.ys + pad_y,
|
||||||
item_max_width,
|
item_max_width,
|
||||||
item_height,
|
item_height,
|
||||||
nullptr,
|
nullptr,
|
||||||
@@ -1840,14 +1841,14 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (const TreeElementOverridesPropertyOperation *override_op_elem =
|
if (const TreeElementOverridesPropertyOperation *override_op_elem =
|
||||||
tree_element_cast<TreeElementOverridesPropertyOperation>(te)) {
|
tree_element_cast<TreeElementOverridesPropertyOperation>(&te)) {
|
||||||
StringRefNull op_label = override_op_elem->getOverrideOperationLabel();
|
StringRefNull op_label = override_op_elem->getOverrideOperationLabel();
|
||||||
uiDefBut(block,
|
uiDefBut(block,
|
||||||
UI_BTYPE_LABEL,
|
UI_BTYPE_LABEL,
|
||||||
0,
|
0,
|
||||||
op_label.c_str(),
|
op_label.c_str(),
|
||||||
x + pad_x,
|
x + pad_x,
|
||||||
te->ys + pad_y,
|
te.ys + pad_y,
|
||||||
item_max_width,
|
item_max_width,
|
||||||
item_height,
|
item_height,
|
||||||
nullptr,
|
nullptr,
|
||||||
@@ -1870,7 +1871,7 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
(prop_type == PROP_ENUM) ? nullptr : "",
|
(prop_type == PROP_ENUM) ? nullptr : "",
|
||||||
ICON_NONE,
|
ICON_NONE,
|
||||||
x + pad_x,
|
x + pad_x,
|
||||||
te->ys + pad_y,
|
te.ys + pad_y,
|
||||||
item_max_width,
|
item_max_width,
|
||||||
item_height);
|
item_height);
|
||||||
/* Added the button successfully, nothing else to do. Otherwise, cases for multiple buttons
|
/* Added the button successfully, nothing else to do. Otherwise, cases for multiple buttons
|
||||||
@@ -1883,7 +1884,7 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
/* TODO what if the array is longer, and doesn't fit nicely? What about multi-dimension
|
/* TODO what if the array is longer, and doesn't fit nicely? What about multi-dimension
|
||||||
* arrays? */
|
* arrays? */
|
||||||
uiDefAutoButsArrayR(
|
uiDefAutoButsArrayR(
|
||||||
block, ptr, prop, ICON_NONE, x + pad_x, te->ys + pad_y, item_max_width, item_height);
|
block, ptr, prop, ICON_NONE, x + pad_x, te.ys + pad_y, item_max_width, item_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1906,19 +1907,20 @@ static void outliner_draw_overrides_restrictbuts(Main *bmain,
|
|||||||
uiBlock *block,
|
uiBlock *block,
|
||||||
const ARegion *region,
|
const ARegion *region,
|
||||||
const SpaceOutliner *space_outliner,
|
const SpaceOutliner *space_outliner,
|
||||||
const ListBase *lb,
|
const SubTree &subtree,
|
||||||
const int x)
|
const int x)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (const TreeElement *, te, lb) {
|
for (const TreeElement &te : subtree) {
|
||||||
const TreeStoreElem *tselem = TREESTORE(te);
|
const TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
if (TSELEM_OPEN(tselem, space_outliner)) {
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
||||||
outliner_draw_overrides_restrictbuts(bmain, block, region, space_outliner, &te->subtree, x);
|
outliner_draw_overrides_restrictbuts(
|
||||||
|
bmain, block, region, space_outliner, te.child_elements, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outliner_is_element_in_view(te, ®ion->v2d)) {
|
if (!outliner_is_element_in_view(&te, ®ion->v2d)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TreeElementID *te_id = tree_element_cast<TreeElementID>(te);
|
TreeElementID *te_id = tree_element_cast<TreeElementID>(&te);
|
||||||
if (!te_id) {
|
if (!te_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1939,7 +1941,7 @@ static void outliner_draw_overrides_restrictbuts(Main *bmain,
|
|||||||
WM_OP_EXEC_DEFAULT,
|
WM_OP_EXEC_DEFAULT,
|
||||||
icon,
|
icon,
|
||||||
x,
|
x,
|
||||||
te->ys,
|
te.ys,
|
||||||
UI_UNIT_X,
|
UI_UNIT_X,
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
"");
|
"");
|
||||||
@@ -3946,12 +3948,13 @@ void draw_outliner(const bContext *C)
|
|||||||
if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
|
if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
|
||||||
UI_block_emboss_set(block, UI_EMBOSS);
|
UI_block_emboss_set(block, UI_EMBOSS);
|
||||||
UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
|
UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
|
||||||
outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
|
outliner_draw_overrides_rna_buts(
|
||||||
|
block, region, space_outliner, space_outliner->runtime->root_elements, x);
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
||||||
}
|
}
|
||||||
else if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_HIERARCHIES) {
|
else if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_HIERARCHIES) {
|
||||||
outliner_draw_overrides_restrictbuts(
|
outliner_draw_overrides_restrictbuts(
|
||||||
mainvar, block, region, space_outliner, &space_outliner->tree, x);
|
mainvar, block, region, space_outliner, space_outliner->runtime->root_elements, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (right_column_width > 0.0f) {
|
else if (right_column_width > 0.0f) {
|
||||||
@@ -3963,7 +3966,7 @@ void draw_outliner(const bContext *C)
|
|||||||
tvc.view_layer,
|
tvc.view_layer,
|
||||||
region,
|
region,
|
||||||
space_outliner,
|
space_outliner,
|
||||||
&space_outliner->tree,
|
space_outliner->runtime->root_elements,
|
||||||
props_active);
|
props_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "RNA_types.h"
|
#include "RNA_types.h"
|
||||||
@@ -40,10 +42,132 @@ namespace blender::ed::outliner {
|
|||||||
|
|
||||||
class AbstractTreeDisplay;
|
class AbstractTreeDisplay;
|
||||||
class AbstractTreeElement;
|
class AbstractTreeElement;
|
||||||
|
struct SpaceOutliner_Runtime;
|
||||||
|
struct TreeElement;
|
||||||
|
|
||||||
namespace treehash = blender::bke::outliner::treehash;
|
namespace treehash = blender::bke::outliner::treehash;
|
||||||
|
|
||||||
struct TreeElement;
|
/**
|
||||||
|
* Container to own a number of tree elements.
|
||||||
|
*/
|
||||||
|
class SubTree {
|
||||||
|
/** The tree element owning this sub-tree. Remains null for root level elements. */
|
||||||
|
TreeElement *parent_ = nullptr;
|
||||||
|
|
||||||
|
std::list<std::unique_ptr<TreeElement>> elements_;
|
||||||
|
|
||||||
|
/* TODO all this boilerplate... make this a generic indirect-iterator? */
|
||||||
|
template<typename IterT, typename NestedIterT, typename ElemT> class IteratorBase {
|
||||||
|
public:
|
||||||
|
NestedIterT iter_;
|
||||||
|
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = ElemT;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = ElemT *;
|
||||||
|
using reference = ElemT &;
|
||||||
|
|
||||||
|
explicit IteratorBase(NestedIterT iter) : iter_(iter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ElemT &operator*()
|
||||||
|
{
|
||||||
|
return **iter_;
|
||||||
|
}
|
||||||
|
ElemT *operator->()
|
||||||
|
{
|
||||||
|
return &**iter_;
|
||||||
|
}
|
||||||
|
IterT &operator++()
|
||||||
|
{
|
||||||
|
++iter_;
|
||||||
|
return *static_cast<IterT *>(this);
|
||||||
|
}
|
||||||
|
IterT &operator--()
|
||||||
|
{
|
||||||
|
--iter_;
|
||||||
|
return *static_cast<IterT *>(this);
|
||||||
|
}
|
||||||
|
IterT operator++(int)
|
||||||
|
{
|
||||||
|
IterT tmp = *this;
|
||||||
|
++iter_;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
IterT operator--(int)
|
||||||
|
{
|
||||||
|
IterT tmp = *this;
|
||||||
|
--iter_;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
friend bool operator==(const IterT &a, const IterT &b)
|
||||||
|
{
|
||||||
|
return a.iter_ == b.iter_;
|
||||||
|
}
|
||||||
|
friend bool operator!=(const IterT &a, const IterT &b)
|
||||||
|
{
|
||||||
|
return a.iter_ != b.iter_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Iterator : public IteratorBase<Iterator, decltype(elements_)::iterator, TreeElement> {
|
||||||
|
using IteratorBase::IteratorBase;
|
||||||
|
};
|
||||||
|
class ConstIterator : public IteratorBase<ConstIterator,
|
||||||
|
decltype(elements_)::const_iterator,
|
||||||
|
const TreeElement> {
|
||||||
|
using IteratorBase::IteratorBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator = Iterator;
|
||||||
|
using const_iterator = Iterator;
|
||||||
|
|
||||||
|
Iterator begin()
|
||||||
|
{
|
||||||
|
return Iterator{elements_.begin()};
|
||||||
|
}
|
||||||
|
std::reverse_iterator<Iterator> rbegin()
|
||||||
|
{
|
||||||
|
return std::reverse_iterator<Iterator>(Iterator{elements_.end()});
|
||||||
|
}
|
||||||
|
Iterator end()
|
||||||
|
{
|
||||||
|
return Iterator{elements_.end()};
|
||||||
|
}
|
||||||
|
std::reverse_iterator<Iterator> rend()
|
||||||
|
{
|
||||||
|
return std::reverse_iterator<Iterator>(Iterator{elements_.begin()});
|
||||||
|
}
|
||||||
|
ConstIterator begin() const
|
||||||
|
{
|
||||||
|
return ConstIterator{elements_.begin()};
|
||||||
|
}
|
||||||
|
ConstIterator end() const
|
||||||
|
{
|
||||||
|
return ConstIterator{elements_.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit SubTree(TreeElement &parent);
|
||||||
|
explicit SubTree(SpaceOutliner_Runtime &root);
|
||||||
|
|
||||||
|
void add_back(std::unique_ptr<TreeElement> elem);
|
||||||
|
void insert_before(Iterator pos, std::unique_ptr<TreeElement> elem);
|
||||||
|
/** Detaches the given element from this sub-tree, and moves ownership of it to the calling
|
||||||
|
* scope (by returning its unique pointer). This way the caller can decide to keep it still,
|
||||||
|
* for example to reinsert it elsewhere. If the caller doesn't use it (e.g. by ignoring the
|
||||||
|
* return value entirely), the element will be destructed and freed cleanly. */
|
||||||
|
std::unique_ptr<TreeElement> remove(TreeElement &element);
|
||||||
|
/** Erase and destruct all elements in the container. */
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
bool has_child(const TreeElement &needle) const;
|
||||||
|
|
||||||
|
bool is_empty() const;
|
||||||
|
/** Get the element owning these children. Will return null in case of root level elements. */
|
||||||
|
TreeElement *parent() const;
|
||||||
|
};
|
||||||
|
|
||||||
struct SpaceOutliner_Runtime {
|
struct SpaceOutliner_Runtime {
|
||||||
/** Object to create and manage the tree for a specific display type (View Layers, Scenes,
|
/** Object to create and manage the tree for a specific display type (View Layers, Scenes,
|
||||||
@@ -53,7 +177,11 @@ struct SpaceOutliner_Runtime {
|
|||||||
/* Hash table for tree-store elements, using `(id, type, index)` as key. */
|
/* Hash table for tree-store elements, using `(id, type, index)` as key. */
|
||||||
std::unique_ptr<treehash::TreeHash> tree_hash;
|
std::unique_ptr<treehash::TreeHash> tree_hash;
|
||||||
|
|
||||||
SpaceOutliner_Runtime() = default;
|
/** Entry point for the outliner tree. This is essentially a sorted vector of #TreeElement's,
|
||||||
|
* whereby each can have its own #SubTree containing the same. */
|
||||||
|
SubTree root_elements;
|
||||||
|
|
||||||
|
SpaceOutliner_Runtime();
|
||||||
/** Used for copying runtime data to a duplicated space. */
|
/** Used for copying runtime data to a duplicated space. */
|
||||||
SpaceOutliner_Runtime(const SpaceOutliner_Runtime &);
|
SpaceOutliner_Runtime(const SpaceOutliner_Runtime &);
|
||||||
~SpaceOutliner_Runtime() = default;
|
~SpaceOutliner_Runtime() = default;
|
||||||
@@ -76,6 +204,12 @@ enum TreeTraversalAction {
|
|||||||
|
|
||||||
typedef TreeTraversalAction (*TreeTraversalFunc)(TreeElement *te, void *customdata);
|
typedef TreeTraversalAction (*TreeTraversalFunc)(TreeElement *te, void *customdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy representation of an item in the Outliner tree. The new representation is
|
||||||
|
* #AbstractTreeElement, efforts should be put into slowly transitioning to it. However, since not
|
||||||
|
* all tree element types support this yet (#TreeElement.abstract_element will be null), things are
|
||||||
|
* split between the too, and the situation is rather chaotic.
|
||||||
|
*/
|
||||||
struct TreeElement {
|
struct TreeElement {
|
||||||
TreeElement *next, *prev, *parent;
|
TreeElement *next, *prev, *parent;
|
||||||
|
|
||||||
@@ -88,6 +222,9 @@ struct TreeElement {
|
|||||||
std::unique_ptr<AbstractTreeElement> abstract_element;
|
std::unique_ptr<AbstractTreeElement> abstract_element;
|
||||||
|
|
||||||
ListBase subtree;
|
ListBase subtree;
|
||||||
|
|
||||||
|
SubTree child_elements;
|
||||||
|
|
||||||
int xs, ys; /* Do selection. */
|
int xs, ys; /* Do selection. */
|
||||||
TreeStoreElem *store_elem; /* Element in tree store. */
|
TreeStoreElem *store_elem; /* Element in tree store. */
|
||||||
short flag; /* Flag for non-saved stuff. */
|
short flag; /* Flag for non-saved stuff. */
|
||||||
@@ -96,6 +233,10 @@ struct TreeElement {
|
|||||||
short xend; /* Width of item display, for select. */
|
short xend; /* Width of item display, for select. */
|
||||||
const char *name;
|
const char *name;
|
||||||
void *directdata; /* Armature Bones, Base, ... */
|
void *directdata; /* Armature Bones, Base, ... */
|
||||||
|
|
||||||
|
TreeElement() : child_elements(*this)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TreeElementIcon {
|
struct TreeElementIcon {
|
||||||
@@ -254,7 +395,6 @@ enum TreeItemSelectAction {
|
|||||||
|
|
||||||
/* outliner_tree.c ----------------------------------------------- */
|
/* outliner_tree.c ----------------------------------------------- */
|
||||||
|
|
||||||
void outliner_free_tree(ListBase *tree);
|
|
||||||
void outliner_cleanup_tree(struct SpaceOutliner *space_outliner);
|
void outliner_cleanup_tree(struct SpaceOutliner *space_outliner);
|
||||||
/**
|
/**
|
||||||
* Free \a element and its sub-tree and remove its link in \a parent_subtree.
|
* Free \a element and its sub-tree and remove its link in \a parent_subtree.
|
||||||
@@ -262,7 +402,7 @@ void outliner_cleanup_tree(struct SpaceOutliner *space_outliner);
|
|||||||
* \note Does not remove the #TreeStoreElem of \a element!
|
* \note Does not remove the #TreeStoreElem of \a element!
|
||||||
* \param parent_subtree: Sub-tree of the parent element, so the list containing \a element.
|
* \param parent_subtree: Sub-tree of the parent element, so the list containing \a element.
|
||||||
*/
|
*/
|
||||||
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree);
|
void outliner_free_tree_element(TreeElement *element, SubTree &parent_subtree);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entry point for building the tree data-structure that the outliner represents.
|
* Main entry point for building the tree data-structure that the outliner represents.
|
||||||
|
@@ -140,7 +140,7 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void check_persistent(
|
static void check_persistent(
|
||||||
SpaceOutliner *space_outliner, TreeElement *te, ID *id, short type, short nr)
|
SpaceOutliner *space_outliner, TreeElement &te, ID *id, short type, short nr)
|
||||||
{
|
{
|
||||||
if (space_outliner->treestore == nullptr) {
|
if (space_outliner->treestore == nullptr) {
|
||||||
/* if treestore was not created in readfile.c, create it here */
|
/* if treestore was not created in readfile.c, create it here */
|
||||||
@@ -156,7 +156,7 @@ static void check_persistent(
|
|||||||
* (note that there may be multiple unused elements in case of linked objects) */
|
* (note that there may be multiple unused elements in case of linked objects) */
|
||||||
TreeStoreElem *tselem = space_outliner->runtime->tree_hash->lookup_unused(type, nr, id);
|
TreeStoreElem *tselem = space_outliner->runtime->tree_hash->lookup_unused(type, nr, id);
|
||||||
if (tselem) {
|
if (tselem) {
|
||||||
te->store_elem = tselem;
|
te.store_elem = tselem;
|
||||||
tselem->used = 1;
|
tselem->used = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ static void check_persistent(
|
|||||||
tselem->id = id;
|
tselem->id = id;
|
||||||
tselem->used = 0;
|
tselem->used = 0;
|
||||||
tselem->flag = TSE_CLOSED;
|
tselem->flag = TSE_CLOSED;
|
||||||
te->store_elem = tselem;
|
te.store_elem = tselem;
|
||||||
space_outliner->runtime->tree_hash->add_element(*tselem);
|
space_outliner->runtime->tree_hash->add_element(*tselem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,31 +178,20 @@ static void check_persistent(
|
|||||||
/** \name Tree Management
|
/** \name Tree Management
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
void outliner_free_tree(ListBase *tree)
|
|
||||||
{
|
|
||||||
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, tree) {
|
|
||||||
outliner_free_tree_element(element, tree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void outliner_cleanup_tree(SpaceOutliner *space_outliner)
|
void outliner_cleanup_tree(SpaceOutliner *space_outliner)
|
||||||
{
|
{
|
||||||
outliner_free_tree(&space_outliner->tree);
|
space_outliner->runtime->root_elements.clear();
|
||||||
outliner_storage_cleanup(space_outliner);
|
outliner_storage_cleanup(space_outliner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
|
void outliner_free_tree_element(TreeElement *element, SubTree &parent_subtree)
|
||||||
{
|
{
|
||||||
BLI_assert(BLI_findindex(parent_subtree, element) > -1);
|
BLI_assert(parent_subtree.has_child(*element));
|
||||||
BLI_remlink(parent_subtree, element);
|
parent_subtree.remove(*element);
|
||||||
|
|
||||||
outliner_free_tree(&element->subtree);
|
|
||||||
|
|
||||||
if (element->flag & TE_FREE_NAME) {
|
if (element->flag & TE_FREE_NAME) {
|
||||||
MEM_freeN((void *)element->name);
|
MEM_freeN((void *)element->name);
|
||||||
}
|
}
|
||||||
element->abstract_element = nullptr;
|
|
||||||
MEM_delete(element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************* */
|
/* ********************************************************* */
|
||||||
@@ -218,29 +207,22 @@ bool outliner_requires_rebuild_on_select_or_active_change(const SpaceOutliner *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* special handling of hierarchical non-lib data */
|
/* special handling of hierarchical non-lib data */
|
||||||
static void outliner_add_bone(SpaceOutliner *space_outliner,
|
static void outliner_add_bone(
|
||||||
ListBase *lb,
|
SpaceOutliner *space_outliner, ID *id, Bone *curBone, TreeElement *parent, int *a)
|
||||||
ID *id,
|
|
||||||
Bone *curBone,
|
|
||||||
TreeElement *parent,
|
|
||||||
int *a)
|
|
||||||
{
|
{
|
||||||
TreeElement *te = outliner_add_element(space_outliner, lb, id, parent, TSE_BONE, *a);
|
TreeElement *te = outliner_add_element(space_outliner, id, parent, TSE_BONE, *a);
|
||||||
|
|
||||||
(*a)++;
|
(*a)++;
|
||||||
te->name = curBone->name;
|
te->name = curBone->name;
|
||||||
te->directdata = curBone;
|
te->directdata = curBone;
|
||||||
|
|
||||||
LISTBASE_FOREACH (Bone *, child_bone, &curBone->childbase) {
|
LISTBASE_FOREACH (Bone *, child_bone, &curBone->childbase) {
|
||||||
outliner_add_bone(space_outliner, &te->subtree, id, child_bone, te, a);
|
outliner_add_bone(space_outliner, id, child_bone, te, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_FREESTYLE
|
#ifdef WITH_FREESTYLE
|
||||||
static void outliner_add_line_styles(SpaceOutliner *space_outliner,
|
static void outliner_add_line_styles(SpaceOutliner *space_outliner, Scene *sce, TreeElement *te)
|
||||||
ListBase *lb,
|
|
||||||
Scene *sce,
|
|
||||||
TreeElement *te)
|
|
||||||
{
|
{
|
||||||
ViewLayer *view_layer;
|
ViewLayer *view_layer;
|
||||||
FreestyleLineSet *lineset;
|
FreestyleLineSet *lineset;
|
||||||
@@ -261,7 +243,7 @@ static void outliner_add_line_styles(SpaceOutliner *space_outliner,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
linestyle->id.tag &= ~LIB_TAG_DOIT;
|
linestyle->id.tag &= ~LIB_TAG_DOIT;
|
||||||
outliner_add_element(space_outliner, lb, linestyle, te, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, linestyle, te, TSE_SOME_ID, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,18 +257,17 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
Object *ob)
|
Object *ob)
|
||||||
{
|
{
|
||||||
if (outliner_animdata_test(ob->adt)) {
|
if (outliner_animdata_test(ob->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, ob, te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: add a special type for this. */
|
/* FIXME: add a special type for this. */
|
||||||
outliner_add_element(space_outliner, &te->subtree, ob->poselib, te, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, ob->poselib, te, TSE_SOME_ID, 0);
|
||||||
|
|
||||||
outliner_add_element(space_outliner, &te->subtree, ob->data, te, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, ob->data, te, TSE_SOME_ID, 0);
|
||||||
|
|
||||||
if (ob->pose) {
|
if (ob->pose) {
|
||||||
bArmature *arm = static_cast<bArmature *>(ob->data);
|
bArmature *arm = static_cast<bArmature *>(ob->data);
|
||||||
TreeElement *tenla = outliner_add_element(
|
TreeElement *tenla = outliner_add_element(space_outliner, ob, te, TSE_POSE_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_POSE_BASE, 0);
|
|
||||||
tenla->name = IFACE_("Pose");
|
tenla->name = IFACE_("Pose");
|
||||||
|
|
||||||
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
|
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
|
||||||
@@ -294,8 +275,7 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
int const_index = 1000; /* ensure unique id for bone constraints */
|
int const_index = 1000; /* ensure unique id for bone constraints */
|
||||||
int a;
|
int a;
|
||||||
LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, a) {
|
LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, a) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, ob, tenla, TSE_POSE_CHANNEL, a);
|
||||||
space_outliner, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
|
|
||||||
ten->name = pchan->name;
|
ten->name = pchan->name;
|
||||||
ten->directdata = pchan;
|
ten->directdata = pchan;
|
||||||
pchan->temp = (void *)ten;
|
pchan->temp = (void *)ten;
|
||||||
@@ -303,13 +283,13 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
if (!BLI_listbase_is_empty(&pchan->constraints)) {
|
if (!BLI_listbase_is_empty(&pchan->constraints)) {
|
||||||
/* Object *target; */
|
/* Object *target; */
|
||||||
TreeElement *tenla1 = outliner_add_element(
|
TreeElement *tenla1 = outliner_add_element(
|
||||||
space_outliner, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
|
space_outliner, ob, ten, TSE_CONSTRAINT_BASE, 0);
|
||||||
tenla1->name = IFACE_("Constraints");
|
tenla1->name = IFACE_("Constraints");
|
||||||
/* char *str; */
|
/* char *str; */
|
||||||
|
|
||||||
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
|
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
|
||||||
TreeElement *ten1 = outliner_add_element(
|
TreeElement *ten1 = outliner_add_element(
|
||||||
space_outliner, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
|
space_outliner, ob, tenla1, TSE_CONSTRAINT, const_index);
|
||||||
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
|
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
|
||||||
target = get_constraint_target(con, &str);
|
target = get_constraint_target(con, &str);
|
||||||
if (str && str[0]) {
|
if (str && str[0]) {
|
||||||
@@ -349,14 +329,13 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
|
|
||||||
/* Pose Groups */
|
/* Pose Groups */
|
||||||
if (!BLI_listbase_is_empty(&ob->pose->agroups)) {
|
if (!BLI_listbase_is_empty(&ob->pose->agroups)) {
|
||||||
TreeElement *ten_bonegrp = outliner_add_element(
|
TreeElement *ten_bonegrp = outliner_add_element(space_outliner, ob, te, TSE_POSEGRP_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
|
|
||||||
ten_bonegrp->name = IFACE_("Bone Groups");
|
ten_bonegrp->name = IFACE_("Bone Groups");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (bActionGroup *, agrp, &ob->pose->agroups, index) {
|
LISTBASE_FOREACH_INDEX (bActionGroup *, agrp, &ob->pose->agroups, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(
|
||||||
space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, index);
|
space_outliner, ob, ten_bonegrp, TSE_POSEGRP, index);
|
||||||
ten->name = agrp->name;
|
ten->name = agrp->name;
|
||||||
ten->directdata = agrp;
|
ten->directdata = agrp;
|
||||||
}
|
}
|
||||||
@@ -364,18 +343,16 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int a = 0; a < ob->totcol; a++) {
|
for (int a = 0; a < ob->totcol; a++) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, ob->mat[a], te, TSE_SOME_ID, a);
|
outliner_add_element(space_outliner, ob->mat[a], te, TSE_SOME_ID, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BLI_listbase_is_empty(&ob->constraints)) {
|
if (!BLI_listbase_is_empty(&ob->constraints)) {
|
||||||
TreeElement *tenla = outliner_add_element(
|
TreeElement *tenla = outliner_add_element(space_outliner, ob, te, TSE_CONSTRAINT_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
|
|
||||||
tenla->name = IFACE_("Constraints");
|
tenla->name = IFACE_("Constraints");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (bConstraint *, con, &ob->constraints, index) {
|
LISTBASE_FOREACH_INDEX (bConstraint *, con, &ob->constraints, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, ob, tenla, TSE_CONSTRAINT, index);
|
||||||
space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, index);
|
|
||||||
#if 0 /* disabled due to constraints system targets recode... code here needs review */
|
#if 0 /* disabled due to constraints system targets recode... code here needs review */
|
||||||
target = get_constraint_target(con, &str);
|
target = get_constraint_target(con, &str);
|
||||||
if (str && str[0]) {
|
if (str && str[0]) {
|
||||||
@@ -395,54 +372,36 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!BLI_listbase_is_empty(&ob->modifiers)) {
|
if (!BLI_listbase_is_empty(&ob->modifiers)) {
|
||||||
TreeElement *ten_mod = outliner_add_element(
|
TreeElement *ten_mod = outliner_add_element(space_outliner, ob, te, TSE_MODIFIER_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
|
|
||||||
ten_mod->name = IFACE_("Modifiers");
|
ten_mod->name = IFACE_("Modifiers");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (ModifierData *, md, &ob->modifiers, index) {
|
LISTBASE_FOREACH_INDEX (ModifierData *, md, &ob->modifiers, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, ob, ten_mod, TSE_MODIFIER, index);
|
||||||
space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
|
|
||||||
ten->name = md->name;
|
ten->name = md->name;
|
||||||
ten->directdata = md;
|
ten->directdata = md;
|
||||||
|
|
||||||
if (md->type == eModifierType_Lattice) {
|
if (md->type == eModifierType_Lattice) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((LatticeModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((LatticeModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eModifierType_Curve) {
|
else if (md->type == eModifierType_Curve) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((CurveModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((CurveModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eModifierType_Armature) {
|
else if (md->type == eModifierType_Armature) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((ArmatureModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((ArmatureModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eModifierType_Hook) {
|
else if (md->type == eModifierType_Hook) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((HookModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((HookModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eModifierType_ParticleSystem) {
|
else if (md->type == eModifierType_ParticleSystem) {
|
||||||
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
|
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
|
||||||
TreeElement *ten_psys;
|
TreeElement *ten_psys;
|
||||||
|
|
||||||
ten_psys = outliner_add_element(space_outliner, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
|
ten_psys = outliner_add_element(space_outliner, ob, te, TSE_LINKED_PSYS, 0);
|
||||||
ten_psys->directdata = psys;
|
ten_psys->directdata = psys;
|
||||||
ten_psys->name = psys->part->id.name + 2;
|
ten_psys->name = psys->part->id.name + 2;
|
||||||
}
|
}
|
||||||
@@ -451,64 +410,45 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
|
|
||||||
/* Grease Pencil modifiers. */
|
/* Grease Pencil modifiers. */
|
||||||
if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) {
|
if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) {
|
||||||
TreeElement *ten_mod = outliner_add_element(
|
TreeElement *ten_mod = outliner_add_element(space_outliner, ob, te, TSE_MODIFIER_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
|
|
||||||
ten_mod->name = IFACE_("Modifiers");
|
ten_mod->name = IFACE_("Modifiers");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) {
|
LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, ob, ten_mod, TSE_MODIFIER, index);
|
||||||
space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
|
|
||||||
ten->name = md->name;
|
ten->name = md->name;
|
||||||
ten->directdata = md;
|
ten->directdata = md;
|
||||||
|
|
||||||
if (md->type == eGpencilModifierType_Armature) {
|
if (md->type == eGpencilModifierType_Armature) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((ArmatureGpencilModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((ArmatureGpencilModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eGpencilModifierType_Hook) {
|
else if (md->type == eGpencilModifierType_Hook) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((HookGpencilModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((HookGpencilModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
else if (md->type == eGpencilModifierType_Lattice) {
|
else if (md->type == eGpencilModifierType_Lattice) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((LatticeGpencilModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((LatticeGpencilModifierData *)md)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grease Pencil effects. */
|
/* Grease Pencil effects. */
|
||||||
if (!BLI_listbase_is_empty(&ob->shader_fx)) {
|
if (!BLI_listbase_is_empty(&ob->shader_fx)) {
|
||||||
TreeElement *ten_fx = outliner_add_element(
|
TreeElement *ten_fx = outliner_add_element(space_outliner, ob, te, TSE_GPENCIL_EFFECT_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_GPENCIL_EFFECT_BASE, 0);
|
|
||||||
ten_fx->name = IFACE_("Effects");
|
ten_fx->name = IFACE_("Effects");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) {
|
LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(
|
||||||
space_outliner, &ten_fx->subtree, ob, ten_fx, TSE_GPENCIL_EFFECT, index);
|
space_outliner, ob, ten_fx, TSE_GPENCIL_EFFECT, index);
|
||||||
ten->name = fx->name;
|
ten->name = fx->name;
|
||||||
ten->directdata = fx;
|
ten->directdata = fx;
|
||||||
|
|
||||||
if (fx->type == eShaderFxType_Swirl) {
|
if (fx->type == eShaderFxType_Swirl) {
|
||||||
outliner_add_element(space_outliner,
|
outliner_add_element(
|
||||||
&ten->subtree,
|
space_outliner, ((SwirlShaderFxData *)fx)->object, ten, TSE_LINKED_OB, 0);
|
||||||
((SwirlShaderFxData *)fx)->object,
|
|
||||||
ten,
|
|
||||||
TSE_LINKED_OB,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -517,14 +457,12 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
if (ELEM(ob->type, OB_MESH, OB_GPENCIL, OB_LATTICE)) {
|
if (ELEM(ob->type, OB_MESH, OB_GPENCIL, OB_LATTICE)) {
|
||||||
const ListBase *defbase = BKE_object_defgroup_list(ob);
|
const ListBase *defbase = BKE_object_defgroup_list(ob);
|
||||||
if (!BLI_listbase_is_empty(defbase)) {
|
if (!BLI_listbase_is_empty(defbase)) {
|
||||||
TreeElement *tenla = outliner_add_element(
|
TreeElement *tenla = outliner_add_element(space_outliner, ob, te, TSE_DEFGROUP_BASE, 0);
|
||||||
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
|
|
||||||
tenla->name = IFACE_("Vertex Groups");
|
tenla->name = IFACE_("Vertex Groups");
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, defbase, index) {
|
LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, defbase, index) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, ob, tenla, TSE_DEFGROUP, index);
|
||||||
space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
|
|
||||||
ten->name = defgroup->name;
|
ten->name = defgroup->name;
|
||||||
ten->directdata = defgroup;
|
ten->directdata = defgroup;
|
||||||
}
|
}
|
||||||
@@ -533,20 +471,19 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
|
|||||||
|
|
||||||
/* duplicated group */
|
/* duplicated group */
|
||||||
if (ob->instance_collection && (ob->transflag & OB_DUPLICOLLECTION)) {
|
if (ob->instance_collection && (ob->transflag & OB_DUPLICOLLECTION)) {
|
||||||
outliner_add_element(
|
outliner_add_element(space_outliner, ob->instance_collection, te, TSE_SOME_ID, 0);
|
||||||
space_outliner, &te->subtree, ob->instance_collection, te, TSE_SOME_ID, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can be inlined if necessary. */
|
/* Can be inlined if necessary. */
|
||||||
static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
||||||
TreeElement *te,
|
TreeElement &te,
|
||||||
TreeStoreElem *tselem,
|
TreeStoreElem *tselem,
|
||||||
ID *id)
|
ID *id)
|
||||||
{
|
{
|
||||||
/* tuck pointer back in object, to construct hierarchy */
|
/* tuck pointer back in object, to construct hierarchy */
|
||||||
if (GS(id->name) == ID_OB) {
|
if (GS(id->name) == ID_OB) {
|
||||||
id->newid = (ID *)te;
|
id->newid = (ID *)&te;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expand specific data always */
|
/* expand specific data always */
|
||||||
@@ -556,19 +493,19 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
BLI_assert_msg(0, "ID type expected to be expanded through new tree-element design");
|
BLI_assert_msg(0, "ID type expected to be expanded through new tree-element design");
|
||||||
break;
|
break;
|
||||||
case ID_OB: {
|
case ID_OB: {
|
||||||
outliner_add_object_contents(space_outliner, te, tselem, (Object *)id);
|
outliner_add_object_contents(space_outliner, &te, tselem, (Object *)id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_ME: {
|
case ID_ME: {
|
||||||
Mesh *me = (Mesh *)id;
|
Mesh *me = (Mesh *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(me->adt)) {
|
if (outliner_animdata_test(me->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, me, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, me, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
outliner_add_element(space_outliner, &te->subtree, me->key, te, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, me->key, &te, TSE_SOME_ID, 0);
|
||||||
for (int a = 0; a < me->totcol; a++) {
|
for (int a = 0; a < me->totcol; a++) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, me->mat[a], te, TSE_SOME_ID, a);
|
outliner_add_element(space_outliner, me->mat[a], &te, TSE_SOME_ID, a);
|
||||||
}
|
}
|
||||||
/* could do tfaces with image links, but the images are not grouped nicely.
|
/* could do tfaces with image links, but the images are not grouped nicely.
|
||||||
* would require going over all tfaces, sort images in use. etc... */
|
* would require going over all tfaces, sort images in use. etc... */
|
||||||
@@ -578,11 +515,11 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
Curve *cu = (Curve *)id;
|
Curve *cu = (Curve *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(cu->adt)) {
|
if (outliner_animdata_test(cu->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, cu, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int a = 0; a < cu->totcol; a++) {
|
for (int a = 0; a < cu->totcol; a++) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, cu->mat[a], te, TSE_SOME_ID, a);
|
outliner_add_element(space_outliner, cu->mat[a], &te, TSE_SOME_ID, a);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -590,40 +527,40 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
MetaBall *mb = (MetaBall *)id;
|
MetaBall *mb = (MetaBall *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(mb->adt)) {
|
if (outliner_animdata_test(mb->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, mb, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int a = 0; a < mb->totcol; a++) {
|
for (int a = 0; a < mb->totcol; a++) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, mb->mat[a], te, TSE_SOME_ID, a);
|
outliner_add_element(space_outliner, mb->mat[a], &te, TSE_SOME_ID, a);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_MA: {
|
case ID_MA: {
|
||||||
Material *ma = (Material *)id;
|
Material *ma = (Material *)id;
|
||||||
if (outliner_animdata_test(ma->adt)) {
|
if (outliner_animdata_test(ma->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, ma, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_TE: {
|
case ID_TE: {
|
||||||
Tex *tex = (Tex *)id;
|
Tex *tex = (Tex *)id;
|
||||||
if (outliner_animdata_test(tex->adt)) {
|
if (outliner_animdata_test(tex->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, tex, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
outliner_add_element(space_outliner, &te->subtree, tex->ima, te, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, tex->ima, &te, TSE_SOME_ID, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_CA: {
|
case ID_CA: {
|
||||||
Camera *ca = (Camera *)id;
|
Camera *ca = (Camera *)id;
|
||||||
if (outliner_animdata_test(ca->adt)) {
|
if (outliner_animdata_test(ca->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, ca, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_CF: {
|
case ID_CF: {
|
||||||
CacheFile *cache_file = (CacheFile *)id;
|
CacheFile *cache_file = (CacheFile *)id;
|
||||||
if (outliner_animdata_test(cache_file->adt)) {
|
if (outliner_animdata_test(cache_file->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, cache_file, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -631,35 +568,35 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
case ID_LA: {
|
case ID_LA: {
|
||||||
Light *la = (Light *)id;
|
Light *la = (Light *)id;
|
||||||
if (outliner_animdata_test(la->adt)) {
|
if (outliner_animdata_test(la->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, la, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, la, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_SPK: {
|
case ID_SPK: {
|
||||||
Speaker *spk = (Speaker *)id;
|
Speaker *spk = (Speaker *)id;
|
||||||
if (outliner_animdata_test(spk->adt)) {
|
if (outliner_animdata_test(spk->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, spk, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_LP: {
|
case ID_LP: {
|
||||||
LightProbe *prb = (LightProbe *)id;
|
LightProbe *prb = (LightProbe *)id;
|
||||||
if (outliner_animdata_test(prb->adt)) {
|
if (outliner_animdata_test(prb->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, prb, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_WO: {
|
case ID_WO: {
|
||||||
World *wrld = (World *)id;
|
World *wrld = (World *)id;
|
||||||
if (outliner_animdata_test(wrld->adt)) {
|
if (outliner_animdata_test(wrld->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, wrld, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_KE: {
|
case ID_KE: {
|
||||||
Key *key = (Key *)id;
|
Key *key = (Key *)id;
|
||||||
if (outliner_animdata_test(key->adt)) {
|
if (outliner_animdata_test(key->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, key, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, key, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -672,14 +609,13 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
bArmature *arm = (bArmature *)id;
|
bArmature *arm = (bArmature *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(arm->adt)) {
|
if (outliner_animdata_test(arm->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, arm, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arm->edbo) {
|
if (arm->edbo) {
|
||||||
int a = 0;
|
int a = 0;
|
||||||
LISTBASE_FOREACH_INDEX (EditBone *, ebone, arm->edbo, a) {
|
LISTBASE_FOREACH_INDEX (EditBone *, ebone, arm->edbo, a) {
|
||||||
TreeElement *ten = outliner_add_element(
|
TreeElement *ten = outliner_add_element(space_outliner, id, &te, TSE_EBONE, a);
|
||||||
space_outliner, &te->subtree, id, te, TSE_EBONE, a);
|
|
||||||
ten->directdata = ebone;
|
ten->directdata = ebone;
|
||||||
ten->name = ebone->name;
|
ten->name = ebone->name;
|
||||||
ebone->temp.p = ten;
|
ebone->temp.p = ten;
|
||||||
@@ -689,20 +625,21 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
static_cast<TreeElement *>(((EditBone *)arm->edbo->first)->temp.p) :
|
static_cast<TreeElement *>(((EditBone *)arm->edbo->first)->temp.p) :
|
||||||
nullptr;
|
nullptr;
|
||||||
while (ten) {
|
while (ten) {
|
||||||
TreeElement *nten = ten->next, *par;
|
TreeElement *nten = ten->next;
|
||||||
|
|
||||||
EditBone *ebone = (EditBone *)ten->directdata;
|
EditBone *ebone = (EditBone *)ten->directdata;
|
||||||
if (ebone->parent) {
|
if (ebone->parent) {
|
||||||
BLI_remlink(&te->subtree, ten);
|
std::unique_ptr ten_uptr = te.child_elements.remove(*ten);
|
||||||
par = static_cast<TreeElement *>(ebone->parent->temp.p);
|
|
||||||
BLI_addtail(&par->subtree, ten);
|
TreeElement *new_parent = static_cast<TreeElement *>(ebone->parent->temp.p);
|
||||||
ten->parent = par;
|
new_parent->child_elements.add_back(std::move(ten_uptr));
|
||||||
}
|
}
|
||||||
ten = nten;
|
ten = nten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* do not extend Armature when we have posemode */
|
/* do not extend Armature when we have posemode */
|
||||||
tselem = TREESTORE(te->parent);
|
tselem = TREESTORE(te.parent);
|
||||||
if (TSE_IS_REAL_ID(tselem) && GS(tselem->id->name) == ID_OB &&
|
if (TSE_IS_REAL_ID(tselem) && GS(tselem->id->name) == ID_OB &&
|
||||||
((Object *)tselem->id)->mode & OB_MODE_POSE) {
|
((Object *)tselem->id)->mode & OB_MODE_POSE) {
|
||||||
/* pass */
|
/* pass */
|
||||||
@@ -710,7 +647,7 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
else {
|
else {
|
||||||
int a = 0;
|
int a = 0;
|
||||||
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
|
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
|
||||||
outliner_add_bone(space_outliner, &te->subtree, id, bone, te, &a);
|
outliner_add_bone(space_outliner, id, bone, &te, &a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -720,12 +657,12 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
|
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(linestyle->adt)) {
|
if (outliner_animdata_test(linestyle->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, linestyle, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int a = 0; a < MAX_MTEX; a++) {
|
for (int a = 0; a < MAX_MTEX; a++) {
|
||||||
if (linestyle->mtex[a]) {
|
if (linestyle->mtex[a]) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
|
outliner_add_element(space_outliner, linestyle->mtex[a]->tex, &te, 0, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -734,50 +671,50 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
bGPdata *gpd = (bGPdata *)id;
|
bGPdata *gpd = (bGPdata *)id;
|
||||||
|
|
||||||
if (outliner_animdata_test(gpd->adt)) {
|
if (outliner_animdata_test(gpd->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, gpd, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: base element for layers? */
|
/* TODO: base element for layers? */
|
||||||
int index = 0;
|
int index = 0;
|
||||||
LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) {
|
LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, index);
|
outliner_add_element(space_outliner, gpl, &te, TSE_GP_LAYER, index);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_GR: {
|
case ID_GR: {
|
||||||
/* Don't expand for instances, creates too many elements. */
|
/* Don't expand for instances, creates too many elements. */
|
||||||
if (!(te->parent && te->parent->idcode == ID_OB)) {
|
if (!(te.parent && te.parent->idcode == ID_OB)) {
|
||||||
Collection *collection = (Collection *)id;
|
Collection *collection = (Collection *)id;
|
||||||
outliner_add_collection_recursive(space_outliner, collection, te);
|
outliner_add_collection_recursive(space_outliner, collection, &te);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_CV: {
|
case ID_CV: {
|
||||||
Curves *curves = (Curves *)id;
|
Curves *curves = (Curves *)id;
|
||||||
if (outliner_animdata_test(curves->adt)) {
|
if (outliner_animdata_test(curves->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, curves, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, curves, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_PT: {
|
case ID_PT: {
|
||||||
PointCloud *pointcloud = (PointCloud *)id;
|
PointCloud *pointcloud = (PointCloud *)id;
|
||||||
if (outliner_animdata_test(pointcloud->adt)) {
|
if (outliner_animdata_test(pointcloud->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, pointcloud, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, pointcloud, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_VO: {
|
case ID_VO: {
|
||||||
Volume *volume = (Volume *)id;
|
Volume *volume = (Volume *)id;
|
||||||
if (outliner_animdata_test(volume->adt)) {
|
if (outliner_animdata_test(volume->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, volume, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, volume, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_SIM: {
|
case ID_SIM: {
|
||||||
Simulation *simulation = (Simulation *)id;
|
Simulation *simulation = (Simulation *)id;
|
||||||
if (outliner_animdata_test(simulation->adt)) {
|
if (outliner_animdata_test(simulation->adt)) {
|
||||||
outliner_add_element(space_outliner, &te->subtree, simulation, te, TSE_ANIM_DATA, 0);
|
outliner_add_element(space_outliner, simulation, &te, TSE_ANIM_DATA, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -787,7 +724,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||||
ListBase *lb,
|
|
||||||
void *idv,
|
void *idv,
|
||||||
TreeElement *parent,
|
TreeElement *parent,
|
||||||
short type,
|
short type,
|
||||||
@@ -823,27 +759,38 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||||||
BLI_assert(TREESTORE_ID_TYPE(id));
|
BLI_assert(TREESTORE_ID_TYPE(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *te = MEM_new<TreeElement>(__func__);
|
std::unique_ptr<TreeElement> te_uptr = std::make_unique<TreeElement>();
|
||||||
/* add to the visual tree */
|
TreeElement &te = *te_uptr;
|
||||||
BLI_addtail(lb, te);
|
|
||||||
|
/* Add to the visual tree. Moves ownership the the proper element storage. */
|
||||||
|
if (parent) {
|
||||||
|
parent->child_elements.add_back(std::move(te_uptr));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
space_outliner->runtime->root_elements.add_back(std::move(te_uptr));
|
||||||
|
}
|
||||||
|
|
||||||
/* add to the storage */
|
/* add to the storage */
|
||||||
check_persistent(space_outliner, te, id, type, index);
|
check_persistent(space_outliner, te, id, type, index);
|
||||||
TreeStoreElem *tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
|
|
||||||
/* if we are searching for something expand to see child elements */
|
/* if we are searching for something expand to see child elements */
|
||||||
if (SEARCHING_OUTLINER(space_outliner)) {
|
if (SEARCHING_OUTLINER(space_outliner)) {
|
||||||
tselem->flag |= TSE_CHILDSEARCH;
|
tselem->flag |= TSE_CHILDSEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
te->parent = parent;
|
if (te.parent != parent) {
|
||||||
te->index = index; /* For data arrays. */
|
printf("error\n");
|
||||||
|
}
|
||||||
|
BLI_assert(te.parent == parent);
|
||||||
|
te.index = index; /* For data arrays. */
|
||||||
|
|
||||||
/* New inheritance based element representation. Not all element types support this yet,
|
/* New inheritance based element representation. Not all element types support this yet,
|
||||||
* eventually it should replace #TreeElement entirely. */
|
* eventually it should replace #TreeElement entirely. */
|
||||||
te->abstract_element = AbstractTreeElement::createFromType(type, *te, idv);
|
te.abstract_element = AbstractTreeElement::createFromType(type, te, idv);
|
||||||
if (te->abstract_element) {
|
if (te.abstract_element) {
|
||||||
/* Element types ported to the new design are expected to have their name set at this point! */
|
/* Element types ported to the new design are expected to have their name set at this point! */
|
||||||
BLI_assert(te->name != nullptr);
|
BLI_assert(te.name != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
|
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
|
||||||
@@ -865,7 +812,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||||||
/* pass */
|
/* pass */
|
||||||
}
|
}
|
||||||
else if (type == TSE_SOME_ID) {
|
else if (type == TSE_SOME_ID) {
|
||||||
if (!te->abstract_element) {
|
if (!te.abstract_element) {
|
||||||
BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design");
|
BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -873,7 +820,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||||||
TSE_LIBRARY_OVERRIDE_BASE,
|
TSE_LIBRARY_OVERRIDE_BASE,
|
||||||
TSE_LIBRARY_OVERRIDE,
|
TSE_LIBRARY_OVERRIDE,
|
||||||
TSE_LIBRARY_OVERRIDE_OPERATION)) {
|
TSE_LIBRARY_OVERRIDE_OPERATION)) {
|
||||||
if (!te->abstract_element) {
|
if (!te.abstract_element) {
|
||||||
BLI_assert_msg(0,
|
BLI_assert_msg(0,
|
||||||
"Expected override types to be ported to new Outliner tree-element design");
|
"Expected override types to be ported to new Outliner tree-element design");
|
||||||
}
|
}
|
||||||
@@ -884,21 +831,21 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||||||
|
|
||||||
/* The new type design sets the name already, don't override that here. We need to figure out
|
/* The new type design sets the name already, don't override that here. We need to figure out
|
||||||
* how to deal with the idcode for non-TSE_SOME_ID types still. Some rely on it... */
|
* how to deal with the idcode for non-TSE_SOME_ID types still. Some rely on it... */
|
||||||
if (!te->abstract_element) {
|
if (!te.abstract_element) {
|
||||||
te->name = id->name + 2; /* Default, can be overridden by Library or non-ID data. */
|
te.name = id->name + 2; /* Default, can be overridden by Library or non-ID data. */
|
||||||
}
|
}
|
||||||
te->idcode = GS(id->name);
|
te.idcode = GS(id->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expand) {
|
if (!expand) {
|
||||||
/* Pass */
|
/* Pass */
|
||||||
}
|
}
|
||||||
else if (te->abstract_element && te->abstract_element->isExpandValid()) {
|
else if (te.abstract_element && te.abstract_element->isExpandValid()) {
|
||||||
tree_element_expand(*te->abstract_element, *space_outliner);
|
tree_element_expand(*te.abstract_element, *space_outliner);
|
||||||
}
|
}
|
||||||
else if (type == TSE_SOME_ID) {
|
else if (type == TSE_SOME_ID) {
|
||||||
/* ID types not (fully) ported to new design yet. */
|
/* ID types not (fully) ported to new design yet. */
|
||||||
if (te->abstract_element->expandPoll(*space_outliner)) {
|
if (te.abstract_element->expandPoll(*space_outliner)) {
|
||||||
outliner_add_id_contents(space_outliner, te, tselem, id);
|
outliner_add_id_contents(space_outliner, te, tselem, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -919,7 +866,17 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||||||
BLI_assert_msg(false, "Element type should already use new AbstractTreeElement design");
|
BLI_assert_msg(false, "Element type should already use new AbstractTreeElement design");
|
||||||
}
|
}
|
||||||
|
|
||||||
return te;
|
return &te;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||||
|
void *idv,
|
||||||
|
SubTree &subtree,
|
||||||
|
short type,
|
||||||
|
short index,
|
||||||
|
const bool expand)
|
||||||
|
{
|
||||||
|
return outliner_add_element(space_outliner, idv, subtree.parent(), type, index, expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================= */
|
/* ======================================================= */
|
||||||
@@ -931,12 +888,11 @@ BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collec
|
|||||||
}
|
}
|
||||||
|
|
||||||
BLI_INLINE void outliner_add_collection_objects(SpaceOutliner *space_outliner,
|
BLI_INLINE void outliner_add_collection_objects(SpaceOutliner *space_outliner,
|
||||||
ListBase *tree,
|
|
||||||
Collection *collection,
|
Collection *collection,
|
||||||
TreeElement *parent)
|
TreeElement *parent)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||||
outliner_add_element(space_outliner, tree, cob->ob, parent, TSE_SOME_ID, 0);
|
outliner_add_element(space_outliner, cob->ob, parent, TSE_SOME_ID, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,12 +903,11 @@ TreeElement *outliner_add_collection_recursive(SpaceOutliner *space_outliner,
|
|||||||
outliner_add_collection_init(ten, collection);
|
outliner_add_collection_init(ten, collection);
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||||
outliner_add_element(
|
outliner_add_element(space_outliner, &child->collection->id, ten, TSE_SOME_ID, 0);
|
||||||
space_outliner, &ten->subtree, &child->collection->id, ten, TSE_SOME_ID, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space_outliner->outlinevis != SO_SCENES) {
|
if (space_outliner->outlinevis != SO_SCENES) {
|
||||||
outliner_add_collection_objects(space_outliner, &ten->subtree, collection, ten);
|
outliner_add_collection_objects(space_outliner, collection, ten);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ten;
|
return ten;
|
||||||
@@ -1504,7 +1459,7 @@ static bool outliner_element_visible_get(ViewLayer *view_layer,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool outliner_filter_has_name(TreeElement *te, const char *name, int flags)
|
static bool outliner_filter_has_name(const TreeElement &te, const char *name, int flags)
|
||||||
{
|
{
|
||||||
int fn_flag = 0;
|
int fn_flag = 0;
|
||||||
|
|
||||||
@@ -1512,7 +1467,7 @@ static bool outliner_filter_has_name(TreeElement *te, const char *name, int flag
|
|||||||
fn_flag |= FNM_CASEFOLD;
|
fn_flag |= FNM_CASEFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fnmatch(name, te->name, fn_flag) == 0;
|
return fnmatch(name, te.name, fn_flag) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool outliner_element_is_collection_or_object(TreeElement *te)
|
static bool outliner_element_is_collection_or_object(TreeElement *te)
|
||||||
@@ -1531,54 +1486,57 @@ static bool outliner_element_is_collection_or_object(TreeElement *te)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TreeElement *outliner_extract_children_from_subtree(TreeElement *element,
|
static SubTree::iterator outliner_extract_children_from_subtree(
|
||||||
ListBase *parent_subtree)
|
SubTree::iterator te_iter,
|
||||||
|
/* The tree the given elemet is in. */
|
||||||
|
SubTree &parent_tree)
|
||||||
{
|
{
|
||||||
TreeElement *te_next = element->next;
|
TreeElement &te = *te_iter;
|
||||||
|
SubTree::iterator te_next = std::next(te_iter);
|
||||||
|
|
||||||
if (outliner_element_is_collection_or_object(element)) {
|
BLI_assert(parent_tree.has_child(te));
|
||||||
TreeElement *te_prev = nullptr;
|
|
||||||
for (TreeElement *te = static_cast<TreeElement *>(element->subtree.last); te; te = te_prev) {
|
|
||||||
te_prev = te->prev;
|
|
||||||
|
|
||||||
if (!outliner_element_is_collection_or_object(te)) {
|
if (outliner_element_is_collection_or_object(&te)) {
|
||||||
|
for (std::reverse_iterator child_iter = te.child_elements.rbegin();
|
||||||
|
child_iter != te.child_elements.rend();
|
||||||
|
++child_iter) {
|
||||||
|
TreeElement &child = *child_iter;
|
||||||
|
|
||||||
|
if (!outliner_element_is_collection_or_object(&child)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
te_next = te;
|
std::unique_ptr floating_child = te.child_elements.remove(child);
|
||||||
BLI_remlink(&element->subtree, te);
|
parent_tree.insert_before(te_iter, std::move(floating_child));
|
||||||
BLI_insertlinkafter(parent_subtree, element->prev, te);
|
te_next = child_iter.base();
|
||||||
te->parent = element->parent;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outliner_free_tree_element(element, parent_subtree);
|
parent_tree.remove(te);
|
||||||
return te_next;
|
return te_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int outliner_filter_subtree(SpaceOutliner *space_outliner,
|
static int outliner_filter_subtree(SpaceOutliner *space_outliner,
|
||||||
ViewLayer *view_layer,
|
ViewLayer *view_layer,
|
||||||
ListBase *lb,
|
SubTree &subtree,
|
||||||
const char *search_string,
|
const char *search_string,
|
||||||
const int exclude_filter)
|
const int exclude_filter)
|
||||||
{
|
{
|
||||||
TreeElement *te, *te_next;
|
for (SubTree::iterator te_iter = subtree.begin(); te_iter != subtree.end(); ++te_iter) {
|
||||||
TreeStoreElem *tselem;
|
TreeElement &te = *te_iter;
|
||||||
|
|
||||||
for (te = static_cast<TreeElement *>(lb->first); te; te = te_next) {
|
if ((outliner_element_visible_get(view_layer, &te, exclude_filter) == false)) {
|
||||||
te_next = te->next;
|
|
||||||
if ((outliner_element_visible_get(view_layer, te, exclude_filter) == false)) {
|
|
||||||
/* Don't free the tree, but extract the children from the parent and add to this tree. */
|
/* Don't free the tree, but extract the children from the parent and add to this tree. */
|
||||||
/* This also needs filtering the subtree prior (see T69246). */
|
/* This also needs filtering the subtree prior (see T69246). */
|
||||||
outliner_filter_subtree(
|
outliner_filter_subtree(
|
||||||
space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
|
space_outliner, view_layer, te.child_elements, search_string, exclude_filter);
|
||||||
te_next = outliner_extract_children_from_subtree(te, lb);
|
te_iter = outliner_extract_children_from_subtree(te_iter, subtree);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
|
if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
|
||||||
/* Filter subtree too. */
|
/* Filter subtree too. */
|
||||||
outliner_filter_subtree(
|
outliner_filter_subtree(
|
||||||
space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
|
space_outliner, view_layer, te.child_elements, search_string, exclude_filter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1589,31 +1547,31 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner,
|
|||||||
* - otherwise, we can't see within the subtree and the item doesn't match,
|
* - otherwise, we can't see within the subtree and the item doesn't match,
|
||||||
* so these can be safely ignored (i.e. the subtree can get freed)
|
* so these can be safely ignored (i.e. the subtree can get freed)
|
||||||
*/
|
*/
|
||||||
tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
|
|
||||||
/* flag as not a found item */
|
/* flag as not a found item */
|
||||||
tselem->flag &= ~TSE_SEARCHMATCH;
|
tselem->flag &= ~TSE_SEARCHMATCH;
|
||||||
|
|
||||||
if ((!TSELEM_OPEN(tselem, space_outliner)) ||
|
if ((!TSELEM_OPEN(tselem, space_outliner)) ||
|
||||||
outliner_filter_subtree(
|
outliner_filter_subtree(
|
||||||
space_outliner, view_layer, &te->subtree, search_string, exclude_filter) == 0) {
|
space_outliner, view_layer, te.child_elements, search_string, exclude_filter) == 0) {
|
||||||
outliner_free_tree_element(te, lb);
|
subtree.remove(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
|
|
||||||
/* flag as a found item - we can then highlight it */
|
/* flag as a found item - we can then highlight it */
|
||||||
tselem->flag |= TSE_SEARCHMATCH;
|
tselem->flag |= TSE_SEARCHMATCH;
|
||||||
|
|
||||||
/* filter subtree too */
|
/* filter subtree too */
|
||||||
outliner_filter_subtree(
|
outliner_filter_subtree(
|
||||||
space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
|
space_outliner, view_layer, te.child_elements, search_string, exclude_filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there are still items in the list, that means that there were still some matches */
|
/* if there are still items in the list, that means that there were still some matches */
|
||||||
return (BLI_listbase_is_empty(lb) == false);
|
return !subtree.is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_layer)
|
static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_layer)
|
||||||
@@ -1636,8 +1594,11 @@ static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_
|
|||||||
search_string = search_buff;
|
search_string = search_buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
outliner_filter_subtree(
|
outliner_filter_subtree(space_outliner,
|
||||||
space_outliner, view_layer, &space_outliner->tree, search_string, exclude_filter);
|
view_layer,
|
||||||
|
space_outliner->runtime->root_elements,
|
||||||
|
search_string,
|
||||||
|
exclude_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void outliner_clear_newid_from_main(Main *bmain)
|
static void outliner_clear_newid_from_main(Main *bmain)
|
||||||
@@ -1691,8 +1652,7 @@ void outliner_build_tree(Main *mainvar,
|
|||||||
OutlinerTreeElementFocus focus;
|
OutlinerTreeElementFocus focus;
|
||||||
outliner_store_scrolling_position(space_outliner, region, &focus);
|
outliner_store_scrolling_position(space_outliner, region, &focus);
|
||||||
|
|
||||||
outliner_free_tree(&space_outliner->tree);
|
outliner_cleanup_tree(space_outliner);
|
||||||
outliner_storage_cleanup(space_outliner);
|
|
||||||
|
|
||||||
space_outliner->runtime->tree_display = AbstractTreeDisplay::createFromDisplayMode(
|
space_outliner->runtime->tree_display = AbstractTreeDisplay::createFromDisplayMode(
|
||||||
space_outliner->outlinevis, *space_outliner);
|
space_outliner->outlinevis, *space_outliner);
|
||||||
@@ -1701,7 +1661,8 @@ void outliner_build_tree(Main *mainvar,
|
|||||||
BLI_assert(space_outliner->runtime->tree_display != nullptr);
|
BLI_assert(space_outliner->runtime->tree_display != nullptr);
|
||||||
|
|
||||||
TreeSourceData source_data{*mainvar, *scene, *view_layer};
|
TreeSourceData source_data{*mainvar, *scene, *view_layer};
|
||||||
space_outliner->tree = space_outliner->runtime->tree_display->buildTree(source_data);
|
space_outliner->runtime->root_elements = space_outliner->runtime->tree_display->buildTree(
|
||||||
|
source_data);
|
||||||
|
|
||||||
if ((space_outliner->flag & SO_SKIP_SORT_ALPHA) == 0) {
|
if ((space_outliner->flag & SO_SKIP_SORT_ALPHA) == 0) {
|
||||||
outliner_sort(&space_outliner->tree);
|
outliner_sort(&space_outliner->tree);
|
||||||
|
@@ -70,8 +70,7 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *space_outliner,
|
|||||||
return te_iter;
|
return te_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLI_listbase_is_empty(&te_iter->subtree) ||
|
if (te_iter->child_elements.is_empty() || !TSELEM_OPEN(TREESTORE(te_iter), space_outliner)) {
|
||||||
!TSELEM_OPEN(TREESTORE(te_iter), space_outliner)) {
|
|
||||||
/* No need for recursion. */
|
/* No need for recursion. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -95,35 +94,31 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *space_outliner,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *parent_te,
|
static TreeElement *outliner_find_item_at_x_in_row_recursive(TreeElement *parent_te,
|
||||||
float view_co_x,
|
float view_co_x,
|
||||||
bool *r_is_merged_icon)
|
bool *r_is_merged_icon)
|
||||||
{
|
{
|
||||||
TreeElement *child_te = static_cast<TreeElement *>(parent_te->subtree.first);
|
for (TreeElement &child_te : parent_te->child_elements) {
|
||||||
|
const bool over_element = (view_co_x > child_te.xs) && (view_co_x < child_te.xend);
|
||||||
while (child_te) {
|
if ((child_te.flag & TE_ICONROW) && over_element) {
|
||||||
const bool over_element = (view_co_x > child_te->xs) && (view_co_x < child_te->xend);
|
return &child_te;
|
||||||
if ((child_te->flag & TE_ICONROW) && over_element) {
|
|
||||||
return child_te;
|
|
||||||
}
|
}
|
||||||
if ((child_te->flag & TE_ICONROW_MERGED) && over_element) {
|
if ((child_te.flag & TE_ICONROW_MERGED) && over_element) {
|
||||||
if (r_is_merged_icon) {
|
if (r_is_merged_icon) {
|
||||||
*r_is_merged_icon = true;
|
*r_is_merged_icon = true;
|
||||||
}
|
}
|
||||||
return child_te;
|
return &child_te;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *te = outliner_find_item_at_x_in_row_recursive(
|
TreeElement *te = outliner_find_item_at_x_in_row_recursive(
|
||||||
child_te, view_co_x, r_is_merged_icon);
|
&child_te, view_co_x, r_is_merged_icon);
|
||||||
if (te != child_te) {
|
if (te != &child_te) {
|
||||||
return te;
|
return te;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_te = child_te->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return parent if no child is hovered */
|
/* return parent if no child is hovered */
|
||||||
return (TreeElement *)parent_te;
|
return parent_te;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *space_outliner,
|
TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *space_outliner,
|
||||||
|
@@ -39,6 +39,10 @@
|
|||||||
|
|
||||||
namespace blender::ed::outliner {
|
namespace blender::ed::outliner {
|
||||||
|
|
||||||
|
SpaceOutliner_Runtime::SpaceOutliner_Runtime() : root_elements()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SpaceOutliner_Runtime::SpaceOutliner_Runtime(const SpaceOutliner_Runtime & /*other*/)
|
SpaceOutliner_Runtime::SpaceOutliner_Runtime(const SpaceOutliner_Runtime & /*other*/)
|
||||||
: tree_display(nullptr), tree_hash(nullptr)
|
: tree_display(nullptr), tree_hash(nullptr)
|
||||||
{
|
{
|
||||||
@@ -345,7 +349,6 @@ static void outliner_free(SpaceLink *sl)
|
|||||||
{
|
{
|
||||||
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
|
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
|
||||||
|
|
||||||
outliner_free_tree(&space_outliner->tree);
|
|
||||||
if (space_outliner->treestore) {
|
if (space_outliner->treestore) {
|
||||||
BLI_mempool_destroy(space_outliner->treestore);
|
BLI_mempool_destroy(space_outliner->treestore);
|
||||||
}
|
}
|
||||||
|
@@ -36,25 +36,26 @@ const char *outliner_idcode_to_plural(short idcode)
|
|||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
void outliner_make_object_parent_hierarchy(ListBase *lb)
|
void outliner_make_object_parent_hierarchy(SubTree &subtree)
|
||||||
{
|
{
|
||||||
/* build hierarchy */
|
/* build hierarchy */
|
||||||
/* XXX also, set extents here... */
|
/* XXX also, set extents here... */
|
||||||
TreeElement *te = static_cast<TreeElement *>(lb->first);
|
for (TreeElement &te : subtree) {
|
||||||
while (te) {
|
TreeStoreElem *tselem = TREESTORE(&te);
|
||||||
TreeElement *ten = te->next;
|
|
||||||
TreeStoreElem *tselem = TREESTORE(te);
|
|
||||||
|
|
||||||
if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_OB) {
|
if ((tselem->type != TSE_SOME_ID) || te.idcode != ID_OB) {
|
||||||
Object *ob = (Object *)tselem->id;
|
continue;
|
||||||
if (ob->parent && ob->parent->id.newid) {
|
|
||||||
BLI_remlink(lb, te);
|
|
||||||
TreeElement *tep = (TreeElement *)ob->parent->id.newid;
|
|
||||||
BLI_addtail(&tep->subtree, te);
|
|
||||||
te->parent = tep;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
te = ten;
|
|
||||||
|
Object *ob = (Object *)tselem->id;
|
||||||
|
if (!ob->parent || !ob->parent->id.newid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeElement *new_parent = reinterpret_cast<TreeElement *>(ob->parent->id.newid);
|
||||||
|
|
||||||
|
std::unique_ptr floating_te = subtree.remove(te);
|
||||||
|
new_parent->child_elements.add_back(std::move(floating_te));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,9 +10,11 @@ struct ListBase;
|
|||||||
|
|
||||||
namespace blender::ed::outliner {
|
namespace blender::ed::outliner {
|
||||||
|
|
||||||
|
class SubTree;
|
||||||
|
|
||||||
const char *outliner_idcode_to_plural(short idcode);
|
const char *outliner_idcode_to_plural(short idcode);
|
||||||
|
|
||||||
void outliner_make_object_parent_hierarchy(ListBase *lb);
|
void outliner_make_object_parent_hierarchy(SubTree &subtree);
|
||||||
bool outliner_animdata_test(const struct AnimData *adt);
|
bool outliner_animdata_test(const struct AnimData *adt);
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
@@ -34,6 +34,7 @@ struct ViewLayer;
|
|||||||
|
|
||||||
namespace blender::ed::outliner {
|
namespace blender::ed::outliner {
|
||||||
|
|
||||||
|
class SubTree;
|
||||||
struct TreeElement;
|
struct TreeElement;
|
||||||
class TreeElementID;
|
class TreeElementID;
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ class AbstractTreeDisplay {
|
|||||||
* Build a tree for this display mode with the Blender context data given in \a source_data and
|
* Build a tree for this display mode with the Blender context data given in \a source_data and
|
||||||
* the view settings in \a space_outliner.
|
* the view settings in \a space_outliner.
|
||||||
*/
|
*/
|
||||||
virtual ListBase buildTree(const TreeSourceData &source_data) = 0;
|
virtual SubTree buildTree(const TreeSourceData &source_data) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define if the display mode should be allowed to show a mode column on the left. This column
|
* Define if the display mode should be allowed to show a mode column on the left. This column
|
||||||
@@ -111,14 +112,14 @@ class TreeDisplayViewLayer final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayViewLayer(SpaceOutliner &space_outliner);
|
TreeDisplayViewLayer(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
bool supportsModeColumn() const override;
|
bool supportsModeColumn() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_view_layer(Scene &, ListBase &, TreeElement *);
|
void add_view_layer(Scene &, SubTree &);
|
||||||
void add_layer_collections_recursive(ListBase &, ListBase &, TreeElement &);
|
void add_layer_collections_recursive(ListBase &, TreeElement &);
|
||||||
void add_layer_collection_objects(ListBase &, LayerCollection &, TreeElement &);
|
void add_layer_collection_objects(LayerCollection &, TreeElement &);
|
||||||
void add_layer_collection_objects_children(TreeElement &);
|
void add_layer_collection_objects_children(TreeElement &);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,10 +133,10 @@ class TreeDisplayLibraries final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayLibraries(SpaceOutliner &space_outliner);
|
TreeDisplayLibraries(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeElement *add_library_contents(Main &, ListBase &, Library *);
|
TreeElement *add_library_contents(Main &, SubTree &, Library *);
|
||||||
bool library_id_filter_poll(const Library *lib, ID *id) const;
|
bool library_id_filter_poll(const Library *lib, ID *id) const;
|
||||||
short id_filter_get() const;
|
short id_filter_get() const;
|
||||||
};
|
};
|
||||||
@@ -150,10 +151,10 @@ class TreeDisplayOverrideLibraryProperties final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayOverrideLibraryProperties(SpaceOutliner &space_outliner);
|
TreeDisplayOverrideLibraryProperties(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListBase add_library_contents(Main &);
|
SubTree add_library_contents(Main &);
|
||||||
short id_filter_get() const;
|
short id_filter_get() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,14 +165,14 @@ class TreeDisplayOverrideLibraryHierarchies final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayOverrideLibraryHierarchies(SpaceOutliner &space_outliner);
|
TreeDisplayOverrideLibraryHierarchies(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
bool is_lazy_built() const override;
|
bool is_lazy_built() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListBase build_hierarchy_for_lib_or_main(Main *bmain,
|
void build_hierarchy_for_lib_or_main(Main *bmain,
|
||||||
TreeElement &parent_te,
|
TreeElement &parent_te,
|
||||||
Library *lib = nullptr);
|
Library *lib = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -190,7 +191,7 @@ class TreeDisplaySequencer final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplaySequencer(SpaceOutliner &space_outliner);
|
TreeDisplaySequencer(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeElement *add_sequencer_contents() const;
|
TreeElement *add_sequencer_contents() const;
|
||||||
@@ -211,7 +212,7 @@ class TreeDisplayIDOrphans final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayIDOrphans(SpaceOutliner &space_outliner);
|
TreeDisplayIDOrphans(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool datablock_has_orphans(ListBase &) const;
|
bool datablock_has_orphans(ListBase &) const;
|
||||||
@@ -227,7 +228,7 @@ class TreeDisplayScenes final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayScenes(SpaceOutliner &space_outliner);
|
TreeDisplayScenes(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
bool supportsModeColumn() const override;
|
bool supportsModeColumn() const override;
|
||||||
};
|
};
|
||||||
@@ -242,7 +243,7 @@ class TreeDisplayDataAPI final : public AbstractTreeDisplay {
|
|||||||
public:
|
public:
|
||||||
TreeDisplayDataAPI(SpaceOutliner &space_outliner);
|
TreeDisplayDataAPI(SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
SubTree buildTree(const TreeSourceData &source_data) override;
|
||||||
|
|
||||||
bool is_lazy_built() const override;
|
bool is_lazy_built() const override;
|
||||||
};
|
};
|
||||||
|
@@ -22,15 +22,15 @@ TreeDisplayDataAPI::TreeDisplayDataAPI(SpaceOutliner &space_outliner)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
PointerRNA mainptr;
|
PointerRNA mainptr;
|
||||||
RNA_main_pointer_create(source_data.bmain, &mainptr);
|
RNA_main_pointer_create(source_data.bmain, &mainptr);
|
||||||
|
|
||||||
TreeElement *te = outliner_add_element(
|
TreeElement *te = outliner_add_element(
|
||||||
&space_outliner_, &tree, (void *)&mainptr, nullptr, TSE_RNA_STRUCT, -1);
|
&space_outliner_, (void *)&mainptr, tree, TSE_RNA_STRUCT, -1);
|
||||||
|
|
||||||
/* On first view open parent data elements */
|
/* On first view open parent data elements */
|
||||||
const int show_opened = !space_outliner_.treestore ||
|
const int show_opened = !space_outliner_.treestore ||
|
||||||
|
@@ -29,9 +29,9 @@ TreeDisplayLibraries::TreeDisplayLibraries(SpaceOutliner &space_outliner)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
{
|
{
|
||||||
/* current file first - mainvar provides tselem with unique pointer - not used */
|
/* current file first - mainvar provides tselem with unique pointer - not used */
|
||||||
@@ -56,13 +56,13 @@ ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* make hierarchy */
|
/* make hierarchy */
|
||||||
for (TreeElement *ten : List<TreeElement>(tree)) {
|
for (TreeElement &ten : tree) {
|
||||||
if (ten == tree.first) {
|
if (&ten == &*tree.begin()) {
|
||||||
/* First item is main, skip. */
|
/* First item is main, skip. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeStoreElem *tselem = TREESTORE(ten);
|
TreeStoreElem *tselem = TREESTORE(&ten);
|
||||||
Library *lib = (Library *)tselem->id;
|
Library *lib = (Library *)tselem->id;
|
||||||
BLI_assert(!lib || (GS(lib->id.name) == ID_LI));
|
BLI_assert(!lib || (GS(lib->id.name) == ID_LI));
|
||||||
if (!lib || !lib->parent) {
|
if (!lib || !lib->parent) {
|
||||||
@@ -73,16 +73,12 @@ ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
|||||||
|
|
||||||
if (tselem->id->tag & LIB_TAG_INDIRECT) {
|
if (tselem->id->tag & LIB_TAG_INDIRECT) {
|
||||||
/* Only remove from 'first level' if lib is not also directly used. */
|
/* Only remove from 'first level' if lib is not also directly used. */
|
||||||
BLI_remlink(&tree, ten);
|
std::unique_ptr<TreeElement> ten_uptr = tree.remove(ten);
|
||||||
BLI_addtail(&parent->subtree, ten);
|
parent->child_elements.add_back(std::move(ten_uptr));
|
||||||
ten->parent = parent;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Else, make a new copy of the libtree for our parent. */
|
/* Else, make a new copy of the libtree for our parent. */
|
||||||
TreeElement *dupten = add_library_contents(*source_data.bmain, parent->subtree, lib);
|
add_library_contents(*source_data.bmain, parent->child_elements, lib);
|
||||||
if (dupten) {
|
|
||||||
dupten->parent = parent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* restore newid pointers */
|
/* restore newid pointers */
|
||||||
@@ -93,7 +89,9 @@ ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, ListBase &lb, Library *lib)
|
TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar,
|
||||||
|
SubTree &subtree,
|
||||||
|
Library *lib)
|
||||||
{
|
{
|
||||||
const short filter_id_type = id_filter_get();
|
const short filter_id_type = id_filter_get();
|
||||||
|
|
||||||
@@ -135,10 +133,10 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, ListBase
|
|||||||
if (!tenlib) {
|
if (!tenlib) {
|
||||||
/* Create library tree element on demand, depending if there are any data-blocks. */
|
/* Create library tree element on demand, depending if there are any data-blocks. */
|
||||||
if (lib) {
|
if (lib) {
|
||||||
tenlib = outliner_add_element(&space_outliner_, &lb, lib, nullptr, TSE_SOME_ID, 0);
|
tenlib = outliner_add_element(&space_outliner_, lib, subtree, TSE_SOME_ID, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tenlib = outliner_add_element(&space_outliner_, &lb, &mainvar, nullptr, TSE_ID_BASE, 0);
|
tenlib = outliner_add_element(&space_outliner_, &mainvar, subtree, TSE_ID_BASE, 0);
|
||||||
tenlib->name = IFACE_("Current File");
|
tenlib->name = IFACE_("Current File");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,15 +149,14 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, ListBase
|
|||||||
ten = tenlib;
|
ten = tenlib;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ten = outliner_add_element(
|
ten = outliner_add_element(&space_outliner_, lib, subtree, TSE_ID_BASE, a);
|
||||||
&space_outliner_, &tenlib->subtree, lib, nullptr, TSE_ID_BASE, a);
|
|
||||||
ten->directdata = lbarray[a];
|
ten->directdata = lbarray[a];
|
||||||
ten->name = outliner_idcode_to_plural(GS(id->name));
|
ten->name = outliner_idcode_to_plural(GS(id->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ID *id : List<ID>(lbarray[a])) {
|
for (ID *id : List<ID>(lbarray[a])) {
|
||||||
if (library_id_filter_poll(lib, id)) {
|
if (library_id_filter_poll(lib, id)) {
|
||||||
outliner_add_element(&space_outliner_, &ten->subtree, id, ten, TSE_SOME_ID, 0);
|
outliner_add_element(&space_outliner_, id, ten, TSE_SOME_ID, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,9 +27,9 @@ TreeDisplayIDOrphans::TreeDisplayIDOrphans(SpaceOutliner &space_outliner)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
ListBase *lbarray[INDEX_ID_MAX];
|
ListBase *lbarray[INDEX_ID_MAX];
|
||||||
short filter_id_type = (space_outliner_.filter & SO_FILTER_ID_TYPE) ?
|
short filter_id_type = (space_outliner_.filter & SO_FILTER_ID_TYPE) ?
|
||||||
space_outliner_.filter_id_type :
|
space_outliner_.filter_id_type :
|
||||||
@@ -56,7 +56,7 @@ ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
|
|||||||
TreeElement *te = nullptr;
|
TreeElement *te = nullptr;
|
||||||
if (!filter_id_type) {
|
if (!filter_id_type) {
|
||||||
ID *id = (ID *)lbarray[a]->first;
|
ID *id = (ID *)lbarray[a]->first;
|
||||||
te = outliner_add_element(&space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0);
|
te = outliner_add_element(&space_outliner_, lbarray[a], tree, TSE_ID_BASE, 0);
|
||||||
te->directdata = lbarray[a];
|
te->directdata = lbarray[a];
|
||||||
te->name = outliner_idcode_to_plural(GS(id->name));
|
te->name = outliner_idcode_to_plural(GS(id->name));
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,7 @@ ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
|
|||||||
/* Add the orphaned data-blocks - these will not be added with any subtrees attached. */
|
/* Add the orphaned data-blocks - these will not be added with any subtrees attached. */
|
||||||
for (ID *id : List<ID>(lbarray[a])) {
|
for (ID *id : List<ID>(lbarray[a])) {
|
||||||
if (ID_REAL_USERS(id) <= 0) {
|
if (ID_REAL_USERS(id) <= 0) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner_, id, te ? te->child_elements : tree, TSE_SOME_ID, 0);
|
||||||
&space_outliner_, (te) ? &te->subtree : &tree, id, te, TSE_SOME_ID, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,13 +33,13 @@ TreeDisplayOverrideLibraryHierarchies::TreeDisplayOverrideLibraryHierarchies(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
/* First step: Build "Current File" hierarchy. */
|
/* First step: Build "Current File" hierarchy. */
|
||||||
TreeElement *current_file_te = outliner_add_element(
|
TreeElement *current_file_te = outliner_add_element(
|
||||||
&space_outliner_, &tree, source_data.bmain, nullptr, TSE_ID_BASE, -1);
|
&space_outliner_, source_data.bmain, tree, TSE_ID_BASE, -1);
|
||||||
current_file_te->name = IFACE_("Current File");
|
current_file_te->name = IFACE_("Current File");
|
||||||
AbstractTreeElement::uncollapse_by_default(current_file_te);
|
AbstractTreeElement::uncollapse_by_default(current_file_te);
|
||||||
{
|
{
|
||||||
@@ -48,7 +48,7 @@ ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &
|
|||||||
/* Add dummy child if there's nothing to display. */
|
/* Add dummy child if there's nothing to display. */
|
||||||
if (BLI_listbase_is_empty(¤t_file_te->subtree)) {
|
if (BLI_listbase_is_empty(¤t_file_te->subtree)) {
|
||||||
TreeElement *dummy_te = outliner_add_element(
|
TreeElement *dummy_te = outliner_add_element(
|
||||||
&space_outliner_, ¤t_file_te->subtree, nullptr, current_file_te, TSE_ID_BASE, 0);
|
&space_outliner_, nullptr, current_file_te, TSE_ID_BASE, 0);
|
||||||
dummy_te->name = IFACE_("No Library Overrides");
|
dummy_te->name = IFACE_("No Library Overrides");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,19 +56,18 @@ ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &
|
|||||||
/* Second step: Build hierarchies for external libraries. */
|
/* Second step: Build hierarchies for external libraries. */
|
||||||
for (Library *lib = (Library *)source_data.bmain->libraries.first; lib;
|
for (Library *lib = (Library *)source_data.bmain->libraries.first; lib;
|
||||||
lib = (Library *)lib->id.next) {
|
lib = (Library *)lib->id.next) {
|
||||||
TreeElement *tenlib = outliner_add_element(
|
TreeElement *tenlib = outliner_add_element(&space_outliner_, lib, tree, TSE_SOME_ID, 0);
|
||||||
&space_outliner_, &tree, lib, nullptr, TSE_SOME_ID, 0);
|
|
||||||
build_hierarchy_for_lib_or_main(source_data.bmain, *tenlib, lib);
|
build_hierarchy_for_lib_or_main(source_data.bmain, *tenlib, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove top level library elements again that don't contain any overrides. */
|
/* Remove top level library elements again that don't contain any overrides. */
|
||||||
LISTBASE_FOREACH_MUTABLE (TreeElement *, top_level_te, &tree) {
|
for (TreeElement &top_level_te : tree) {
|
||||||
if (top_level_te == current_file_te) {
|
if (&top_level_te == current_file_te) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLI_listbase_is_empty(&top_level_te->subtree)) {
|
if (top_level_te.child_elements.is_empty()) {
|
||||||
outliner_free_tree_element(top_level_te, &tree);
|
tree.remove(top_level_te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,11 +114,10 @@ class OverrideIDHierarchyBuilder {
|
|||||||
TreeElement &te_to_expand);
|
TreeElement &te_to_expand);
|
||||||
};
|
};
|
||||||
|
|
||||||
ListBase TreeDisplayOverrideLibraryHierarchies::build_hierarchy_for_lib_or_main(
|
void TreeDisplayOverrideLibraryHierarchies::build_hierarchy_for_lib_or_main(Main *bmain,
|
||||||
Main *bmain, TreeElement &parent_te, Library *lib)
|
TreeElement &parent_te,
|
||||||
|
Library *lib)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
|
||||||
|
|
||||||
/* Ensure #Main.relations contains the latest mapping of relations. Must be freed before
|
/* Ensure #Main.relations contains the latest mapping of relations. Must be freed before
|
||||||
* returning. */
|
* returning. */
|
||||||
BKE_main_relations_create(bmain, 0);
|
BKE_main_relations_create(bmain, 0);
|
||||||
@@ -141,26 +139,20 @@ ListBase TreeDisplayOverrideLibraryHierarchies::build_hierarchy_for_lib_or_main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *new_base_te = id_base_te_map.lookup_or_add_cb(GS(iter_id->name), [&]() {
|
TreeElement *new_base_te = id_base_te_map.lookup_or_add_cb(GS(iter_id->name), [&]() {
|
||||||
TreeElement *new_te = outliner_add_element(&space_outliner_,
|
TreeElement *new_te = outliner_add_element(
|
||||||
&parent_te.subtree,
|
&space_outliner_, lib ? (void *)lib : bmain, &parent_te, TSE_ID_BASE, base_index++);
|
||||||
lib ? (void *)lib : bmain,
|
|
||||||
&parent_te,
|
|
||||||
TSE_ID_BASE,
|
|
||||||
base_index++);
|
|
||||||
new_te->name = outliner_idcode_to_plural(GS(iter_id->name));
|
new_te->name = outliner_idcode_to_plural(GS(iter_id->name));
|
||||||
return new_te;
|
return new_te;
|
||||||
});
|
});
|
||||||
|
|
||||||
TreeElement *new_id_te = outliner_add_element(
|
TreeElement *new_id_te = outliner_add_element(
|
||||||
&space_outliner_, &new_base_te->subtree, iter_id, new_base_te, TSE_SOME_ID, 0, false);
|
&space_outliner_, iter_id, new_base_te, TSE_SOME_ID, 0, false);
|
||||||
|
|
||||||
builder.build_hierarchy_for_ID(*iter_id, *new_id_te);
|
builder.build_hierarchy_for_ID(*iter_id, *new_id_te);
|
||||||
}
|
}
|
||||||
FOREACH_MAIN_ID_END;
|
FOREACH_MAIN_ID_END;
|
||||||
|
|
||||||
BKE_main_relations_free(bmain);
|
BKE_main_relations_free(bmain);
|
||||||
|
|
||||||
return tree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverrideIDHierarchyBuilder::build_hierarchy_for_ID(ID &override_root_id,
|
void OverrideIDHierarchyBuilder::build_hierarchy_for_ID(ID &override_root_id,
|
||||||
@@ -220,7 +212,7 @@ void OverrideIDHierarchyBuilder::build_hierarchy_for_ID_recursive(const ID &pare
|
|||||||
}
|
}
|
||||||
|
|
||||||
TreeElement *new_te = outliner_add_element(
|
TreeElement *new_te = outliner_add_element(
|
||||||
&space_outliner_, &te_to_expand.subtree, &id, &te_to_expand, TSE_SOME_ID, 0, false);
|
&space_outliner_, &id, &te_to_expand, TSE_SOME_ID, 0, false);
|
||||||
|
|
||||||
build_data.sibling_ids.add(&id);
|
build_data.sibling_ids.add(&id);
|
||||||
|
|
||||||
|
@@ -31,12 +31,12 @@ TreeDisplayOverrideLibraryProperties::TreeDisplayOverrideLibraryProperties(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayOverrideLibraryProperties::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayOverrideLibraryProperties::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = add_library_contents(*source_data.bmain);
|
SubTree tree = add_library_contents(*source_data.bmain);
|
||||||
|
|
||||||
for (TreeElement *top_level_te : List<TreeElement>(tree)) {
|
for (TreeElement &top_level_te : tree) {
|
||||||
TreeStoreElem *tselem = TREESTORE(top_level_te);
|
TreeStoreElem *tselem = TREESTORE(&top_level_te);
|
||||||
if (!tselem->used) {
|
if (!tselem->used) {
|
||||||
tselem->flag &= ~TSE_CLOSED;
|
tselem->flag &= ~TSE_CLOSED;
|
||||||
}
|
}
|
||||||
@@ -45,9 +45,9 @@ ListBase TreeDisplayOverrideLibraryProperties::buildTree(const TreeSourceData &s
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayOverrideLibraryProperties::add_library_contents(Main &mainvar)
|
SubTree TreeDisplayOverrideLibraryProperties::add_library_contents(Main &mainvar)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
const short filter_id_type = id_filter_get();
|
const short filter_id_type = id_filter_get();
|
||||||
|
|
||||||
@@ -82,33 +82,32 @@ ListBase TreeDisplayOverrideLibraryProperties::add_library_contents(Main &mainva
|
|||||||
|
|
||||||
/* Create data-block list parent element on demand. */
|
/* Create data-block list parent element on demand. */
|
||||||
TreeElement *id_base_te = nullptr;
|
TreeElement *id_base_te = nullptr;
|
||||||
ListBase *lb_to_expand = &tree;
|
SubTree *subtree_to_expand = &tree;
|
||||||
|
|
||||||
if (!filter_id_type) {
|
if (!filter_id_type) {
|
||||||
id_base_te = outliner_add_element(
|
id_base_te = outliner_add_element(&space_outliner_, lbarray[a], tree, TSE_ID_BASE, 0);
|
||||||
&space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0);
|
|
||||||
id_base_te->directdata = lbarray[a];
|
id_base_te->directdata = lbarray[a];
|
||||||
id_base_te->name = outliner_idcode_to_plural(GS(id->name));
|
id_base_te->name = outliner_idcode_to_plural(GS(id->name));
|
||||||
|
|
||||||
lb_to_expand = &id_base_te->subtree;
|
subtree_to_expand = &id_base_te->child_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ID *id : List<ID>(lbarray[a])) {
|
for (ID *id : List<ID>(lbarray[a])) {
|
||||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id)) {
|
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id)) {
|
||||||
TreeElement *override_tree_element = outliner_add_element(
|
TreeElement *override_tree_element = outliner_add_element(
|
||||||
&space_outliner_, lb_to_expand, id, id_base_te, TSE_LIBRARY_OVERRIDE_BASE, 0);
|
&space_outliner_, id, id_base_te, TSE_LIBRARY_OVERRIDE_BASE, 0);
|
||||||
|
|
||||||
if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
|
if (override_tree_element->child_elements.is_empty()) {
|
||||||
outliner_free_tree_element(override_tree_element, lb_to_expand);
|
subtree_to_expand->remove(*override_tree_element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove ID base elements that turn out to be empty. */
|
/* Remove ID base elements that turn out to be empty. */
|
||||||
LISTBASE_FOREACH_MUTABLE (TreeElement *, te, &tree) {
|
for (TreeElement &te : tree) {
|
||||||
if (BLI_listbase_is_empty(&te->subtree)) {
|
if (te.child_elements.is_empty()) {
|
||||||
outliner_free_tree_element(te, &tree);
|
tree.remove(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,17 +31,16 @@ bool TreeDisplayScenes::supportsModeColumn() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayScenes::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
/* On first view we open scenes. */
|
/* On first view we open scenes. */
|
||||||
const int show_opened = !space_outliner_.treestore ||
|
const int show_opened = !space_outliner_.treestore ||
|
||||||
!BLI_mempool_len(space_outliner_.treestore);
|
!BLI_mempool_len(space_outliner_.treestore);
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
for (ID *id : List<ID>(source_data.bmain->scenes)) {
|
for (ID *id : List<ID>(source_data.bmain->scenes)) {
|
||||||
Scene *scene = reinterpret_cast<Scene *>(id);
|
Scene *scene = reinterpret_cast<Scene *>(id);
|
||||||
TreeElement *te = outliner_add_element(
|
TreeElement *te = outliner_add_element(&space_outliner_, scene, tree, TSE_SOME_ID, 0);
|
||||||
&space_outliner_, &tree, scene, nullptr, TSE_SOME_ID, 0);
|
|
||||||
TreeStoreElem *tselem = TREESTORE(te);
|
TreeStoreElem *tselem = TREESTORE(te);
|
||||||
|
|
||||||
/* New scene elements open by default */
|
/* New scene elements open by default */
|
||||||
@@ -49,7 +48,7 @@ ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data)
|
|||||||
tselem->flag &= ~TSE_CLOSED;
|
tselem->flag &= ~TSE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
outliner_make_object_parent_hierarchy(&te->subtree);
|
outliner_make_object_parent_hierarchy(te->child_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
|
@@ -28,9 +28,9 @@ TreeDisplaySequencer::TreeDisplaySequencer(SpaceOutliner &space_outliner)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplaySequencer::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree tree;
|
||||||
|
|
||||||
Editing *ed = SEQ_editing_get(source_data.scene);
|
Editing *ed = SEQ_editing_get(source_data.scene);
|
||||||
if (ed == nullptr) {
|
if (ed == nullptr) {
|
||||||
@@ -40,11 +40,10 @@ ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data)
|
|||||||
for (Sequence *seq : List<Sequence>(ed->seqbasep)) {
|
for (Sequence *seq : List<Sequence>(ed->seqbasep)) {
|
||||||
SequenceAddOp op = need_add_seq_dup(seq);
|
SequenceAddOp op = need_add_seq_dup(seq);
|
||||||
if (op == SEQUENCE_DUPLICATE_NONE) {
|
if (op == SEQUENCE_DUPLICATE_NONE) {
|
||||||
outliner_add_element(&space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE, 0);
|
outliner_add_element(&space_outliner_, seq, tree, TSE_SEQUENCE, 0);
|
||||||
}
|
}
|
||||||
else if (op == SEQUENCE_DUPLICATE_ADD) {
|
else if (op == SEQUENCE_DUPLICATE_ADD) {
|
||||||
TreeElement *te = outliner_add_element(
|
TreeElement *te = outliner_add_element(&space_outliner_, seq, tree, TSE_SEQUENCE_DUP, 0);
|
||||||
&space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE_DUP, 0);
|
|
||||||
add_seq_dup(seq, te, 0);
|
add_seq_dup(seq, te, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +100,7 @@ void TreeDisplaySequencer::add_seq_dup(Sequence *seq, TreeElement *te, short ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
|
if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
|
||||||
outliner_add_element(&space_outliner_, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
|
outliner_add_element(&space_outliner_, (void *)p, te, TSE_SEQUENCE, index);
|
||||||
}
|
}
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
@@ -60,9 +60,9 @@ bool TreeDisplayViewLayer::supportsModeColumn() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
|
SubTree TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
|
||||||
{
|
{
|
||||||
ListBase tree = {nullptr};
|
SubTree subtree;
|
||||||
Scene *scene = source_data.scene;
|
Scene *scene = source_data.scene;
|
||||||
show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT);
|
show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT);
|
||||||
|
|
||||||
@@ -74,23 +74,23 @@ ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_view_layer(*scene, tree, (TreeElement *)nullptr);
|
add_view_layer(*scene, subtree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TreeElement &te_view_layer = *outliner_add_element(
|
TreeElement &te_view_layer = *outliner_add_element(
|
||||||
&space_outliner_, &tree, scene, nullptr, TSE_R_LAYER, 0);
|
&space_outliner_, scene, subtree, TSE_R_LAYER, 0);
|
||||||
TREESTORE(&te_view_layer)->flag &= ~TSE_CLOSED;
|
TREESTORE(&te_view_layer)->flag &= ~TSE_CLOSED;
|
||||||
te_view_layer.name = view_layer->name;
|
te_view_layer.name = view_layer->name;
|
||||||
te_view_layer.directdata = view_layer;
|
te_view_layer.directdata = view_layer;
|
||||||
|
|
||||||
add_view_layer(*scene, te_view_layer.subtree, &te_view_layer);
|
add_view_layer(*scene, te_view_layer.child_elements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree;
|
return subtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElement *parent)
|
void TreeDisplayViewLayer::add_view_layer(Scene &scene, SubTree &subtree)
|
||||||
{
|
{
|
||||||
const bool show_children = (space_outliner_.filter & SO_FILTER_NO_CHILDREN) == 0;
|
const bool show_children = (space_outliner_.filter & SO_FILTER_NO_CHILDREN) == 0;
|
||||||
|
|
||||||
@@ -98,18 +98,18 @@ void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElem
|
|||||||
/* Show objects in the view layer. */
|
/* Show objects in the view layer. */
|
||||||
for (Base *base : List<Base>(view_layer_->object_bases)) {
|
for (Base *base : List<Base>(view_layer_->object_bases)) {
|
||||||
TreeElement *te_object = outliner_add_element(
|
TreeElement *te_object = outliner_add_element(
|
||||||
&space_outliner_, &tree, base->object, parent, TSE_SOME_ID, 0);
|
&space_outliner_, base->object, subtree, TSE_SOME_ID, 0);
|
||||||
te_object->directdata = base;
|
te_object->directdata = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_children) {
|
if (show_children) {
|
||||||
outliner_make_object_parent_hierarchy(&tree);
|
outliner_make_object_parent_hierarchy(subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Show collections in the view layer. */
|
/* Show collections in the view layer. */
|
||||||
TreeElement &ten = *outliner_add_element(
|
TreeElement &ten = *outliner_add_element(
|
||||||
&space_outliner_, &tree, &scene, parent, TSE_VIEW_COLLECTION_BASE, 0);
|
&space_outliner_, &scene, subtree, TSE_VIEW_COLLECTION_BASE, 0);
|
||||||
ten.name = IFACE_("Scene Collection");
|
ten.name = IFACE_("Scene Collection");
|
||||||
TREESTORE(&ten)->flag &= ~TSE_CLOSED;
|
TREESTORE(&ten)->flag &= ~TSE_CLOSED;
|
||||||
|
|
||||||
@@ -119,9 +119,9 @@ void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_layer_collections_recursive(ten.subtree, lc->layer_collections, ten);
|
add_layer_collections_recursive(lc->layer_collections, ten);
|
||||||
if (show_objects_) {
|
if (show_objects_) {
|
||||||
add_layer_collection_objects(ten.subtree, *lc, ten);
|
add_layer_collection_objects(*lc, ten);
|
||||||
}
|
}
|
||||||
if (show_children) {
|
if (show_children) {
|
||||||
add_layer_collection_objects_children(ten);
|
add_layer_collection_objects_children(ten);
|
||||||
@@ -129,8 +129,7 @@ void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
|
void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &layer_collections,
|
||||||
ListBase &layer_collections,
|
|
||||||
TreeElement &parent_ten)
|
TreeElement &parent_ten)
|
||||||
{
|
{
|
||||||
for (LayerCollection *lc : List<LayerCollection>(layer_collections)) {
|
for (LayerCollection *lc : List<LayerCollection>(layer_collections)) {
|
||||||
@@ -142,8 +141,7 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ID *id = &lc->collection->id;
|
ID *id = &lc->collection->id;
|
||||||
ten = outliner_add_element(
|
ten = outliner_add_element(&space_outliner_, id, &parent_ten, TSE_LAYER_COLLECTION, 0);
|
||||||
&space_outliner_, &tree, id, &parent_ten, TSE_LAYER_COLLECTION, 0);
|
|
||||||
|
|
||||||
ten->name = id->name + 2;
|
ten->name = id->name + 2;
|
||||||
ten->directdata = lc;
|
ten->directdata = lc;
|
||||||
@@ -155,21 +153,19 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_layer_collections_recursive(ten->subtree, lc->layer_collections, *ten);
|
add_layer_collections_recursive(lc->layer_collections, *ten);
|
||||||
if (!exclude && show_objects_) {
|
if (!exclude && show_objects_) {
|
||||||
add_layer_collection_objects(ten->subtree, *lc, *ten);
|
add_layer_collection_objects(*lc, *ten);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeDisplayViewLayer::add_layer_collection_objects(ListBase &tree,
|
void TreeDisplayViewLayer::add_layer_collection_objects(LayerCollection &lc, TreeElement &ten)
|
||||||
LayerCollection &lc,
|
|
||||||
TreeElement &ten)
|
|
||||||
{
|
{
|
||||||
for (CollectionObject *cob : List<CollectionObject>(lc.collection->gobject)) {
|
for (CollectionObject *cob : List<CollectionObject>(lc.collection->gobject)) {
|
||||||
Base *base = BKE_view_layer_base_find(view_layer_, cob->ob);
|
Base *base = BKE_view_layer_base_find(view_layer_, cob->ob);
|
||||||
TreeElement *te_object = outliner_add_element(
|
TreeElement *te_object = outliner_add_element(
|
||||||
&space_outliner_, &tree, base->object, &ten, TSE_SOME_ID, 0);
|
&space_outliner_, base->object, &ten, TSE_SOME_ID, 0);
|
||||||
te_object->directdata = base;
|
te_object->directdata = base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,9 +257,10 @@ void ObjectsChildrenBuilder::make_object_parent_hierarchy_collections()
|
|||||||
for (TreeElement *child_ob_tree_element : child_ob_tree_elements) {
|
for (TreeElement *child_ob_tree_element : child_ob_tree_elements) {
|
||||||
if (child_ob_tree_element->parent == parent_ob_collection_tree_element) {
|
if (child_ob_tree_element->parent == parent_ob_collection_tree_element) {
|
||||||
/* Move from the collection subtree into the parent object subtree. */
|
/* Move from the collection subtree into the parent object subtree. */
|
||||||
BLI_remlink(&parent_ob_collection_tree_element->subtree, child_ob_tree_element);
|
std::unique_ptr<TreeElement> removed_te =
|
||||||
BLI_addtail(&parent_ob_tree_element->subtree, child_ob_tree_element);
|
parent_ob_collection_tree_element->child_elements.remove(*child_ob_tree_element);
|
||||||
child_ob_tree_element->parent = parent_ob_tree_element;
|
parent_ob_tree_element->child_elements.add_back(std::move(removed_te));
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -272,13 +269,8 @@ void ObjectsChildrenBuilder::make_object_parent_hierarchy_collections()
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
/* We add the child in the tree even if it is not in the collection.
|
/* We add the child in the tree even if it is not in the collection.
|
||||||
* We don't expand its sub-tree though, to make it less prominent. */
|
* We don't expand its sub-tree though, to make it less prominent. */
|
||||||
TreeElement *child_ob_tree_element = outliner_add_element(&outliner_,
|
TreeElement *child_ob_tree_element = outliner_add_element(
|
||||||
&parent_ob_tree_element->subtree,
|
&outliner_, child, parent_ob_tree_element, TSE_SOME_ID, 0, false);
|
||||||
child,
|
|
||||||
parent_ob_tree_element,
|
|
||||||
TSE_SOME_ID,
|
|
||||||
0,
|
|
||||||
false);
|
|
||||||
child_ob_tree_element->flag |= TE_CHILD_NOT_IN_COLLECTION;
|
child_ob_tree_element->flag |= TE_CHILD_NOT_IN_COLLECTION;
|
||||||
child_ob_tree_elements.append(child_ob_tree_element);
|
child_ob_tree_elements.append(child_ob_tree_element);
|
||||||
}
|
}
|
||||||
|
@@ -146,4 +146,75 @@ void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner
|
|||||||
tree_element.expand(space_outliner);
|
tree_element.expand(space_outliner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SubTree::SubTree(TreeElement &parent) : parent_(&parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SubTree::SubTree(SpaceOutliner_Runtime &) : parent_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubTree::add_back(std::unique_ptr<TreeElement> element)
|
||||||
|
{
|
||||||
|
element->parent = parent_;
|
||||||
|
/* TODO is this the right place for this? */
|
||||||
|
element->child_elements.parent_ = element.get();
|
||||||
|
elements_.push_back(std::move(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubTree::insert_before(Iterator pos, std::unique_ptr<TreeElement> element)
|
||||||
|
{
|
||||||
|
element->parent = parent_;
|
||||||
|
elements_.insert(pos.iter_, std::move(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<TreeElement> SubTree::remove(TreeElement &element)
|
||||||
|
{
|
||||||
|
std::unique_ptr<TreeElement> element_uptr = nullptr;
|
||||||
|
/* TODO doesn't free element entirely yet, #TreeElement.name may need freeing! See
|
||||||
|
* #outliner_free_tree_element(). */
|
||||||
|
|
||||||
|
for (decltype(elements_)::iterator iter = elements_.begin(); iter != elements_.end(); ++iter) {
|
||||||
|
if (iter->get() == &element) {
|
||||||
|
element_uptr = std::move(*iter);
|
||||||
|
elements_.erase(iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_assert(!has_child(element));
|
||||||
|
|
||||||
|
if (element_uptr) {
|
||||||
|
element_uptr->parent = nullptr;
|
||||||
|
}
|
||||||
|
return element_uptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubTree::clear()
|
||||||
|
{
|
||||||
|
elements_.clear();
|
||||||
|
/* No need to clear the parent pointer, elements get destructed entirely anyway. */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubTree::has_child(const TreeElement &needle) const
|
||||||
|
{
|
||||||
|
for (const TreeElement &te : *this) {
|
||||||
|
if (&te == &needle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubTree::is_empty() const
|
||||||
|
{
|
||||||
|
return elements_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeElement *SubTree::parent() const
|
||||||
|
{
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
@@ -18,6 +18,7 @@ struct SpaceOutliner;
|
|||||||
namespace blender::ed::outliner {
|
namespace blender::ed::outliner {
|
||||||
|
|
||||||
struct TreeElement;
|
struct TreeElement;
|
||||||
|
class SubTree;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Tree-Display Interface */
|
/* Tree-Display Interface */
|
||||||
@@ -114,21 +115,28 @@ class AbstractTreeElement {
|
|||||||
* TODO: this function needs to be split up! It's getting a bit too large...
|
* TODO: this function needs to be split up! It's getting a bit too large...
|
||||||
*
|
*
|
||||||
* \note "ID" is not always a real ID.
|
* \note "ID" is not always a real ID.
|
||||||
* \note If child items are only added to the tree if the item is open,
|
* \note If child items are only added to the tree if the item is open, the `TSE_` type _must_ be
|
||||||
* the `TSE_` type _must_ be added to #outliner_element_needs_rebuild_on_open_change().
|
* added to #outliner_element_needs_rebuild_on_open_change().
|
||||||
*
|
*
|
||||||
|
* \param parent: The parent element to add the new element to. If this is null, the new element
|
||||||
|
* will be added to the root level of the tree.
|
||||||
* \param expand: If true, the element may add its own sub-tree. E.g. objects will list their
|
* \param expand: If true, the element may add its own sub-tree. E.g. objects will list their
|
||||||
* animation data, object data, constraints, modifiers, ... This often adds visual
|
* animation data, object data, constraints, modifiers, ... This often adds visual
|
||||||
* noise, and can be expensive to add in big scenes. So prefer setting this to
|
* noise, and can be expensive to add in big scenes. So prefer setting this to
|
||||||
* false.
|
* false.
|
||||||
*/
|
*/
|
||||||
struct TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||||
ListBase *lb,
|
void *idv,
|
||||||
void *idv,
|
TreeElement *parent,
|
||||||
struct TreeElement *parent,
|
short type,
|
||||||
short type,
|
short index,
|
||||||
short index,
|
const bool expand = true);
|
||||||
const bool expand = true);
|
TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||||
|
void *idv,
|
||||||
|
SubTree &subtree,
|
||||||
|
short type,
|
||||||
|
short index,
|
||||||
|
const bool expand = true);
|
||||||
|
|
||||||
void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner);
|
void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner);
|
||||||
|
|
||||||
|
@@ -30,8 +30,7 @@ TreeElementAnimData::TreeElementAnimData(TreeElement &legacy_te, AnimData &anim_
|
|||||||
void TreeElementAnimData::expand(SpaceOutliner &space_outliner) const
|
void TreeElementAnimData::expand(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
/* Animation data-block itself. */
|
/* Animation data-block itself. */
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, anim_data_.action, &legacy_te_, TSE_SOME_ID, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, anim_data_.action, &legacy_te_, TSE_SOME_ID, 0);
|
|
||||||
|
|
||||||
expand_drivers(space_outliner);
|
expand_drivers(space_outliner);
|
||||||
expand_NLA_tracks(space_outliner);
|
expand_NLA_tracks(space_outliner);
|
||||||
@@ -42,8 +41,7 @@ void TreeElementAnimData::expand_drivers(SpaceOutliner &space_outliner) const
|
|||||||
if (BLI_listbase_is_empty(&anim_data_.drivers)) {
|
if (BLI_listbase_is_empty(&anim_data_.drivers)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &anim_data_, &legacy_te_, TSE_DRIVER_BASE, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, &anim_data_, &legacy_te_, TSE_DRIVER_BASE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeElementAnimData::expand_NLA_tracks(SpaceOutliner &space_outliner) const
|
void TreeElementAnimData::expand_NLA_tracks(SpaceOutliner &space_outliner) const
|
||||||
@@ -51,7 +49,7 @@ void TreeElementAnimData::expand_NLA_tracks(SpaceOutliner &space_outliner) const
|
|||||||
if (BLI_listbase_is_empty(&anim_data_.nla_tracks)) {
|
if (BLI_listbase_is_empty(&anim_data_.nla_tracks)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
outliner_add_element(&space_outliner, &legacy_te_.subtree, &anim_data_, &legacy_te_, TSE_NLA, 0);
|
outliner_add_element(&space_outliner, &anim_data_, &legacy_te_, TSE_NLA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
@@ -40,8 +40,7 @@ void TreeElementDriverBase::expand(SpaceOutliner &space_outliner) const
|
|||||||
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
|
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
|
||||||
if (lastadded != dtar->id) {
|
if (lastadded != dtar->id) {
|
||||||
/* XXX this lastadded check is rather lame, and also fails quite badly... */
|
/* XXX this lastadded check is rather lame, and also fails quite badly... */
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, dtar->id, &legacy_te_, TSE_LINKED_OB, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, dtar->id, &legacy_te_, TSE_LINKED_OB, 0);
|
|
||||||
lastadded = dtar->id;
|
lastadded = dtar->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -107,8 +107,7 @@ void TreeElementID::expand_animation_data(SpaceOutliner &space_outliner,
|
|||||||
const AnimData *anim_data) const
|
const AnimData *anim_data) const
|
||||||
{
|
{
|
||||||
if (outliner_animdata_test(anim_data)) {
|
if (outliner_animdata_test(anim_data)) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &id_, &legacy_te_, TSE_ANIM_DATA, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, &id_, &legacy_te_, TSE_ANIM_DATA, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,26 +36,22 @@ void TreeElementIDScene::expand(SpaceOutliner &space_outliner) const
|
|||||||
|
|
||||||
void TreeElementIDScene::expandViewLayers(SpaceOutliner &space_outliner) const
|
void TreeElementIDScene::expandViewLayers(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &scene_, &legacy_te_, TSE_R_LAYER_BASE, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, &scene_, &legacy_te_, TSE_R_LAYER_BASE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeElementIDScene::expandWorld(SpaceOutliner &space_outliner) const
|
void TreeElementIDScene::expandWorld(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, scene_.world, &legacy_te_, TSE_SOME_ID, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, scene_.world, &legacy_te_, TSE_SOME_ID, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeElementIDScene::expandCollections(SpaceOutliner &space_outliner) const
|
void TreeElementIDScene::expandCollections(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &scene_, &legacy_te_, TSE_SCENE_COLLECTION_BASE, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, &scene_, &legacy_te_, TSE_SCENE_COLLECTION_BASE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeElementIDScene::expandObjects(SpaceOutliner &space_outliner) const
|
void TreeElementIDScene::expandObjects(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &scene_, &legacy_te_, TSE_SCENE_OBJECTS_BASE, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, &scene_, &legacy_te_, TSE_SCENE_OBJECTS_BASE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
@@ -30,7 +30,7 @@ void TreeElementNLA::expand(SpaceOutliner &space_outliner) const
|
|||||||
{
|
{
|
||||||
int a = 0;
|
int a = 0;
|
||||||
for (NlaTrack *nlt : ListBaseWrapper<NlaTrack>(anim_data_.nla_tracks)) {
|
for (NlaTrack *nlt : ListBaseWrapper<NlaTrack>(anim_data_.nla_tracks)) {
|
||||||
outliner_add_element(&space_outliner, &legacy_te_.subtree, nlt, &legacy_te_, TSE_NLA_TRACK, a);
|
outliner_add_element(&space_outliner, nlt, &legacy_te_, TSE_NLA_TRACK, a);
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,8 +48,7 @@ void TreeElementNLATrack::expand(SpaceOutliner &space_outliner) const
|
|||||||
{
|
{
|
||||||
int a = 0;
|
int a = 0;
|
||||||
for (NlaStrip *strip : ListBaseWrapper<NlaStrip>(track_.strips)) {
|
for (NlaStrip *strip : ListBaseWrapper<NlaStrip>(track_.strips)) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, strip->act, &legacy_te_, TSE_NLA_ACTION, a);
|
||||||
&space_outliner, &legacy_te_.subtree, strip->act, &legacy_te_, TSE_NLA_ACTION, a);
|
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -353,12 +353,8 @@ void OverrideRNAPathTreeBuilder::build_path(TreeElement &parent,
|
|||||||
* values), so the element may already be present. At this point they are displayed as a single
|
* values), so the element may already be present. At this point they are displayed as a single
|
||||||
* property in the tree, so don't add it multiple times here. */
|
* property in the tree, so don't add it multiple times here. */
|
||||||
else if (!path_te_map.contains(override_data.override_property.rna_path)) {
|
else if (!path_te_map.contains(override_data.override_property.rna_path)) {
|
||||||
outliner_add_element(&space_outliner_,
|
outliner_add_element(
|
||||||
&te_to_expand->subtree,
|
&space_outliner_, &override_data, te_to_expand, TSE_LIBRARY_OVERRIDE, index++);
|
||||||
&override_data,
|
|
||||||
te_to_expand,
|
|
||||||
TSE_LIBRARY_OVERRIDE,
|
|
||||||
index++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_delete(elem_path);
|
MEM_delete(elem_path);
|
||||||
@@ -403,7 +399,6 @@ void OverrideRNAPathTreeBuilder::ensure_entire_collection(
|
|||||||
override_op_data.operation = item_operation;
|
override_op_data.operation = item_operation;
|
||||||
|
|
||||||
current_te = outliner_add_element(&space_outliner_,
|
current_te = outliner_add_element(&space_outliner_,
|
||||||
&te_to_expand.subtree,
|
|
||||||
/* Element will store a copy. */
|
/* Element will store a copy. */
|
||||||
&override_op_data,
|
&override_op_data,
|
||||||
&te_to_expand,
|
&te_to_expand,
|
||||||
@@ -446,7 +441,6 @@ TreeElement &OverrideRNAPathTreeBuilder::ensure_label_element_for_prop(
|
|||||||
{
|
{
|
||||||
return *path_te_map.lookup_or_add_cb(elem_path, [&]() {
|
return *path_te_map.lookup_or_add_cb(elem_path, [&]() {
|
||||||
TreeElement *new_te = outliner_add_element(&space_outliner_,
|
TreeElement *new_te = outliner_add_element(&space_outliner_,
|
||||||
&parent.subtree,
|
|
||||||
(void *)RNA_property_ui_name(&prop),
|
(void *)RNA_property_ui_name(&prop),
|
||||||
&parent,
|
&parent,
|
||||||
TSE_GENERIC_LABEL,
|
TSE_GENERIC_LABEL,
|
||||||
@@ -469,7 +463,6 @@ TreeElement &OverrideRNAPathTreeBuilder::ensure_label_element_for_ptr(TreeElemen
|
|||||||
|
|
||||||
TreeElement *new_te = outliner_add_element(
|
TreeElement *new_te = outliner_add_element(
|
||||||
&space_outliner_,
|
&space_outliner_,
|
||||||
&parent.subtree,
|
|
||||||
(void *)(dyn_name ? dyn_name : RNA_struct_ui_name(ptr.type)),
|
(void *)(dyn_name ? dyn_name : RNA_struct_ui_name(ptr.type)),
|
||||||
&parent,
|
&parent,
|
||||||
TSE_GENERIC_LABEL,
|
TSE_GENERIC_LABEL,
|
||||||
|
@@ -118,8 +118,7 @@ void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const
|
|||||||
PointerRNA propptr;
|
PointerRNA propptr;
|
||||||
RNA_property_collection_lookup_int(&ptr, iterprop, index, &propptr);
|
RNA_property_collection_lookup_int(&ptr, iterprop, index, &propptr);
|
||||||
if (!(RNA_property_flag(static_cast<PropertyRNA *>(propptr.data)) & PROP_HIDDEN)) {
|
if (!(RNA_property_flag(static_cast<PropertyRNA *>(propptr.data)) & PROP_HIDDEN)) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &ptr, &legacy_te_, TSE_RNA_PROPERTY, index);
|
||||||
&space_outliner, &legacy_te_.subtree, &ptr, &legacy_te_, TSE_RNA_PROPERTY, index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,8 +167,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
|
|||||||
|
|
||||||
if (pptr.data) {
|
if (pptr.data) {
|
||||||
if (TSELEM_OPEN(&tselem, &space_outliner)) {
|
if (TSELEM_OPEN(&tselem, &space_outliner)) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &pptr, &legacy_te_, TSE_RNA_STRUCT, -1);
|
||||||
&space_outliner, &legacy_te_.subtree, &pptr, &legacy_te_, TSE_RNA_STRUCT, -1);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
|
legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
|
||||||
@@ -184,8 +182,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
|
|||||||
for (int index = 0; index < tot; index++) {
|
for (int index = 0; index < tot; index++) {
|
||||||
PointerRNA pptr;
|
PointerRNA pptr;
|
||||||
RNA_property_collection_lookup_int(&rna_ptr, rna_prop_, index, &pptr);
|
RNA_property_collection_lookup_int(&rna_ptr, rna_prop_, index, &pptr);
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, &pptr, &legacy_te_, TSE_RNA_STRUCT, index);
|
||||||
&space_outliner, &legacy_te_.subtree, &pptr, &legacy_te_, TSE_RNA_STRUCT, index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tot) {
|
else if (tot) {
|
||||||
@@ -198,12 +195,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
|
|||||||
|
|
||||||
if (TSELEM_OPEN(&tselem, &space_outliner)) {
|
if (TSELEM_OPEN(&tselem, &space_outliner)) {
|
||||||
for (int index = 0; index < tot; index++) {
|
for (int index = 0; index < tot; index++) {
|
||||||
outliner_add_element(&space_outliner,
|
outliner_add_element(&space_outliner, &rna_ptr, &legacy_te_, TSE_RNA_ARRAY_ELEM, index);
|
||||||
&legacy_te_.subtree,
|
|
||||||
&rna_ptr,
|
|
||||||
&legacy_te_,
|
|
||||||
TSE_RNA_ARRAY_ELEM,
|
|
||||||
index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tot) {
|
else if (tot) {
|
||||||
|
@@ -29,10 +29,10 @@ TreeElementSceneObjectsBase::TreeElementSceneObjectsBase(TreeElement &legacy_te,
|
|||||||
void TreeElementSceneObjectsBase::expand(SpaceOutliner &space_outliner) const
|
void TreeElementSceneObjectsBase::expand(SpaceOutliner &space_outliner) const
|
||||||
{
|
{
|
||||||
FOREACH_SCENE_OBJECT_BEGIN (&scene_, ob) {
|
FOREACH_SCENE_OBJECT_BEGIN (&scene_, ob) {
|
||||||
outliner_add_element(&space_outliner, &legacy_te_.subtree, ob, &legacy_te_, TSE_SOME_ID, 0);
|
outliner_add_element(&space_outliner, ob, &legacy_te_, TSE_SOME_ID, 0);
|
||||||
}
|
}
|
||||||
FOREACH_SCENE_OBJECT_END;
|
FOREACH_SCENE_OBJECT_END;
|
||||||
outliner_make_object_parent_hierarchy(&legacy_te_.subtree);
|
outliner_make_object_parent_hierarchy(legacy_te_.child_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
@@ -45,13 +45,11 @@ void TreeElementSequence::expand(SpaceOutliner &space_outliner) const
|
|||||||
|
|
||||||
if (sequence_.type == SEQ_TYPE_META) {
|
if (sequence_.type == SEQ_TYPE_META) {
|
||||||
LISTBASE_FOREACH (Sequence *, child, &sequence_.seqbase) {
|
LISTBASE_FOREACH (Sequence *, child, &sequence_.seqbase) {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, child, &legacy_te_, TSE_SEQUENCE, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, child, &legacy_te_, TSE_SEQUENCE, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outliner_add_element(
|
outliner_add_element(&space_outliner, sequence_.strip, &legacy_te_, TSE_SEQ_STRIP, 0);
|
||||||
&space_outliner, &legacy_te_.subtree, sequence_.strip, &legacy_te_, TSE_SEQ_STRIP, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ void TreeElementViewLayerBase::expand(SpaceOutliner &space_outliner) const
|
|||||||
{
|
{
|
||||||
for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene_.view_layers)) {
|
for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene_.view_layers)) {
|
||||||
TreeElement *tenlay = outliner_add_element(
|
TreeElement *tenlay = outliner_add_element(
|
||||||
&space_outliner, &legacy_te_.subtree, &scene_, &legacy_te_, TSE_R_LAYER, 0);
|
&space_outliner, &scene_, &legacy_te_, TSE_R_LAYER, 0);
|
||||||
tenlay->name = view_layer->name;
|
tenlay->name = view_layer->name;
|
||||||
tenlay->directdata = view_layer;
|
tenlay->directdata = view_layer;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user