From 9cd60da3cb75370f8a7f91212b0fbb4048cf52df Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 28 Jul 2023 15:14:56 +0200 Subject: [PATCH] Refactor: extract code from dopesheet draw function No functional changes Extracting code into two new functions in the dopesheet draw code to improve readability and reduce variable scopes. in addition to the extraction two if checks were negated to reduce indentation. the diff makes it look a bit convoluted, but it's just copy paste into functions Pull Request: https://projects.blender.org/blender/blender/pulls/110290 --- .../editors/space_action/action_draw.cc | 519 +++++++++--------- 1 file changed, 269 insertions(+), 250 deletions(-) diff --git a/source/blender/editors/space_action/action_draw.cc b/source/blender/editors/space_action/action_draw.cc index 1c21935bf05..6507c01e79d 100644 --- a/source/blender/editors/space_action/action_draw.cc +++ b/source/blender/editors/space_action/action_draw.cc @@ -181,15 +181,8 @@ static void draw_channel_action_ranges(ListBase *anim_data, View2D *v2d) } } -void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region) +static void draw_backdrops(bAnimContext *ac, ListBase &anim_data, View2D *v2d, uint pos) { - ListBase anim_data = {nullptr, nullptr}; - bAnimListElem *ale; - - View2D *v2d = ®ion->v2d; - bDopeSheet *ads = &saction->ads; - AnimData *adt = nullptr; - uchar col1[4], col2[4]; uchar col1a[4], col2a[4]; uchar col1b[4], col2b[4]; @@ -208,6 +201,272 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELOB, col1b); UI_GetThemeColor4ubv(TH_DOPESHEET_CHANNELSUBOB, col2b); + float ymax = ANIM_UI_get_first_channel_top(v2d); + const float channel_step = ANIM_UI_get_channel_step(); + bAnimListElem *ale; + for (ale = static_cast(anim_data.first); ale; + ale = ale->next, ymax -= channel_step) + { + const float ymin = ymax - ANIM_UI_get_channel_height(); + + /* check if visible */ + if (!(IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax))) + { + continue; + } + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + int sel = 0; + + /* determine if any need to draw channel */ + if (ale->datatype == ALE_NONE) { + continue; + } + /* determine if channel is selected */ + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) { + sel = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT); + } + + if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) { + switch (ale->type) { + case ANIMTYPE_SUMMARY: { + /* reddish color from NLA */ + immUniformThemeColor(TH_ANIM_ACTIVE); + break; + } + case ANIMTYPE_SCENE: + case ANIMTYPE_OBJECT: { + immUniformColor3ubvAlpha(col1b, sel ? col1[3] : col1b[3]); + break; + } + case ANIMTYPE_FILLACTD: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: { + immUniformColor3ubvAlpha(col2b, sel ? col1[3] : col2b[3]); + break; + } + case ANIMTYPE_GROUP: { + bActionGroup *agrp = static_cast(ale->data); + if (show_group_colors && agrp->customCol) { + if (sel) { + immUniformColor3ubvAlpha((uchar *)agrp->cs.select, col1a[3]); + } + else { + immUniformColor3ubvAlpha((uchar *)agrp->cs.solid, col2a[3]); + } + } + else { + immUniformColor4ubv(sel ? col1a : col2a); + } + break; + } + case ANIMTYPE_FCURVE: { + FCurve *fcu = static_cast(ale->data); + if (show_group_colors && fcu->grp && fcu->grp->customCol) { + immUniformColor3ubvAlpha((uchar *)fcu->grp->cs.active, sel ? col1[3] : col2[3]); + } + else { + immUniformColor4ubv(sel ? col1 : col2); + } + break; + } + case ANIMTYPE_GPLAYER: { + if (show_group_colors) { + uchar gpl_col[4]; + bGPDlayer *gpl = (bGPDlayer *)ale->data; + rgb_float_to_uchar(gpl_col, gpl->color); + gpl_col[3] = col1[3]; + + immUniformColor4ubv(sel ? col1 : gpl_col); + } + else { + immUniformColor4ubv(sel ? col1 : col2); + } + break; + } + default: { + immUniformColor4ubv(sel ? col1 : col2); + } + } + + /* draw region twice: firstly backdrop, then the current range */ + immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); + } + else if (ac->datatype == ANIMCONT_GPENCIL) { + uchar *color; + uchar gpl_col[4]; + if (ale->type == ANIMTYPE_SUMMARY) { + color = col_summary; + } + else if ((show_group_colors) && (ale->type == ANIMTYPE_GPLAYER)) { + bGPDlayer *gpl = (bGPDlayer *)ale->data; + rgb_float_to_uchar(gpl_col, gpl->color); + gpl_col[3] = col1[3]; + + color = sel ? col1 : gpl_col; + } + else { + color = sel ? col1 : col2; + } + + /* Color overlay on frames between the start/end frames. */ + immUniformColor4ubv(color); + immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); + + /* Color overlay outside the start/end frame range get a more transparent overlay. */ + immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); + immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); + immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); + } + else if (ac->datatype == ANIMCONT_MASK) { + /* TODO: this is a copy of gpencil. */ + uchar *color; + if (ale->type == ANIMTYPE_SUMMARY) { + color = col_summary; + } + else { + color = sel ? col1 : col2; + } + + /* Color overlay on frames between the start/end frames. */ + immUniformColor4ubv(color); + immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); + + /* Color overlay outside the start/end frame range get a more transparent overlay. */ + immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); + immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); + immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); + } + } +} + +static void draw_keyframes(bAnimContext *ac, + View2D *v2d, + SpaceAction *saction, + ListBase &anim_data) +{ + /* Draw keyframes + * 1) Only channels that are visible in the Action Editor get drawn/evaluated. + * This is to try to optimize this for heavier data sets + * 2) Keyframes which are out of view horizontally are disregarded + */ + int action_flag = saction->flag; + bDopeSheet *ads = &saction->ads; + + if (saction->mode == SACTCONT_TIMELINE) { + action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES); + } + + const float channel_step = ANIM_UI_get_channel_step(); + float ymax = ANIM_UI_get_first_channel_top(v2d); + + AnimKeylistDrawList *draw_list = ED_keylist_draw_list_create(); + + const float scale_factor = ANIM_UI_get_keyframe_scale_factor(); + + bAnimListElem *ale; + for (ale = static_cast(anim_data.first); ale; + ale = ale->next, ymax -= channel_step) + { + const float ymin = ymax - ANIM_UI_get_channel_height(); + float ycenter = (ymin + ymax) / 2.0f; + + /* check if visible */ + if (!(IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) || + IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax))) + { + continue; + } + + /* check if anything to show for this channel */ + if (ale->datatype == ALE_NONE) { + continue; + } + + AnimData *adt = ANIM_nla_mapping_get(ac, ale); + + /* draw 'keyframes' for each specific datatype */ + switch (ale->datatype) { + case ALE_ALL: + draw_summary_channel( + draw_list, static_cast(ale->data), ycenter, scale_factor, action_flag); + break; + case ALE_SCE: + draw_scene_channel(draw_list, + ads, + static_cast(ale->key_data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_OB: + draw_object_channel(draw_list, + ads, + static_cast(ale->key_data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_ACT: + draw_action_channel(draw_list, + adt, + static_cast(ale->key_data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_GROUP: + draw_agroup_channel(draw_list, + adt, + static_cast(ale->data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_FCURVE: + draw_fcurve_channel(draw_list, + adt, + static_cast(ale->key_data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_GREASE_PENCIL_CELS: + draw_grease_pencil_cels_channel(draw_list, + ads, + static_cast(ale->data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_GPFRAME: + draw_gpl_channel(draw_list, + ads, + static_cast(ale->data), + ycenter, + scale_factor, + action_flag); + break; + case ALE_MASKLAY: + draw_masklay_channel(draw_list, + ads, + static_cast(ale->data), + ycenter, + scale_factor, + action_flag); + break; + } + } + + ED_keylist_draw_list_flush(draw_list, v2d); + ED_keylist_draw_list_free(draw_list); +} + +void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region) +{ + ListBase anim_data = {nullptr, nullptr}; + View2D *v2d = ®ion->v2d; + /* build list of channels to draw */ eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); @@ -233,139 +492,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region GPU_blend(GPU_BLEND_ALPHA); /* first backdrop strips */ - float ymax = ANIM_UI_get_first_channel_top(v2d); - const float channel_step = ANIM_UI_get_channel_step(); - for (ale = static_cast(anim_data.first); ale; - ale = ale->next, ymax -= channel_step) - { - const float ymin = ymax - ANIM_UI_get_channel_height(); + draw_backdrops(ac, anim_data, v2d, pos); - /* check if visible */ - 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; - - /* determine if any need to draw channel */ - if (ale->datatype != ALE_NONE) { - /* determine if channel is selected */ - if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) { - sel = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT); - } - - if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) { - switch (ale->type) { - case ANIMTYPE_SUMMARY: { - /* reddish color from NLA */ - immUniformThemeColor(TH_ANIM_ACTIVE); - break; - } - case ANIMTYPE_SCENE: - case ANIMTYPE_OBJECT: { - immUniformColor3ubvAlpha(col1b, sel ? col1[3] : col1b[3]); - break; - } - case ANIMTYPE_FILLACTD: - case ANIMTYPE_DSSKEY: - case ANIMTYPE_DSWOR: { - immUniformColor3ubvAlpha(col2b, sel ? col1[3] : col2b[3]); - break; - } - case ANIMTYPE_GROUP: { - bActionGroup *agrp = static_cast(ale->data); - if (show_group_colors && agrp->customCol) { - if (sel) { - immUniformColor3ubvAlpha((uchar *)agrp->cs.select, col1a[3]); - } - else { - immUniformColor3ubvAlpha((uchar *)agrp->cs.solid, col2a[3]); - } - } - else { - immUniformColor4ubv(sel ? col1a : col2a); - } - break; - } - case ANIMTYPE_FCURVE: { - FCurve *fcu = static_cast(ale->data); - if (show_group_colors && fcu->grp && fcu->grp->customCol) { - immUniformColor3ubvAlpha((uchar *)fcu->grp->cs.active, sel ? col1[3] : col2[3]); - } - else { - immUniformColor4ubv(sel ? col1 : col2); - } - break; - } - case ANIMTYPE_GPLAYER: { - if (show_group_colors) { - uchar gpl_col[4]; - bGPDlayer *gpl = (bGPDlayer *)ale->data; - rgb_float_to_uchar(gpl_col, gpl->color); - gpl_col[3] = col1[3]; - - immUniformColor4ubv(sel ? col1 : gpl_col); - } - else { - immUniformColor4ubv(sel ? col1 : col2); - } - break; - } - default: { - immUniformColor4ubv(sel ? col1 : col2); - } - } - - /* draw region twice: firstly backdrop, then the current range */ - immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); - } - else if (ac->datatype == ANIMCONT_GPENCIL) { - uchar *color; - uchar gpl_col[4]; - if (ale->type == ANIMTYPE_SUMMARY) { - color = col_summary; - } - else if ((show_group_colors) && (ale->type == ANIMTYPE_GPLAYER)) { - bGPDlayer *gpl = (bGPDlayer *)ale->data; - rgb_float_to_uchar(gpl_col, gpl->color); - gpl_col[3] = col1[3]; - - color = sel ? col1 : gpl_col; - } - else { - color = sel ? col1 : col2; - } - - /* Color overlay on frames between the start/end frames. */ - immUniformColor4ubv(color); - immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); - - /* Color overlay outside the start/end frame range get a more transparent overlay. */ - immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); - immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); - immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); - } - else if (ac->datatype == ANIMCONT_MASK) { - /* TODO: this is a copy of gpencil. */ - uchar *color; - if (ale->type == ANIMTYPE_SUMMARY) { - color = col_summary; - } - else { - color = sel ? col1 : col2; - } - - /* Color overlay on frames between the start/end frames. */ - immUniformColor4ubv(color); - immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); - - /* Color overlay outside the start/end frame range get a more transparent overlay. */ - immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); - immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); - immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); - } - } - } - } GPU_blend(GPU_BLEND_NONE); /* black line marking 'current frame' for Time-Slide transform mode */ @@ -379,116 +507,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region } immUnbindProgram(); - /* Draw keyframes - * 1) Only channels that are visible in the Action Editor get drawn/evaluated. - * This is to try to optimize this for heavier data sets - * 2) Keyframes which are out of view horizontally are disregarded - */ - int action_flag = saction->flag; - - if (saction->mode == SACTCONT_TIMELINE) { - action_flag &= ~(SACTION_SHOW_INTERPOLATION | SACTION_SHOW_EXTREMES); - } - - ymax = ANIM_UI_get_first_channel_top(v2d); - - AnimKeylistDrawList *draw_list = ED_keylist_draw_list_create(); - - const float scale_factor = ANIM_UI_get_keyframe_scale_factor(); - - for (ale = static_cast(anim_data.first); ale; - ale = ale->next, ymax -= channel_step) - { - const float ymin = ymax - ANIM_UI_get_channel_height(); - float ycenter = (ymin + ymax) / 2.0f; - - /* check if visible */ - 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); - - /* draw 'keyframes' for each specific datatype */ - switch (ale->datatype) { - case ALE_ALL: - draw_summary_channel(draw_list, - static_cast(ale->data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_SCE: - draw_scene_channel(draw_list, - ads, - static_cast(ale->key_data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_OB: - draw_object_channel(draw_list, - ads, - static_cast(ale->key_data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_ACT: - draw_action_channel(draw_list, - adt, - static_cast(ale->key_data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_GROUP: - draw_agroup_channel(draw_list, - adt, - static_cast(ale->data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_FCURVE: - draw_fcurve_channel(draw_list, - adt, - static_cast(ale->key_data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_GREASE_PENCIL_CELS: - draw_grease_pencil_cels_channel(draw_list, - ads, - static_cast(ale->data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_GPFRAME: - draw_gpl_channel(draw_list, - ads, - static_cast(ale->data), - ycenter, - scale_factor, - action_flag); - break; - case ALE_MASKLAY: - draw_masklay_channel(draw_list, - ads, - static_cast(ale->data), - ycenter, - scale_factor, - action_flag); - break; - } - } - } - } - - ED_keylist_draw_list_flush(draw_list, v2d); - ED_keylist_draw_list_free(draw_list); + draw_keyframes(ac, v2d, saction, anim_data); /* free temporary channels used for drawing */ ANIM_animdata_freelist(&anim_data);