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);
}
}