diff options
Diffstat (limited to 'source')
5 files changed, 118 insertions, 53 deletions
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 41e54ee8b86..363e8ed8bb7 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRC tree/tree_display_libraries.cc tree/tree_display_view_layer.cc tree/tree_display_sequencer.cc + tree/tree_display_orphaned.cc outliner_intern.h tree/tree_display.h diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d3976821f8f..f3c982d5995 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1313,58 +1313,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, /* ======================================================= */ -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) { te->name = BKE_collection_ui_name_get(collection); @@ -2194,7 +2142,8 @@ void outliner_build_tree(Main *mainvar, } } else if (space_outliner->outlinevis == SO_ID_ORPHANS) { - outliner_add_orphaned_datablocks(mainvar, space_outliner); + /* Ported to new tree-display, should be built there already. */ + BLI_assert(false); } else if (space_outliner->outlinevis == SO_VIEW_LAYER) { /* Ported to new tree-display, should be built there already. */ diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc index 1419295c81c..bf976d79103 100644 --- a/source/blender/editors/space_outliner/tree/tree_display.cc +++ b/source/blender/editors/space_outliner/tree/tree_display.cc @@ -40,7 +40,9 @@ TreeDisplay *outliner_tree_display_create(eSpaceOutliner_Mode mode, SpaceOutline tree_display = new TreeDisplaySequencer(*space_outliner); break; case SO_DATA_API: + break; case SO_ID_ORPHANS: + tree_display = new TreeDisplayIDOrphans(*space_outliner); break; case SO_VIEW_LAYER: tree_display = new TreeDisplayViewLayer(*space_outliner); diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh index 0901451e5d3..a933a8d7609 100644 --- a/source/blender/editors/space_outliner/tree/tree_display.hh +++ b/source/blender/editors/space_outliner/tree/tree_display.hh @@ -134,4 +134,20 @@ class TreeDisplaySequencer final : public AbstractTreeDisplay { void add_seq_dup(Sequence *seq, TreeElement *te, short index) const; }; +/* -------------------------------------------------------------------- */ +/* Orphaned Data Tree-Display */ + +/** + * \brief Tree-Display for the Orphaned Data display mode + */ +class TreeDisplayIDOrphans final : public AbstractTreeDisplay { + public: + TreeDisplayIDOrphans(SpaceOutliner &space_outliner); + + ListBase buildTree(const TreeSourceData &source_data) override; + + private: + bool datablock_has_orphans(ListBase &) const; +}; + } // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc new file mode 100644 index 00000000000..71c1d344057 --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc @@ -0,0 +1,97 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup spoutliner + */ + +#include "DNA_ID.h" + +#include "BLI_listbase.h" +#include "BLI_listbase_wrapper.hh" +#include "BLI_utildefines.h" + +#include "BKE_main.h" + +#include "../outliner_intern.h" +#include "tree_display.hh" + +namespace blender::ed::outliner { + +/* Convenience/readability. */ +template<typename T> using List = ListBaseWrapper<T>; + +TreeDisplayIDOrphans::TreeDisplayIDOrphans(SpaceOutliner &space_outliner) + : AbstractTreeDisplay(space_outliner) +{ +} + +ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data) +{ + ListBase tree = {nullptr}; + ListBase *lbarray[MAX_LIBARRAY]; + short filter_id_type = (space_outliner_.filter & SO_FILTER_ID_TYPE) ? + space_outliner_.filter_id_type : + 0; + + int tot; + if (filter_id_type) { + lbarray[0] = which_libbase(source_data.bmain, filter_id_type); + tot = 1; + } + else { + tot = set_listbasepointers(source_data.bmain, lbarray); + } + + for (int a = 0; a < tot; a++) { + if (BLI_listbase_is_empty(lbarray[a])) { + continue; + } + if (!datablock_has_orphans(*lbarray[a])) { + continue; + } + + /* Header for this type of data-block. */ + TreeElement *te = nullptr; + if (!filter_id_type) { + ID *id = (ID *)lbarray[a]->first; + te = outliner_add_element(&space_outliner_, &tree, lbarray[a], NULL, TSE_ID_BASE, 0); + te->directdata = lbarray[a]; + te->name = outliner_idcode_to_plural(GS(id->name)); + } + + /* Add the orphaned data-blocks - these will not be added with any subtrees attached. */ + for (ID *id : List<ID>(lbarray[a])) { + if (ID_REAL_USERS(id) <= 0) { + outliner_add_element(&space_outliner_, (te) ? &te->subtree : &tree, id, te, 0, 0); + } + } + } + + return tree; +} + +bool TreeDisplayIDOrphans::datablock_has_orphans(ListBase &lb) const +{ + for (ID *id : List<ID>(lb)) { + if (ID_REAL_USERS(id) <= 0) { + return true; + } + } + return false; +} + +} // namespace blender::ed::outliner |