From a9588e46e1dffc18b2c079c686b797bbab3f6e62 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 5 Sep 2025 23:17:07 +0200 Subject: [PATCH] UI: Changes to Animation Playhead Design This PR changes the animation playhead to make it more recognizable, have a shape that can be better represented in icons, and to more easily distinguish it from other indicators like markers. Pull Request: https://projects.blender.org/blender/blender/pulls/145081 --- .../editors/animation/time_scrub_ui.cc | 95 ++++++++++++------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/animation/time_scrub_ui.cc b/source/blender/editors/animation/time_scrub_ui.cc index aafc6b2eea9..f5831fceeb8 100644 --- a/source/blender/editors/animation/time_scrub_ui.cc +++ b/source/blender/editors/animation/time_scrub_ui.cc @@ -88,12 +88,35 @@ static void draw_current_frame(const Scene *scene, char frame_str[64]; get_current_time_str(scene, display_seconds, current_frame, frame_str, sizeof(frame_str)); - float text_width = UI_fontstyle_string_width(fstyle, frame_str); - float box_width = std::max(text_width + 8 * UI_SCALE_FAC, 24 * UI_SCALE_FAC); - float box_padding = 3 * UI_SCALE_FAC; + const float box_min_width = 24.0f * UI_SCALE_FAC; + const float text_padding = 4.0f * UI_SCALE_FAC; + const float text_width = UI_fontstyle_string_width(fstyle, frame_str); + const float box_width = std::max(text_width + (2.0f * text_padding), box_min_width); + const float box_margin = 2.0f * UI_SCALE_FAC; + const float shadow_width = U.pixelsize; + + float fg_color[4]; + UI_GetThemeColor4fv(TH_CFRAME, fg_color); float bg_color[4]; - UI_GetThemeColorShade4fv(TH_CFRAME, -5, bg_color); + UI_GetThemeColorShade4fv(TH_BACK, -20, bg_color); + + /* Box. */ + UI_draw_roundbox_corner_set(UI_CNR_ALL); + const float box_corner_radius = 4.0f * UI_SCALE_FAC; + rctf rect{}; + rect.xmin = frame_x - (box_width / 2.0f); + rect.xmax = frame_x + (box_width / 2.0f) + 1.0f; + rect.ymin = floor(scrub_region_rect->ymin + (box_margin - shadow_width)); + rect.ymax = ceil(scrub_region_rect->ymax - box_margin + shadow_width); + UI_draw_roundbox_4fv_ex( + &rect, fg_color, nullptr, 1.0f, bg_color, shadow_width, box_corner_radius); + + /* Frame number text. */ + uchar text_color[4]; + UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color); + const int y = BLI_rcti_cent_y(scrub_region_rect) - int(fstyle->points * UI_SCALE_FAC * 0.38f); + UI_fontstyle_draw_simple(fstyle, frame_x - (text_width / 2.0f), y, frame_str, text_color); if (display_stalk) { /* Draw vertical line from the bottom of the current frame box to the bottom of the screen. */ @@ -107,45 +130,49 @@ static void draw_current_frame(const Scene *scene, * used to force an odd width (but still pixel-aligned) to better * line up with the odd widths of the keyframe icons. #98089. */ - /* Outline. */ - immUniformThemeColorShadeAlpha(TH_BACK, -25, -100); - immRectf(pos, - floor(subframe_x - U.pixelsize - U.pixelsize), - scrub_region_rect->ymax - box_padding - U.pixelsize, - floor(subframe_x + U.pixelsize + 1.0f + U.pixelsize), - 0.0f); + const float tri_top = floor(scrub_region_rect->ymin + box_margin); + const float tri_half_width = 6.0f * UI_SCALE_FAC; + const float tri_height = 6.0f * UI_SCALE_FAC; + + /* Shadow. */ + GPU_polygon_smooth(true); + immUniformColor4fv(bg_color); + immBegin(GPU_PRIM_TRI_STRIP, 6); + immVertex2f(pos, floor(subframe_x + U.pixelsize + 1.0f + shadow_width), 0.0f); + immVertex2f(pos, floor(subframe_x - U.pixelsize - shadow_width), 0.0f); + + float diag_offset = 0.4f * UI_SCALE_FAC; + immVertex2f(pos, + floor(subframe_x + U.pixelsize + 1.0f + shadow_width), + tri_top - tri_height + shadow_width - diag_offset); + immVertex2f(pos, + floor(subframe_x - U.pixelsize - shadow_width), + tri_top - tri_height + shadow_width - diag_offset); + immVertex2f(pos, floor(frame_x + tri_half_width + shadow_width + 1.0f + diag_offset), tri_top); + immVertex2f(pos, floor(frame_x - tri_half_width - shadow_width - diag_offset), tri_top); + immEnd(); + GPU_polygon_smooth(false); /* Line. */ - immUniformThemeColor(TH_CFRAME); + immUniformColor4fv(fg_color); immRectf(pos, floor(subframe_x - U.pixelsize), - scrub_region_rect->ymax - box_padding - U.pixelsize, + scrub_region_rect->ymin, floor(subframe_x + U.pixelsize + 1.0f), 0.0f); + + /* Triangular base. */ + GPU_polygon_smooth(true); + immUniformColor4fv(fg_color); + immBegin(GPU_PRIM_TRIS, 3); + immVertex2f(pos, frame_x - tri_half_width, tri_top); + immVertex2f(pos, frame_x + tri_half_width + 1, tri_top); + immVertex2f(pos, frame_x + 0.5f, tri_top - tri_height); + immEnd(); immUnbindProgram(); + GPU_polygon_smooth(false); GPU_blend(GPU_BLEND_NONE); } - - UI_draw_roundbox_corner_set(UI_CNR_ALL); - - float outline_color[4]; - UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color); - - rctf rect{}; - rect.xmin = floor(frame_x - (box_width / 2.0f) + U.pixelsize + 1.0f); - rect.xmax = ceil(frame_x + (box_width / 2.0f)); - rect.ymin = floor(scrub_region_rect->ymin + box_padding); - rect.ymax = ceil(scrub_region_rect->ymax - box_padding); - UI_draw_roundbox_4fv_ex( - &rect, bg_color, nullptr, 1.0f, outline_color, U.pixelsize, 4 * UI_SCALE_FAC); - - uchar text_color[4]; - UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color); - - const int y = BLI_rcti_cent_y(scrub_region_rect) - int(fstyle->points * UI_SCALE_FAC * 0.38f); - - UI_fontstyle_draw_simple( - fstyle, ceil(frame_x - (text_width / 2.0f) + 1.0f), y, frame_str, text_color); } void ED_time_scrub_draw_current_frame(const ARegion *region,