Action Editor WIP: Adding new actions in Action Editor now uses the "stash and create new" operator

In constrast to the old "new" operator, this operator will stash the existing action
in the stack to prevent it from being lost. This situation isn't totally ideal yet,
since the NLA Editor still calls the old method.
This commit is contained in:
Joshua Leung 2015-03-01 00:38:44 +13:00
parent 13a0dce51c
commit 741a66e472
4 changed files with 92 additions and 12 deletions

View File

@ -122,7 +122,7 @@ class DOPESHEET_HT_header(Header):
dopesheet_filter(layout, context, genericFiltersOnly=True)
if st.mode in {'ACTION', 'SHAPEKEY'}:
layout.template_ID(st, "action", new="action.new")
layout.template_ID(st, "action", new="action.stash_and_create")
row = layout.row(align=True)
row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN')

View File

@ -206,7 +206,6 @@ void ACTION_OT_new(wmOperatorType *ot)
/* api callbacks */
ot->exec = action_new_exec;
// TODO: add a new invoke() callback to catch cases where users unexpectedly delete their data
/* NOTE: this is used in the NLA too... */
//ot->poll = ED_operator_action_active;
@ -311,27 +310,20 @@ static int action_stash_exec(bContext *C, wmOperator *op)
else {
/* stash the action */
if (BKE_nla_action_stash(adt)) {
bAction *new_action = NULL;
/* create new action (if required) */
// XXX: maybe this should be a separate operator?
if (RNA_boolean_get(op->ptr, "create_new")) {
new_action = action_create_new(C, saction->action);
}
/* The stash operation will remove the user already,
* so the flushing step later shouldn't double up
* the usercount fixes. Hence, we must unset this ref
* first before setting the new action.
*/
saction->action = NULL;
actedit_change_action(C, new_action);
}
else {
/* action has already been added - simply warn about this, and clear */
BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
actedit_change_action(C, NULL);
}
/* clear action refs from editor, and then also the backing data (not necessary) */
actedit_change_action(C, NULL);
}
}
@ -359,6 +351,92 @@ void ACTION_OT_stash(wmOperatorType *ot)
"Create a new action once the existing one has been safely stored");
}
/* ----------------- */
/* Criteria:
* 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions
* 2) The associated AnimData block must not be in tweakmode
*/
static int action_stash_create_poll(bContext *C)
{
if (ED_operator_action_active(C)) {
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Scene *scene = CTX_data_scene(C);
/* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
/* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
if (!(scene->flag & SCE_NLA_EDIT_ON)) {
/* For now, actions are only for the active object, and on object and shapekey levels... */
return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
}
}
/* something failed... */
return false;
}
static int action_stash_create_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = actedit_animdata_from_context(C);
/* Check for no action... */
if (saction->action == NULL) {
/* just create a new action */
bAction *action = action_create_new(C, NULL);
actedit_change_action(C, action);
}
else if (adt) {
/* Perform stashing operation */
if (action_has_motion(adt->action) == 0) {
/* don't do anything if this action is empty... */
BKE_report(op->reports, RPT_WARNING, "Action needs have at least a keyframe or some FModifiers");
return OPERATOR_CANCELLED;
}
else {
/* stash the action */
if (BKE_nla_action_stash(adt)) {
bAction *new_action = NULL;
/* create new action based on the old one */
new_action = action_create_new(C, saction->action);
/* The stash operation will remove the user already,
* so the flushing step later shouldn't double up
* the usercount fixes. Hence, we must unset this ref
* first before setting the new action.
*/
saction->action = NULL;
actedit_change_action(C, new_action);
}
else {
/* action has already been added - simply warn about this, and clear */
BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
actedit_change_action(C, NULL);
}
}
}
/* Send notifiers that stuff has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
}
void ACTION_OT_stash_and_create(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Stash Action";
ot->idname = "ACTION_OT_stash_and_create";
ot->description = "Store this action in the NLA stack as a non-contributing strip for later use, and create a new action";
/* callbacks */
ot->exec = action_stash_create_exec;
ot->poll = action_stash_create_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
/* POSE MARKERS STUFF */

View File

@ -103,6 +103,7 @@ void ACTION_OT_mirror(struct wmOperatorType *ot);
void ACTION_OT_new(struct wmOperatorType *ot);
void ACTION_OT_push_down(struct wmOperatorType *ot);
void ACTION_OT_stash(struct wmOperatorType *ot);
void ACTION_OT_stash_and_create(struct wmOperatorType *ot);
void ACTION_OT_markers_make_local(struct wmOperatorType *ot);

View File

@ -81,6 +81,7 @@ void action_operatortypes(void)
WM_operatortype_append(ACTION_OT_new);
WM_operatortype_append(ACTION_OT_push_down);
WM_operatortype_append(ACTION_OT_stash);
WM_operatortype_append(ACTION_OT_stash_and_create);
WM_operatortype_append(ACTION_OT_previewrange_set);
WM_operatortype_append(ACTION_OT_view_all);