VSE: Keep zoom levels constant when resizing

We can apply the `V2D_KEEPZOOM` and `V2D_KEEPOFS_Y` flags to the main VSE
region to make sure this happens. If `V2D_KEEPZOOM` is set, we should update
the view2d's `oldwinx` and `oldwiny` in `ui_view2d_curRect_validate_resize`
just like the `V2D_KEEPASPECT` case.

Divide-by-zero is a real possibility here, since initialization status of
`oldwinx/y` cannot be determined from the `resize` boolean alone (e.g. loading
regions from disk on startup yields a `true` `resize` parameter, so any old
regions that have `KEEPZOOM` added through versioning will get this error since
their `oldwinx/y` is uninitialized). Avoid by initializing `oldwinx/y` if it is zero in
`ui_view2d_curRect_validate_resize`.

Addresses #136508.

Pull Request: https://projects.blender.org/blender/blender/pulls/137802
This commit is contained in:
John Kiril Swenson
2025-04-23 03:04:55 +02:00
committed by John Kiril Swenson
parent 38a58a319d
commit 7d9499bdc4
5 changed files with 35 additions and 9 deletions

View File

@@ -27,7 +27,7 @@
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 45
#define BLENDER_FILE_SUBVERSION 46
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@@ -8834,6 +8834,25 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
FOREACH_NODETREE_END;
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 46)) {
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_SEQ) {
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
&sl->regionbase;
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
region->v2d.keepzoom |= V2D_KEEPZOOM;
region->v2d.keepofs |= V2D_KEEPOFS_X | V2D_KEEPOFS_Y;
}
}
}
}
}
}
}
/* Always run this versioning (keep at the bottom of the function). Meshes are written with the
* legacy format which always needs to be converted to the new format on file load. To be moved
* to a subversion check in 5.0. */

View File

@@ -437,8 +437,14 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
}
winx = std::max<float>(winx, 1);
winy = std::max<float>(winy, 1);
if (v2d->oldwinx == 0) {
v2d->oldwinx = winx;
}
if (v2d->oldwiny == 0) {
v2d->oldwiny = winy;
}
/* V2D_LIMITZOOM indicates that zoom level should be preserved when the window size changes */
/* V2D_KEEPZOOM indicates that zoom level should be preserved when the window size changes. */
if (resize && (v2d->keepzoom & V2D_KEEPZOOM)) {
float zoom, oldzoom;
@@ -581,12 +587,12 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
height = width * winRatio;
}
}
/* store region size for next time */
v2d->oldwinx = short(winx);
v2d->oldwiny = short(winy);
}
/* Store region size for next time. */
v2d->oldwinx = short(winx);
v2d->oldwiny = short(winy);
/* Step 2: apply new sizes to cur rect,
* but need to take into account alignment settings here... */
if ((width != curwidth) || (height != curheight)) {

View File

@@ -194,8 +194,9 @@ static SpaceLink *sequencer_create(const ScrArea * /*area*/, const Scene *scene)
region->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
region->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES);
region->v2d.keepzoom = 0;
region->v2d.keeptot = 0;
region->v2d.keepzoom = V2D_KEEPZOOM;
region->v2d.keepofs = V2D_KEEPOFS_X | V2D_KEEPOFS_Y;
region->v2d.keeptot = V2D_KEEPTOT_FREE;
region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
region->v2d.align = V2D_ALIGN_NO_NEG_Y;

View File

@@ -47,7 +47,7 @@ typedef struct View2D {
short winx, winy;
/**
* Storage of previous winx/winy values encountered by #UI_view2d_curRect_validate(),
* for keep-aspect.
* for V2D_KEEPZOOM and V2D_KEEPASPECT.
*/
short oldwinx, oldwiny;