From 75eaecf350849be9ca936ced179a19a358730e9e Mon Sep 17 00:00:00 2001 From: Nika Kutsniashvili Date: Mon, 13 Oct 2025 18:01:21 +0200 Subject: [PATCH] UI: Dope Sheet: Custom theme color for interpolation modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the "Interpolation Line" theme property into three for each interpolation mode, and use them accordingly. In the current theme refactor, almost all theme properties of the dope sheet are getting either removed (unused), or moved (shared). This decluttering opens up the possibility to allow more theming, and let artists read the Dope Sheet better. ## Avoiding Confusion There's two "Bézier" interpolation types: - Called "Bézier" in the interpolation type menu, and - Called "Bézier" in the code, for the types that are labeled as **"Easing" and "Dynamic"** in the interpolation type menu. Since this commit is about the interpolation lines, which are **not** drawn for the former, **this PR only covers Constant, Linear, and the latter form of Bézier interpolation types.** Pull Request: https://projects.blender.org/blender/blender/pulls/144255 --- .../datafiles/userdef/userdef_default_theme.c | 4 +- .../presets/interface_theme/Blender_Light.xml | 4 +- .../blender/blenkernel/BKE_blender_version.h | 2 +- .../blenloader/intern/versioning_userdef.cc | 6 +++ .../editors/animation/keyframes_draw.cc | 48 ++++++++++++++----- .../editors/animation/keyframes_keylist.cc | 16 ++++++- .../editors/include/ED_keyframes_keylist.hh | 8 +++- .../blender/editors/include/UI_resources.hh | 2 + source/blender/editors/interface/resources.cc | 8 +++- source/blender/makesdna/DNA_theme_types.h | 3 +- source/blender/makesrna/intern/rna_userdef.cc | 17 +++++-- 11 files changed, 93 insertions(+), 25 deletions(-) diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index f8d3020bcea..d2480b073dc 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -494,7 +494,9 @@ const bTheme U_theme_default = { .header_text_hi = RGBA(0xffffffff), .shade1 = RGBA(0xc0c0c000), .grid = RGBA(0x161616ff), - .ds_ipoline = RGBA(0x94e575cc), + .anim_interpolation_linear = RGBA(0x94e575cc), + .anim_interpolation_constant = RGBA(0xe59c7bcc), + .anim_interpolation_other = RGBA(0x5dbabeb3), .keyborder = RGBA(0x000000ff), .keyborder_select = RGBA(0x000000ff), .vertex_size = 3, diff --git a/scripts/presets/interface_theme/Blender_Light.xml b/scripts/presets/interface_theme/Blender_Light.xml index 725d3b3c622..d870e52249c 100644 --- a/scripts/presets/interface_theme/Blender_Light.xml +++ b/scripts/presets/interface_theme/Blender_Light.xml @@ -630,7 +630,9 @@ keyframe_border_selected="#000000ff" keyframe_scale_factor="1" summary="#d3660066" - interpolation_line="#94e575cc" + anim_interpolation_linear="#94e575cc" + anim_interpolation_constant="#e59c7bcc" + anim_interpolation_other="#5dbabeb3" simulated_frames="#721e65ff" > diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 49d3a56b79d..3429a549d6c 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 2 +#define BLENDER_FILE_SUBVERSION 3 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_userdef.cc b/source/blender/blenloader/intern/versioning_userdef.cc index c0bd67798ac..a2aaebab74f 100644 --- a/source/blender/blenloader/intern/versioning_userdef.cc +++ b/source/blender/blenloader/intern/versioning_userdef.cc @@ -390,6 +390,12 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme) FROM_DEFAULT_V4_UCHAR(common.anim.scene_strip_range); } + if (!USER_VERSION_ATLEAST(501, 3)) { + FROM_DEFAULT_V4_UCHAR(space_action.anim_interpolation_other); + FROM_DEFAULT_V4_UCHAR(space_action.anim_interpolation_constant); + FROM_DEFAULT_V4_UCHAR(space_action.anim_interpolation_linear); + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a USER_VERSION_ATLEAST check. diff --git a/source/blender/editors/animation/keyframes_draw.cc b/source/blender/editors/animation/keyframes_draw.cc index 0adeb1c692d..3f64c1eebe8 100644 --- a/source/blender/editors/animation/keyframes_draw.cc +++ b/source/blender/editors/animation/keyframes_draw.cc @@ -190,7 +190,10 @@ struct DrawKeylistUIData { float unsel_color[4]; float sel_mhcol[4]; float unsel_mhcol[4]; - float ipo_color[4]; + + float ipo_color_linear[4]; + float ipo_color_constant[4]; + float ipo_color_other[4]; float ipo_color_mix[4]; /* Show interpolation and handle type? */ @@ -218,18 +221,22 @@ static void channel_ui_data_init(DrawKeylistUIData *ctx, UI_GetThemeColor4fv(TH_LONGKEY_SELECT, ctx->sel_color); UI_GetThemeColor4fv(TH_LONGKEY, ctx->unsel_color); - UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ctx->ipo_color); + UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ctx->ipo_color_linear); + UI_GetThemeColor4fv(TH_DOPESHEET_IPOCONST, ctx->ipo_color_constant); + UI_GetThemeColor4fv(TH_DOPESHEET_IPOOTHER, ctx->ipo_color_other); + UI_GetThemeColor4fv(TH_KEYTYPE_KEYFRAME, ctx->ipo_color_mix); ctx->sel_color[3] *= ctx->alpha; ctx->unsel_color[3] *= ctx->alpha; - ctx->ipo_color[3] *= ctx->alpha; + ctx->ipo_color_linear[3] *= ctx->alpha; + ctx->ipo_color_constant[3] *= ctx->alpha; + ctx->ipo_color_other[3] *= ctx->alpha; + ctx->ipo_color_mix[3] *= ctx->alpha * 0.5f; copy_v4_v4(ctx->sel_mhcol, ctx->sel_color); ctx->sel_mhcol[3] *= 0.8f; copy_v4_v4(ctx->unsel_mhcol, ctx->unsel_color); ctx->unsel_mhcol[3] *= 0.8f; - copy_v4_v4(ctx->ipo_color_mix, ctx->ipo_color); - ctx->ipo_color_mix[3] *= 0.5f; } static void draw_keylist_block_gpencil(const DrawKeylistUIData *ctx, @@ -298,11 +305,28 @@ static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, box.ymin = ypos - ctx->ipo_size; box.ymax = ypos + ctx->ipo_size; - UI_draw_roundbox_4fv(&box, - true, - 3.0f, - (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : - ctx->ipo_color); + /* Color for interpolation lines based on their type */ + const float *color; + + constexpr short IPO_FLAGS = ACTKEYBLOCK_FLAG_IPO_OTHER | ACTKEYBLOCK_FLAG_IPO_LINEAR | + ACTKEYBLOCK_FLAG_IPO_CONSTANT; + if (ab->block.conflict & IPO_FLAGS) { + /* This is a summary line that combines multiple interpolation modes. */ + color = ctx->ipo_color_mix; + } + else { + if (ab->block.flag & ACTKEYBLOCK_FLAG_IPO_OTHER) { + color = ctx->ipo_color_other; + } + else if (ab->block.flag & ACTKEYBLOCK_FLAG_IPO_LINEAR) { + color = ctx->ipo_color_linear; + } + else if (ab->block.flag & ACTKEYBLOCK_FLAG_IPO_CONSTANT) { + color = ctx->ipo_color_constant; + } + } + + UI_draw_roundbox_4fv(&box, true, 3.0f, color); } static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) @@ -326,9 +350,7 @@ static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn draw_keylist_block_standard(ctx, ab, ypos); } } - if (ctx->show_ipo && actkeyblock_is_valid(ab) && - (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) - { + if (ctx->show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag)) { /* draw an interpolation line */ draw_keylist_block_interpolation_line(ctx, ab, ypos); } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 4c3c98252ef..06b905e5872 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -869,8 +869,20 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, } /* Remember non-bezier interpolation info. */ - if (prev->ipo != BEZT_IPO_BEZ) { - info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; + switch (eBezTriple_Interpolation(prev->ipo)) { + case BEZT_IPO_BEZ: + break; + case BEZT_IPO_LIN: + info->flag |= ACTKEYBLOCK_FLAG_IPO_LINEAR; + break; + case BEZT_IPO_CONST: + info->flag |= ACTKEYBLOCK_FLAG_IPO_CONSTANT; + break; + default: + /* For automatic bezier interpolations, such as easings (cubic, circular, etc), and dynamic + * (back, bounce, elastic). */ + info->flag |= ACTKEYBLOCK_FLAG_IPO_OTHER; + break; } info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); diff --git a/source/blender/editors/include/ED_keyframes_keylist.hh b/source/blender/editors/include/ED_keyframes_keylist.hh index 825ca2852a8..f9025aa9722 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.hh +++ b/source/blender/editors/include/ED_keyframes_keylist.hh @@ -88,10 +88,14 @@ enum eActKeyBlock_Hold { ACTKEYBLOCK_FLAG_STATIC_HOLD = (1 << 1), /** Key block represents any kind of hold. */ ACTKEYBLOCK_FLAG_ANY_HOLD = (1 << 2), - /** The curve segment uses non-bezier interpolation. */ - ACTKEYBLOCK_FLAG_NON_BEZIER = (1 << 3), /** The block is grease pencil. */ ACTKEYBLOCK_FLAG_GPENCIL = (1 << 4), + /** The curve segment uses linear interpolation. */ + ACTKEYBLOCK_FLAG_IPO_LINEAR = (1 << 5), + /** The curve segment uses constant interpolation. */ + ACTKEYBLOCK_FLAG_IPO_CONSTANT = (1 << 6), + /** The curve segment uses easing or dynamic interpolation. */ + ACTKEYBLOCK_FLAG_IPO_OTHER = (1 << 7), }; /* *********************** Keyframe Drawing ****************************** */ diff --git a/source/blender/editors/include/UI_resources.hh b/source/blender/editors/include/UI_resources.hh index e05fe37c625..e86f85591c3 100644 --- a/source/blender/editors/include/UI_resources.hh +++ b/source/blender/editors/include/UI_resources.hh @@ -243,6 +243,8 @@ enum ThemeColorID { TH_DOPESHEET_CHANNELOB, TH_DOPESHEET_CHANNELSUBOB, TH_DOPESHEET_IPOLINE, + TH_DOPESHEET_IPOCONST, + TH_DOPESHEET_IPOOTHER, TH_PREVIEW_BACK, diff --git a/source/blender/editors/interface/resources.cc b/source/blender/editors/interface/resources.cc index ae6fca018fd..dd05b0d6c4d 100644 --- a/source/blender/editors/interface/resources.cc +++ b/source/blender/editors/interface/resources.cc @@ -793,7 +793,13 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) cp = btheme->common.anim.channels_sub; break; case TH_DOPESHEET_IPOLINE: - cp = ts->ds_ipoline; + cp = ts->anim_interpolation_linear; + break; + case TH_DOPESHEET_IPOCONST: + cp = ts->anim_interpolation_constant; + break; + case TH_DOPESHEET_IPOOTHER: + cp = ts->anim_interpolation_other; break; case TH_PREVIEW_BACK: diff --git a/source/blender/makesdna/DNA_theme_types.h b/source/blender/makesdna/DNA_theme_types.h index 8e911dd6da6..4951e68dcb3 100644 --- a/source/blender/makesdna/DNA_theme_types.h +++ b/source/blender/makesdna/DNA_theme_types.h @@ -342,7 +342,8 @@ typedef struct ThemeSpace { char _pad5[4]; /** Dope-sheet. */ - unsigned char ds_ipoline[4]; + unsigned char anim_interpolation_linear[4], anim_interpolation_constant[4], + anim_interpolation_other[4]; /** Keyframe border. */ unsigned char keyborder[4], keyborder_select[4]; char _pad4[3]; diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index 332db472401..cd4301689fe 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -3913,11 +3913,22 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Summary", "Color of summary channel"); RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); - prop = RNA_def_property(srna, "interpolation_line", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, nullptr, "ds_ipoline"); + prop = RNA_def_property(srna, "anim_interpolation_linear", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 4); RNA_def_property_ui_text( - prop, "Interpolation Line", "Color of lines showing non-Bézier interpolation modes"); + prop, "Linear Interpolation", "Color of lines showing linear interpolation mode"); + RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); + + prop = RNA_def_property(srna, "anim_interpolation_constant", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text( + prop, "Constant Interpolation", "Color of lines showing constant interpolation mode"); + RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); + + prop = RNA_def_property(srna, "anim_interpolation_other", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text( + prop, "Other Interpolation", "Color of lines showing easings & dynamic interpolation mode"); RNA_def_property_update(prop, 0, "rna_userdef_theme_update"); prop = RNA_def_property(srna, "simulated_frames", PROP_FLOAT, PROP_COLOR_GAMMA);