Blender  V2.93
time_scrub_ui.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "BKE_context.h"
25 #include "BKE_scene.h"
26 
27 #include "GPU_immediate.h"
28 #include "GPU_matrix.h"
29 #include "GPU_state.h"
30 
31 #include "ED_time_scrub_ui.h"
32 
33 #include "WM_api.h"
34 #include "WM_types.h"
35 
36 #include "UI_interface.h"
37 #include "UI_interface_icons.h"
38 #include "UI_resources.h"
39 #include "UI_view2d.h"
40 
41 #include "DNA_scene_types.h"
42 
43 #include "BLI_math.h"
44 #include "BLI_rect.h"
45 #include "BLI_string.h"
46 #include "BLI_timecode.h"
47 
48 #include "RNA_access.h"
49 
50 static void get_time_scrub_region_rect(const ARegion *region, rcti *rect)
51 {
52  rect->xmin = 0;
53  rect->xmax = region->winx;
54  rect->ymax = region->winy;
55  rect->ymin = rect->ymax - UI_TIME_SCRUB_MARGIN_Y;
56 }
57 
58 static int get_centered_text_y(const rcti *rect)
59 {
60  return BLI_rcti_cent_y(rect) - UI_DPI_FAC * 4;
61 }
62 
63 static void draw_background(const rcti *rect)
64 {
67 
69 
71 
72  immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
73 
75 
77 }
78 
80  const Scene *scene, bool display_seconds, int frame, uint max_len, char *r_str)
81 {
82  if (display_seconds) {
83  BLI_timecode_string_from_time(r_str, max_len, 0, FRA2TIME(frame), FPS, U.timecode_style);
84  }
85  else {
86  BLI_snprintf(r_str, max_len, "%d", frame);
87  }
88 }
89 
90 static void draw_current_frame(const Scene *scene,
91  bool display_seconds,
92  const View2D *v2d,
93  const rcti *scrub_region_rect,
94  int current_frame,
95  bool draw_line)
96 {
97  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
98  int frame_x = UI_view2d_view_to_region_x(v2d, current_frame);
99 
100  char frame_str[64];
101  get_current_time_str(scene, display_seconds, current_frame, sizeof(frame_str), frame_str);
102  float text_width = UI_fontstyle_string_width(fstyle, frame_str);
103  float box_width = MAX2(text_width + 8 * UI_DPI_FAC, 24 * UI_DPI_FAC);
104  float box_padding = 3 * UI_DPI_FAC;
105 
106  float bg_color[4];
107  UI_GetThemeColorShade4fv(TH_CFRAME, -5, bg_color);
108 
109  if (draw_line) {
110  /* Draw vertical line to from the bottom of the current frame box to the bottom of the screen.
111  */
112  const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_frame_get(scene));
117  immRectf(pos,
118  subframe_x - U.pixelsize,
119  scrub_region_rect->ymax - box_padding,
120  subframe_x + U.pixelsize,
121  0.0f);
123  }
124 
126 
127  float outline_color[4];
128  UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color);
129 
131  &(const rctf){
132  .xmin = frame_x - box_width / 2 + U.pixelsize / 2,
133  .xmax = frame_x + box_width / 2 + U.pixelsize / 2,
134  .ymin = scrub_region_rect->ymin + box_padding,
135  .ymax = scrub_region_rect->ymax - box_padding,
136  },
137  bg_color,
138  NULL,
139  1.0f,
140  outline_color,
141  U.pixelsize,
142  4 * UI_DPI_FAC);
143 
144  uchar text_color[4];
147  frame_x - text_width / 2 + U.pixelsize / 2,
148  get_centered_text_y(scrub_region_rect),
149  frame_str,
150  text_color);
151 }
152 
154  const Scene *scene,
155  bool display_seconds,
156  bool draw_line)
157 {
158  const View2D *v2d = &region->v2d;
161 
162  rcti scrub_region_rect;
163  get_time_scrub_region_rect(region, &scrub_region_rect);
164 
165  draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra, draw_line);
167 }
168 
169 void ED_time_scrub_draw(const ARegion *region,
170  const Scene *scene,
171  bool display_seconds,
172  bool discrete_frames)
173 {
174  const View2D *v2d = &region->v2d;
175 
178 
179  rcti scrub_region_rect;
180  get_time_scrub_region_rect(region, &scrub_region_rect);
181 
182  draw_background(&scrub_region_rect);
183 
184  rcti numbers_rect = scrub_region_rect;
185  numbers_rect.ymin = get_centered_text_y(&scrub_region_rect) - 4 * UI_DPI_FAC;
186  if (discrete_frames) {
188  region, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
189  }
190  else {
192  region, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
193  }
194 
196 }
197 
198 bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
199 {
200  rcti rect = region->winrct;
201  rect.ymin = rect.ymax - UI_TIME_SCRUB_MARGIN_Y;
202  return BLI_rcti_isect_pt(&rect, event->x, event->y);
203 }
204 
206 {
209 
210  rcti rect;
211  rect.xmin = 0;
212  rect.xmax = region->winx;
213  rect.ymin = region->winy - UI_TIME_SCRUB_MARGIN_Y;
214  rect.ymax = region->winy;
215 
219  immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
221 
222  PointerRNA ptr;
223  RNA_pointer_create(&CTX_wm_screen(C)->id, &RNA_DopeSheet, dopesheet, &ptr);
224 
225  const uiStyle *style = UI_style_get_dpi();
226  const float padding_x = 2 * UI_DPI_FAC;
227  const float padding_y = UI_DPI_FAC;
228 
229  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
230  uiLayout *layout = UI_block_layout(block,
233  rect.xmin + padding_x,
234  rect.ymin + UI_UNIT_Y + padding_y,
235  BLI_rcti_size_x(&rect) - 2 * padding_x,
236  1,
237  0,
238  style);
239  uiLayoutSetScaleY(layout, (UI_UNIT_Y - padding_y) / UI_UNIT_Y);
240  UI_block_layout_set_current(block, layout);
241  UI_block_align_begin(block);
242  uiItemR(layout, &ptr, "filter_text", 0, "", ICON_NONE);
243  uiItemR(layout, &ptr, "use_filter_invert", 0, "", ICON_ARROW_LEFTRIGHT);
244  UI_block_align_end(block);
246 
247  /* Make sure the events are consumed from the search and dont reach other UI blocks since this is
248  * drawn on top of animchannels. */
250  UI_block_bounds_set_normal(block, 0);
251  UI_block_end(C, block);
252  UI_block_draw(C, block);
253 
255 }
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
float BKE_scene_frame_get(const struct Scene *scene)
bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
Definition: BLI_rect.h:140
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
size_t BLI_timecode_string_from_time(char *str, const size_t maxncpy, const int brevity_level, const float time_seconds, const double scene_fps, const short timecode_style) ATTR_NONNULL()
Definition: timecode.c:51
#define MAX2(a, b)
#define FPS
#define FRA2TIME(a)
void immUnbindProgram(void)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
GPUVertFormat * immVertexFormat(void)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:156
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:149
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
StructRNA RNA_DopeSheet
#define C
Definition: RandGen.cpp:39
#define UI_UNIT_Y
@ UI_EMBOSS
Definition: UI_interface.h:107
const struct uiStyle * UI_style_get_dpi(void)
@ UI_CNR_ALL
@ UI_LAYOUT_HEADER
void uiLayoutSetScaleY(uiLayout *layout, float scale)
void UI_block_bounds_set_normal(struct uiBlock *block, int addval)
Definition: interface.c:580
void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
void UI_draw_roundbox_corner_set(int type)
void UI_block_end(const struct bContext *C, uiBlock *block)
void UI_block_draw(const struct bContext *C, struct uiBlock *block)
#define UI_DPI_FAC
Definition: UI_interface.h:309
@ UI_BLOCK_CLIP_EVENTS
Definition: UI_interface.h:155
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const struct uiStyle *style)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void UI_block_align_begin(uiBlock *block)
Definition: interface.c:3821
int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str)
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
void UI_draw_roundbox_4fv_ex(const struct rctf *rect, const float inner1[4], const float inner2[4], float shade_dir, const float outline[4], float outline_width, float rad)
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
#define UI_FSTYLE_WIDGET
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
@ UI_LAYOUT_VERTICAL
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.c:6067
void UI_block_align_end(uiBlock *block)
Definition: interface.c:3834
@ TH_TIME_SCRUB_BACKGROUND
Definition: UI_resources.h:114
@ TH_BACK
Definition: UI_resources.h:55
@ TH_CFRAME
Definition: UI_resources.h:113
@ TH_HEADER_TEXT_HI
Definition: UI_resources.h:69
@ TH_TEXT
Definition: UI_resources.h:58
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
Definition: resources.c:1359
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1381
float UI_view2d_view_to_region_x(const struct View2D *v2d, float x)
#define UI_TIME_SCRUB_MARGIN_Y
Definition: UI_view2d.h:283
void UI_view2d_draw_scale_x__discrete_frames_or_seconds(const struct ARegion *region, const struct View2D *v2d, const struct rcti *rect, const struct Scene *scene, bool display_seconds, int colorid)
Definition: view2d_draw.c:560
void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *region, const struct View2D *v2d, const struct rcti *rect, const struct Scene *scene, bool display_seconds, int colorid)
Definition: view2d_draw.c:575
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
uint pos
format
Definition: logImageCore.h:47
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
struct RenderData r
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
int y
Definition: WM_types.h:581
int x
Definition: WM_types.h:581
static void get_current_time_str(const Scene *scene, bool display_seconds, int frame, uint max_len, char *r_str)
Definition: time_scrub_ui.c:79
static void draw_background(const rcti *rect)
Definition: time_scrub_ui.c:63
void ED_time_scrub_draw_current_frame(const ARegion *region, const Scene *scene, bool display_seconds, bool draw_line)
void ED_time_scrub_channel_search_draw(const bContext *C, ARegion *region, bDopeSheet *dopesheet)
static void draw_current_frame(const Scene *scene, bool display_seconds, const View2D *v2d, const rcti *scrub_region_rect, int current_frame, bool draw_line)
Definition: time_scrub_ui.c:90
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)
Definition: time_scrub_ui.c:58
static void get_time_scrub_region_rect(const ARegion *region, rcti *rect)
Definition: time_scrub_ui.c:50
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
PointerRNA * ptr
Definition: wm_files.c:3157
void wmOrtho2_region_pixelspace(const ARegion *region)
Definition: wm_subwindow.c:120