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/ui/space_dopesheet.py2
-rw-r--r--release/scripts/ui/space_graph.py5
-rw-r--r--release/scripts/ui/space_nla.py4
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c543
-rw-r--r--source/blender/editors/animation/anim_filter.c100
-rw-r--r--source/blender/editors/space_nla/nla_ops.c24
-rw-r--r--source/blender/editors/space_nla/space_nla.c6
-rw-r--r--source/blender/makesdna/DNA_anim_types.h3
8 files changed, 352 insertions, 335 deletions
diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py
index c9209791289..b416c9ee01a 100644
--- a/release/scripts/ui/space_dopesheet.py
+++ b/release/scripts/ui/space_dopesheet.py
@@ -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"
diff --git a/release/scripts/ui/space_graph.py b/release/scripts/ui/space_graph.py
index fe4f2cc1bfd..f33d5866d0b 100644
--- a/release/scripts/ui/space_graph.py
+++ b/release/scripts/ui/space_graph.py
@@ -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"
diff --git a/release/scripts/ui/space_nla.py b/release/scripts/ui/space_nla.py
index 3b187d707ec..3e1cf93df07 100644
--- a/release/scripts/ui/space_nla.py
+++ b/release/scripts/ui/space_nla.py
@@ -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:
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 16eb08be933..7f67b00fd75 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -25,6 +25,10 @@
* ***** 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);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 0e61d761463..5b0d6c2c299 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -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);
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 13380cd17f7..c5d6cde62c6 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -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)
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 25c53687597..3bff1d4159f 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -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);
}
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 8c2fc7db390..498ecdcd183 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -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') */