From e16ff4132e35cab6a757105741b8563679bda0bd Mon Sep 17 00:00:00 2001 From: ok what Date: Thu, 21 Apr 2022 00:38:39 +0200 Subject: VSE: Add frame selected operator for preview This operator moves the view to show the selected visible strips. Reviewed By: ISS Differential Revision: https://developer.blender.org/D14222 --- .../editors/space_sequencer/sequencer_view.c | 106 ++++++++++++++------- .../blender/editors/transform/transform_gizmo_2d.c | 12 +-- source/blender/sequencer/SEQ_transform.h | 16 ++++ source/blender/sequencer/intern/strip_transform.c | 15 +++ 4 files changed, 102 insertions(+), 47 deletions(-) (limited to 'source') diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 4d245b9ddaa..c407dad623d 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -22,9 +22,11 @@ #include "RNA_define.h" +#include "SEQ_iterator.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" /* For menu, popup, icons, etc. */ #include "ED_anim_api.h" @@ -260,14 +262,30 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot) /** \name Frame Selected Operator * \{ */ -static int sequencer_view_selected_exec(bContext *C, wmOperator *op) +static void seq_view_collection_rect_preview(Scene *scene, SeqCollection *strips, rctf *rect) +{ + float min[2], max[2]; + SEQ_image_transform_bounding_box_from_collection(scene, strips, true, min, max); + + rect->xmin = min[0]; + rect->xmax = max[0]; + rect->ymin = min[1]; + rect->ymax = max[1]; + + float minsize = min_ff(BLI_rctf_size_x(rect), BLI_rctf_size_y(rect)); + + /* If the size of the strip is smaller than a pixel, add padding to prevent division by zero. */ + if (minsize < 1.0f) { + BLI_rctf_pad(rect, 20.0f, 20.0f); + } + + /* Add padding. */ + BLI_rctf_scale(rect, 1.1f); +} + +static void seq_view_collection_rect_timeline(Scene *scene, SeqCollection *strips, rctf *rect) { - Scene *scene = CTX_data_scene(C); - View2D *v2d = UI_view2d_fromcontext(C); - ARegion *region = CTX_wm_region(C); - Editing *ed = SEQ_editing_get(scene); Sequence *seq; - rctf cur_new = v2d->cur; int xmin = MAXFRAME * 2; int xmax = -MAXFRAME * 2; @@ -278,49 +296,63 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) int ymargin = 1; int xmargin = FPS; - if (ed == NULL) { - return OPERATOR_CANCELLED; - } - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT) { - xmin = min_ii(xmin, seq->startdisp); - xmax = max_ii(xmax, seq->enddisp); + SEQ_ITERATOR_FOREACH (seq, strips) { + xmin = min_ii(xmin, seq->startdisp); + xmax = max_ii(xmax, seq->enddisp); - ymin = min_ii(ymin, seq->machine); - ymax = max_ii(ymax, seq->machine); - } + ymin = min_ii(ymin, seq->machine); + ymax = max_ii(ymax, seq->machine); } - if (ymax != 0) { - const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + xmax += xmargin; + xmin -= xmargin; + ymax += ymargin; + ymin -= ymargin; - xmax += xmargin; - xmin -= xmargin; - ymax += ymargin; - ymin -= ymargin; + orig_height = BLI_rctf_size_y(rect); - orig_height = BLI_rctf_size_y(&cur_new); + rect->xmin = xmin; + rect->xmax = xmax; - cur_new.xmin = xmin; - cur_new.xmax = xmax; + rect->ymin = ymin; + rect->ymax = ymax; - cur_new.ymin = ymin; - cur_new.ymax = ymax; + /* Only zoom out vertically. */ + if (orig_height > BLI_rctf_size_y(rect)) { + ymid = BLI_rctf_cent_y(rect); - /* Only zoom out vertically. */ - if (orig_height > BLI_rctf_size_y(&cur_new)) { - ymid = BLI_rctf_cent_y(&cur_new); + rect->ymin = ymid - (orig_height / 2); + rect->ymax = ymid + (orig_height / 2); + } +} - cur_new.ymin = ymid - (orig_height / 2); - cur_new.ymax = ymid + (orig_height / 2); - } +static int sequencer_view_selected_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + ARegion *region = CTX_wm_region(C); + SeqCollection *strips = selected_strips_from_context(C); + View2D *v2d = UI_view2d_fromcontext(C); + rctf cur_new = v2d->cur; - UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx); + if (SEQ_collection_len(strips) == 0) { + return OPERATOR_CANCELLED; + } - return OPERATOR_FINISHED; + if (sequencer_view_has_preview_poll(C) && !sequencer_view_preview_only_poll(C)) { + return OPERATOR_CANCELLED; } - return OPERATOR_CANCELLED; + + if (region && region->regiontype == RGN_TYPE_PREVIEW) { + seq_view_collection_rect_preview(scene, strips, &cur_new); + } + else { + seq_view_collection_rect_timeline(scene, strips, &cur_new); + } + + const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx); + + return OPERATOR_FINISHED; } void SEQUENCER_OT_view_selected(wmOperatorType *ot) diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index f2fb5b26305..838b40c2040 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -251,17 +251,9 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min SEQ_filter_selected_strips(strips); int selected_strips = SEQ_collection_len(strips); if (selected_strips > 0) { - INIT_MINMAX2(r_min, r_max); has_select = true; - - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, strips) { - float quad[4][2]; - SEQ_image_transform_quad_get(scene, seq, selected_strips != 1, quad); - for (int i = 0; i < 4; i++) { - minmax_v2v2_v2(r_min, r_max, quad[i]); - } - } + SEQ_image_transform_bounding_box_from_collection( + scene, strips, selected_strips != 1, r_min, r_max); } SEQ_collection_free(strips); if (selected_strips > 1) { diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index eb910a5a5d1..a342dfe10a2 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -119,6 +119,22 @@ void SEQ_image_preview_unit_from_px(const struct Scene *scene, const float co_src[2], float co_dst[2]); +/** + * Get viewport axis aligned bounding box from a collection of sequences. + * The collection must have one or more strips + * + * \param scene: Scene in which strips are located + * \param strips: Collection of strips to get the bounding box from + * \param apply_rotation: Include sequence rotation transform in the bounding box calculation + * \param r_min: Minimum x and y values + * \param r_max: Maximum x and y values + */ +void SEQ_image_transform_bounding_box_from_collection(struct Scene *scene, + struct SeqCollection *strips, + bool apply_rotation, + float r_min[2], + float r_max[2]); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 087e2610bd6..e614dfa9b82 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -517,3 +517,18 @@ void SEQ_image_preview_unit_from_px(const Scene *scene, const float co_src[2], f co_dst[0] = co_src[0] / scene->r.xsch; co_dst[1] = co_src[1] / scene->r.ysch; } + +void SEQ_image_transform_bounding_box_from_collection( + Scene *scene, SeqCollection *strips, bool apply_rotation, float r_min[2], float r_max[2]) +{ + Sequence *seq; + + INIT_MINMAX2(r_min, r_max); + SEQ_ITERATOR_FOREACH (seq, strips) { + float quad[4][2]; + SEQ_image_transform_quad_get(scene, seq, apply_rotation, quad); + for (int i = 0; i < 4; i++) { + minmax_v2v2_v2(r_min, r_max, quad[i]); + } + } +} -- cgit v1.2.3