diff options
author | Richard Antalik <richardantalik@gmail.com> | 2022-04-28 17:07:57 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2022-04-28 17:14:51 +0300 |
commit | 17769489d920f86310464297e8906f34d5ec61b9 (patch) | |
tree | 7880dd7b626d9254a46894eaf11b06ae311a8cee /source/blender/editors/space_sequencer | |
parent | b1b153b88c14b516183f7dd43b2c0111c0e7b041 (diff) |
VSE: Add option to limit timeline view height
When height is limited, it is defined by space occupied by strips,
but at least channels 1 to 7 will be always visible. This allows it to
easily overview timeline content by zooming out to maximum extent in Y
axis and panning in X axis.
More channels can be "created" on demand by moving strip to higher
channel. When strip is removed and highest channel becomes empty, view
will stay as is until it is moved down. Then new highest point is
remembered and it is not possible to pan upwards until strip is moved to
higher channel.
Limiting takes into account height of scrubbing and markers area as
well as scrollers. This means that when zoomed out to maximum extent,
no strips are obstructed by fixed UI element.
Fixes T57976
Reviewed By: Severin
Differential Revision: https://developer.blender.org/D14263
Diffstat (limited to 'source/blender/editors/space_sequencer')
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_view.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/space_sequencer.c | 93 |
2 files changed, 103 insertions, 1 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index c407dad623d..d271ad1ec66 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -32,6 +32,7 @@ #include "ED_anim_api.h" #include "ED_screen.h" #include "ED_util_imbuf.h" +#include "ED_time_scrub_ui.h" /* Own include. */ #include "sequencer_intern.h" @@ -86,6 +87,16 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) box.xmax = ms->disp_range[1] + 1; } SEQ_timeline_expand_boundbox(SEQ_active_seqbase_get(ed), &box); + + View2D *v2d = ®ion->v2d; + rcti scrub_rect; + ED_time_scrub_region_rect_get(region, &scrub_rect); + const float pixel_view_size_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); + const float scrub_bar_height = BLI_rcti_size_y(&scrub_rect) * pixel_view_size_y; + + /* Channel n has range of <n, n+1>. */ + box.ymax += 1.0f + scrub_bar_height; + UI_view2d_smooth_view(C, region, &box, smooth_viewtx); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index ed669f5f8d2..8e4bd61f600 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -16,6 +16,7 @@ #include "BLI_blenlib.h" #include "BLI_ghash.h" +#include "BLI_math_base.h" #include "BKE_global.h" #include "BKE_lib_remap.h" @@ -24,8 +25,10 @@ #include "GPU_state.h" +#include "ED_markers.h" #include "ED_screen.h" #include "ED_space_api.h" +#include "ED_time_scrub_ui.h" #include "ED_transform.h" #include "ED_view3d.h" #include "ED_view3d_offscreen.h" /* Only for sequencer view3d drawing callback. */ @@ -33,6 +36,8 @@ #include "WM_api.h" #include "WM_message.h" +#include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "SEQ_transform.h" #include "SEQ_utils.h" @@ -164,7 +169,7 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce region->v2d.tot.xmin = 0.0f; region->v2d.tot.ymin = 0.0f; region->v2d.tot.xmax = scene->r.efra; - region->v2d.tot.ymax = 8.0f; + region->v2d.tot.ymax = 8.5f; region->v2d.cur = region->v2d.tot; @@ -534,6 +539,90 @@ static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *regio draw_timeline_seq_display(C, region); } +static void sequencer_main_clamp_view(const bContext *C, ARegion *region) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + + if ((sseq->flag & SEQ_CLAMP_VIEW) == 0) { + return; + } + + View2D *v2d = ®ion->v2d; + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); + + /* Transformation uses edge panning to move view. Also if smooth view is running, don't apply + * clamping to prevent overriding this functionality. */ + if (G.moving || v2d->smooth_timer != NULL) { + return; + } + + /* Initialize default view with 7 channels, that are visible even if empty. */ + rctf strip_boundbox; + BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, 7.0f); + SEQ_timeline_expand_boundbox(ed->seqbasep, &strip_boundbox); + + /* Clamp Y max. Scrubbing area height must be added, so strips aren't occluded. */ + rcti scrub_rect; + ED_time_scrub_region_rect_get(region, &scrub_rect); + const float pixel_view_size_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); + const float scrub_bar_height = BLI_rcti_size_y(&scrub_rect) * pixel_view_size_y; + + /* Channel n has range of <n, n+1>. */ + strip_boundbox.ymax += 1.0f + scrub_bar_height; + + /* Clamp Y min. Scroller and marker area height must be added, so strips aren't occluded. */ + float scroll_bar_height = v2d->hor.ymax * pixel_view_size_y; + + ListBase *markers = ED_context_get_markers(C); + if (markers != NULL && !BLI_listbase_is_empty(markers)) { + float markers_size = UI_MARKER_MARGIN_Y * pixel_view_size_y; + strip_boundbox.ymin -= markers_size; + } + else { + strip_boundbox.ymin -= scroll_bar_height; + } + + /* If strip is deleted, don't move view automatically, keep current range until it is changed. */ + strip_boundbox.ymax = max_ff(sseq->runtime.timeline_clamp_custom_range, strip_boundbox.ymax); + + rctf view_clamped = v2d->cur; + bool do_clamp = false; + + const float range_y = BLI_rctf_size_y(&view_clamped); + if (view_clamped.ymax > strip_boundbox.ymax) { + view_clamped.ymax = strip_boundbox.ymax; + view_clamped.ymin = max_ff(strip_boundbox.ymin, strip_boundbox.ymax - range_y); + do_clamp = true; + } + if (view_clamped.ymin < strip_boundbox.ymin) { + view_clamped.ymin = strip_boundbox.ymin; + view_clamped.ymax = min_ff(strip_boundbox.ymax, strip_boundbox.ymin + range_y); + do_clamp = true; + } +} + +static void sequencer_main_region_clamp_custom_set(const bContext *C, ARegion *region) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + View2D *v2d = ®ion->v2d; + + if ((v2d->flag & V2D_IS_NAVIGATING) == 0) { + sseq->runtime.timeline_clamp_custom_range = v2d->cur.ymax; + } +} + +static void sequencer_main_region_layout(const bContext *C, ARegion *region) +{ + sequencer_main_region_clamp_custom_set(C, region); + sequencer_main_clamp_view(C, region); +} + +static void sequencer_main_region_view2d_changed(const bContext *C, ARegion *region) +{ + sequencer_main_region_clamp_custom_set(C, region); + sequencer_main_clamp_view(C, region); +} + static void sequencer_main_region_listener(const wmRegionListenerParams *params) { ARegion *region = params->region; @@ -926,6 +1015,8 @@ void ED_spacetype_sequencer(void) art->init = sequencer_main_region_init; art->draw = sequencer_main_region_draw; art->draw_overlay = sequencer_main_region_draw_overlay; + art->layout = sequencer_main_region_layout; + art->on_view2d_changed = sequencer_main_region_view2d_changed; art->listener = sequencer_main_region_listener; art->message_subscribe = sequencer_main_region_message_subscribe; /* NOTE: inclusion of #ED_KEYMAP_GIZMO is currently for scripts and isn't used by default. */ |