NLA Editor: View selected also recenters the view now (as in the DopeSheet Editor)

This commit is contained in:
Joshua Leung 2014-05-09 16:05:34 +12:00
parent b3cd9d289a
commit ddc52b49ec
1 changed files with 76 additions and 4 deletions

View File

@ -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);