From ddc52b49ec38c50455d0db433bf987cecc629c56 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 May 2014 16:05:34 +1200 Subject: NLA Editor: View selected also recenters the view now (as in the DopeSheet Editor) --- source/blender/editors/space_nla/nla_edit.c | 80 +++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 328e0b69707..51a8413a6e5 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -356,7 +356,62 @@ void NLA_OT_previewrange_set(wmOperatorType *ot) /* ****************** View-All Operator ****************** */ -static int nlaedit_viewall(bContext *C, const bool onlySel) +/* Find the extents of the active channel + * > min: (float) bottom y-extent of channel + * > max: (float) top y-extent of channel + * > returns: success of finding a selected channel + */ +static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, float *max) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + SpaceNla *snla = (SpaceNla *)ac->sl; + const float half_height = NLACHANNEL_HEIGHT_HALF(snla); + short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */ + float y; + + /* get all items - we need to do it this way */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* loop through all channels, finding the first one that's selected */ + y = (float)NLACHANNEL_FIRST; + + for (ale = anim_data.first; ale; ale = ale->next) { + bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + + /* must be selected... */ + if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) && + ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT)) + { + /* update best estimate */ + *min = (float)(y - half_height); + *max = (float)(y + half_height); + + /* is this high enough priority yet? */ + found = acf->channel_role; + + /* only stop our search when we've found an actual channel + * - datablock expanders get less priority so that we don't abort prematurely + */ + if (found == ACHANNEL_ROLE_CHANNEL) { + break; + } + } + + /* adjust y-position for next one */ + y -= NLACHANNEL_STEP(snla); + } + + /* free all temp data */ + BLI_freelistN(&anim_data); + + return (found != 0); +} + +static int nlaedit_viewall(bContext *C, const bool only_sel) { bAnimContext ac; View2D *v2d; @@ -368,15 +423,32 @@ static int nlaedit_viewall(bContext *C, const bool onlySel) v2d = &ac.ar->v2d; /* set the horizontal range, with an extra offset so that the extreme keys will be in view */ - get_nlastrip_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, onlySel); + get_nlastrip_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel); extra = 0.1f * BLI_rctf_size_x(&v2d->cur); v2d->cur.xmin -= extra; v2d->cur.xmax += extra; /* set vertical range */ - v2d->cur.ymax = 0.0f; - v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask); + if (only_sel == false) { + /* view all -> the summary channel is usually the shows everything, and resides right at the top... */ + v2d->cur.ymax = 0.0f; + v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask); + } + else { + /* locate first selected channel (or the active one), and frame those */ + float ymin = v2d->cur.ymin; + float ymax = v2d->cur.ymax; + + if (nla_channels_get_selected_extents(&ac, &ymin, &ymax)) { + /* recenter the view so that this range is in the middle */ + float ymid = (ymax - ymin) / 2.0f + ymin; + float x_center; + + UI_view2d_center_get(v2d, &x_center, NULL); + UI_view2d_center_set(v2d, x_center, ymid); + } + } /* do View2D syncing */ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); -- cgit v1.2.3