From a7302d32245b29cf391486e49f6f4e4c8f5fd1c1 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Wed, 11 Nov 2026 21:13:53 -0500 Subject: [PATCH] refactor(desktop): share the large browse dialogs' sizing LargeDialogBounds computes the bounds the large browse dialogs open at: nine tenths of the owner screen's working area, centered, never below the dialog's minimum size. WinForms' DialogBounds now calls it with the screen's working area, with unchanged behaviour. Co-Authored-By: Claude Opus 5.5 --- .../LargeDialogBoundsTests.cs | 28 +++++++++++++++++++ OpenNest.Desktop/LargeDialogBounds.cs | 24 ++++++++++++++++ OpenNest/Forms/DialogBounds.cs | 13 ++++----- 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 OpenNest.Desktop.Tests/LargeDialogBoundsTests.cs create mode 100644 OpenNest.Desktop/LargeDialogBounds.cs diff --git a/OpenNest.Desktop.Tests/LargeDialogBoundsTests.cs b/OpenNest.Desktop.Tests/LargeDialogBoundsTests.cs new file mode 100644 index 00000000..ac0d1746 --- /dev/null +++ b/OpenNest.Desktop.Tests/LargeDialogBoundsTests.cs @@ -0,0 +1,28 @@ +namespace OpenNest.Desktop.Tests; + +public class LargeDialogBoundsTests +{ + [Fact] + public void Centered_NineTenthsOfTheWorkingArea() + { + var bounds = LargeDialogBounds.Centered(new PixelRect(0, 0, 1920, 1040), 800, 600); + + Assert.Equal(new PixelRect(96, 52, 1728, 936), bounds); + } + + [Fact] + public void Centered_OnASecondaryScreen() + { + var bounds = LargeDialogBounds.Centered(new PixelRect(1920, -200, 2560, 1400), 800, 600); + + Assert.Equal(new PixelRect(1920 + 128, -200 + 70, 2304, 1260), bounds); + } + + [Fact] + public void Centered_NeverBelowTheMinimumOrBeforeTheWorkingArea() + { + var bounds = LargeDialogBounds.Centered(new PixelRect(100, 50, 1000, 700), 1200, 900); + + Assert.Equal(new PixelRect(100, 50, 1200, 900), bounds); + } +} diff --git a/OpenNest.Desktop/LargeDialogBounds.cs b/OpenNest.Desktop/LargeDialogBounds.cs new file mode 100644 index 00000000..6481d877 --- /dev/null +++ b/OpenNest.Desktop/LargeDialogBounds.cs @@ -0,0 +1,24 @@ +namespace OpenNest.Desktop; + +/// +/// Sizing shared by the large browse dialogs (File > Open, Drawing Library, Shape Library) so +/// they open at the same size: a normal window nine tenths of the owner screen's working area, +/// centered in it so its bottom row stays clear of the taskbar. +/// +public static class LargeDialogBounds +{ + /// + /// The bounds in (screen pixels), never smaller than the + /// dialog's minimum size and never starting left of or above the working area. + /// + public static PixelRect Centered(PixelRect workingArea, int minimumWidth, int minimumHeight) + { + var width = System.Math.Max(minimumWidth, workingArea.Width * 9 / 10); + var height = System.Math.Max(minimumHeight, workingArea.Height * 9 / 10); + return new PixelRect( + System.Math.Max(workingArea.X, workingArea.X + (workingArea.Width - width) / 2), + System.Math.Max(workingArea.Y, workingArea.Y + (workingArea.Height - height) / 2), + width, + height); + } +} diff --git a/OpenNest/Forms/DialogBounds.cs b/OpenNest/Forms/DialogBounds.cs index 98c90415..72000430 100644 --- a/OpenNest/Forms/DialogBounds.cs +++ b/OpenNest/Forms/DialogBounds.cs @@ -1,5 +1,6 @@ using System.Drawing; using System.Windows.Forms; +using OpenNest.Desktop; namespace OpenNest.Forms; @@ -20,12 +21,10 @@ internal static class DialogBounds public static void FitToOwnerScreen(Form form) { var area = Screen.FromControl(form.Owner ?? form).WorkingArea; - var width = System.Math.Max(form.MinimumSize.Width, area.Width * 9 / 10); - var height = System.Math.Max(form.MinimumSize.Height, area.Height * 9 / 10); - form.Bounds = new Rectangle( - System.Math.Max(area.Left, area.Left + (area.Width - width) / 2), - System.Math.Max(area.Top, area.Top + (area.Height - height) / 2), - width, - height); + var bounds = LargeDialogBounds.Centered( + new PixelRect(area.X, area.Y, area.Width, area.Height), + form.MinimumSize.Width, + form.MinimumSize.Height); + form.Bounds = new Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height); } }