diff options
-rw-r--r-- | release/scripts/ui/space_dopesheet.py | 2 | ||||
-rw-r--r-- | release/scripts/ui/space_graph.py | 5 | ||||
-rw-r--r-- | release/scripts/ui/space_nla.py | 4 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 543 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 100 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_ops.c | 24 | ||||
-rw-r--r-- | source/blender/editors/space_nla/space_nla.c | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 3 |
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') */ |