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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_outliner/outliner_tree.c')
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c324
1 files changed, 40 insertions, 284 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 159511546be..7308b161d18 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -80,12 +80,11 @@
#include "RNA_access.h"
-#include "SEQ_sequencer.h"
-
#include "UI_interface.h"
#include "outliner_intern.h"
#include "tree/tree_display.h"
+#include "tree/tree_element.h"
#ifdef WIN32
# include "BLI_math_base.h" /* M_PI */
@@ -132,9 +131,9 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
if (BLI_mempool_len(ts) == unused) {
BLI_mempool_destroy(ts);
space_outliner->treestore = NULL;
- if (space_outliner->treehash) {
- BKE_outliner_treehash_free(space_outliner->treehash);
- space_outliner->treehash = NULL;
+ if (space_outliner->runtime->treehash) {
+ BKE_outliner_treehash_free(space_outliner->runtime->treehash);
+ space_outliner->runtime->treehash = NULL;
}
}
else {
@@ -150,16 +149,16 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
}
BLI_mempool_destroy(ts);
space_outliner->treestore = new_ts;
- if (space_outliner->treehash) {
+ if (space_outliner->runtime->treehash) {
/* update hash table to fix broken pointers */
- BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
+ BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
space_outliner->treestore);
}
}
}
}
- else if (space_outliner->treehash) {
- BKE_outliner_treehash_clear_used(space_outliner->treehash);
+ else if (space_outliner->runtime->treehash) {
+ BKE_outliner_treehash_clear_used(space_outliner->runtime->treehash);
}
}
}
@@ -174,14 +173,14 @@ static void check_persistent(
space_outliner->treestore = BLI_mempool_create(
sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
}
- if (space_outliner->treehash == NULL) {
- space_outliner->treehash = BKE_outliner_treehash_create_from_treestore(
+ if (space_outliner->runtime->treehash == NULL) {
+ space_outliner->runtime->treehash = BKE_outliner_treehash_create_from_treestore(
space_outliner->treestore);
}
/* find any unused tree element in treestore and mark it as used
* (note that there may be multiple unused elements in case of linked objects) */
- tselem = BKE_outliner_treehash_lookup_unused(space_outliner->treehash, type, nr, id);
+ tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
@@ -196,7 +195,7 @@ static void check_persistent(
tselem->used = 0;
tselem->flag = TSE_CLOSED;
te->store_elem = tselem;
- BKE_outliner_treehash_add_element(space_outliner->treehash, tselem);
+ BKE_outliner_treehash_add_element(space_outliner->runtime->treehash, tselem);
}
/* ********************************************************* */
@@ -232,6 +231,7 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
if (element->flag & TE_FREE_NAME) {
MEM_freeN((void *)element->name);
}
+ outliner_tree_element_type_free(&element->type);
MEM_freeN(element);
}
@@ -961,13 +961,18 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->parent = parent;
te->index = index; /* For data arrays. */
+
+ /* New C++ based type handle (`TreeElementType` in C, `AbstractTreeElement` in C++). Only some
+ * support this, eventually this should replace `TreeElement` entirely. */
+ te->type = outliner_tree_element_type_create(type, te, idv);
+
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
/* pass */
}
else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
/* pass */
}
- else if (type == TSE_ANIM_DATA) {
+ else if (ELEM(type, TSE_ANIM_DATA, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE)) {
/* pass */
}
else if (type == TSE_GP_LAYER) {
@@ -979,7 +984,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
else if (type == TSE_ID_BASE) {
/* pass */
}
+ else if (ELEM(type, TSE_KEYMAP, TSE_KEYMAP_ITEM)) {
+ /* pass */
+ }
else {
+ /* Other cases must be caught above. */
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+
/* do here too, for blend file viewer, own ID_LI then shows file name */
if (GS(id->name) == ID_LI) {
te->name = ((Library *)id)->filepath;
@@ -990,7 +1001,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->idcode = GS(id->name);
}
- if (type == 0) {
+ if (te->type) {
+ outliner_tree_element_type_expand(te->type, space_outliner);
+ }
+ else if (type == 0) {
TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
/* ID data-block. */
@@ -998,73 +1012,9 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
outliner_add_id_contents(space_outliner, te, tselem, id);
}
}
- else if (type == TSE_ANIM_DATA) {
- IdAdtTemplate *iat = (IdAdtTemplate *)idv;
- AnimData *adt = (AnimData *)iat->adt;
-
- /* this element's info */
- te->name = IFACE_("Animation");
- te->directdata = adt;
-
- /* Action */
- outliner_add_element(space_outliner, &te->subtree, adt->action, te, 0, 0);
-
- /* Drivers */
- if (adt->drivers.first) {
- TreeElement *ted = outliner_add_element(
- space_outliner, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
- ID *lastadded = NULL;
- FCurve *fcu;
-
- ted->name = IFACE_("Drivers");
-
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- if (fcu->driver && fcu->driver->variables.first) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* loop over all targets used here */
- DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- if (lastadded != dtar->id) {
- /* XXX this lastadded check is rather lame, and also fails quite badly... */
- outliner_add_element(
- space_outliner, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
- lastadded = dtar->id;
- }
- }
- DRIVER_TARGETS_LOOPER_END;
- }
- }
- }
- }
-
- /* NLA Data */
- if (adt->nla_tracks.first) {
- TreeElement *tenla = outliner_add_element(space_outliner, &te->subtree, adt, te, TSE_NLA, 0);
- NlaTrack *nlt;
- int a = 0;
-
- tenla->name = IFACE_("NLA Tracks");
-
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- TreeElement *tenlt = outliner_add_element(
- space_outliner, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
- NlaStrip *strip;
- TreeElement *ten;
- int b = 0;
-
- tenlt->name = nlt->name;
-
- for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
- ten = outliner_add_element(
- space_outliner, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
- if (ten) {
- ten->directdata = strip;
- }
- }
- }
- }
+ else if (ELEM(type, TSE_ANIM_DATA, TSE_DRIVER_BASE, TSE_NLA, TSE_NLA_ACTION, TSE_NLA_TRACK)) {
+ /* Should already use new AbstractTreeElement design. */
+ BLI_assert(0);
}
else if (type == TSE_GP_LAYER) {
bGPDlayer *gpl = (bGPDlayer *)idv;
@@ -1314,125 +1264,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
/* ======================================================= */
-/* Sequencer mode tree building */
-
-/* Helped function to put duplicate sequence in the same tree. */
-static int need_add_seq_dup(Sequence *seq)
-{
- Sequence *p;
-
- if ((!seq->strip) || (!seq->strip->stripdata)) {
- return 1;
- }
-
- /*
- * First check backward, if we found a duplicate
- * sequence before this, don't need it, just return.
- */
- p = seq->prev;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->prev;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 2;
- }
- p = p->prev;
- }
-
- p = seq->next;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 0;
- }
- p = p->next;
- }
- return 1;
-}
-
-static void outliner_add_seq_dup(SpaceOutliner *space_outliner,
- Sequence *seq,
- TreeElement *te,
- short index)
-{
- /* TreeElement *ch; */ /* UNUSED */
- Sequence *p;
-
- p = seq;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- /* ch = */ /* UNUSED */ outliner_add_element(
- space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- }
- p = p->next;
- }
-}
-
-/* ----------------------------------------------- */
-
-static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOutliner *space_outliner)
-{
- TreeElement *ten;
- ListBase *lbarray[MAX_LIBARRAY];
- int a, tot;
- short filter_id_type = (space_outliner->filter & SO_FILTER_ID_TYPE) ?
- space_outliner->filter_id_type :
- 0;
-
- if (filter_id_type) {
- lbarray[0] = which_libbase(mainvar, space_outliner->filter_id_type);
- tot = 1;
- }
- else {
- tot = set_listbasepointers(mainvar, lbarray);
- }
-
- for (a = 0; a < tot; a++) {
- if (lbarray[a] && lbarray[a]->first) {
- ID *id = lbarray[a]->first;
-
- /* check if there are any data-blocks of this type which are orphans */
- for (; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- break;
- }
- }
-
- if (id) {
- /* header for this type of data-block */
- if (filter_id_type) {
- ten = NULL;
- }
- else {
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
-
- /* add the orphaned data-blocks - these will not be added with any subtrees attached */
- for (id = lbarray[a]->first; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- outliner_add_element(
- space_outliner, (ten) ? &ten->subtree : &space_outliner->tree, id, ten, 0, 0);
- }
- }
- }
- }
- }
-}
BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collection)
{
@@ -2175,18 +2006,12 @@ static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_
/* Main Tree Building API */
/* Main entry point for building the tree data-structure that the outliner represents. */
-/* TODO: split each mode into its own function? */
void outliner_build_tree(Main *mainvar,
Scene *scene,
ViewLayer *view_layer,
SpaceOutliner *space_outliner,
ARegion *region)
{
- TreeElement *te = NULL, *ten;
- TreeStoreElem *tselem;
- /* on first view, we open scenes */
- int show_opened = !space_outliner->treestore || !BLI_mempool_len(space_outliner->treestore);
-
/* Are we looking for something - we want to tag parents to filter child matches
* - NOT in data-blocks view - searching all data-blocks takes way too long to be useful
* - this variable is only set once per tree build */
@@ -2197,12 +2022,12 @@ void outliner_build_tree(Main *mainvar,
space_outliner->search_flags &= ~SO_SEARCH_RECURSIVE;
}
- if (space_outliner->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
+ if (space_outliner->runtime->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
space_outliner->treestore) {
- space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
- BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
+ BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
space_outliner->treestore);
}
+ space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
if (region->do_draw & RGN_DRAW_NO_REBUILD) {
return;
@@ -2217,82 +2042,13 @@ void outliner_build_tree(Main *mainvar,
space_outliner->runtime->tree_display = outliner_tree_display_create(space_outliner->outlinevis,
space_outliner);
- if (space_outliner->runtime->tree_display) {
- TreeSourceData source_data = {.bmain = mainvar, .scene = scene, .view_layer = view_layer};
- space_outliner->tree = outliner_tree_display_build_tree(space_outliner->runtime->tree_display,
- &source_data);
- }
- if (space_outliner->runtime->tree_display) {
- /* Skip if there's a tree-display that's responsible for adding all elements. */
- }
- /* options */
- else if (space_outliner->outlinevis == SO_LIBRARIES) {
- /* Ported to new tree-display, should be built there already. */
- BLI_assert(false);
- }
- else if (space_outliner->outlinevis == SO_SCENES) {
- Scene *sce;
- for (sce = mainvar->scenes.first; sce; sce = sce->id.next) {
- te = outliner_add_element(space_outliner, &space_outliner->tree, sce, NULL, 0, 0);
- tselem = TREESTORE(te);
-
- /* New scene elements open by default */
- if ((sce == scene && show_opened) || !tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
-
- outliner_make_object_parent_hierarchy(&te->subtree);
- }
- }
- else if (space_outliner->outlinevis == SO_SEQUENCE) {
- Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- int op;
-
- if (ed == NULL) {
- return;
- }
-
- seq = ed->seqbasep->first;
- if (!seq) {
- return;
- }
-
- while (seq) {
- op = need_add_seq_dup(seq);
- if (op == 1) {
- /* ten = */ outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
- }
- else if (op == 0) {
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
- outliner_add_seq_dup(space_outliner, seq, ten, 0);
- }
- seq = seq->next;
- }
- }
- else if (space_outliner->outlinevis == SO_DATA_API) {
- PointerRNA mainptr;
+ /* All tree displays should be created as sub-classes of AbstractTreeDisplay. */
+ BLI_assert(space_outliner->runtime->tree_display != NULL);
- RNA_main_pointer_create(mainvar, &mainptr);
-
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
-
- if (show_opened) {
- tselem = TREESTORE(ten);
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- else if (space_outliner->outlinevis == SO_ID_ORPHANS) {
- outliner_add_orphaned_datablocks(mainvar, space_outliner);
- }
- else if (space_outliner->outlinevis == SO_VIEW_LAYER) {
- /* Ported to new tree-display, should be built there already. */
- BLI_assert(false);
- }
+ TreeSourceData source_data = {.bmain = mainvar, .scene = scene, .view_layer = view_layer};
+ space_outliner->tree = outliner_tree_display_build_tree(space_outliner->runtime->tree_display,
+ &source_data);
if ((space_outliner->flag & SO_SKIP_SORT_ALPHA) == 0) {
outliner_sort(&space_outliner->tree);