From 625a360b4b1f70262931294a4bff6bec244cd8c4 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 29 Nov 2009 04:52:01 +0000 Subject: [PATCH] Animation Editor (mostly Graph Editor) bugfixes: * Durian Report / Own Todo: Action Groups with no F-Curves in them visible were still shown in the animation editors. After several failed attempts in the past, finally got this working by making a little shuffling + a simpler solution. * Bugfix #20134: Graph Editor Keys -> Transform Menu was using the wrong operators. C+P error from copying menus over from Dopesheet * Muting Action Groups didn't draw all F-Curves contained in group as being muted too. --- .../blender/editors/animation/anim_filter.c | 116 +++++++++++------- .../blender/editors/space_graph/graph_draw.c | 2 +- .../editors/space_graph/graph_header.c | 5 +- 3 files changed, 76 insertions(+), 47 deletions(-) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index eb3a0377711..6586317b6dc 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -734,7 +734,6 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s ale->flag= nlt->flag; - // XXX or should this be done some other way? ale->key_data= &nlt->strips; ale->datatype= ALE_NLASTRIP; } @@ -755,12 +754,10 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s /* ----------------------------------------- */ - -static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id) +/* find the next F-Curve that is usable for inclusion */ +static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id) { - bAnimListElem *ale = NULL; - FCurve *fcu; - int items = 0; + FCurve *fcu = NULL; /* loop over F-Curves - assume that the caller of this has already checked that these should be included * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too... @@ -803,18 +800,42 @@ static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu)) ) { /* only include if this curve is active */ if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) { - ale= make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id); - - if (ale) { - BLI_addtail(anim_data, ale); - items++; - } + /* this F-Curve can be used, so return it */ + return fcu; } } } } } + /* no (more) F-Curves from the list are suitable... */ + return NULL; +} + +static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id) +{ + FCurve *fcu; + int items = 0; + + /* loop over every F-Curve able to be included + * - this for-loop works like this: + * 1) the starting F-Curve is assigned to the fcu pointer so that we have a starting point to search from + * 2) the first valid F-Curve to start from (which may include the one given as 'first') in the remaining + * list of F-Curves is found, and verified to be non-null + * 3) the F-Curve referenced by fcu pointer is added to the list + * 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through + * the rest of the F-Curve list without an eternal loop. Back to step 2 :) + */ + for (fcu=first; ( (fcu = animdata_filter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next) + { + bAnimListElem *ale = make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id); + + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } + } + /* return the number of items added to the list */ return items; } @@ -829,50 +850,57 @@ static int animdata_filter_action (ListBase *anim_data, bDopeSheet *ads, bAction /* loop over groups */ // TODO: in future, should we expect to need nested groups? for (agrp= act->groups.first; agrp; agrp= agrp->next) { - /* add this group as a channel first */ - if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) { - /* check if filtering by selection */ - if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) { - ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id); - if (ale) { - BLI_addtail(anim_data, ale); - items++; - } - } - } + FCurve *first_fcu; /* store reference to last channel of group */ if (agrp->channels.last) lastchan= agrp->channels.last; + /* get the first F-Curve in this group we can start to use, + * and if there isn't any F-Curve to start from, then don't + * this group at all... + */ + first_fcu = animdata_filter_fcurve_next(ads, agrp->channels.first, agrp, filter_mode, owner_id); - /* there are some situations, where only the channels of the action group should get considered */ - if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) { - /* filters here are a bit convoulted... - * - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes - * - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed) - * - * cases when we should include F-Curves inside group: - * - we don't care about visibility - * - group is expanded - * - we just need the F-Curves present - */ - if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) || (filter_mode & ANIMFILTER_CURVESONLY) ) - { - /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter, - * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing - * all its sub-curves to be shown + if (first_fcu) { + /* add this group as a channel first */ + if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) { + /* check if filtering by selection */ + if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) { + ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } + } + } + + /* there are some situations, where only the channels of the action group should get considered */ + if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) { + /* filters here are a bit convoulted... + * - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes + * - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed) + * + * cases when we should include F-Curves inside group: + * - we don't care about visibility + * - group is expanded + * - we just need the F-Curves present */ - if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) ) + if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) || (filter_mode & ANIMFILTER_CURVESONLY) ) { - if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) { - items += animdata_filter_fcurves(anim_data, ads, agrp->channels.first, agrp, owner, ownertype, filter_mode, owner_id); + /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter, + * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing + * all its sub-curves to be shown + */ + if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) ) + { + if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) { + items += animdata_filter_fcurves(anim_data, ads, first_fcu, agrp, owner, ownertype, filter_mode, owner_id); + } } } } } - - // TODO: but we still need to deal with the case when the group may be closed, but it has no visible curves too } /* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 6e0878972f8..3a7f9024510 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -818,7 +818,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri /* protected curves (non editable) are drawn with dotted lines */ setlinestyle(2); } - if (fcu->flag & FCURVE_MUTED) { + if ( ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) || (fcu->flag & FCURVE_MUTED) ) { /* muted curves are drawn in a greyish hue */ // XXX should we have some variations? UI_ThemeColorShade(TH_HEADER, 50); diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index a5f9cb23555..e05e41f1b66 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -154,9 +154,10 @@ static void graph_channelmenu(bContext *C, uiLayout *layout, void *arg_unused) static void graph_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiItemEnumO(layout, "Grab/Move", 0, "TFM_OT_transform", "mode", TFM_TIME_TRANSLATE); + uiItemO(layout, "Grab/Move", 0, "TFM_OT_translate"); uiItemEnumO(layout, "Extend", 0, "TFM_OT_transform", "mode", TFM_TIME_EXTEND); - uiItemEnumO(layout, "Scale", 0, "TFM_OT_transform", "mode", TFM_TIME_SCALE); + uiItemO(layout, "Rotate", 0, "TFM_OT_rotate"); + uiItemO(layout, "Scale", 0, "TFM_OT_resize"); } static void graph_editmenu(bContext *C, uiLayout *layout, void *arg_unused)