From fa59346c1340da4189e5c7d38164a74dc096db10 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 3 May 2019 13:00:18 +0200 Subject: Refactor: Support arbitrary y offset for channel list At first you could think that this refactor would not be necessary, because `ACHANNEL_FIRST` exists already. It contained the small y offset that all channels had. Unfortunately, a lot of code assumed that `ACHANNEL_FIRST = -ACHANNEL_HEIGHT`, making the define pretty much useless. This refactor fixes that for the action and nla editor. As a nice side effect, this patch fixes channel box select. Before there was always have a half-channel offset. Reviewers: brecht Differential Revision: https://developer.blender.org/D4783 --- .../blender/editors/animation/anim_channels_edit.c | 50 +++----- source/blender/editors/include/ED_anim_api.h | 13 +- source/blender/editors/include/UI_view2d.h | 20 +-- source/blender/editors/interface/view2d.c | 140 +++------------------ source/blender/editors/space_action/action_draw.c | 137 +++++++------------- source/blender/editors/space_action/action_edit.c | 12 +- .../blender/editors/space_action/action_select.c | 24 ++-- source/blender/editors/space_graph/graph_draw.c | 48 +++---- source/blender/editors/space_nla/nla_channels.c | 13 +- source/blender/editors/space_nla/nla_draw.c | 96 ++++++-------- source/blender/editors/space_nla/nla_edit.c | 13 +- source/blender/editors/space_nla/nla_select.c | 11 +- 12 files changed, 162 insertions(+), 415 deletions(-) (limited to 'source') diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 6e0277d5fff..adc6ec3f6be 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2531,17 +2531,6 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm SpaceNla *snla = (SpaceNla *)ac->sl; View2D *v2d = &ac->ar->v2d; rctf rectf; - float ymin, ymax; - - /* set initial y extents */ - if (ac->datatype == ANIMCONT_NLA) { - ymin = (float)(-NLACHANNEL_HEIGHT(snla)); - ymax = 0.0f; - } - else { - ymin = 0.0f; - ymax = (float)(-ACHANNEL_HEIGHT(ac)); - } /* convert border-region to view coordinates */ UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin); @@ -2551,8 +2540,17 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + float ymax; + if (ac->datatype == ANIMCONT_NLA) { + ymax = NLACHANNEL_FIRST_TOP(snla); + } + else { + ymax = ACHANNEL_FIRST_TOP(ac); + } + /* loop over data, doing box select */ for (ale = anim_data.first; ale; ale = ale->next) { + float ymin; if (ac->datatype == ANIMCONT_NLA) { ymin = ymax - NLACHANNEL_STEP(snla); } @@ -2729,32 +2727,25 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2]) ar = ac->ar; v2d = &ar->v2d; - /* Figure out which channel user clicked in. - * - * Note: although channels technically start at (y = ACHANNEL_FIRST), - * we need to adjust by half a channel's height so that the tops of channels get caught ok. - * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF. - */ + /* Figure out which channel user clicked in. */ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); if (ac->datatype == ANIMCONT_NLA) { SpaceNla *snla = (SpaceNla *)ac->sl; - UI_view2d_listview_view_to_cell(v2d, - NLACHANNEL_NAMEWIDTH, + UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, - (float)NLACHANNEL_HEIGHT_HALF(snla), + NLACHANNEL_FIRST_TOP(snla), x, y, NULL, &channel_index); } else { - UI_view2d_listview_view_to_cell(v2d, - ACHANNEL_NAMEWIDTH, + UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(ac), 0, - (float)ACHANNEL_HEIGHT_HALF(ac), + ACHANNEL_FIRST_TOP(ac), x, y, NULL, @@ -3206,19 +3197,12 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE selectmode = SELECT_REPLACE; } - /* figure out which channel user clicked in - * - * Note: - * although channels technically start at (y = ACHANNEL_FIRST), - * we need to adjust by half a channel's height so that the tops of channels get caught ok. - * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF. - */ + /* figure out which channel user clicked in */ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y); - UI_view2d_listview_view_to_cell(v2d, - ACHANNEL_NAMEWIDTH, + UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(&ac), 0, - (float)ACHANNEL_HEIGHT_HALF(&ac), + ACHANNEL_FIRST_TOP(&ac), x, y, NULL, diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index d947322f708..6342a8b26d9 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -403,11 +403,13 @@ typedef enum eAnimFilter_Flags { /* -------------- Channel Defines -------------- */ /* channel heights */ -#define ACHANNEL_FIRST(ac) (-0.8f * (ac)->yscale_fac * U.widget_unit) +#define ACHANNEL_FIRST_TOP(ac) (-0.4f * (ac)->yscale_fac * U.widget_unit) #define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit) -#define ACHANNEL_HEIGHT_HALF(ac) (0.4f * (ac)->yscale_fac * U.widget_unit) #define ACHANNEL_SKIP (0.1f * U.widget_unit) #define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP) +/* Additional offset to give some room at the end. */ +#define ACHANNEL_TOT_HEIGHT(ac, item_amount) \ + (-ACHANNEL_FIRST_TOP(ac) + ACHANNEL_STEP(ac) * (item_amount + 1)) /* channel widths */ #define ACHANNEL_NAMEWIDTH (10 * U.widget_unit) @@ -418,13 +420,14 @@ typedef enum eAnimFilter_Flags { /* -------------- NLA Channel Defines -------------- */ /* NLA channel heights */ -#define NLACHANNEL_FIRST (-0.8f * U.widget_unit) +#define NLACHANNEL_FIRST_TOP(snla) (-0.4f * U.widget_unit) #define NLACHANNEL_HEIGHT(snla) \ ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit)) -#define NLACHANNEL_HEIGHT_HALF(snla) \ - ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.4f * U.widget_unit) : (0.6f * U.widget_unit)) #define NLACHANNEL_SKIP (0.1f * U.widget_unit) #define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP) +/* Additional offset to give some room at the end. */ +#define NLACHANNEL_TOT_HEIGHT(snla, item_amount) \ + (-NLACHANNEL_FIRST_TOP(snla) + NLACHANNEL_STEP(snla) * (item_amount + 1)) /* channel widths */ #define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit) diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 07dbb49ac07..b1dfa89ae7d 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -183,16 +183,7 @@ void UI_view2d_scrollers_draw(struct View2D *v2d, View2DScrollers *scrollers); void UI_view2d_scrollers_free(View2DScrollers *scrollers); /* list view tools */ -void UI_view2d_listview_cell_to_view(struct View2D *v2d, - float columnwidth, - float rowheight, - float startx, - float starty, - int column, - int row, - struct rctf *rect); -void UI_view2d_listview_view_to_cell(struct View2D *v2d, - float columnwidth, +void UI_view2d_listview_view_to_cell(float columnwidth, float rowheight, float startx, float starty, @@ -200,15 +191,6 @@ void UI_view2d_listview_view_to_cell(struct View2D *v2d, float viewy, int *column, int *row); -void UI_view2d_listview_visible_cells(struct View2D *v2d, - float columnwidth, - float rowheight, - float startx, - float starty, - int *column_min, - int *column_max, - int *row_min, - int *row_max); /* coordinate conversion */ float UI_view2d_region_to_view_x(const struct View2D *v2d, float x); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 58d26c4a840..9de7a33b757 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1644,59 +1644,6 @@ void UI_view2d_scrollers_free(View2DScrollers *scrollers) /* *********************************************************************** */ /* List View Utilities */ -/** Get the view-coordinates of the nominated cell - * - * \param columnwidth, rowheight: size of each 'cell' - * \param startx, starty: coordinates (in 'tot' rect space) that the list starts from. - * This should be (0,0) for most views. However, for those where the starting row was offsetted - * (like for Animation Editor channel lists, to make the first entry more visible), these will be - * the min-coordinates of the first item. - * \param column, row: The 2d-coordinates - * (in 2D-view / 'tot' rect space) the cell exists at - * \param rect: coordinates of the cell - * (passed as single var instead of 4 separate, as it's more useful this way) - */ -void UI_view2d_listview_cell_to_view(View2D *v2d, - float columnwidth, - float rowheight, - float startx, - float starty, - int column, - int row, - rctf *rect) -{ - /* sanity checks */ - if (ELEM(NULL, v2d, rect)) { - return; - } - - if ((columnwidth <= 0) && (rowheight <= 0)) { - rect->xmin = rect->xmax = 0.0f; - rect->ymin = rect->ymax = 0.0f; - return; - } - - /* x-coordinates */ - rect->xmin = startx + (float)(columnwidth * column); - rect->xmax = startx + (float)(columnwidth * (column + 1)); - - if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) { - /* simply negate the values for the coordinates if in negative half */ - rect->xmin = -rect->xmin; - rect->xmax = -rect->xmax; - } - - /* y-coordinates */ - rect->ymin = starty + (float)(rowheight * row); - rect->ymax = starty + (float)(rowheight * (row + 1)); - - if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) { - /* simply negate the values for the coordinates if in negative half */ - rect->ymin = -rect->ymin; - rect->ymax = -rect->ymax; - } -} - /** * Get the 'cell' (row, column) that the given 2D-view coordinates * (i.e. in 'tot' rect space) lie in. @@ -1709,8 +1656,7 @@ void UI_view2d_listview_cell_to_view(View2D *v2d, * \param viewx, viewy: 2D-coordinates (in 2D-view / 'tot' rect space) to get the cell for * \param r_column, r_row: the 'coordinates' of the relevant 'cell' */ -void UI_view2d_listview_view_to_cell(View2D *v2d, - float columnwidth, +void UI_view2d_listview_view_to_cell(float columnwidth, float rowheight, float startx, float starty, @@ -1719,80 +1665,24 @@ void UI_view2d_listview_view_to_cell(View2D *v2d, int *r_column, int *r_row) { - /* adjust view coordinates to be all positive ints, corrected for the start offset */ - const int x = (int)(floorf(fabsf(viewx) + 0.5f) - startx); - const int y = (int)(floorf(fabsf(viewy) + 0.5f) - starty); - - /* sizes must not be negative */ - if ((v2d == NULL) || ((columnwidth <= 0) && (rowheight <= 0))) { - if (r_column) { - *r_column = 0; + if (r_column) { + if (columnwidth > 0) { + /* Columns go from left to right (x increases). */ + *r_column = floorf((viewx - startx) / columnwidth); } - if (r_row) { - *r_row = 0; + else { + *r_column = 0; } - - return; - } - - /* get column */ - if ((r_column) && (columnwidth > 0)) { - *r_column = x / columnwidth; - } - else if (r_column) { - *r_column = 0; } - /* get row */ - if ((r_row) && (rowheight > 0)) { - *r_row = y / rowheight; - } - else if (r_row) { - *r_row = 0; - } -} - -/** - * Get the 'extreme' (min/max) column and row indices which are visible within the 'cur' rect - * - * \param columnwidth, rowheight: Size of each 'cell' - * \param startx, starty: Coordinates that the list starts from, - * which should be (0,0) for most views. - * \param column_min, column_max, row_min, row_max: The starting and ending column/row indices - */ -void UI_view2d_listview_visible_cells(View2D *v2d, - float columnwidth, - float rowheight, - float startx, - float starty, - int *column_min, - int *column_max, - int *row_min, - int *row_max) -{ - /* using 'cur' rect coordinates, call the cell-getting function to get the cells for this */ - if (v2d) { - /* min */ - UI_view2d_listview_view_to_cell(v2d, - columnwidth, - rowheight, - startx, - starty, - v2d->cur.xmin, - v2d->cur.ymin, - column_min, - row_min); - - /* max*/ - UI_view2d_listview_view_to_cell(v2d, - columnwidth, - rowheight, - startx, - starty, - v2d->cur.xmax, - v2d->cur.ymax, - column_max, - row_max); + if (r_row) { + if (rowheight > 0) { + /* Rows got from top to bottom (y decreases). */ + *r_row = floorf((starty - viewy) / rowheight); + } + else { + *r_row = 0; + } } } diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 9827967f947..2a6ae93fc99 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -71,68 +71,50 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) int filter; View2D *v2d = &ar->v2d; - float y = 0.0f; size_t items; - int height; /* build list of channels to draw */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac))); - if (height > BLI_rcti_size_y(&v2d->mask)) { - /* don't use totrect set, as the width stays the same - * (NOTE: this is ok here, the configuration is pretty straightforward) - */ - v2d->tot.ymin = (float)(-height); - } + int height = ACHANNEL_TOT_HEIGHT(ac, items); + v2d->tot.ymin = -height; + /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */ UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY); /* loop through channels, and set up drawing depending on their type */ { /* first pass: just the standard GL-drawing for backdrop + text */ size_t channel_index = 0; + float ymax = ACHANNEL_FIRST_TOP(ac); - y = (float)ACHANNEL_FIRST(ac); - - for (ale = anim_data.first; ale; ale = ale->next) { - float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ - ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index); + ANIM_channel_draw(ac, ale, ymin, ymax, channel_index); } - - /* adjust y-position for next one */ - y -= ACHANNEL_STEP(ac); - channel_index++; } } { /* second pass: widgets */ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; + float ymax = ACHANNEL_FIRST_TOP(ac); - y = (float)ACHANNEL_FIRST(ac); - - for (ale = anim_data.first; ale; ale = ale->next) { - float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ rctf channel_rect; - BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, yminc, ymaxc); + BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, ymin, ymax); ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index); } - - /* adjust y-position for next one */ - y -= ACHANNEL_STEP(ac); - channel_index++; } UI_block_end(C, block); @@ -159,8 +141,6 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) bDopeSheet *ads = &saction->ads; AnimData *adt = NULL; - float y; - unsigned char col1[4], col2[4]; unsigned char col1a[4], col2a[4]; unsigned char col1b[4], col2b[4]; @@ -181,14 +161,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac))); - /* don't use totrect set, as the width stays the same - * (NOTE: this is ok here, the configuration is pretty straightforward) - */ - v2d->tot.ymin = (float)(-height); - - /* first backdrop strips */ - y = (float)(-ACHANNEL_HEIGHT(ac)); + int height = ACHANNEL_TOT_HEIGHT(ac, items); + v2d->tot.ymin = -height; GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -197,13 +171,15 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) GPU_blend(true); - for (ale = anim_data.first; ale; ale = ale->next) { - const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + /* first backdrop strips */ + float ymax = ACHANNEL_FIRST_TOP(ac); + + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); int sel = 0; @@ -264,11 +240,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) } /* draw region twice: firstly backdrop, then the current range */ - immRectf(pos, - v2d->cur.xmin, - (float)y - ACHANNEL_HEIGHT_HALF(ac), - v2d->cur.xmax + EXTRA_SCROLL_PAD, - (float)y + ACHANNEL_HEIGHT_HALF(ac)); + immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); } else if (ac->datatype == ANIMCONT_GPENCIL) { unsigned char *color; @@ -285,44 +257,25 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) } /* frames less than one get less saturated background */ immUniformColor4ubv(color); - immRectf(pos, - 0.0f, - (float)y - ACHANNEL_HEIGHT_HALF(ac), - v2d->cur.xmin, - (float)y + ACHANNEL_HEIGHT_HALF(ac)); + immRectf(pos, 0.0f, ymin, v2d->cur.xmin, ymax); /* frames one and higher get a saturated background */ immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2)); - immRectf(pos, - v2d->cur.xmin, - (float)y - ACHANNEL_HEIGHT_HALF(ac), - v2d->cur.xmax + EXTRA_SCROLL_PAD, - (float)y + ACHANNEL_HEIGHT_HALF(ac)); + immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); } else if (ac->datatype == ANIMCONT_MASK) { /* TODO --- this is a copy of gpencil */ /* frames less than one get less saturated background */ unsigned char *color = sel ? col1 : col2; immUniformColor4ubv(color); - immRectf(pos, - 0.0f, - (float)y - ACHANNEL_HEIGHT_HALF(ac), - v2d->cur.xmin, - (float)y + ACHANNEL_HEIGHT_HALF(ac)); + immRectf(pos, 0.0f, ymin, v2d->cur.xmin, ymax); /* frames one and higher get a saturated background */ immUniformColor3ubvAlpha(color, MIN2(255, color[3] * 2)); - immRectf(pos, - v2d->cur.xmin, - (float)y - ACHANNEL_HEIGHT_HALF(ac), - v2d->cur.xmax + EXTRA_SCROLL_PAD, - (float)y + ACHANNEL_HEIGHT_HALF(ac)); + immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); } } } - - /* Increment the step */ - y -= ACHANNEL_STEP(ac); } GPU_blend(false); @@ -342,21 +295,21 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) * This is to try to optimize this for heavier data sets * 2) Keyframes which are out of view horizontally are disregarded */ - y = (float)(-ACHANNEL_HEIGHT(ac)); - int action_flag = saction->flag; if (saction->mode == SACTCONT_TIMELINE) { action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES); } - for (ale = anim_data.first; ale; ale = ale->next) { - const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + ymax = ACHANNEL_FIRST_TOP(ac); + + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); + float ycenter = (ymin + ymax) / 2.0f; /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* check if anything to show for this channel */ if (ale->datatype != ALE_NONE) { adt = ANIM_nla_mapping_get(ac, ale); @@ -364,34 +317,32 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) /* draw 'keyframes' for each specific datatype */ switch (ale->datatype) { case ALE_ALL: - draw_summary_channel(v2d, ale->data, y, ac->yscale_fac, action_flag); + draw_summary_channel(v2d, ale->data, ycenter, ac->yscale_fac, action_flag); break; case ALE_SCE: - draw_scene_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag); + draw_scene_channel(v2d, ads, ale->key_data, ycenter, ac->yscale_fac, action_flag); break; case ALE_OB: - draw_object_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, action_flag); + draw_object_channel(v2d, ads, ale->key_data, ycenter, ac->yscale_fac, action_flag); break; case ALE_ACT: - draw_action_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag); + draw_action_channel(v2d, adt, ale->key_data, ycenter, ac->yscale_fac, action_flag); break; case ALE_GROUP: - draw_agroup_channel(v2d, adt, ale->data, y, ac->yscale_fac, action_flag); + draw_agroup_channel(v2d, adt, ale->data, ycenter, ac->yscale_fac, action_flag); break; case ALE_FCURVE: - draw_fcurve_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, action_flag); + draw_fcurve_channel(v2d, adt, ale->key_data, ycenter, ac->yscale_fac, action_flag); break; case ALE_GPFRAME: - draw_gpl_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag); + draw_gpl_channel(v2d, ads, ale->data, ycenter, ac->yscale_fac, action_flag); break; case ALE_MASKLAY: - draw_masklay_channel(v2d, ads, ale->data, y, ac->yscale_fac, action_flag); + draw_masklay_channel(v2d, ads, ale->data, ycenter, ac->yscale_fac, action_flag); break; } } } - - y -= ACHANNEL_STEP(ac); } /* free temporary channels used for drawing */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 8df773e98d6..d8ed25c86d3 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -325,24 +325,23 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min, /* NOTE: not bool, since we want prioritise individual channels over expanders */ short found = 0; - 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)ACHANNEL_FIRST(ac); + float ymax = ACHANNEL_FIRST_TOP(ac); - for (ale = anim_data.first; ale; ale = ale->next) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { const 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 - ACHANNEL_HEIGHT_HALF(ac)); - *max = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + *min = ymax - ACHANNEL_HEIGHT(ac); + *max = ymax; /* is this high enough priority yet? */ found = acf->channel_role; @@ -354,9 +353,6 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min, break; } } - - /* adjust y-position for next one */ - y -= ACHANNEL_STEP(ac); } /* free all temp data */ diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 1614e1c432d..8ecd25bda76 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -230,7 +230,6 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho KeyframeEditFunc ok_cb, select_cb; View2D *v2d = &ac->ar->v2d; rctf rectf; - float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac)); /* Convert mouse coordinates to frame ranges and channel * coordinates corrected for view pan/zoom. */ @@ -254,12 +253,14 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho /* init editing data */ memset(&ked, 0, sizeof(KeyframeEditData)); + float ymax = ACHANNEL_FIRST_TOP(ac); + /* loop over data, doing box select */ - for (ale = anim_data.first; ale; ale = ale->next) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* get new vertical minimum extent of channel */ - ymin = ymax - ACHANNEL_STEP(ac); + float ymin = ymax - ACHANNEL_STEP(ac); /* set horizontal range (if applicable) */ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) { @@ -314,9 +315,6 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho } } } - - /* set minimum extent to be the maximum of the next channel */ - ymax = ymin; } /* cleanup */ @@ -418,7 +416,6 @@ static void region_select_action_keys( KeyframeEditFunc ok_cb, select_cb; View2D *v2d = &ac->ar->v2d; rctf rectf, scaled_rectf; - float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac)); /* Convert mouse coordinates to frame ranges and channel * coordinates corrected for view pan/zoom. */ @@ -448,15 +445,17 @@ static void region_select_action_keys( ked.data = &scaled_rectf; } + float ymax = ACHANNEL_FIRST_TOP(ac); + /* loop over data, doing region select */ - for (ale = anim_data.first; ale; ale = ale->next) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* get new vertical minimum extent of channel */ - ymin = ymax - ACHANNEL_STEP(ac); + float ymin = ymax - ACHANNEL_STEP(ac); /* compute midpoint of channel (used for testing if the key is in the region or not) */ - ked.channel_y = ymin + ACHANNEL_HEIGHT_HALF(ac); + ked.channel_y = (ymin + ymax) / 2.0f; /* if channel is mapped in NLA, apply correction * - Apply to the bounds being checked, not all the keyframe points, @@ -520,9 +519,6 @@ static void region_select_action_keys( break; } } - - /* set minimum extent to be the maximum of the next channel */ - ymax = ymin; } /* cleanup */ @@ -1453,7 +1449,7 @@ static void mouse_action_keys(bAnimContext *ac, /* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); UI_view2d_listview_view_to_cell( - v2d, 0, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index); + 0, ACHANNEL_STEP(ac), 0, ACHANNEL_FIRST_TOP(ac), x, y, NULL, &channel_index); /* x-range to check is +/- 7px for standard keyframe under standard dpi/y-scale * (in screen/region-space), on either side of mouse click (size of keyframe icon). diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index dfc59a79c49..062c9f86fab 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -1230,9 +1230,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) int filter; View2D *v2d = &ar->v2d; - float y = 0.0f, height; + float height; size_t items; - int i = 0; /* build list of channels to draw */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); @@ -1240,62 +1239,47 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) /* Update max-extent of channels here (taking into account scrollers): * - this is done to allow the channel list to be scrollable, but must be done here - * to avoid regenerating the list again and/or also because channels list is drawn first - * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for - * start of list offset, and the second is as a correction for the scrollers. - */ - height = (float)((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac) * 2)); - UI_view2d_totRect_set(v2d, BLI_rcti_size_x(&ar->v2d.mask), height); + * to avoid regenerating the list again and/or also because channels list is drawn first */ + height = ACHANNEL_TOT_HEIGHT(ac, items); + v2d->tot.ymin = -height; /* loop through channels, and set up drawing depending on their type */ { /* first pass: just the standard GL-drawing for backdrop + text */ size_t channel_index = 0; + float ymax = ACHANNEL_FIRST_TOP(ac); - y = (float)ACHANNEL_FIRST(ac); - - for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) { - const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ - ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index); + ANIM_channel_draw(ac, ale, ymin, ymax, channel_index); } - - /* adjust y-position for next one */ - y -= ACHANNEL_STEP(ac); - channel_index++; } } { /* second pass: widgets */ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; - - y = (float)ACHANNEL_FIRST(ac); + float ymax = ACHANNEL_FIRST_TOP(ac); /* set blending again, as may not be set in previous step */ GPU_blend_set_func_separate( GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) { - const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac)); - const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac)); + for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { + float ymin = ymax - ACHANNEL_HEIGHT(ac); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ rctf channel_rect; - BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax - V2D_SCROLL_WIDTH, yminc, ymaxc); + BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax - V2D_SCROLL_WIDTH, ymin, ymax); ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index); } - - /* adjust y-position for next one */ - y -= ACHANNEL_STEP(ac); - channel_index++; } UI_block_end(C, block); diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 4115d6b49ba..3e4eb6af098 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -384,19 +384,12 @@ static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEv selectmode = SELECT_REPLACE; } - /** - * Figure out which channel user clicked in: - * - * \note Although channels technically start at y= NLACHANNEL_FIRST, - * we need to adjust by half a channel's height so that the tops of channels get caught ok. - * Since NLACHANNEL_FIRST is really NLACHANNEL_HEIGHT, we simply use NLACHANNEL_HEIGHT_HALF. - */ + /* Figure out which channel user clicked in. */ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y); - UI_view2d_listview_view_to_cell(v2d, - NLACHANNEL_NAMEWIDTH, + UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, - (float)NLACHANNEL_HEIGHT_HALF(snla), + NLACHANNEL_FIRST_TOP(snla), x, y, NULL, diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 1df2190b7af..b821a246dc5 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -689,23 +689,19 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for * start of list offset, and the second is as a correction for the scrollers. */ - int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2)); - - /* don't use totrect set, as the width stays the same - * (NOTE: this is ok here, the configuration is pretty straightforward) - */ - v2d->tot.ymin = (float)(-height); + int height = NLACHANNEL_TOT_HEIGHT(snla, items); + v2d->tot.ymin = -height; /* loop through channels, and set up drawing depending on their type */ - float y = (float)(-NLACHANNEL_HEIGHT(snla)); + float ymax = NLACHANNEL_FIRST_TOP(snla); - for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) { - const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla)); - const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla)); + for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) { + float ymin = ymax - NLACHANNEL_HEIGHT(snla); + float ycenter = (ymax + ymin) / 2.0f; /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* data to draw depends on the type of channel */ switch (ale->type) { case ANIMTYPE_NLATRACK: { @@ -721,18 +717,18 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) const float xmaxc = strip->end + text_margin_x; /* draw the visualization of the strip */ - nla_draw_strip(snla, adt, nlt, strip, v2d, yminc, ymaxc); + nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax); /* add the text for this strip to the cache */ if (xminc < xmaxc) { - nla_draw_strip_text(adt, nlt, strip, index, v2d, xminc, xmaxc, yminc, ymaxc); + nla_draw_strip_text(adt, nlt, strip, index, v2d, xminc, xmaxc, ymin, ymax); } /* if transforming strips (only real reason for temp-metas currently), * add to the cache the frame numbers of the strip's extents */ if (strip->flag & NLASTRIP_FLAG_TEMP_META) { - nla_draw_strip_frames_text(nlt, strip, v2d, yminc, ymaxc); + nla_draw_strip_frames_text(nlt, strip, v2d, ymin, ymax); } } } @@ -761,27 +757,27 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) * but also slightly shorter for some more contrast when viewing the strips */ immRectf( - pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP); + pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP, v2d->cur.xmax, ymax - NLACHANNEL_SKIP); /* draw 'embossed' lines above and below the strip for effect */ /* white base-lines */ GPU_line_width(2.0f); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.3f); immBegin(GPU_PRIM_LINES, 4); - immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmax, ymin + NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmin, ymax - NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmax, ymax - NLACHANNEL_SKIP); immEnd(); /* black top-lines */ GPU_line_width(1.0f); immUniformColor3f(0.0f, 0.0f, 0.0f); immBegin(GPU_PRIM_LINES, 4); - immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP); - immVertex2f(pos, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmax, ymin + NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmin, ymax - NLACHANNEL_SKIP); + immVertex2f(pos, v2d->cur.xmax, ymax - NLACHANNEL_SKIP); immEnd(); /* TODO: these lines but better --^ */ @@ -790,16 +786,13 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) /* draw keyframes in the action */ nla_action_draw_keyframes( - v2d, adt, ale->data, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP); + v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP); GPU_blend(false); break; } } } - - /* adjust y-position for next one */ - y -= NLACHANNEL_STEP(snla); } /* free tempolary channels */ @@ -817,7 +810,6 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar) SpaceNla *snla = (SpaceNla *)ac->sl; View2D *v2d = &ar->v2d; - float y = 0.0f; size_t items; /* build list of channels to draw */ @@ -830,11 +822,9 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar) * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for * start of list offset, and the second is as a correction for the scrollers. */ - int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2)); - /* don't use totrect set, as the width stays the same - * (NOTE: this is ok here, the configuration is pretty straightforward) - */ - v2d->tot.ymin = (float)(-height); + int height = NLACHANNEL_TOT_HEIGHT(snla, items); + v2d->tot.ymin = -height; + /* need to do a view-sync here, so that the keys area doesn't jump around * (it must copy this) */ UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY); @@ -842,30 +832,24 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar) /* draw channels */ { /* first pass: just the standard GL-drawing for backdrop + text */ size_t channel_index = 0; + float ymax = NLACHANNEL_FIRST_TOP(snla); - y = (float)(-NLACHANNEL_HEIGHT(snla)); - - for (ale = anim_data.first; ale; ale = ale->next) { - float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla)); - float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla)); + for (ale = anim_data.first; ale; + ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) { + float ymin = ymax - NLACHANNEL_HEIGHT(snla); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ - ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index); + ANIM_channel_draw(ac, ale, ymin, ymax, channel_index); } - - /* adjust y-position for next one */ - y -= NLACHANNEL_STEP(snla); - channel_index++; } } { /* second pass: UI widgets */ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; - - y = (float)(-NLACHANNEL_HEIGHT(snla)); + float ymax = NLACHANNEL_FIRST_TOP(snla); /* set blending again, as may not be set in previous step */ GPU_blend_set_func_separate( @@ -873,22 +857,18 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar) GPU_blend(true); /* loop through channels, and set up drawing depending on their type */ - for (ale = anim_data.first; ale; ale = ale->next) { - const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla)); - const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla)); + for (ale = anim_data.first; ale; + ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) { + float ymin = ymax - NLACHANNEL_HEIGHT(snla); /* check if visible */ - if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || - IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { + if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) { /* draw all channels using standard channel-drawing API */ rctf channel_rect; - BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, yminc, ymaxc); + BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, ymin, ymax); ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index); } - - /* adjust y-position for next one */ - y -= NLACHANNEL_STEP(snla); - channel_index++; } UI_block_end(C, block); diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 0446235a776..07853e5850a 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -421,27 +421,25 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa int filter; SpaceNla *snla = (SpaceNla *)ac->sl; - const float half_height = NLACHANNEL_HEIGHT_HALF(snla); /* NOTE: not bool, since we want prioritise individual channels over expanders */ short found = 0; - 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; + float ymax = NLACHANNEL_FIRST_TOP(snla); - for (ale = anim_data.first; ale; ale = ale->next) { + for (ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) { const 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); + *min = ymax - NLACHANNEL_HEIGHT(snla); + *max = ymax; /* is this high enough priority yet? */ found = acf->channel_role; @@ -453,9 +451,6 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa break; } } - - /* adjust y-position for next one */ - y -= NLACHANNEL_STEP(snla); } /* free all temp data */ diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c index 5c9e48f3d5d..accd82525f5 100644 --- a/source/blender/editors/space_nla/nla_select.c +++ b/source/blender/editors/space_nla/nla_select.c @@ -541,15 +541,8 @@ static void mouse_nla_strips( /* use View2D to determine the index of the channel * (i.e a row in the list) where keyframe was */ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); - UI_view2d_listview_view_to_cell(v2d, - 0, - NLACHANNEL_STEP(snla), - 0, - (float)NLACHANNEL_HEIGHT_HALF(snla), - x, - y, - NULL, - &channel_index); + UI_view2d_listview_view_to_cell( + 0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(snla), x, y, NULL, &channel_index); /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click * (that is the size of keyframe icons, so user should be expecting similar tolerances) -- cgit v1.2.3