diff --git a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.VP.cs b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.VP.cs index fa4fba4b..2cfdaaf6 100644 --- a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.VP.cs +++ b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.VP.cs @@ -317,6 +317,41 @@ void SetViewport(int width, int height) yZoomPixels = newHeight - (height - sideYPixels); } + if (ucfg.RestrictPanning) + { + // Don't let the user pan or zoom outside of half the video's height + int newY = (int)(y - yZoomPixels * ucfg.zoomCenter.Y); + int bottom = newHeight + newY; + if (newY > height / 2d) + { + y = (int)((height / 2d) + yZoomPixels * ucfg.zoomCenter.Y); + ucfg.panYOffset = (y - SideYPixels / 2) / (double)height; + } + else if (bottom < height / 2d) + { + int newBottom = (int)(height / 2d); + int newNewY = newBottom - newHeight; + y = (int)(newNewY + yZoomPixels * ucfg.zoomCenter.Y); + ucfg.panYOffset = (y - SideYPixels / 2) / (double)height; + } + + // Don't let the user pan or zoom outside of half the video's width + int newX = (int)(x - xZoomPixels * ucfg.zoomCenter.X); + int right = newWidth + newX; + if (newX > width / 2d) + { + x = (int)((width / 2d) + xZoomPixels * ucfg.zoomCenter.X); + ucfg.panXOffset = (x - SideXPixels / 2) / (double)width; + } + else if (right < width / 2d) + { + int newRight = (int)(width / 2d); + int newNewX = newRight - newWidth; + x = (int)(newNewX + xZoomPixels * (float)ucfg.zoomCenter.X); + ucfg.panXOffset = (x - SideXPixels / 2) / (double)width; + } + } + Viewport = new((int)(x - xZoomPixels * (float)ucfg.zoomCenter.X), (int)(y - yZoomPixels * (float)ucfg.zoomCenter.Y), newWidth, newHeight); ViewportChanged?.Invoke(this, new()); } @@ -503,6 +538,16 @@ public WPoint public int ZoomOffset { get => zoomOffset; set { Set(ref zoomOffset, value); } } int zoomOffset = 10; + /// + /// Restrict panning of the video outside of half the video width or height + /// + public bool RestrictPanning { get; set; } = true; + + /// + /// Reset pan and zoom level when zooming out to less than 100% + /// + public bool ResetPanOnZoomedOut { get; set; } = true; + public void ResetViewport() => SetViewport(0, 0, 0, 100, new(0.5, 0.5), CropRect.Empty, AspectRatio.Keep, false, false); @@ -551,6 +596,12 @@ internal void SetZoomWithCenterPoint(Point p, double zoom) */ zoom = SnapToInt(zoom); + if (ResetPanOnZoomedOut && zoom <= 1.0) + { + zoom = 1.0; + panXOffset = 0; + panYOffset = 0; + } Viewport view = vp.Viewport; if (!(p.X >= view.X && p.X < view.X + view.Width && p.Y >= view.Y && p.Y < view.Y + view.Height)) // Point out of view