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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
if (r_column) {
|
||||
if (columnwidth > 0) {
|
||||
/* Columns go from left to right (x increases). */
|
||||
*r_column = floorf((viewx - startx) / columnwidth);
|
||||
}
|
||||
else {
|
||||
*r_column = 0;
|
||||
}
|
||||
if (r_row) {
|
||||
}
|
||||
|
||||
if (r_row) {
|
||||
if (rowheight > 0) {
|
||||
/* Rows got from top to bottom (y decreases). */
|
||||
*r_row = floorf((starty - viewy) / rowheight);
|
||||
}
|
||||
else {
|
||||
*r_row = 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user