Blender V5.0
tree_element_id_action.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DNA_action_types.h"
10#include "DNA_outliner_types.h"
11#include "DNA_space_types.h"
12
13#include "../outliner_intern.hh"
14
17
18#include "ANIM_action.hh"
19
20namespace blender::ed::outliner {
21
23 : TreeElementID(legacy_te, action.id), action_(action)
24{
25 /* If the outliner is showing the Action because it's in some hierarchical data mode, only show
26 * the slot that is used by the parent ID tree element. Showing all slots will create quadratic
27 * complexity, as each user of the Action has a child tree element for the Action. This means the
28 * complexity is O(U x S), where U = the number of users of the Action, and S = the number of
29 * slots. Typically U = S.
30 *
31 * In `SO_LIBRARIES` mode, the outliner shows Actions as a flat list in the 'Actions' subtree,
32 * and also (just like `SO_SCENES` and `SO_VIEW_LAYER`) underneath each user. The former should
33 * show all slots, whereas the latter should only show the assigned one. The difference is
34 * detected by the type of the parent tree element.
35 *
36 * To simplify the code, the mode of the Outliner is ignored, and whether to show all slots or
37 * not is determined purely by the type of the parent tree element. See the constructor. */
38
39 /* Fetch the assigned slot handle from the parent node in the tree. This is done this way,
40 * because AbstractTreeElement::add_element() constructs the element and immediately calls its
41 * expand() function. That means that there is no time for the creator of this
42 * TreeElementIDAction to pass us the slot handle explicitly.
43 *
44 * Adding a constructor parameter for this is also not feasible, due to the generic nature of the
45 * code that constructs this TreeElement. */
46 const TreeElement *legacy_parent = legacy_te.parent;
47 if (!legacy_parent) {
48 return;
49 }
50
52 legacy_parent);
53 if (!parent_anim_te) {
54 return;
55 }
56
57 this->slot_handle_.emplace(parent_anim_te->get_slot_handle());
58}
59
60void TreeElementIDAction::expand(SpaceOutliner & /*space_outliner*/) const
61{
62 animrig::Action &action = action_.wrap();
63 if (!this->slot_handle_.has_value()) {
64 /* Show all slots of the Action. */
65 for (animrig::Slot *slot : action.slots()) {
66 add_element(&legacy_te_.subtree,
67 reinterpret_cast<ID *>(&action_),
68 slot,
71 0);
72 }
73 return;
74 }
75
76 /* Only show a single slot. Note that the slot handle value itself could be animrig::unassigned,
77 * in which case there will not be a slot to show. */
78 animrig::Slot *slot = action.slot_for_handle(this->slot_handle_.value());
79 if (!slot) {
80 return;
81 }
82 add_element(&legacy_te_.subtree,
83 reinterpret_cast<ID *>(&action_),
84 slot,
87 0);
88}
89
90} // namespace blender::ed::outliner
Functions and classes to work with Actions.
@ TSE_ACTION_SLOT
blender::Span< const Slot * > slots() const
Slot * slot_for_handle(slot_handle_t handle)
TreeElement * add_element(ListBase *lb, ID *owner_id, void *create_data, TreeElement *parent, short type, short index, const bool expand=true) const
TreeElementIDAction(TreeElement &legacy_te, bAction &action)
void expand(SpaceOutliner &space_outliner) const override
TreeElementID(TreeElement &legacy_te, ID &id)
TreeElementT * tree_element_cast(const TreeElement *te)
Definition DNA_ID.h:414