Anim: add operator for creating a new Action Slot to the dope sheet header

Add new operator `anim.slot_new_for_object`, which creates a new action
slot for the active object. Since this slot is created on the action
used by the object, it requires that this action exists and is a
layered/slotted action (which by definition includes empty actions).

Pull Request: https://projects.blender.org/blender/blender/pulls/126934
This commit is contained in:
Sybren A. Stüvel
2024-08-29 15:37:03 +02:00
parent b6e022d913
commit 090c7aa68e
2 changed files with 54 additions and 1 deletions

View File

@@ -253,7 +253,7 @@ class DOPESHEET_HT_editor_buttons:
layout.template_search(
adt, "action_slot",
adt, "action_slots",
new="",
new="anim.slot_new_for_object",
unlink="anim.slot_unassign_object",
)

View File

@@ -718,6 +718,58 @@ static void ANIM_OT_scene_range_frame(wmOperatorType *ot)
/** \name Slots
* \{ */
static bool slot_new_for_object_poll(bContext *C)
{
using namespace blender;
Object *object = CTX_data_active_object(C);
if (!object) {
return false;
}
animrig::Action *action = animrig::get_action(object->id);
if (!action) {
CTX_wm_operator_poll_msg_set(
C, "Creating a new Action Slot is only possible when an Action is already assigned");
return false;
}
return action->is_action_layered();
}
static int slot_new_for_object_exec(bContext *C, wmOperator * /*op*/)
{
using namespace blender;
Object *object = CTX_data_active_object(C);
animrig::Action *action = animrig::get_action(object->id);
BLI_assert_msg(action, "The poll function should have ensured the Action is not NULL");
animrig::Slot &slot = action->slot_add_for_id(object->id);
{ /* Assign the newly created slot. */
const bool ok = action->assign_id(&slot, object->id);
BLI_assert_msg(ok, "Assigning a slot that was made for this ID should always work");
UNUSED_VARS_NDEBUG(ok);
}
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, nullptr);
return OPERATOR_FINISHED;
}
static void ANIM_OT_slot_new_for_object(wmOperatorType *ot)
{
/* identifiers */
ot->name = "New Slot";
ot->idname = "ANIM_OT_slot_new_for_object";
ot->description = "Create a new Slot for this object, on the Action already assigned to it";
/* api callbacks */
ot->exec = slot_new_for_object_exec;
ot->poll = slot_new_for_object_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool slot_unassign_object_poll(bContext *C)
{
Object *object = CTX_data_active_object(C);
@@ -873,6 +925,7 @@ void ED_operatortypes_anim()
WM_operatortype_append(ANIM_OT_keying_set_active_set);
WM_operatortype_append(ANIM_OT_slot_new_for_object);
WM_operatortype_append(ANIM_OT_slot_unassign_object);
WM_operatortype_append(ANIM_OT_convert_legacy_action);
}