UI: Dope Sheet: Custom theme color for interpolation modes

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
This commit is contained in:
Nika Kutsniashvili
2025-10-13 18:01:21 +02:00
committed by Sybren A. Stüvel
parent 97e3fb0e03
commit 75eaecf350
11 changed files with 93 additions and 25 deletions

View File

@@ -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,

View File

@@ -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"
>
<space>

View File

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

View File

@@ -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.

View File

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

View File

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

View File

@@ -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 ****************************** */

View File

@@ -243,6 +243,8 @@ enum ThemeColorID {
TH_DOPESHEET_CHANNELOB,
TH_DOPESHEET_CHANNELSUBOB,
TH_DOPESHEET_IPOLINE,
TH_DOPESHEET_IPOCONST,
TH_DOPESHEET_IPOOTHER,
TH_PREVIEW_BACK,

View File

@@ -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:

View File

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

View File

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