diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 0b6f62e2924..7f00d0b8b28 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -41,6 +41,7 @@ set(SRC tree/tree_display_sequencer.cc tree/tree_display_view_layer.cc tree/tree_element.cc + tree/tree_element_action_slot.cc tree/tree_element_anim_data.cc tree/tree_element_bone.cc tree/tree_element_bone_collection.cc @@ -53,6 +54,7 @@ set(SRC tree/tree_element_gpencil_layer.cc tree/tree_element_grease_pencil_node.cc tree/tree_element_id.cc + tree/tree_element_id_action.cc tree/tree_element_id_armature.cc tree/tree_element_id_collection.cc tree/tree_element_id_curve.cc @@ -85,6 +87,7 @@ set(SRC tree/common.hh tree/tree_display.hh tree/tree_element.hh + tree/tree_element_action_slot.hh tree/tree_element_anim_data.hh tree/tree_element_bone.hh tree/tree_element_bone_collection.hh @@ -97,6 +100,7 @@ set(SRC tree/tree_element_gpencil_layer.hh tree/tree_element_grease_pencil_node.hh tree/tree_element_id.hh + tree/tree_element_id_action.hh tree/tree_element_id_armature.hh tree/tree_element_id_collection.hh tree/tree_element_id_curve.hh diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 3e8b0db7089..fde45f40416 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -932,6 +932,12 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) undo_str = "Rename Bone Collection"; break; } + + case TSE_ACTION_SLOT: { + WM_event_add_notifier(C, NC_ID | NA_RENAME, nullptr); + undo_str = "Rename Action Slot"; + break; + } } } tselem->flag &= ~TSE_TEXTBUT; @@ -2603,6 +2609,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) if (tselem->type != TSE_SOME_ID) { switch (tselem->type) { + case TSE_ACTION_SLOT: + data.icon = ICON_ACTION_SLOT; + break; case TSE_ANIM_DATA: data.icon = ICON_ANIM_DATA; /* XXX */ break; @@ -3172,7 +3181,8 @@ static void outliner_draw_iconrow(uiBlock *block, TSE_EBONE, TSE_POSE_CHANNEL, TSE_BONE_COLLECTION, - TSE_DEFGROUP)) + TSE_DEFGROUP, + TSE_ACTION_SLOT)) { outliner_draw_iconrow_doit(block, te, xmax, offsx, ys, alpha_fac, active, 1); } diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index 6d71d569cec..52352a3b191 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -308,6 +308,9 @@ TreeElement *AbstractTreeDisplay::add_element(ListBase *lb, else if (ELEM(type, TSE_ANIM_DATA, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE)) { /* pass */ } + else if (ELEM(type, TSE_ACTION_SLOT)) { + /* pass */ + } else if (ELEM(type, TSE_GP_LAYER, TSE_GREASE_PENCIL_NODE)) { /* pass */ } diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc index f50a47a06e5..6930d649a1f 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.cc +++ b/source/blender/editors/space_outliner/tree/tree_element.cc @@ -16,6 +16,7 @@ #include "UI_resources.hh" #include "tree_display.hh" +#include "tree_element_action_slot.hh" #include "tree_element_anim_data.hh" #include "tree_element_bone.hh" #include "tree_element_bone_collection.hh" @@ -200,6 +201,9 @@ std::unique_ptr AbstractTreeElement::create_from_type(const legacy_te, *reinterpret_cast(owner_id), *static_cast(create_data)); + case TSE_ACTION_SLOT: + return std::make_unique( + legacy_te, *reinterpret_cast(create_data)); default: break; diff --git a/source/blender/editors/space_outliner/tree/tree_element_action_slot.cc b/source/blender/editors/space_outliner/tree/tree_element_action_slot.cc new file mode 100644 index 00000000000..be7521af66b --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_action_slot.cc @@ -0,0 +1,26 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#include "DNA_action_types.h" + +#include "../outliner_intern.hh" + +#include "tree_element_action_slot.hh" + +#include "ANIM_action.hh" + +namespace blender::ed::outliner { + +TreeElementActionSlot::TreeElementActionSlot(TreeElement &legacy_te, blender::animrig::Slot &slot) + : AbstractTreeElement(legacy_te) +{ + legacy_te.name = &slot.identifier[2]; + legacy_te.directdata = &slot; +} + +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_element_action_slot.hh b/source/blender/editors/space_outliner/tree/tree_element_action_slot.hh new file mode 100644 index 00000000000..dac93611505 --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_action_slot.hh @@ -0,0 +1,26 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#pragma once + +#include "tree_element.hh" + +struct bAction; +namespace blender::animrig { +class Slot; +} + +namespace blender::ed::outliner { + +class TreeElementActionSlot final : public AbstractTreeElement { + + public: + TreeElementActionSlot(TreeElement &legacy_te, blender::animrig::Slot &slot); +}; + +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.cc b/source/blender/editors/space_outliner/tree/tree_element_id.cc index 523de3a1a6e..e81734b9801 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_id.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_id.cc @@ -13,6 +13,7 @@ #include "../outliner_intern.hh" #include "common.hh" +#include "tree_element_id_action.hh" #include "tree_element_id_armature.hh" #include "tree_element_id_collection.hh" #include "tree_element_id_curve.hh" @@ -62,6 +63,8 @@ std::unique_ptr TreeElementID::create_from_id(TreeElement &legacy return std::make_unique(legacy_te, (bArmature &)id); case ID_OB: return std::make_unique(legacy_te, (Object &)id); + case ID_AC: + return std::make_unique(legacy_te, (bAction &)id); case ID_MA: case ID_LT: case ID_LA: @@ -85,7 +88,6 @@ std::unique_ptr TreeElementID::create_from_id(TreeElement &legacy case ID_VF: case ID_TXT: case ID_SO: - case ID_AC: case ID_PAL: case ID_PC: case ID_CF: diff --git a/source/blender/editors/space_outliner/tree/tree_element_id_action.cc b/source/blender/editors/space_outliner/tree/tree_element_id_action.cc new file mode 100644 index 00000000000..b0694a7dd5b --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_id_action.cc @@ -0,0 +1,38 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#include "DNA_action_types.h" +#include "DNA_outliner_types.h" + +#include "../outliner_intern.hh" + +#include "tree_element_id_action.hh" + +#include "ANIM_action.hh" + +namespace blender::ed::outliner { + +TreeElementIDAction::TreeElementIDAction(TreeElement &legacy_te, bAction &action) + : TreeElementID(legacy_te, action.id), action_(action) +{ +} + +void TreeElementIDAction::expand(SpaceOutliner & /* space_outliner */) const +{ + blender::animrig::Action &action = action_.wrap(); + for (blender::animrig::Slot *slot : action.slots()) { + add_element(&legacy_te_.subtree, + reinterpret_cast(&action_), + slot, + &legacy_te_, + TSE_ACTION_SLOT, + 0); + } +} + +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_element_id_action.hh b/source/blender/editors/space_outliner/tree/tree_element_id_action.hh new file mode 100644 index 00000000000..1b3fda901fb --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_id_action.hh @@ -0,0 +1,26 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#pragma once + +#include "tree_element_id.hh" + +struct bAction; + +namespace blender::ed::outliner { + +class TreeElementIDAction final : public TreeElementID { + bAction &action_; + + public: + TreeElementIDAction(TreeElement &legacy_te, bAction &action); + + void expand(SpaceOutliner &space_outliner) const override; +}; + +} // namespace blender::ed::outliner diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index f9ef2d8f43a..e95a656fbcc 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -115,6 +115,7 @@ typedef enum eTreeStoreElemType { TSE_GENERIC_LABEL = 47, /* No ID */ TSE_GREASE_PENCIL_NODE = 48, TSE_LINKED_NODE_TREE = 49, + TSE_ACTION_SLOT = 50, } eTreeStoreElemType; /** Check whether given #TreeStoreElem should have a real ID in #TreeStoreElem.id member. */ diff --git a/source/blender/makesrna/intern/rna_action.cc b/source/blender/makesrna/intern/rna_action.cc index 03e94c65d89..762ea0afc51 100644 --- a/source/blender/makesrna/intern/rna_action.cc +++ b/source/blender/makesrna/intern/rna_action.cc @@ -2163,7 +2163,8 @@ static void rna_def_action_slot(BlenderRNA *brna) "rna_ActionSlot_name_display_length", "rna_ActionSlot_name_display_set"); RNA_def_property_string_maxlength(prop, sizeof(ActionSlot::identifier) - 2); - RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN, "rna_ActionSlot_identifier_update"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, "rna_ActionSlot_identifier_update"); RNA_def_property_ui_text( prop, "Slot Display Name",