NLA SoC: Operator for adding new NLA-Tracks
authorJoshua Leung <aligorith@gmail.com>
Thu, 11 Jun 2009 03:19:08 +0000 (03:19 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 11 Jun 2009 03:19:08 +0000 (03:19 +0000)
New tracks can be added in the following ways (with the mouse hovering over the channels-list):
* Shift-A - this will add a new track at the top of the stack (i.e. above all the existing NLA-tracks but below the Active Action) for every AnimData block where there was a selected NLA-Track

* Ctrl-Shift-A - this will add a new track above every selected one

source/blender/blenkernel/BKE_nla.h
source/blender/blenkernel/intern/nla.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_nla/nla_edit.c
source/blender/editors/space_nla/nla_intern.h
source/blender/editors/space_nla/nla_ops.c

index da824fd20933c83e9c810bbb1114a5dcf0cb9136..078c1ba52bb870431d01f89e5ca1883b189e6130 100644 (file)
@@ -46,7 +46,7 @@ struct NlaStrip *copy_nlastrip(struct NlaStrip *strip);
 struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt);
 void copy_nladata(ListBase *dst, ListBase *src);
 
-struct NlaTrack *add_nlatrack(struct AnimData *adt);
+struct NlaTrack *add_nlatrack(struct AnimData *adt, struct NlaTrack *prev);
 struct NlaStrip *add_nlastrip(struct bAction *act);
 struct NlaStrip *add_nlastrip_to_stack(struct AnimData *adt, struct bAction *act);
 
index 9acbad32a426cefdeb02e848afe31cd9768512b0..cef141280327143b81cbee933f0be7cc5ffcdfea 100644 (file)
@@ -215,8 +215,10 @@ void copy_nladata (ListBase *dst, ListBase *src)
 
 /* Adding ------------------------------------------- */
 
-/* Add a NLA Track to the given AnimData */
-NlaTrack *add_nlatrack (AnimData *adt)
+/* Add a NLA Track to the given AnimData 
+ *     - prev: NLA-Track to add the new one after
+ */
+NlaTrack *add_nlatrack (AnimData *adt, NlaTrack *prev)
 {
        NlaTrack *nlt;
        
@@ -232,7 +234,10 @@ NlaTrack *add_nlatrack (AnimData *adt)
        nlt->index= BLI_countlist(&adt->nla_tracks);
        
        /* add track to stack, and make it the active one */
-       BLI_addtail(&adt->nla_tracks, nlt);
+       if (prev)
+               BLI_insertlinkafter(&adt->nla_tracks, prev, nlt);
+       else
+               BLI_addtail(&adt->nla_tracks, nlt);
        BKE_nlatrack_set_active(&adt->nla_tracks, nlt);
        
        /* must have unique name, but we need to seed this */
@@ -308,7 +313,7 @@ NlaStrip *add_nlastrip_to_stack (AnimData *adt, bAction *act)
                 (BKE_nlatrack_has_space(adt->nla_tracks.last, strip->start, strip->end)==0) ) 
        {
                /* no space, so add to a new track... */
-               nlt= add_nlatrack(adt);
+               nlt= add_nlatrack(adt, NULL);
        }
        else 
        {
index b40b1bf0f4d37f24429ee7f30b2e588a36f8c88f..992c5bfa756816714d4bb743b2c782dd2006d595 100644 (file)
@@ -459,3 +459,76 @@ void NLA_OT_channels_click (wmOperatorType *ot)
 }
 
 /* *********************************************** */
+/* Special Operators */
+
+/* ******************** Add Tracks Operator ***************************** */
+/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
+
+static int nlaedit_add_tracks_exec (bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       
+       AnimData *lastAdt = NULL;
+       short above_sel= RNA_boolean_get(op->ptr, "above_selected");
+       
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+               
+       /* get a list of the AnimData blocks being shown in the NLA */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_SEL);
+       ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+       
+       /* add tracks... */
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               NlaTrack *nlt= (NlaTrack *)ale->data;
+               AnimData *adt= BKE_animdata_from_id(ale->id);
+               
+               /* check if just adding a new track above this one,
+                * or whether we're adding a new one to the top of the stack that this one belongs to
+                */
+               if (above_sel) {
+                       /* just add a new one above this one */
+                       add_nlatrack(adt, nlt);
+               }
+               else if ((lastAdt == NULL) || (adt != lastAdt)) {
+                       /* add one track to the top of the owning AnimData's stack, then don't add anymore to this stack */
+                       add_nlatrack(adt, NULL);
+                       lastAdt= adt;
+               }
+       }
+       
+       /* free temp data */
+       BLI_freelistN(&anim_data);
+       
+       /* set notifier that things have changed */
+       ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+       WM_event_add_notifier(C, NC_SCENE, NULL);
+       
+       /* done */
+       return OPERATOR_FINISHED;
+}
+
+void NLA_OT_add_tracks (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Track(s)";
+       ot->idname= "NLA_OT_add_tracks";
+       ot->description= "Add NLA-Tracks above/after the selected tracks.";
+       
+       /* api callbacks */
+       ot->exec= nlaedit_add_tracks_exec;
+       ot->poll= nlaop_poll_tweakmode_off;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "above_selected", 0, "Above Selected", "Add a new NLA Track above every existing selected one.");
+}
+
+/* *********************************************** */
index 93ac726c17e09ce022c603bf5460983deae899bb..e8af67aebd120b5d70c7d54f62acb09e59304e80 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <math.h>
 
 #include "DNA_anim_types.h"
 #include "DNA_action_types.h"
index 9511f67f8242d2f8ef228bc4a60ecf1c4f4c3a97..b0a9ba5b1825acff0ca640d7ec1d39c0dd183cc7 100644 (file)
@@ -102,6 +102,8 @@ void NLAEDIT_OT_split(wmOperatorType *ot);
 void NLA_OT_channels_select_border(wmOperatorType *ot);
 void NLA_OT_channels_click(wmOperatorType *ot);
 
+void NLA_OT_add_tracks(wmOperatorType *ot);
+
 /* **************************************** */
 /* nla_ops.c */
 
index 14c6f2a32d25e836390b54d3964089ad04bd042a..6cba19bb2cfad87af5da6e82beb4192bd8f48a7d 100644 (file)
@@ -124,6 +124,8 @@ void nla_operatortypes(void)
        WM_operatortype_append(NLA_OT_channels_click);
        WM_operatortype_append(NLA_OT_channels_select_border);
        
+       WM_operatortype_append(NLA_OT_add_tracks);
+       
        /* select */
        WM_operatortype_append(NLAEDIT_OT_click_select);
        WM_operatortype_append(NLAEDIT_OT_select_border);
@@ -148,9 +150,14 @@ static void nla_keymap_channels (wmWindowManager *wm, ListBase *keymap)
        WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
        
-       /* borderselect */ 
+               /* borderselect */ 
        WM_keymap_add_item(keymap, "NLA_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
        
+       /* channel operations */
+               /* add tracks */
+       WM_keymap_add_item(keymap, "NLA_OT_add_tracks", AKEY, KM_PRESS, KM_SHIFT, 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "NLA_OT_add_tracks", AKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "above_selected", 1);
+       
        /* General Animation Channels keymap (see anim_channels.c) ----------------------- */
                /* deselect all */
        WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);