Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py2
-rw-r--r--source/blender/editors/space_action/action_edit.c100
-rw-r--r--source/blender/editors/space_action/action_intern.h1
-rw-r--r--source/blender/editors/space_action/action_ops.c1
4 files changed, 92 insertions, 12 deletions
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 5358670c2f2..67849a99abe 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -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')
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 */
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index f0f651dd07a..61d4249ae20 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -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);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 0bf31d2dfb3..8c706d8da57 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -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);