Blender V5.0
tree_element.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <iostream>
10#include <string>
11#include <string_view>
12
13#include "DNA_listBase.h"
14#include "DNA_space_types.h"
15
16#include "UI_resources.hh"
17
18#include "tree_display.hh"
21#include "tree_element_bone.hh"
31#include "tree_element_id.hh"
32#include "tree_element_label.hh"
37#include "tree_element_nla.hh"
40#include "tree_element_pose.hh"
41#include "tree_element_rna.hh"
43#include "tree_element_seq.hh"
46
47#include "../outliner_intern.hh"
48#include "tree_element.hh"
49
50namespace blender::ed::outliner {
51
52std::unique_ptr<AbstractTreeElement> AbstractTreeElement::create_from_type(const int type,
53 TreeElement &legacy_te,
54 ID *owner_id,
55 void *create_data)
56{
57 if (owner_id == nullptr && create_data == nullptr) {
58 return nullptr;
59 }
60
61 /*
62 * The following calls make an implicit assumption about what data was passed to the
63 * `create_data` argument of #add_element(). The old code does this already, here we just
64 * centralize it as much as possible for now. Would be nice to entirely get rid of that, no more
65 * `void *`.
66 *
67 * Once #add_element() is sufficiently simplified, it should be replaced by a C++ call. It could
68 * take the derived type as template parameter (e.g. #TreeElementAnimData) and use C++ perfect
69 * forwarding to pass any data to the type's constructor. If general Outliner code wants to
70 * access the data, they can query that through the derived element type then. There's no need
71 * for `void *` anymore then.
72 */
73
74 switch (type) {
75 case TSE_SOME_ID:
76 return TreeElementID::create_from_id(legacy_te, *owner_id);
78 return std::make_unique<TreeElementLabel>(legacy_te, static_cast<const char *>(create_data));
79 case TSE_ANIM_DATA:
80 return std::make_unique<TreeElementAnimData>(legacy_te,
81 *static_cast<AnimData *>(create_data));
82 case TSE_DRIVER_BASE:
83 return std::make_unique<TreeElementDriverBase>(legacy_te,
84 *static_cast<AnimData *>(create_data));
85 case TSE_NLA:
86 return std::make_unique<TreeElementNLA>(legacy_te, *static_cast<AnimData *>(create_data));
87 case TSE_NLA_TRACK:
88 return std::make_unique<TreeElementNLATrack>(legacy_te,
89 *static_cast<NlaTrack *>(create_data));
90 case TSE_NLA_ACTION:
91 return std::make_unique<TreeElementNLAAction>(legacy_te,
92 *reinterpret_cast<bAction *>(owner_id));
93 case TSE_GP_LAYER:
94 return std::make_unique<TreeElementGPencilLayer>(legacy_te,
95 *static_cast<bGPDlayer *>(create_data));
97 return std::make_unique<TreeElementGreasePencilNode>(
98 legacy_te,
99 *reinterpret_cast<GreasePencil *>(owner_id),
100 *static_cast<bke::greasepencil::TreeNode *>(create_data));
101 case TSE_R_LAYER_BASE:
102 return std::make_unique<TreeElementViewLayerBase>(legacy_te,
103 *reinterpret_cast<Scene *>(owner_id));
104 case TSE_R_LAYER:
105 return std::make_unique<TreeElementViewLayer>(
106 legacy_te, *reinterpret_cast<Scene *>(owner_id), *static_cast<ViewLayer *>(create_data));
108 return std::make_unique<TreeElementCollectionBase>(legacy_te,
109 *reinterpret_cast<Scene *>(owner_id));
111 return std::make_unique<TreeElementSceneObjectsBase>(legacy_te,
112 *reinterpret_cast<Scene *>(owner_id));
114 return std::make_unique<TreeElementOverridesBase>(legacy_te, *owner_id);
116 return std::make_unique<TreeElementOverridesProperty>(
117 legacy_te, *static_cast<TreeElementOverridesData *>(create_data));
119 return std::make_unique<TreeElementOverridesPropertyOperation>(
120 legacy_te, *static_cast<TreeElementOverridesData *>(create_data));
121 case TSE_RNA_STRUCT:
122 return std::make_unique<TreeElementRNAStruct>(legacy_te,
123 *static_cast<PointerRNA *>(create_data));
124 case TSE_RNA_PROPERTY:
125 return std::make_unique<TreeElementRNAProperty>(
126 legacy_te, *static_cast<PointerRNA *>(create_data), legacy_te.index);
128 return std::make_unique<TreeElementRNAArrayElement>(
129 legacy_te, *static_cast<PointerRNA *>(create_data), legacy_te.index);
130 case TSE_STRIP:
131 return std::make_unique<TreeElementStrip>(legacy_te, *static_cast<Strip *>(create_data));
132 case TSE_STRIP_DATA:
133 return std::make_unique<TreeElementStripData>(legacy_te,
134 *static_cast<StripData *>(create_data));
135 case TSE_STRIP_DUP:
136 return std::make_unique<TreeElementStripDuplicate>(legacy_te,
137 *static_cast<Strip *>(create_data));
138 case TSE_BONE:
139 return std::make_unique<TreeElementBone>(
140 legacy_te, *owner_id, *static_cast<Bone *>(create_data));
141 case TSE_EBONE:
142 return std::make_unique<TreeElementEditBone>(
143 legacy_te, *owner_id, *static_cast<EditBone *>(create_data));
145 return std::make_unique<TreeElementGPencilEffect>(legacy_te,
146 *reinterpret_cast<Object *>(owner_id),
147 *static_cast<ShaderFxData *>(create_data));
149 return std::make_unique<TreeElementGPencilEffectBase>(legacy_te,
150 *reinterpret_cast<Object *>(owner_id));
152 return std::make_unique<TreeElementDeformGroupBase>(legacy_te,
153 *reinterpret_cast<Object *>(owner_id));
154 case TSE_DEFGROUP:
155 return std::make_unique<TreeElementDeformGroup>(legacy_te,
156 *reinterpret_cast<Object *>(owner_id),
157 *static_cast<bDeformGroup *>(create_data));
158 case TSE_LINKED_PSYS:
159 return std::make_unique<TreeElementParticleSystem>(
160 legacy_te,
161 *reinterpret_cast<Object *>(owner_id),
162 *static_cast<ParticleSystem *>(create_data));
164 return std::make_unique<TreeElementConstraintBase>(legacy_te,
165 *reinterpret_cast<Object *>(owner_id));
166 case TSE_CONSTRAINT:
167 return std::make_unique<TreeElementConstraint>(legacy_te,
168 *reinterpret_cast<Object *>(owner_id),
169 *static_cast<bConstraint *>(create_data));
170 case TSE_POSE_BASE:
171 return std::make_unique<TreeElementPoseBase>(legacy_te,
172 *reinterpret_cast<Object *>(owner_id));
173 case TSE_POSE_CHANNEL:
174 return std::make_unique<TreeElementPoseChannel>(legacy_te,
175 *reinterpret_cast<Object *>(owner_id),
176 *static_cast<bPoseChannel *>(create_data));
178 return std::make_unique<TreeElementModifierBase>(legacy_te,
179 *reinterpret_cast<Object *>(owner_id));
180 case TSE_MODIFIER:
181 return std::make_unique<TreeElementModifier>(
182 legacy_te,
183 *reinterpret_cast<Object *>(owner_id),
184 *static_cast<ModifierDataStoreElem *>(create_data));
186 return std::make_unique<TreeElementLinkedNodeTree>(legacy_te, *owner_id);
187 case TSE_LINKED_OB:
188 return std::make_unique<TreeElementLinkedObject>(legacy_te, *owner_id);
190 return std::make_unique<TreeElementViewCollectionBase>(legacy_te,
191 *reinterpret_cast<Scene *>(owner_id));
193 return std::make_unique<TreeElementLayerCollection>(
194 legacy_te, *static_cast<LayerCollection *>(create_data));
195
197 return std::make_unique<TreeElementBoneCollectionBase>(
198 legacy_te, *reinterpret_cast<bArmature *>(owner_id));
200 return std::make_unique<TreeElementBoneCollection>(
201 legacy_te,
202 *reinterpret_cast<bArmature *>(owner_id),
203 *static_cast<BoneCollection *>(create_data));
204 case TSE_ACTION_SLOT:
205 return std::make_unique<TreeElementActionSlot>(
206 legacy_te, *reinterpret_cast<blender::animrig::Slot *>(create_data));
207
208 default:
209 break;
210 }
211
212 return nullptr;
213}
214
216{
217 return "";
218}
219
220std::optional<BIFIconID> AbstractTreeElement::get_icon() const
221{
222 return {};
223}
224
226{
227 std::string path = legacy_te_.name;
228
229 for (TreeElement *parent = legacy_te_.parent; parent; parent = parent->parent) {
230 path = parent->name + std::string_view("/") + path;
231 }
232
233 std::cout << path << std::endl;
234}
235
237{
238 if (!TREESTORE(legacy_te)->used) {
239 TREESTORE(legacy_te)->flag &= ~TSE_CLOSED;
240 }
241}
242
244 ID *owner_id,
245 void *create_data,
246 TreeElement *parent,
247 short type,
248 short index,
249 const bool expand) const
250{
251 if (!display_) {
252 BLI_assert_msg(false,
253 "Element not registered properly through AbstractTreeDisplay::add_element(), "
254 "cannot expand the tree further");
255 return nullptr;
256 }
257
258 return display_->add_element(lb, owner_id, create_data, parent, type, index, expand);
259}
260
261void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner)
262{
263 /* Most types can just expand. IDs optionally expand (hence the poll) and do additional, common
264 * expanding. Could be done nicer, we could request a small "expander" helper object from the
265 * element type, that the IDs have a more advanced implementation for. */
266 if (!tree_element.expand_poll(space_outliner)) {
267 return;
268 }
269 tree_element.expand(space_outliner);
270}
271
272} // namespace blender::ed::outliner
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
These structs are the foundation for all linked lists in the library system.
@ TSE_STRIP_DUP
@ TSE_BONE_COLLECTION
@ TSE_ACTION_SLOT
@ TSE_POSE_CHANNEL
@ TSE_CONSTRAINT_BASE
@ TSE_LIBRARY_OVERRIDE_OPERATION
@ TSE_STRIP
@ TSE_MODIFIER_BASE
@ TSE_GP_LAYER
@ TSE_RNA_ARRAY_ELEM
@ TSE_GPENCIL_EFFECT
@ TSE_LINKED_NODE_TREE
@ TSE_STRIP_DATA
@ TSE_VIEW_COLLECTION_BASE
@ TSE_ANIM_DATA
@ TSE_LIBRARY_OVERRIDE
@ TSE_RNA_PROPERTY
@ TSE_LIBRARY_OVERRIDE_BASE
@ TSE_EBONE
@ TSE_NLA_TRACK
@ TSE_BONE
@ TSE_LINKED_PSYS
@ TSE_DEFGROUP_BASE
@ TSE_CONSTRAINT
@ TSE_SCENE_COLLECTION_BASE
@ TSE_SCENE_OBJECTS_BASE
@ TSE_R_LAYER_BASE
@ TSE_LAYER_COLLECTION
@ TSE_GREASE_PENCIL_NODE
@ TSE_GENERIC_LABEL
@ TSE_GPENCIL_EFFECT_BASE
@ TSE_LINKED_OB
@ TSE_NLA
@ TSE_SOME_ID
@ TSE_DRIVER_BASE
@ TSE_NLA_ACTION
@ TSE_MODIFIER
@ TSE_BONE_COLLECTION_BASE
@ TSE_R_LAYER
@ TSE_RNA_STRUCT
@ TSE_POSE_BASE
@ TSE_DEFGROUP
@ TSE_CLOSED
virtual StringRefNull get_warning() const
static std::unique_ptr< AbstractTreeElement > create_from_type(int type, TreeElement &legacy_te, ID *owner_id, void *create_data)
TreeElement * add_element(ListBase *lb, ID *owner_id, void *create_data, TreeElement *parent, short type, short index, const bool expand=true) const
static void uncollapse_by_default(TreeElement *legacy_te)
virtual bool expand_poll(const SpaceOutliner &) const
virtual void expand(SpaceOutliner &) const
virtual std::optional< BIFIconID > get_icon() const
static std::unique_ptr< TreeElementID > create_from_id(TreeElement &legacy_te, ID &id)
void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner)
#define TREESTORE(a)
Definition DNA_ID.h:414
Establish and manage Outliner trees for different display modes.