Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Antalik <richardantalik@gmail.com>2022-04-28 17:07:57 +0300
committerRichard Antalik <richardantalik@gmail.com>2022-04-28 17:14:51 +0300
commit17769489d920f86310464297e8906f34d5ec61b9 (patch)
tree7880dd7b626d9254a46894eaf11b06ae311a8cee
parentb1b153b88c14b516183f7dd43b2c0111c0e7b041 (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
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py1
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenloader/intern/versioning_300.c27
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c6
-rw-r--r--source/blender/editors/include/ED_time_scrub_ui.h2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c11
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c93
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c24
-rw-r--r--source/blender/makesdna/DNA_space_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_space.c38
-rw-r--r--source/blender/sequencer/intern/strip_time.c2
11 files changed, 193 insertions, 17 deletions
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 00ace072bda..8289b7b8556 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -439,6 +439,7 @@ class SEQUENCER_MT_view(Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("sequencer.view_all")
layout.operator("view2d.zoom_border", text="Zoom")
+ layout.prop(st, "clamp_view")
if is_preview:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index ef419b9def9..7f0a4c0d7af 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -25,7 +25,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 13
+#define BLENDER_FILE_SUBVERSION 14
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 8190de649bd..e6a214452fe 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -786,6 +786,33 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 302, 14)) {
+ /* Sequencer channels region. */
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype != SPACE_SEQ) {
+ continue;
+ }
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+ sseq->flag |= SEQ_CLAMP_VIEW;
+
+ if (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) {
+ continue;
+ }
+
+ ARegion *timeline_region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+
+ if (timeline_region == NULL) {
+ continue;
+ }
+
+ timeline_region->v2d.cur.ymax = 8.5f;
+ timeline_region->v2d.align &= ~V2D_ALIGN_NO_NEG_Y;
+ }
+ }
+ }
+ }
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index ba7b83173ce..623d4e605ba 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -32,7 +32,7 @@
#include "RNA_access.h"
#include "RNA_prototypes.h"
-static void get_time_scrub_region_rect(const ARegion *region, rcti *rect)
+void ED_time_scrub_region_rect_get(const ARegion *region, rcti *rect)
{
rect->xmin = 0;
rect->xmax = region->winx;
@@ -154,7 +154,7 @@ void ED_time_scrub_draw_current_frame(const ARegion *region,
wmOrtho2_region_pixelspace(region);
rcti scrub_region_rect;
- get_time_scrub_region_rect(region, &scrub_region_rect);
+ ED_time_scrub_region_rect_get(region, &scrub_region_rect);
draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra);
GPU_matrix_pop_projection();
@@ -171,7 +171,7 @@ void ED_time_scrub_draw(const ARegion *region,
wmOrtho2_region_pixelspace(region);
rcti scrub_region_rect;
- get_time_scrub_region_rect(region, &scrub_region_rect);
+ ED_time_scrub_region_rect_get(region, &scrub_region_rect);
draw_background(&scrub_region_rect);
diff --git a/source/blender/editors/include/ED_time_scrub_ui.h b/source/blender/editors/include/ED_time_scrub_ui.h
index 596fdd87afc..efc972ef69d 100644
--- a/source/blender/editors/include/ED_time_scrub_ui.h
+++ b/source/blender/editors/include/ED_time_scrub_ui.h
@@ -14,6 +14,7 @@ extern "C" {
struct bContext;
struct bDopeSheet;
struct wmEvent;
+struct rcti;
void ED_time_scrub_draw_current_frame(const struct ARegion *region,
const struct Scene *scene,
@@ -29,6 +30,7 @@ bool ED_time_scrub_event_in_region(const struct ARegion *region, const struct wm
void ED_time_scrub_channel_search_draw(const struct bContext *C,
struct ARegion *region,
struct bDopeSheet *dopesheet);
+void ED_time_scrub_region_rect_get(const struct ARegion *region, struct rcti *rect);
#ifdef __cplusplus
}
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 = &region->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 = &region->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 = &region->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. */
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index c1e8dab3b3e..5964af7ed4b 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -35,7 +35,7 @@
#include "transform.h"
#include "transform_convert.h"
-#define SEQ_EDGE_PAN_INSIDE_PAD 2
+#define SEQ_EDGE_PAN_INSIDE_PAD 3.5
#define SEQ_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for panning, use whole screen. */
#define SEQ_EDGE_PAN_SPEED_RAMP 1
#define SEQ_EDGE_PAN_MAX_SPEED 4 /* In UI units per second, slower than default. */
@@ -769,6 +769,11 @@ void createTransSeqData(TransInfo *t)
return;
}
+ /* Disable cursor wrapping for edge pan. */
+ if (t->mode == TFM_TRANSLATION) {
+ t->flag |= T_NO_CURSOR_WRAP;
+ }
+
tc->custom.type.free_cb = freeSeqData;
t->frame_side = transform_convert_frame_side_dir_get(t, (float)CFRA);
@@ -845,14 +850,6 @@ static void view2d_edge_pan_loc_compensate(TransInfo *t, float loc_in[2], float
const rctf *rect_src = &ts->initial_v2d_cur;
const rctf *rect_dst = &t->region->v2d.cur;
- copy_v2_v2(r_loc, loc_in);
- /* Additional offset due to change in view2D rect. */
- BLI_rctf_transform_pt_v(rect_dst, rect_src, r_loc, r_loc);
-}
-
-static void flushTransSeq(TransInfo *t)
-{
- TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
if (t->options & CTX_VIEW2D_EDGE_PAN) {
if (t->state == TRANS_CANCEL) {
UI_view2d_edge_pan_cancel(t->context, &ts->edge_pan);
@@ -867,6 +864,13 @@ static void flushTransSeq(TransInfo *t)
}
}
+ copy_v2_v2(r_loc, loc_in);
+ /* Additional offset due to change in view2D rect. */
+ BLI_rctf_transform_pt_v(rect_dst, rect_src, r_loc, r_loc);
+}
+
+static void flushTransSeq(TransInfo *t)
+{
/* Editing null check already done */
ListBase *seqbasep = seqbase_active_get(t);
@@ -934,6 +938,8 @@ static void flushTransSeq(TransInfo *t)
}
}
+ TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
+
/* Update animation for effects. */
SEQ_ITERATOR_FOREACH (seq, ts->time_dependent_strips) {
SEQ_offset_animdata(t->scene, seq, max_offset);
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index bce124a26cf..c1e96bcfaf3 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -618,7 +618,7 @@ typedef struct SpaceSeqRuntime {
/** Stores lists of most recently displayed thumbnails. */
struct GHash *last_displayed_thumbnails;
int rename_channel_index;
- char _pad0[4];
+ float timeline_clamp_custom_range;
} SpaceSeqRuntime;
/** Sequencer. */
@@ -691,7 +691,7 @@ typedef enum eSpaceSeq_Flag {
SEQ_DRAWFRAMES = (1 << 0),
SEQ_MARKER_TRANS = (1 << 1),
SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
- SPACE_SEQ_FLAG_UNUSED_3 = (1 << 3),
+ SEQ_CLAMP_VIEW = (1 << 3),
SPACE_SEQ_FLAG_UNUSED_4 = (1 << 4),
SPACE_SEQ_FLAG_UNUSED_5 = (1 << 5),
SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 1f68855622f..0ba8658568c 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2346,6 +2346,36 @@ static void rna_SequenceEditor_render_size_update(bContext *C, PointerRNA *ptr)
rna_SequenceEditor_update_cache(CTX_data_main(C), CTX_data_scene(C), ptr);
}
+static bool rna_SequenceEditor_clamp_view_get(PointerRNA *ptr)
+{
+ SpaceSeq *sseq = ptr->data;
+ return (sseq->flag & SEQ_CLAMP_VIEW) != 0;
+}
+
+static void rna_SequenceEditor_clamp_view_set(PointerRNA *ptr, bool value)
+{
+ SpaceSeq *sseq = ptr->data;
+ ScrArea *area;
+ ARegion *region;
+
+ area = rna_area_from_space(ptr); /* can be NULL */
+ if (area == NULL) {
+ return;
+ }
+
+ region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+ if (region) {
+ if (value) {
+ sseq->flag |= SEQ_CLAMP_VIEW;
+ region->v2d.align &= ~V2D_ALIGN_NO_NEG_Y;
+ }
+ else {
+ sseq->flag &= ~SEQ_CLAMP_VIEW;
+ region->v2d.align |= V2D_ALIGN_NO_NEG_Y;
+ }
+ }
+}
+
static void rna_Sequencer_view_type_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *ptr)
@@ -5709,6 +5739,14 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
prop, "Use Proxies", "Use optimized files for faster scrubbing when available");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, "rna_SequenceEditor_update_cache");
+ prop = RNA_def_property(srna, "clamp_view", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CLAMP_VIEW);
+ RNA_def_property_boolean_funcs(
+ prop, "rna_SequenceEditor_clamp_view_get", "rna_SequenceEditor_clamp_view_set");
+ RNA_def_property_ui_text(
+ prop, "Limit View to Contents", "Limit timeline height to maximum used channel slot");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c
index 06571b7ad43..a5341dbc528 100644
--- a/source/blender/sequencer/intern/strip_time.c
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -445,7 +445,7 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect)
rect->xmax = seq->enddisp + 1;
}
if (rect->ymax < seq->machine) {
- rect->ymax = seq->machine + 2;
+ rect->ymax = seq->machine;
}
}
}