Blender V4.3
time_scrub_ui.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_context.hh"
10#include "BKE_scene.hh"
11
12#include "GPU_immediate.hh"
13#include "GPU_matrix.hh"
14#include "GPU_state.hh"
15
16#include "ED_time_scrub_ui.hh"
17
18#include "WM_api.hh"
19#include "WM_types.hh"
20
21#include "UI_interface.hh"
22#include "UI_interface_icons.hh"
23#include "UI_resources.hh"
24#include "UI_view2d.hh"
25
26#include "DNA_scene_types.h"
27
28#include "BLI_rect.h"
29#include "BLI_string.h"
30#include "BLI_timecode.h"
31
32#include "RNA_access.hh"
33#include "RNA_prototypes.hh"
34
35void ED_time_scrub_region_rect_get(const ARegion *region, rcti *r_rect)
36{
37 r_rect->xmin = 0;
38 r_rect->xmax = region->winx;
39 r_rect->ymax = region->winy;
40 r_rect->ymin = r_rect->ymax - UI_TIME_SCRUB_MARGIN_Y;
41}
42
43static int get_centered_text_y(const rcti *rect)
44{
45 return BLI_rcti_cent_y(rect) - UI_SCALE_FAC * 4;
46}
47
63
65 const Scene *scene, bool display_seconds, int frame, char *r_str, uint str_maxncpy)
66{
67 if (display_seconds) {
68 BLI_timecode_string_from_time(r_str, str_maxncpy, -1, FRA2TIME(frame), FPS, U.timecode_style);
69 }
70 else {
71 BLI_snprintf(r_str, str_maxncpy, "%d", frame);
72 }
73}
74
75static void draw_current_frame(const Scene *scene,
76 bool display_seconds,
77 const View2D *v2d,
78 const rcti *scrub_region_rect,
79 int current_frame)
80{
81 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
82 int frame_x = UI_view2d_view_to_region_x(v2d, current_frame);
83
84 char frame_str[64];
85 get_current_time_str(scene, display_seconds, current_frame, frame_str, sizeof(frame_str));
86 float text_width = UI_fontstyle_string_width(fstyle, frame_str);
87 float box_width = std::max(text_width + 8 * UI_SCALE_FAC, 24 * UI_SCALE_FAC);
88 float box_padding = 3 * UI_SCALE_FAC;
89 const int line_outline = max_ii(1, round_fl_to_int(1 * UI_SCALE_FAC));
90
91 float bg_color[4];
93
94 /* Draw vertical line from the bottom of the current frame box to the bottom of the screen. */
95 const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_ctime_get(scene));
98
101
102 /* Outline. */
105 subframe_x - (line_outline + U.pixelsize),
106 scrub_region_rect->ymax - box_padding,
107 subframe_x + (line_outline + U.pixelsize),
108 0.0f);
109
110 /* Line. */
113 subframe_x - U.pixelsize,
114 scrub_region_rect->ymax - box_padding,
115 subframe_x + U.pixelsize,
116 0.0f);
119
121
122 float outline_color[4];
123 UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color);
124
125 rctf rect{};
126 rect.xmin = frame_x - box_width / 2 + U.pixelsize / 2;
127 rect.xmax = frame_x + box_width / 2 + U.pixelsize / 2;
128 rect.ymin = scrub_region_rect->ymin + box_padding;
129 rect.ymax = scrub_region_rect->ymax - box_padding;
131 &rect, bg_color, nullptr, 1.0f, outline_color, U.pixelsize, 4 * UI_SCALE_FAC);
132
133 uchar text_color[4];
135
136 const int y = BLI_rcti_cent_y(scrub_region_rect) - int(fstyle->points * UI_SCALE_FAC * 0.35f);
137
139 +fstyle, frame_x - text_width / 2 + U.pixelsize / 2, y, frame_str, text_color);
140}
141
143 const Scene *scene,
144 bool display_seconds)
145{
146 const View2D *v2d = &region->v2d;
149
150 rcti scrub_region_rect;
151 ED_time_scrub_region_rect_get(region, &scrub_region_rect);
152
153 draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra);
155}
156
157void ED_time_scrub_draw(const ARegion *region,
158 const Scene *scene,
159 bool display_seconds,
160 bool discrete_frames)
161{
162 const View2D *v2d = &region->v2d;
163
166
167 rcti scrub_region_rect;
168 ED_time_scrub_region_rect_get(region, &scrub_region_rect);
169
170 draw_background(&scrub_region_rect);
171
172 rcti numbers_rect = scrub_region_rect;
173 numbers_rect.ymin = get_centered_text_y(&scrub_region_rect) - 4 * UI_SCALE_FAC;
174 if (discrete_frames) {
176 region, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
177 }
178 else {
180 region, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
181 }
182
184}
185
187{
188 rcti clamped_mask = scroller_mask;
189 clamped_mask.ymax -= UI_TIME_SCRUB_MARGIN_Y;
190 return clamped_mask;
191}
192
193bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
194{
195 rcti rect = region->winrct;
196 rect.ymin = rect.ymax - UI_TIME_SCRUB_MARGIN_Y;
197 return BLI_rcti_isect_pt_v(&rect, event->xy);
198}
199
201{
204
205 rcti rect;
206 rect.xmin = 0;
207 rect.xmax = region->winx;
208 rect.ymin = region->winy - UI_TIME_SCRUB_MARGIN_Y;
209 rect.ymax = region->winy;
210
214 immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
216
217 PointerRNA ptr = RNA_pointer_create(&CTX_wm_screen(C)->id, &RNA_DopeSheet, dopesheet);
218
219 const uiStyle *style = UI_style_get_dpi();
220 const float padding_x = 2 * UI_SCALE_FAC;
221 const float padding_y = UI_SCALE_FAC;
222
223 uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
224 uiLayout *layout = UI_block_layout(block,
227 rect.xmin + padding_x,
228 rect.ymin + UI_UNIT_Y + padding_y,
229 BLI_rcti_size_x(&rect) - 2 * padding_x,
230 1,
231 0,
232 style);
233 uiLayoutSetScaleY(layout, (UI_UNIT_Y - padding_y) / UI_UNIT_Y);
234 UI_block_layout_set_current(block, layout);
236 uiItemR(layout, &ptr, "filter_text", UI_ITEM_NONE, "", ICON_NONE);
237 uiItemR(layout, &ptr, "use_filter_invert", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
238 UI_block_align_end(block);
239 UI_block_layout_resolve(block, nullptr, nullptr);
240
241 /* Make sure the events are consumed from the search and don't reach other UI blocks since this
242 * is drawn on top of animation-channels. */
245 UI_block_end(C, block);
246 UI_block_draw(C, block);
247
249}
bScreen * CTX_wm_screen(const bContext *C)
float BKE_scene_ctime_get(const Scene *scene)
Definition scene.cc:2317
MINLINE int round_fl_to_int(float a)
MINLINE int max_ii(int a, int b)
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
Definition BLI_rect.h:176
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned char uchar
unsigned int uint
size_t BLI_timecode_string_from_time(char *str, size_t maxncpy, int brevity_level, float time_seconds, double fps, short timecode_style) ATTR_NONNULL()
Definition timecode.c:23
#define FPS
#define FRA2TIME(a)
#define UI_SCALE_FAC
void immUnbindProgram()
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
GPUVertFormat * immVertexFormat()
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_matrix_push_projection()
void GPU_matrix_pop_projection()
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
#define UI_UNIT_Y
@ UI_EMBOSS
void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
@ UI_BLOCK_CLIP_EVENTS
void uiLayoutSetScaleY(uiLayout *layout, float scale)
void UI_block_bounds_set_normal(uiBlock *block, int addval)
Definition interface.cc:574
void UI_draw_roundbox_4fv_ex(const rctf *rect, const float inner1[4], const float inner2[4], float shade_dir, const float outline[4], float outline_width, float rad)
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const uiStyle *style)
const uiStyle * UI_style_get_dpi()
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
void UI_draw_roundbox_corner_set(int type)
#define UI_ITEM_NONE
void UI_block_draw(const bContext *C, uiBlock *block)
@ UI_LAYOUT_VERTICAL
void UI_block_align_begin(uiBlock *block)
@ UI_LAYOUT_HEADER
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
@ UI_CNR_ALL
#define UI_FSTYLE_WIDGET
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
void UI_block_flag_enable(uiBlock *block, int flag)
void UI_block_end(const bContext *C, uiBlock *block)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void UI_block_align_end(uiBlock *block)
@ TH_TIME_SCRUB_BACKGROUND
@ TH_BACK
@ TH_CFRAME
@ TH_HEADER_TEXT_HI
@ TH_TEXT
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
void UI_view2d_draw_scale_x__discrete_frames_or_seconds(const ARegion *region, const View2D *v2d, const rcti *rect, const Scene *scene, bool display_seconds, int colorid)
void UI_view2d_draw_scale_x__frames_or_seconds(const ARegion *region, const View2D *v2d, const rcti *rect, const Scene *scene, bool display_seconds, int colorid)
#define UI_TIME_SCRUB_MARGIN_Y
Definition UI_view2d.hh:472
float UI_view2d_view_to_region_x(const View2D *v2d, float x)
Definition view2d.cc:1686
unsigned int U
Definition btGjkEpa3.h:78
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
format
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
static void draw_background()
float xmin
int ymin
int ymax
int xmin
int xmax
int xy[2]
Definition WM_types.hh:726
static void get_current_time_str(const Scene *scene, bool display_seconds, int frame, char *r_str, uint str_maxncpy)
rcti ED_time_scrub_clamp_scroller_mask(const rcti &scroller_mask)
void ED_time_scrub_region_rect_get(const ARegion *region, rcti *r_rect)
void ED_time_scrub_draw_current_frame(const ARegion *region, const Scene *scene, bool display_seconds)
void ED_time_scrub_channel_search_draw(const bContext *C, ARegion *region, bDopeSheet *dopesheet)
void ED_time_scrub_draw(const ARegion *region, const Scene *scene, bool display_seconds, bool discrete_frames)
static int get_centered_text_y(const rcti *rect)
static void draw_current_frame(const Scene *scene, bool display_seconds, const View2D *v2d, const rcti *scrub_region_rect, int current_frame)
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4126
void wmOrtho2_region_pixelspace(const ARegion *region)