diff options
Diffstat (limited to 'source/blender/editors/space_action/action_edit.c')
-rw-r--r-- | source/blender/editors/space_action/action_edit.c | 100 |
1 files changed, 89 insertions, 11 deletions
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index ba06c7cf0e2..0e96c90f139 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -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 */ |