VSE: Clamp "Move Strips" starting position to region bounds

This patch clamps newly added strips with the "Move Strips" property
to the VSE region bounds.

It is often the case that the file browser popup ends up away from the
VSE region, leading to strips getting added off-screen, which defeats
the intended purpose of the property (to make it easier to know where
strips are when they're first added). This patch ensures they are always
visible by default.

Minimum frame and channel to clamp to are defined by the region
bounds, and maximum x and y are 90% of the area. The time scrub
bar is taken into consideration to avoid it obscuring the new strips.

Another possibility is to center the strips if they end up offscreen,
but by having strips start out at the edge, they naturally tend to
recenter themselves if the user brings the mouse cursor closer to the
sequencer region.

Pull Request: https://projects.blender.org/blender/blender/pulls/141838
This commit is contained in:
John Kiril Swenson
2025-07-18 23:26:06 +02:00
committed by John Kiril Swenson
parent fef8c23e9e
commit 27af4a2f52

View File

@@ -52,6 +52,7 @@
/* For menu, popup, icons, etc. */
#include "ED_screen.hh"
#include "ED_sequencer.hh"
#include "ED_time_scrub_ui.hh"
#include "UI_interface.hh"
#include "UI_interface_layout.hh"
@@ -492,13 +493,27 @@ static bool load_data_init_from_operator(seq::LoadData *load_data, bContext *C,
RNA_property_boolean_get(op->ptr, prop))
{
const wmWindow *win = CTX_wm_window(C);
const float2 mouse_region(win->eventstate->xy[0] - region->winrct.xmin,
win->eventstate->xy[1] - region->winrct.ymin);
int2 mouse_region(win->eventstate->xy[0] - region->winrct.xmin,
win->eventstate->xy[1] - region->winrct.ymin);
/* Clamp mouse cursor location (strip starting position) to the sequencer region bounds so that
* it is immediately visible even if the mouse cursor is out of bounds. For maximums, use 90%
* of the bounds instead of 1 frame away, which works well even if zoomed out. */
const rcti mask = ED_time_scrub_clamp_scroller_mask(region->v2d.mask);
rcti clamp_bounds;
BLI_rcti_init(&clamp_bounds,
mask.xmin,
mask.xmin + 0.9 * BLI_rcti_size_x(&mask),
mask.ymin,
mask.ymin + 0.9 * BLI_rcti_size_y(&mask));
BLI_rcti_clamp_pt_v(&clamp_bounds, mouse_region);
float2 mouse_view;
UI_view2d_region_to_view(
&region->v2d, mouse_region.x, mouse_region.y, &mouse_view.x, &mouse_view.y);
load_data->start_frame = mouse_view.x;
load_data->channel = mouse_view.y;
load_data->start_frame = std::trunc(mouse_view.x);
load_data->channel = std::trunc(mouse_view.y);
load_data->image.end_frame = load_data->start_frame + DEFAULT_IMG_STRIP_LENGTH;
load_data->effect.end_frame = load_data->image.end_frame;
}