Blender V4.3
sequencer_view.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_utildefines.h"
10
11#include "DNA_scene_types.h"
12
13#include "BKE_context.hh"
14#include "BKE_scene.hh"
15
16#include "WM_api.hh"
17#include "WM_types.hh"
18
19#include "RNA_define.hh"
20
21#include "UI_view2d.hh"
22
23#include "SEQ_sequencer.hh"
24#include "SEQ_time.hh"
25#include "SEQ_transform.hh"
26
27/* For menu, popup, icons, etc. */
28#include "ED_anim_api.hh"
29#include "ED_markers.hh"
30#include "ED_screen.hh"
31#include "ED_sequencer.hh"
32#include "ED_time_scrub_ui.hh"
33#include "ED_util_imbuf.hh"
34
35/* Own include. */
36#include "sequencer_intern.hh"
37
38/* -------------------------------------------------------------------- */
43{
44 /* Identifiers. */
45 ot->name = "Sample Color";
46 ot->idname = "SEQUENCER_OT_sample";
47 ot->description = "Use mouse to sample color in current frame";
48
49 /* Api callbacks. */
54
55 /* Flags. */
57
58 /* Not implemented. */
59 PropertyRNA *prop;
60 prop = RNA_def_int(ot->srna, "size", 1, 1, 128, "Sample Size", "", 1, 64);
63}
64
67/* -------------------------------------------------------------------- */
70void SEQ_get_timeline_region_padding(const bContext *C, float *r_pad_top, float *r_pad_bottom)
71{
72 *r_pad_top = UI_TIME_SCRUB_MARGIN_Y;
73 const SpaceSeq *sseq = CTX_wm_space_seq(C);
74 if (sseq->flag & SEQ_SHOW_OVERLAY && sseq->cache_overlay.flag & SEQ_CACHE_SHOW &&
76 {
77 *r_pad_top += UI_TIME_CACHE_MARGIN_Y;
78 }
79
82}
83
85{
86 /* Calculate and add margin to the view.
87 * This is needed so that the focused strips are not occluded by the scrub area or other
88 * overlays.
89 */
90 float pad_top, pad_bottom;
91 SEQ_get_timeline_region_padding(C, &pad_top, &pad_bottom);
92
93 ARegion *region = CTX_wm_region(C);
94 BLI_rctf_pad_y(view_box, region->winy, pad_bottom, pad_top);
95}
96
98{
99 ARegion *region = CTX_wm_region(C);
100 rctf box;
101
102 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
103 Scene *scene = CTX_data_scene(C);
104 const Editing *ed = SEQ_editing_get(scene);
105
106 SEQ_timeline_init_boundbox(scene, &box);
108 /* Use meta strip range instead of scene. */
109 if (ms != nullptr) {
110 box.xmin = ms->disp_range[0] - 1;
111 box.xmax = ms->disp_range[1] + 1;
112 }
114
116
117 UI_view2d_smooth_view(C, region, &box, smooth_viewtx);
118 return OPERATOR_FINISHED;
119}
120
122{
123 /* Identifiers. */
124 ot->name = "Frame All";
125 ot->idname = "SEQUENCER_OT_view_all";
126 ot->description = "View all the strips in the sequencer";
127
128 /* Api callbacks. */
131
132 /* Flags. */
134}
135
138/* -------------------------------------------------------------------- */
143{
144 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
145 ANIM_center_frame(C, smooth_viewtx);
146
147 return OPERATOR_FINISHED;
148}
149
151{
152 /* Identifiers. */
153 ot->name = "Go to Current Frame";
154 ot->idname = "SEQUENCER_OT_view_frame";
155 ot->description = "Move the view to the current frame";
156
157 /* Api callbacks. */
160
161 /* Flags. */
162 ot->flag = 0;
163}
164
167/* -------------------------------------------------------------------- */
172{
173 SpaceSeq *sseq = CTX_wm_space_seq(C);
174 bScreen *screen = CTX_wm_screen(C);
175 ScrArea *area = CTX_wm_area(C);
176#if 0
177 ARegion *region = CTX_wm_region(C);
178 Scene *scene = CTX_data_scene(C);
179#endif
181
182 v2d->cur = v2d->tot;
184 UI_view2d_sync(screen, area, v2d, V2D_LOCK_COPY);
185
186#if 0
187 /* Like zooming on an image view. */
188 float zoomX, zoomY;
189 int width, height, imgwidth, imgheight;
190
191 width = region->winx;
192 height = region->winy;
193
194 seq_reset_imageofs(sseq);
195
196 BKE_render_resolution(&scene->r, false, &imgwidth, &imgheight);
197
198 /* Apply aspect, doesn't need to be that accurate. */
199 imgwidth = int(imgwidth * (scene->r.xasp / scene->r.yasp));
200
201 if (((imgwidth >= width) || (imgheight >= height)) && ((width > 0) && (height > 0))) {
202 /* Find the zoom value that will fit the image in the image space. */
203 zoomX = float(width) / float(imgwidth);
204 zoomY = float(height) / float(imgheight);
205 sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
206
207 sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
208 }
209 else {
210 sseq->zoom = 1.0f;
211 }
212#endif
213
214 sseq->flag |= SEQ_ZOOM_TO_FIT;
215
217 return OPERATOR_FINISHED;
218}
219
221{
222 /* Identifiers. */
223 ot->name = "Frame All";
224 ot->idname = "SEQUENCER_OT_view_all_preview";
225 ot->description = "Zoom preview to fit in the area";
226
227 /* Api callbacks. */
230
231 /* Flags. */
233}
234
237/* -------------------------------------------------------------------- */
242{
243 const RenderData *rd = &CTX_data_scene(C)->r;
245
246 float ratio = RNA_float_get(op->ptr, "ratio");
247
248 int winx, winy;
249 BKE_render_resolution(rd, false, &winx, &winy);
250
251 float facx = BLI_rcti_size_x(&v2d->mask) / float(winx);
252 float facy = BLI_rcti_size_y(&v2d->mask) / float(winy);
253
254 BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
255
257
259
260 return OPERATOR_FINISHED;
261}
262
264{
265 /* Identifiers. */
266 ot->name = "Sequencer View Zoom Ratio";
267 ot->idname = "SEQUENCER_OT_view_zoom_ratio";
268 ot->description = "Change zoom ratio of sequencer preview";
269
270 /* Api callbacks. */
273
274 /* Properties. */
276 "ratio",
277 1.0f,
278 -FLT_MAX,
279 FLT_MAX,
280 "Ratio",
281 "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out",
282 -FLT_MAX,
283 FLT_MAX);
284}
285
288/* -------------------------------------------------------------------- */
294 rctf *rect)
295{
296 float min[2], max[2];
297 SEQ_image_transform_bounding_box_from_collection(scene, strips, true, min, max);
298
299 rect->xmin = min[0];
300 rect->xmax = max[0];
301 rect->ymin = min[1];
302 rect->ymax = max[1];
303
304 float minsize = min_ff(BLI_rctf_size_x(rect), BLI_rctf_size_y(rect));
305
306 /* If the size of the strip is smaller than a pixel, add padding to prevent division by zero. */
307 if (minsize < 1.0f) {
308 BLI_rctf_pad(rect, 20.0f, 20.0f);
309 }
310
311 /* Add padding. */
312 BLI_rctf_scale(rect, 1.1f);
313}
314
317 rctf *rect)
318{
319 const Scene *scene = CTX_data_scene(C);
320 int xmin = MAXFRAME * 2;
321 int xmax = -MAXFRAME * 2;
322 int ymin = SEQ_MAX_CHANNELS + 1;
323 int ymax = 0;
324 int xmargin = FPS;
325
326 for (Sequence *seq : strips) {
327 xmin = min_ii(xmin, SEQ_time_left_handle_frame_get(scene, seq));
328 xmax = max_ii(xmax, SEQ_time_right_handle_frame_get(scene, seq));
329
330 ymin = min_ii(ymin, seq->machine);
331 /* "+1" because each channel has a thickness of 1. */
332 ymax = max_ii(ymax, seq->machine + 1);
333 }
334
335 xmax += xmargin;
336 xmin -= xmargin;
337
338 float orig_height = BLI_rctf_size_y(rect);
339 rctf new_viewport;
340
341 new_viewport.xmin = xmin;
342 new_viewport.xmax = xmax;
343
344 new_viewport.ymin = ymin;
345 new_viewport.ymax = ymax;
346
347 SEQ_add_timeline_region_padding(C, &new_viewport);
348
349 /* Y axis should only zoom out if needed, never zoom in. */
350 if (orig_height > BLI_rctf_size_y(&new_viewport)) {
351 /* Get the current max/min channel we can display. */
352 const Editing *ed = SEQ_editing_get(scene);
353 rctf box;
356 float timeline_ymin = box.ymin;
357 float timeline_ymax = box.ymax;
358
359 if (orig_height > timeline_ymax - timeline_ymin) {
360 /* Only apply the x axis movement, we can't align the viewport any better
361 * on the y-axis if we are zoomed out further than the current timeline bounds. */
362 rect->xmin = new_viewport.xmin;
363 rect->xmax = new_viewport.xmax;
364 return;
365 }
366
367 float ymid = BLI_rctf_cent_y(&new_viewport);
368
369 new_viewport.ymin = ymid - (orig_height / 2.0f);
370 new_viewport.ymax = ymid + (orig_height / 2.0f);
371
372 if (new_viewport.ymin < timeline_ymin) {
373 new_viewport.ymin = timeline_ymin;
374 new_viewport.ymax = new_viewport.ymin + orig_height;
375 }
376 else if (new_viewport.ymax > timeline_ymax) {
377 new_viewport.ymax = timeline_ymax;
378 new_viewport.ymin = new_viewport.ymax - orig_height;
379 }
380 }
381 *rect = new_viewport;
382}
383
385{
386 Scene *scene = CTX_data_scene(C);
387 ARegion *region = CTX_wm_region(C);
390 rctf cur_new = v2d->cur;
391
392 if (strips.is_empty()) {
393 return OPERATOR_CANCELLED;
394 }
395
397 return OPERATOR_CANCELLED;
398 }
399
400 if (region && region->regiontype == RGN_TYPE_PREVIEW) {
401 seq_view_collection_rect_preview(scene, strips, &cur_new);
402 }
403 else {
404 seq_view_collection_rect_timeline(C, strips, &cur_new);
405 }
406
407 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
408 UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx);
409
410 return OPERATOR_FINISHED;
411}
412
414{
415 /* Identifiers. */
416 ot->name = "Frame Selected";
417 ot->idname = "SEQUENCER_OT_view_selected";
418 ot->description = "Zoom the sequencer on the selected strips";
419
420 /* Api callbacks. */
423
424 /* Flags. */
426}
427
430/* -------------------------------------------------------------------- */
435{
436 Scene *scene = CTX_data_scene(C);
438
439 rctf rect;
440
441 /* Convert coordinates of rect to 'tot' rect coordinates. */
443 UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
444
445 rect.xmin /= fabsf(BLI_rctf_size_x(&v2d->tot));
446 rect.ymin /= fabsf(BLI_rctf_size_y(&v2d->tot));
447
448 rect.xmax /= fabsf(BLI_rctf_size_x(&v2d->tot));
449 rect.ymax /= fabsf(BLI_rctf_size_y(&v2d->tot));
450
451 rect.xmin += 0.5f;
452 rect.xmax += 0.5f;
453 rect.ymin += 0.5f;
454 rect.ymax += 0.5f;
455
456 CLAMP(rect.xmin, 0.0f, 1.0f);
457 CLAMP(rect.ymin, 0.0f, 1.0f);
458 CLAMP(rect.xmax, 0.0f, 1.0f);
459 CLAMP(rect.ymax, 0.0f, 1.0f);
460
461 scene->ed->overlay_frame_rect = rect;
462
464
465 return OPERATOR_FINISHED;
466}
467
469{
470 /* Identifiers. */
471 ot->name = "Border Offset View";
472 ot->idname = "SEQUENCER_OT_view_ghost_border";
473 ot->description = "Set the boundaries of the border used for offset view";
474
475 /* Api callbacks. */
481
482 /* Flags. */
483 ot->flag = 0;
484
485 /* Properties. */
487}
488
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
SpaceSeq * CTX_wm_space_seq(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2877
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE float power_of_2(float f)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition BLI_rect.h:184
void BLI_rctf_pad_y(struct rctf *rect, float boundary_size, float pad_min, float pad_max)
Definition rct.c:683
void BLI_rctf_scale(rctf *rect, float scale)
Definition rct.c:671
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
void BLI_rctf_pad(struct rctf *rect, float pad_x, float pad_y)
Definition rct.c:631
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:197
void BLI_rctf_resize(struct rctf *rect, float x, float y)
Definition rct.c:651
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:201
#define CLAMP(a, b, c)
#define FPS
#define MAXFRAME
@ RGN_TYPE_PREVIEW
@ SEQ_CACHE_SHOW
@ SEQ_CACHE_SHOW_FINAL_OUT
@ SEQ_ZOOM_TO_FIT
@ SEQ_SHOW_OVERLAY
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:708
bool ED_operator_sequencer_active(bContext *C)
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:634
blender::VectorSet< Sequence * > ED_sequencer_selected_strips_from_context(bContext *C)
void ED_imbuf_sample_cancel(bContext *C, wmOperator *op)
int ED_imbuf_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool ED_imbuf_sample_poll(bContext *C)
int ED_imbuf_sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ PROP_HIDDEN
Definition RNA_types.hh:239
@ PROP_PIXEL
Definition RNA_types.hh:151
constexpr int SEQ_MAX_CHANNELS
void UI_view2d_smooth_view(const bContext *C, ARegion *region, const rctf *cur, int smooth_viewtx)
void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
Definition view2d.cc:861
#define V2D_LOCK_COPY
Definition UI_view2d.hh:85
#define UI_MARKER_MARGIN_Y
Definition UI_view2d.hh:471
#define V2D_SCROLL_HANDLE_HEIGHT
Definition UI_view2d.hh:67
#define UI_TIME_CACHE_MARGIN_Y
Definition UI_view2d.hh:473
void UI_view2d_curRect_changed(const bContext *C, View2D *v2d)
Definition view2d.cc:829
#define UI_TIME_SCRUB_MARGIN_Y
Definition UI_view2d.hh:472
View2D * UI_view2d_fromcontext(const bContext *C)
Definition view2d.cc:1850
void UI_view2d_region_to_view_rctf(const View2D *v2d, const rctf *rect_src, rctf *rect_dst) ATTR_NONNULL()
Definition view2d.cc:1670
#define ND_SEQUENCER
Definition WM_types.hh:404
@ OPTYPE_BLOCKING
Definition WM_types.hh:164
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_SCENE
Definition WM_types.hh:345
void ANIM_center_frame(bContext *C, int smooth_viewtx)
Definition anim_draw.cc:663
ListBase * ED_context_get_markers(const bContext *C)
#define ceilf(x)
#define fabsf(x)
draw_view in_light_buf[] float
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
float RNA_float_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition sequencer.cc:416
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
MetaStack * SEQ_meta_stack_active_get(const Editing *ed)
Definition sequencer.cc:448
bool sequencer_view_preview_only_poll(const bContext *C)
bool sequencer_view_has_preview_poll(bContext *C)
bool sequencer_editing_initialized_and_active(bContext *C)
void SEQ_get_timeline_region_padding(const bContext *C, float *r_pad_top, float *r_pad_bottom)
static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
static int sequencer_view_all_exec(bContext *C, wmOperator *op)
static int sequencer_view_all_preview_exec(bContext *C, wmOperator *)
static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
static void seq_view_collection_rect_preview(Scene *scene, blender::Span< Sequence * > strips, rctf *rect)
void SEQUENCER_OT_sample(wmOperatorType *ot)
static void seq_view_collection_rect_timeline(const bContext *C, blender::Span< Sequence * > strips, rctf *rect)
void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_view_frame(wmOperatorType *ot)
void SEQUENCER_OT_view_selected(wmOperatorType *ot)
void SEQUENCER_OT_view_all(wmOperatorType *ot)
void SEQ_add_timeline_region_padding(const bContext *C, rctf *view_box)
static int view_ghost_border_exec(bContext *C, wmOperator *op)
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
void SEQ_timeline_expand_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
void SEQ_timeline_init_boundbox(const Scene *scene, rctf *r_rect)
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *r_rect)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
void SEQ_image_transform_bounding_box_from_collection(Scene *scene, blender::Span< Sequence * > strips, bool apply_rotation, float r_min[2], float r_max[2])
struct RenderData r
struct SequencerCacheOverlay cache_overlay
float xmax
float xmin
float ymax
float ymin
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1028
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_border_to_rctf(wmOperator *op, rctf *r_rect)
int WM_operator_smooth_viewtx_get(const wmOperator *op)