Animation Editors: Channel Reordering
authorJoshua Leung <aligorith@gmail.com>
Sun, 7 Nov 2010 12:09:15 +0000 (12:09 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 7 Nov 2010 12:09:15 +0000 (12:09 +0000)
This commit restores the ability to reorder channels in the animation editors (DopeSheet/Action/etc., Graph/Drivers, NLA). The hotkeys for this are:
- Shift-PageUp = Move Up
- Shift-PageDown = Move Down

- Ctrl-Shift-PageUp = Move to Top of List
- Ctrl-Shift-PageDown = Move to Bottom of List

Do note that only animation data can get reordered using this.
So, do not expect to be able to change the object order (that is actually taken from the order that Blender actually evaluates them per update/frame).

---

In the process, I've fixed a couple of other bugs:
* Removed 'optimisation step' check in anim_filter.c for dopesheet with no filtering options modified, since this meant that the ANIMFILTER_ANIMDATA data filter was not getting processed (and potentially there were other maintenance problems with that).

* Made NLA Editor's channel list not totally duplicate the basic Animation Channels keymap. Instead, the "NLA Channels" keymap now only defines the parts that are different, and this then gets specified before the standard one so that these different parts will override the standard ones.

* Attempted to fix BorderSelect on NLA Channels list. Still not totally working correctly yet though.

* Moved "Euler Discontinuity" menu entry from "Channels" to "Keys". It really belongs in the latter, since it affects the keyframe values, rather than some aspect of the channel (i.e. ordering of channels or how they're displayed)

release/scripts/ui/space_dopesheet.py
release/scripts/ui/space_graph.py
release/scripts/ui/space_nla.py
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/space_nla/nla_ops.c
source/blender/editors/space_nla/space_nla.c
source/blender/makesdna/DNA_anim_types.h

index c92097912890244c456587f043e8880451752b32..b416c9ee01a89790b72229479ea10c8c5575e1f6 100644 (file)
@@ -199,6 +199,8 @@ class DOPESHEET_MT_channel(bpy.types.Menu):
         layout.operator("anim.channels_expand")
         layout.operator("anim.channels_collapse")
 
+        layout.separator()
+        layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
 
 class DOPESHEET_MT_key(bpy.types.Menu):
     bl_label = "Key"
index fe4f2cc1bfd6800763a61b742618181134057057..f33d5866d0bb6f8fa1091dac3ca62688f4188ffc 100644 (file)
@@ -158,7 +158,7 @@ class GRAPH_MT_channel(bpy.types.Menu):
         layout.operator("anim.channels_collapse")
 
         layout.separator()
-        layout.operator("graph.euler_filter", text="Discontinuity (Euler) Filter")
+        layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
 
 
 class GRAPH_MT_key(bpy.types.Menu):
@@ -195,6 +195,9 @@ class GRAPH_MT_key(bpy.types.Menu):
         layout.operator("graph.copy")
         layout.operator("graph.paste")
 
+        layout.separator()
+        layout.operator("graph.euler_filter", text="Discontinuity (Euler) Filter")
+
 
 class GRAPH_MT_key_transform(bpy.types.Menu):
     bl_label = "Transform"
index 3b187d707ec0400bccf23ca1bc9b8c2027abe279..3e1cf93df07ad58323b0d59706b64481f7080127 100644 (file)
@@ -122,6 +122,10 @@ class NLA_MT_edit(bpy.types.Menu):
         layout.operator("nla.move_up")
         layout.operator("nla.move_down")
 
+        # TODO: this really belongs more in a "channel" (or better, "track") menu
+        layout.separator()
+        layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...")
+
         layout.separator()
         # TODO: names of these tools for 'tweakmode' need changing?
         if scene.is_nla_tweakmode:
index 16eb08be933518c4bdf5be8778bb517d4a16abf2..7f67b00fd75ef843cfc7cdf937c1c8b66ffddc89 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> 
+
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
@@ -542,94 +546,29 @@ int animedit_poll_channels_nla_tweakmode_off (bContext *C)
 }
 
 /* ****************** Rearrange Channels Operator ******************* */
-/* This operator only works for Action Editor mode for now, as having it elsewhere makes things difficult */
-
-#if 0 // XXX old animation system - needs to be updated for new system...
 
 /* constants for channel rearranging */
 /* WARNING: don't change exising ones without modifying rearrange func accordingly */
 enum {
-       REARRANGE_ACTCHAN_TOP= -2,
-       REARRANGE_ACTCHAN_UP= -1,
-       REARRANGE_ACTCHAN_DOWN= 1,
-       REARRANGE_ACTCHAN_BOTTOM= 2
+       REARRANGE_ANIMCHAN_TOP= -2,
+       REARRANGE_ANIMCHAN_UP= -1,
+       REARRANGE_ANIMCHAN_DOWN= 1,
+       REARRANGE_ANIMCHAN_BOTTOM= 2
 };
 
-/* make sure all action-channels belong to a group (and clear action's list) */
-static void split_groups_action_temp (bAction *act, bActionGroup *tgrp)
-{
-       bActionChannel *achan;
-       bActionGroup *agrp;
-       
-       /* Separate action-channels into lists per group */
-       for (agrp= act->groups.first; agrp; agrp= agrp->next) {
-               if (agrp->channels.first) {
-                       achan= agrp->channels.last;
-                       act->chanbase.first= achan->next;
-                       
-                       achan= agrp->channels.first;
-                       achan->prev= NULL;
-                       
-                       achan= agrp->channels.last;
-                       achan->next= NULL;
-               }
-       }
-       
-       /* Initialise memory for temp-group */
-       memset(tgrp, 0, sizeof(bActionGroup));
-       tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP);
-       strcpy(tgrp->name, "#TempGroup");
-               
-       /* Move any action-channels not already moved, to the temp group */
-       if (act->chanbase.first) {
-               /* start of list */
-               achan= act->chanbase.first;
-               achan->prev= NULL;
-               tgrp->channels.first= achan;
-               act->chanbase.first= NULL;
-               
-               /* end of list */
-               achan= act->chanbase.last;
-               achan->next= NULL;
-               tgrp->channels.last= achan;
-               act->chanbase.last= NULL;
-       }
-       
-       /* Add temp-group to list */
-       BLI_addtail(&act->groups, tgrp);
-}
-
-/* link lists of channels that groups have */
-static void join_groups_action_temp (bAction *act)
-{
-       bActionGroup *agrp;
-       bActionChannel *achan;
-       
-       for (agrp= act->groups.first; agrp; agrp= agrp->next) {
-               ListBase tempGroup;
-               
-               /* add list of channels to action's channels */
-               tempGroup= agrp->channels;
-               addlisttolist(&act->chanbase, &agrp->channels);
-               agrp->channels= tempGroup;
-               
-               /* clear moved flag */
-               agrp->flag &= ~AGRP_MOVED;
-               
-               /* if temp-group... remove from list (but don't free as it's on the stack!) */
-               if (agrp->flag & AGRP_TEMP) {
-                       BLI_remlink(&act->groups, agrp);
-                       break;
-               }
-       }
-       
-       /* clear "moved" flag from all achans */
-       for (achan= act->chanbase.first; achan; achan= achan->next) 
-               achan->flag &= ~ACHAN_MOVED;
-}
+/* defines for rearranging channels */
+EnumPropertyItem prop_animchannel_rearrange_types[] = {
+       {REARRANGE_ANIMCHAN_TOP, "TOP", 0, "To Top", ""},
+       {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
+       {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
+       {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
+       {0, NULL, 0, NULL, NULL}
+};
 
+/* Rearrange Utilities --------------------------------------------- */
 
-static short rearrange_actchannel_is_ok (Link *channel, short type)
+/* checks if a channel should be considered for moving */
+static short rearrange_animchannel_is_ok (Link *channel, short type)
 {
        if (type == ANIMTYPE_GROUP) {
                bActionGroup *agrp= (bActionGroup *)channel;
@@ -637,17 +576,25 @@ static short rearrange_actchannel_is_ok (Link *channel, short type)
                if (SEL_AGRP(agrp) && !(agrp->flag & AGRP_MOVED))
                        return 1;
        }
-       else if (type == ANIMTYPE_ACHAN) {
-               bActionChannel *achan= (bActionChannel *)channel;
+       else if (type == ANIMTYPE_FCURVE) {
+               FCurve *fcu= (FCurve *)channel;
                
-               if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED))
+               // FIXME: F-Curve visibility is difficult... needs special filtering tests these days...
+               if (SEL_FCU(fcu) && !(fcu->flag & FCURVE_TAGGED))
+                       return 1;
+       }
+       else if (type == ANIMTYPE_NLATRACK) {
+               NlaTrack *nlt = (NlaTrack *)channel;
+               
+               if (SEL_NLT(nlt) && !(nlt->flag & NLASTRIP_FLAG_EDIT_TOUCHED))
                        return 1;
        }
        
        return 0;
 }
 
-static short rearrange_actchannel_after_ok (Link *channel, short type)
+/* checks if another channel can be placed after the given one */
+static short rearrange_animchannel_after_ok (Link *channel, short type)
 {
        if (type == ANIMTYPE_GROUP) {
                bActionGroup *agrp= (bActionGroup *)channel;
@@ -659,10 +606,11 @@ static short rearrange_actchannel_after_ok (Link *channel, short type)
        return 1;
 }
 
+/* Rearrange Methods --------------------------------------------- */
 
-static short rearrange_actchannel_top (ListBase *list, Link *channel, short type)
+static short rearrange_animchannel_top (ListBase *list, Link *channel, short type)
 {
-       if (rearrange_actchannel_is_ok(channel, type)) {
+       if (rearrange_animchannel_is_ok(channel, type)) {
                /* take it out off the chain keep data */
                BLI_remlink(list, channel);
                
@@ -675,9 +623,9 @@ static short rearrange_actchannel_top (ListBase *list, Link *channel, short type
        return 0;
 }
 
-static short rearrange_actchannel_up (ListBase *list, Link *channel, short type)
+static short rearrange_animchannel_up (ListBase *list, Link *channel, short type)
 {
-       if (rearrange_actchannel_is_ok(channel, type)) {
+       if (rearrange_animchannel_is_ok(channel, type)) {
                Link *prev= channel->prev;
                
                if (prev) {
@@ -694,9 +642,9 @@ static short rearrange_actchannel_up (ListBase *list, Link *channel, short type)
        return 0;
 }
 
-static short rearrange_actchannel_down (ListBase *list, Link *channel, short type)
+static short rearrange_animchannel_down (ListBase *list, Link *channel, short type)
 {
-       if (rearrange_actchannel_is_ok(channel, type)) {
+       if (rearrange_animchannel_is_ok(channel, type)) {
                Link *next = (channel->next) ? channel->next->next : NULL;
                
                if (next) {
@@ -708,7 +656,7 @@ static short rearrange_actchannel_down (ListBase *list, Link *channel, short typ
                        
                        return 1;
                }
-               else if (rearrange_actchannel_after_ok(list->last, type)) {
+               else if (rearrange_animchannel_after_ok(list->last, type)) {
                        /* take it out off the chain keep data */
                        BLI_remlink(list, channel);
                        
@@ -731,10 +679,10 @@ static short rearrange_actchannel_down (ListBase *list, Link *channel, short typ
        return 0;
 }
 
-static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short type)
+static short rearrange_animchannel_bottom (ListBase *list, Link *channel, short type)
 {
-       if (rearrange_actchannel_is_ok(channel, type)) {
-               if (rearrange_actchannel_after_ok(list->last, type)) {
+       if (rearrange_animchannel_is_ok(channel, type)) {
+               if (rearrange_animchannel_after_ok(list->last, type)) {
                        /* take it out off the chain keep data */
                        BLI_remlink(list, channel);
                        
@@ -748,51 +696,238 @@ static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short t
        return 0;
 }
 
+/* Generic Stuff ---------------------------------------------------------- */
 
-/* Change the order of action-channels 
- *     mode: REARRANGE_ACTCHAN_*  
+/* typedef for channel rearranging function 
+ * < list: list that channels belong to
+ * < channel: channel to be moved
+ * < type: type of channel (eAnim_ChannelType)
+ * > return[0]: whether operation was a success
  */
-static void rearrange_action_channels (bAnimContext *ac, short mode)
+typedef short (*AnimChanRearrangeFp)(ListBase *list, Link *channel, short type);
+
+/* get rearranging function, given 'rearrange' mode */
+static AnimChanRearrangeFp rearrange_get_mode_func (short mode)
 {
-       bAction *act;
-       bActionChannel *achan, *chan;
-       bActionGroup *agrp, *grp;
-       bActionGroup tgrp;
+       switch (mode) {
+               case REARRANGE_ANIMCHAN_TOP:
+                       return rearrange_animchannel_top;
+               case REARRANGE_ANIMCHAN_UP:
+                       return rearrange_animchannel_up;
+               case REARRANGE_ANIMCHAN_DOWN:
+                       return rearrange_animchannel_down;
+               case REARRANGE_ANIMCHAN_BOTTOM:
+                       return rearrange_animchannel_bottom;
+               default:
+                       return NULL;
+       }
+}
+
+/* ........ */
+
+/* These iteration helpers (ideally should be inlined, but probably not necessary) */
+
+static Link *rearrange_iter_first (ListBase *list, short mode)
+{
+       return (mode > 0) ? list->first : list->last;
+}
+
+static Link *rearrange_iter_next (Link *item, short mode)
+{
+       return (mode > 0) ? item->next : item->prev;
+}
+
+/* ........ */
+
+/* Clear 'tag' on all F-Curves */
+static void rearrange_clear_fcurve_tags (ListBase *list)
+{
+       FCurve *fcu;
        
-       short (*rearrange_func)(ListBase *, Link *, short);
-       short do_channels = 1;
+       for (fcu = list->first; fcu; fcu = fcu->next)
+               fcu->flag &= ~FCURVE_TAGGED;
+}
+
+/* NLA Specific Stuff ----------------------------------------------------- */
+
+/* Change the order NLA Tracks within NLA Stack
+ * ! NLA tracks are displayed in opposite order, so directions need care
+ *     mode: REARRANGE_ANIMCHAN_*  
+ */
+static void rearrange_nla_channels (bAnimContext *ac, AnimData *adt, short mode)
+{
+       NlaTrack *nlt, *track;
        
-       /* Get the active action, exit if none are selected */
-       act= (bAction *)ac->data;
+       AnimChanRearrangeFp rearrange_func;
        
-       /* exit if invalid mode */
-       switch (mode) {
-               case REARRANGE_ACTCHAN_TOP:
-                       rearrange_func= rearrange_actchannel_top;
-                       break;
-               case REARRANGE_ACTCHAN_UP:
-                       rearrange_func= rearrange_actchannel_up;
-                       break;
-               case REARRANGE_ACTCHAN_DOWN:
-                       rearrange_func= rearrange_actchannel_down;
-                       break;
-               case REARRANGE_ACTCHAN_BOTTOM:
-                       rearrange_func= rearrange_actchannel_bottom;
+       /* hack: invert mode so that functions will work in right order */
+       mode *= -1;
+       
+       /* get rearranging function */
+       rearrange_func = rearrange_get_mode_func(mode);
+       if (rearrange_func == NULL)
+               return;
+       
+       /* only consider NLA data if it's accessible */ 
+       //if (EXPANDED_DRVD(adt) == 0)
+       //      return;
+       
+       /* clear "moved" flag from all tracks */
+       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) 
+               nlt->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
+       
+       /* reorder all selected tracks */
+       for (nlt= rearrange_iter_first(&adt->nla_tracks, mode); nlt; nlt= track) {
+               /* Get next channel to consider */
+               track= rearrange_iter_next(nlt, mode);
+               
+               /* Try to do channel */
+               if (rearrange_func(&adt->nla_tracks, (Link *)nlt, ANIMTYPE_NLATRACK))
+                       nlt->flag |= NLASTRIP_FLAG_EDIT_TOUCHED;
+       }
+       
+       /* clear "moved" flag from all tracks */
+       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) 
+               nlt->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
+}
+
+/* Drivers Specific Stuff ------------------------------------------------- */
+
+/* Change the order drivers within AnimData block
+ *     mode: REARRANGE_ANIMCHAN_*  
+ */
+static void rearrange_driver_channels (bAnimContext *ac, AnimData *adt, short mode)
+{
+       FCurve *fcu, *fcun;
+       
+       /* get rearranging function */
+       AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+       
+       if (rearrange_func == NULL)
+               return;
+       
+       /* only consider drivers if they're accessible */       
+       if (EXPANDED_DRVD(adt) == 0)
+               return;
+       
+       rearrange_clear_fcurve_tags(&adt->drivers);
+       
+       /* reorder all selected driver F-Curves */
+       for (fcu= rearrange_iter_first(&adt->drivers, mode); fcu; fcu= fcun) {
+               /* Get next channel to consider */
+               fcun= rearrange_iter_next(fcu, mode);
+               
+               /* Try to do channel */
+               if (rearrange_func(&adt->drivers, (Link *)fcu, ANIMTYPE_FCURVE))
+                       fcu->flag |= FCURVE_TAGGED;
+       }
+       
+       rearrange_clear_fcurve_tags(&adt->drivers);
+}
+
+/* Action Specific Stuff ------------------------------------------------- */
+
+/* make sure all action-channels belong to a group (and clear action's list) */
+static void split_groups_action_temp (bAction *act, bActionGroup *tgrp)
+{
+       bActionGroup *agrp;
+       FCurve *fcu;
+       
+       if (act == NULL)
+               return;
+       
+       /* clear "moved" flag from all FCurves */
+       rearrange_clear_fcurve_tags(&act->curves);
+       
+       /* Separate F-Curves into lists per group */
+       for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+               if (agrp->channels.first) {
+                       fcu= agrp->channels.last;
+                       act->curves.first= fcu->next;
+                       
+                       fcu= agrp->channels.first;
+                       fcu->prev= NULL;
+                       
+                       fcu= agrp->channels.last;
+                       fcu->next= NULL;
+               }
+       }
+       
+       /* Initialise memory for temp-group */
+       memset(tgrp, 0, sizeof(bActionGroup));
+       tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP);
+       BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
+       
+       /* Move any action-channels not already moved, to the temp group */
+       if (act->curves.first) {
+               /* start of list */
+               fcu= act->curves.first;
+               fcu->prev= NULL;
+               tgrp->channels.first= fcu;
+               act->curves.first= NULL;
+               
+               /* end of list */
+               fcu= act->curves.last;
+               fcu->next= NULL;
+               tgrp->channels.last= fcu;
+               act->curves.last= NULL;
+       }
+       
+       /* Add temp-group to list */
+       BLI_addtail(&act->groups, tgrp);
+}
+
+/* link lists of channels that groups have */
+static void join_groups_action_temp (bAction *act)
+{
+       bActionGroup *agrp;
+       FCurve *fcu;
+       
+       for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+               ListBase tempGroup;
+               
+               /* add list of channels to action's channels */
+               tempGroup= agrp->channels;
+               addlisttolist(&act->curves, &agrp->channels);
+               agrp->channels= tempGroup;
+               
+               /* clear moved flag */
+               agrp->flag &= ~AGRP_MOVED;
+               
+               /* if temp-group... remove from list (but don't free as it's on the stack!) */
+               if (agrp->flag & AGRP_TEMP) {
+                       BLI_remlink(&act->groups, agrp);
                        break;
-               default:
-                       return;
+               }
        }
        
+       /* clear "moved" flag from all fcurve's */
+       rearrange_clear_fcurve_tags(&act->curves);
+}
+
+/* Change the order of anim-channels within action 
+ *     mode: REARRANGE_ANIMCHAN_*  
+ */
+static void rearrange_action_channels (bAnimContext *ac, bAction *act, short mode)
+{
+       bActionGroup *agrp, *grp;
+       bActionGroup tgrp;
+       FCurve *fcu, *fcun;
+       short do_channels = 1;
+       
+       /* get rearranging function */
+       AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+       
+       if (rearrange_func == NULL)
+               return;
+       
        /* make sure we're only operating with groups */
        split_groups_action_temp(act, &tgrp);
        
        /* rearrange groups first (and then, only consider channels if the groups weren't moved) */
-       #define GET_FIRST(list) ((mode > 0) ? (list.first) : (list.last))
-       #define GET_NEXT(item) ((mode > 0) ? (item->next) : (item->prev))
-       
-       for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
+       for (agrp= rearrange_iter_first(&act->groups, mode); agrp; agrp= grp) {
                /* Get next group to consider */
-               grp= GET_NEXT(agrp);
+               grp= rearrange_iter_next(agrp, mode);
                
                /* try to do group first */
                if (rearrange_func(&act->groups, (Link *)agrp, ANIMTYPE_GROUP)) {
@@ -802,25 +937,23 @@ static void rearrange_action_channels (bAnimContext *ac, short mode)
        }
        
        if (do_channels) {
-               for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
+               for (agrp= rearrange_iter_first(&act->groups, mode); agrp; agrp= grp) {
                        /* Get next group to consider */
-                       grp= GET_NEXT(agrp);
+                       grp= rearrange_iter_next(agrp, mode);
                        
-                       /* only consider action-channels if they're visible (group expanded) */
+                       /* only consider F-Curves if they're visible (group expanded) */
                        if (EXPANDED_AGRP(agrp)) {
-                               for (achan= GET_FIRST(agrp->channels); achan; achan= chan) {
+                               for (fcu= rearrange_iter_first(&agrp->channels, mode); fcu; fcu= fcun) {
                                        /* Get next channel to consider */
-                                       chan= GET_NEXT(achan);
+                                       fcun= rearrange_iter_next(fcu, mode);
                                        
                                        /* Try to do channel */
-                                       if (rearrange_func(&agrp->channels, (Link *)achan, ANIMTYPE_ACHAN))
-                                               achan->flag |= ACHAN_MOVED;
+                                       if (rearrange_func(&agrp->channels, (Link *)fcu, ANIMTYPE_FCURVE))
+                                               fcu->flag |= FCURVE_TAGGED;
                                }
                        }
                }
        }
-       #undef GET_FIRST
-       #undef GET_NEXT
        
        /* assemble lists into one list (and clear moved tags) */
        join_groups_action_temp(act);
@@ -831,95 +964,79 @@ static void rearrange_action_channels (bAnimContext *ac, short mode)
 static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
 {
        bAnimContext ac;
+       
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       
        short mode;
        
-       /* get editor data - only for Action Editor (for now) */
+       /* get editor data */
        if (ANIM_animdata_get_context(C, &ac) == 0)
                return OPERATOR_CANCELLED;
-       if (ac.datatype != ANIMCONT_ACTION)
-               return OPERATOR_PASS_THROUGH;
                
-       /* get mode, then rearrange channels */
+       /* get mode */
        mode= RNA_enum_get(op->ptr, "direction");
-       rearrange_action_channels(&ac, mode);
        
-       /* send notifier that things have changed */
-       WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
-       
-       return OPERATOR_FINISHED;
-}
-
-void ANIM_OT_channels_move_up (wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Move Channel(s) Up";
-       ot->idname= "ANIM_OT_channels_move_up";
-       
-       /* api callbacks */
-       ot->exec= animchannels_rearrange_exec;
-       ot->poll= ED_operator_areaactive;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-       
-       /* props */
-       RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_UP, "Direction", "");
-}
-
-void ANIM_OT_channels_move_down (wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Move Channel(s) Down";
-       ot->idname= "ANIM_OT_channels_move_down";
-       
-       /* api callbacks */
-       ot->exec= animchannels_rearrange_exec;
-       ot->poll= ED_operator_areaactive;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       /* get animdata blocks */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
+       ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
        
-       /* props */
-       RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_DOWN, "Direction", "");
-}
-
-void ANIM_OT_channels_move_top (wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Move Channel(s) to Top";
-       ot->idname= "ANIM_OT_channels_move_to_top";
+       for (ale = anim_data.first; ale; ale = ale->next) {
+               AnimData *adt= ale->data;
+               
+               switch (ac.datatype) {
+                       case ANIMCONT_NLA: /* NLA-tracks only */
+                               rearrange_nla_channels(&ac, adt, mode);
+                               break;
+                       
+                       case ANIMCONT_DRIVERS: /* Drivers list only */
+                               rearrange_driver_channels(&ac, adt, mode);
+                               break;
+                               
+#if 0
+                       case ANIMCONT_GPENCIL: /* Grease Pencil channels */
+                               break;
+#endif
+                               
+                       case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
+                               
+                       default: /* some collection of actions */
+                               // FIXME: actions should only be considered once!
+                               if (adt->action)
+                                       rearrange_action_channels(&ac, adt->action, mode);
+                               else
+                                       printf("animdata has no action\n");
+                               break;
+               }
+       }
        
-       /* api callbacks */
-       ot->exec= animchannels_rearrange_exec;
-       ot->poll= ED_operator_areaactive;
+       /* free temp data */
+       BLI_freelistN(&anim_data);
        
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       /* send notifier that things have changed */
+       WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
        
-       /* props */
-       RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_TOP, "Direction", "");
+       return OPERATOR_FINISHED;
 }
 
-void ANIM_OT_channels_move_bottom (wmOperatorType *ot)
+void ANIM_OT_channels_move (wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Move Channel(s) to Bottom";
-       ot->idname= "ANIM_OT_channels_move_to_bottom";
+       ot->name= "Move Channels";
+       ot->idname= "ANIM_OT_channels_move";
        
        /* api callbacks */
        ot->exec= animchannels_rearrange_exec;
-       ot->poll= ED_operator_areaactive;
+       ot->poll= animedit_poll_channels_nla_tweakmode_off;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_BOTTOM, "Direction", "");
+       RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
 }
 
-#endif // XXX old animation system - needs to be updated for new system...
-
 /* ******************** Delete Channel Operator *********************** */
 
 static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1530,7 +1647,14 @@ static void borderselect_anim_channels (bAnimContext *ac, rcti *rect, short sele
        
        View2D *v2d= &ac->ar->v2d;
        rctf rectf;
-       float ymin=0, ymax=(float)(-ACHANNEL_HEIGHT);
+       float ymin, ymax;
+       
+       /* set initial y extents */
+       if (ac->datatype == ANIMCONT_NLA)
+               ymax = (float)(-NLACHANNEL_HEIGHT);
+       else
+               ymax = (float)(-ACHANNEL_HEIGHT);
+       ymin = 0.0f;
        
        /* convert border-region to view coordinates */
        UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin+2, &rectf.xmin, &rectf.ymin);
@@ -1542,7 +1666,10 @@ static void borderselect_anim_channels (bAnimContext *ac, rcti *rect, short sele
        
        /* loop over data, doing border select */
        for (ale= anim_data.first; ale; ale= ale->next) {
-               ymin= ymax - ACHANNEL_STEP;
+               if (ac->datatype == ANIMCONT_NLA)
+                       ymin= ymax - NLACHANNEL_STEP;
+               else
+                       ymin= ymax - ACHANNEL_STEP;
                
                /* if channel is within border-select region, alter it */
                if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
@@ -1969,11 +2096,7 @@ void ED_operatortypes_animchannels(void)
                // XXX does this need to be a separate operator?
        WM_operatortype_append(ANIM_OT_channels_editable_toggle);
        
-               // XXX these need to be updated for new system... todo...
-       //WM_operatortype_append(ANIM_OT_channels_move_up);
-       //WM_operatortype_append(ANIM_OT_channels_move_down);
-       //WM_operatortype_append(ANIM_OT_channels_move_top);
-       //WM_operatortype_append(ANIM_OT_channels_move_bottom);
+       WM_operatortype_append(ANIM_OT_channels_move);
        
        WM_operatortype_append(ANIM_OT_channels_expand);
        WM_operatortype_append(ANIM_OT_channels_collapse);
@@ -2021,11 +2144,11 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
        RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0);
        
-       /* rearranging - actions only */
-       //WM_keymap_add_item(keymap, "ANIM_OT_channels_move_up", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0);
-       //WM_keymap_add_item(keymap, "ANIM_OT_channels_move_down", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0);
-       //WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_top", PAGEUPKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
-       //WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_bottom", PAGEDOWNKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+       /* rearranging */
+       RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_UP);
+       RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_DOWN);
+       RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_TOP);
+       RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_BOTTOM);
        
        /* Graph Editor only */
        WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_set", VKEY, KM_PRESS, 0, 0);
index 0e61d761463593605921459a8aa57629dc9d764b..5b0d6c2c29962c62213a6b0219a444259069f978 100644 (file)
@@ -2149,7 +2149,7 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
                        }
                        
                        /* additionally, dopesheet filtering also affects what objects to consider */
-                       if (ads->filterflag) {
+                       {
                                /* check selection and object type filters */
                                if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) )  {
                                        /* only selected should be shown */
@@ -2399,104 +2399,6 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
                                if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
                                        continue;
                        }
-                       else {
-                               /* check data-types */
-                               actOk= ANIMDATA_HAS_KEYS(ob);
-                               keyOk= (key != NULL);
-                               
-                               /* materials - only for geometric types */
-                               matOk= 0; /* by default, not ok... */
-                               if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) && (ob->totcol)) 
-                               {
-                                       int a;
-                                       
-                                       /* firstly check that we actuallly have some materials */
-                                       for (a=1; a <= ob->totcol; a++) {
-                                               Material *ma= give_current_material(ob, a);
-                                               int mtInd;
-                                               
-                                               if ((ma) && ANIMDATA_HAS_KEYS(ma)) {
-                                                       matOk= 1;
-                                                       break;
-                                               }
-                                                               
-                                               if(ma) {
-                                                       for (mtInd= 0; mtInd < MAX_MTEX; mtInd++) {
-                                                               MTex *mtex= ma->mtex[mtInd];
-                                                               
-                                                               if (mtex && mtex->tex && ANIMDATA_HAS_KEYS(mtex->tex)) {                                                                        
-                                                                       matOk= 1; 
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-
-                                               if(matOk)
-                                                       break;
-                                       }
-                               }
-                               
-                               /* data */
-                               switch (ob->type) {
-                                       case OB_CAMERA: /* ------- Camera ------------ */
-                                       {
-                                               Camera *ca= (Camera *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(ca);                                          
-                                       }
-                                               break;
-                                       case OB_LAMP: /* ---------- Lamp ----------- */
-                                       {
-                                               Lamp *la= (Lamp *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(la);  
-                                       }
-                                               break;
-                                       case OB_CURVE: /* ------- Curve ---------- */
-                                       case OB_SURF: /* ------- Nurbs Surface ---------- */
-                                       case OB_FONT: /* ------- Text Curve ---------- */
-                                       {
-                                               Curve *cu= (Curve *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(cu);  
-                                       }
-                                               break;
-                                       case OB_MBALL: /* -------- Metas ---------- */
-                                       {
-                                               MetaBall *mb= (MetaBall *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(mb);  
-                                       }
-                                               break;
-                                       case OB_ARMATURE: /* -------- Armature ---------- */
-                                       {
-                                               bArmature *arm= (bArmature *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(arm); 
-                                       }
-                                               break;
-                                       case OB_MESH: /* -------- Mesh ---------- */
-                                       {
-                                               Mesh *me= (Mesh *)ob->data;
-                                               dataOk= ANIMDATA_HAS_KEYS(me);  
-                                       }
-                                               break;
-                                       default: /* --- other --- */
-                                               dataOk= 0;
-                                               break;
-                               }
-                               
-                               /* particles */
-                               partOk = 0;
-                               if (ob->particlesystem.first) {
-                                       ParticleSystem *psys = ob->particlesystem.first;
-                                       for(; psys; psys=psys->next) {
-                                               if(psys->part && ANIMDATA_HAS_KEYS(psys->part)) {
-                                                       partOk = 1;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               
-                               /* check if all bad (i.e. nothing to show) */
-                               if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
-                                       continue;
-                       }
                        
                        /* since we're still here, this object should be usable */
                        items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
index 13380cd17f7d6ff57c393215da753f2edb9827d4..c5d6cde62c6d3953a47737dd993d610d7e44262d 100644 (file)
@@ -173,30 +173,6 @@ static void nla_keymap_channels(wmKeyMap *keymap)
                /* delete tracks */
        WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", XKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", DELKEY, KM_PRESS, 0, 0);
-       
-       /* General Animation Channels keymap (see anim_channels.c) ----------------------- */
-       /* selection */
-               /* borderselect - not in tweakmode */ 
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
-               
-               /* deselect all - not in tweakmode */
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);
-       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
-       
-       /* settings */
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_disable", WKEY, KM_PRESS, KM_ALT, 0);
-       
-       /* settings - specialised hotkeys */
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
-       
-       /* expand/collapse */
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0);
-       
-       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
-       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
 }
 
 static void nla_keymap_main (wmKeyConfig *keyconf, wmKeyMap *keymap)
index 25c53687597d15e28a47adce0236f612daef7e16..3bff1d4159f95c6d254d27683e7a738331e625d2 100644 (file)
@@ -209,9 +209,13 @@ static void nla_channel_area_init(wmWindowManager *wm, ARegion *ar)
        UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
        
        /* own keymap */
-       // TODO: cannot use generic copy, need special NLA version
+               /* own channels map first to override some channel keymaps */
        keymap= WM_keymap_find(wm->defaultconf, "NLA Channels", SPACE_NLA, 0);
        WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+               /* now generic channels map for everything else that can apply */
+       keymap= WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0);
+       WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+       
        keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0);
        WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
 }
index 8c2fc7db390fcef3672b28e70a7581b27daf7714..498ecdcd1833747043dcb3eb05cbe353b51dff2c 100644 (file)
@@ -465,6 +465,9 @@ typedef enum eFCurve_Flags {
        FCURVE_INT_VALUES               = (1<<11),
                /* curve can only have certain discrete-number values (no interpolation at all, for enums/booleans) */
        FCURVE_DISCRETE_VALUES  = (1<<12),
+       
+               /* temporary tag for editing */
+       FCURVE_TAGGED                   = (1<<15),
 } eFCurve_Flags;
 
 /* extrapolation modes (only simple value 'extending') */