Action Editor: Added "Push Down" operator to send the current action on to the NLA...
authorJoshua Leung <aligorith@gmail.com>
Fri, 27 Feb 2015 04:06:44 +0000 (17:06 +1300)
committerJoshua Leung <aligorith@gmail.com>
Sat, 28 Feb 2015 13:34:41 +0000 (02:34 +1300)
This commit exposes the "Push Down" button/functionality found in the NLA Editor
to the Action Editor, so that actions can be added NLA Stack from here too. The
main point of this for now is to make the whole layered-animation workflow nicer
more efficient, but not requiring the second editor be visible in common cases.
It also conveniently sets things up for the next few changes (already hinted at
here)...

release/scripts/startup/bl_ui/space_dopesheet.py
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_intern.h
source/blender/editors/space_action/action_ops.c

index e52d180c1cb84554f0fab45e1fedfc78498e4421..16dfb1d75cc12dc6eea9927e55e967ff2cf89869 100644 (file)
@@ -124,6 +124,10 @@ class DOPESHEET_HT_header(Header):
         if st.mode in {'ACTION', 'SHAPEKEY'}:
             layout.template_ID(st, "action", new="action.new")
 
+            row = layout.row(align=True)
+            row.operator("action.push_down", text="", icon='NLA_PUSHDOWN')
+            row.operator("action.push_down", text="", icon='FREEZE') # XXX: "stash"
+
         # Grease Pencil mode doesn't need snapping, as it's frame-aligned only
         if st.mode != 'GPENCIL':
             layout.prop(st, "auto_snap", text="")
index 28e10a90a874eef5369af7d9d0ae2140c971240e..e8ee993314c10295205035c8615d50d689411b22 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "DNA_anim_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_mask_types.h"
 
@@ -52,6 +54,7 @@
 #include "BKE_action.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
+#include "BKE_key.h"
 #include "BKE_main.h"
 #include "BKE_nla.h"
 #include "BKE_context.h"
@@ -145,6 +148,87 @@ void ACTION_OT_new(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* ******************* Action Push-Down Operator ******************** */
+
+/* Criteria:
+ *  1) There must be an dopesheet/action editor, and it must be in a mode which uses actions 
+ *  2) There must be an action active
+ *  3) The associated AnimData block must not be in tweakmode
+ */
+static int action_pushdown_poll(bContext *C)
+{
+       if (ED_operator_action_active(C)) {
+               SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+               Scene *scene = CTX_data_scene(C);
+               Object *ob = CTX_data_active_object(C);
+               
+               /* Check for actions and that tweakmode is off */
+               if ((saction->action) && !(scene->flag & SCE_NLA_EDIT_ON)) {
+                       /* For now, actions are only for the active object, and on object and shapekey levels... */
+                       if (saction->mode == SACTCONT_ACTION) {
+                               return (ob->adt != NULL);
+                       }
+                       else if (saction->mode == SACTCONT_SHAPEKEY) {
+                               Key *key = BKE_key_from_object(ob);
+                               
+                               return (key && key->adt);
+                       }
+               }       
+       }
+       
+       /* something failed... */
+       return false;
+}
+
+static int action_pushdown_exec(bContext *C, wmOperator *op)
+{
+       SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+       Object *ob = CTX_data_active_object(C);
+       AnimData *adt = NULL;
+       
+       /* Get AnimData block to use */
+       if (saction->mode == SACTCONT_ACTION) {
+               /* Currently, "Action Editor" means object-level only... */
+               adt = ob->adt;
+       }
+       else if (saction->mode == SACTCONT_SHAPEKEY) {
+               Key *key = BKE_key_from_object(ob);
+               adt = key->adt;
+       }
+       
+       /* Do the deed... */
+       if (adt) {
+               /* Perform the pushdown operation
+                * - This will deal with all the AnimData-side usercounts
+                */
+               BKE_nla_action_pushdown(adt);
+               
+               /* Stop displaying this action in this editor
+                * NOTE: The editor itself doesn't set a user...
+                */
+               saction->action = NULL;
+       }
+       
+       /* Send notifiers that stuff has changed */
+       WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+       return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_push_down(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Push Down Action";
+       ot->idname = "ACTION_OT_push_down";
+       ot->description = "Push action down on to the NLA stack as a new strip";
+       
+       /* callbacks */
+       ot->exec = action_pushdown_exec;
+       ot->poll = action_pushdown_poll;
+       
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* ************************************************************************** */
 /* POSE MARKERS STUFF */
 
index 8f39a38157af23baa4a100364e02bd131fcc3023..8bade7a011f30d823a7cb1a02382c26a33e25d30 100644 (file)
@@ -101,6 +101,7 @@ void ACTION_OT_snap(struct wmOperatorType *ot);
 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_markers_make_local(struct wmOperatorType *ot);
 
index 0fbacefa8e33b395c11ef39b6e9e9a1b04a95911..76b08012c5619400d6cf33c71840c25e7f24f31a 100644 (file)
@@ -77,7 +77,9 @@ void action_operatortypes(void)
        WM_operatortype_append(ACTION_OT_keyframe_insert);
        WM_operatortype_append(ACTION_OT_copy);
        WM_operatortype_append(ACTION_OT_paste);
+       
        WM_operatortype_append(ACTION_OT_new);
+       WM_operatortype_append(ACTION_OT_push_down);
        
        WM_operatortype_append(ACTION_OT_previewrange_set);
        WM_operatortype_append(ACTION_OT_view_all);