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:
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user