From e7499f14c2c94ab00a43168308c462987bd43686 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 1 Nov 2026 17:17:30 -0500 Subject: [PATCH] fix(ui): return to Select after one Zoom To Area Co-Authored-By: Claude Opus 5.5 --- .../Actions/ActionZoomWindowTests.cs | 87 +++++++++++++++++++ OpenNest/Actions/ActionZoomWindow.cs | 21 +++-- 2 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 OpenNest.WinForms.Tests/Actions/ActionZoomWindowTests.cs diff --git a/OpenNest.WinForms.Tests/Actions/ActionZoomWindowTests.cs b/OpenNest.WinForms.Tests/Actions/ActionZoomWindowTests.cs new file mode 100644 index 00000000..eb0da5b5 --- /dev/null +++ b/OpenNest.WinForms.Tests/Actions/ActionZoomWindowTests.cs @@ -0,0 +1,87 @@ +using System.Drawing; +using System.Windows.Forms; +using OpenNest.Actions; +using OpenNest.Controls; +using OpenNest.Geometry; +using static OpenNest.WinForms.Tests.FormTesting; + +namespace OpenNest.WinForms.Tests.Actions; + +/// Zoom To Area is a one-shot tool: a single zoom hands the view back to Select. +public class ActionZoomWindowTests +{ + private static PlateView ZoomView() + { + var view = new PlateView { Plate = new Plate(48, 120), Size = new System.Drawing.Size(900, 450) }; + view.ZoomToFit(); + view.SetAction(typeof(ActionZoomWindow)); + return view; + } + + private static Point At(PlateView view, double x, double y) => view.PointWorldToControl(new Vector(x, y)); + + private static void Press(PlateView view, Point p) => + Raise(view, "OnMouseDown", new MouseEventArgs(MouseButtons.Left, 1, p.X, p.Y, 0)); + + private static void Release(PlateView view, Point p) => + Raise(view, "OnMouseUp", new MouseEventArgs(MouseButtons.Left, 1, p.X, p.Y, 0)); + + private static void Click(PlateView view, Point p) + { + Press(view, p); + Release(view, p); + } + + [Fact] + public void DraggingAWindowZoomsAndReturnsToSelect() => StaTestThread.Run(() => + { + using var view = ZoomView(); + var scale = view.ViewScale; + + Press(view, At(view, 5, 5)); + Release(view, At(view, 20, 20)); + + Assert.True(view.ViewScale > scale); + Assert.IsType(view.Actions.CurrentAction); + }, TimeSpan.FromMinutes(1), "The STA test did not complete."); + + [Fact] + public void ClickingTwoCornersZoomsAndReturnsToSelect() => StaTestThread.Run(() => + { + using var view = ZoomView(); + var scale = view.ViewScale; + + Click(view, At(view, 5, 5)); + Assert.IsType(view.Actions.CurrentAction); + + Click(view, At(view, 20, 20)); + + Assert.True(view.ViewScale > scale); + Assert.IsType(view.Actions.CurrentAction); + }, TimeSpan.FromMinutes(1), "The STA test did not complete."); + + [Fact] + public void EscapeFromSelectDoesNotBringTheToolBack() => StaTestThread.Run(() => + { + using var view = ZoomView(); + + Press(view, At(view, 5, 5)); + Release(view, At(view, 20, 20)); + view.Actions.ProcessEscapeKey(); + + Assert.IsType(view.Actions.CurrentAction); + }, TimeSpan.FromMinutes(1), "The STA test did not complete."); + + [Fact] + public void CancellingKeepsTheToolArmed() => StaTestThread.Run(() => + { + using var view = ZoomView(); + var scale = view.ViewScale; + + Click(view, At(view, 5, 5)); + view.Actions.ProcessEscapeKey(); + + Assert.Equal(scale, view.ViewScale); + Assert.IsType(view.Actions.CurrentAction); + }, TimeSpan.FromMinutes(1), "The STA test did not complete."); +} diff --git a/OpenNest/Actions/ActionZoomWindow.cs b/OpenNest/Actions/ActionZoomWindow.cs index e2bf210f..b95df713 100644 --- a/OpenNest/Actions/ActionZoomWindow.cs +++ b/OpenNest/Actions/ActionZoomWindow.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using OpenNest.Controls; @@ -17,6 +17,9 @@ namespace OpenNest.Actions private Status status; + // One zoom ends this tool; Escape from Select must not bring it back. + public override bool ResumeOnEscape => false; + public ActionZoomWindow(PlateView plateView) : base(plateView) { @@ -96,22 +99,22 @@ namespace OpenNest.Actions var distance2 = plateView.LengthWorldToGui(distance1); if (distance2 > 40) - { - ZoomWindow(); - CancelAction(); - } + ZoomAndFinish(); else - { status = Status.SetSecondPoint; - } } else if (status == Status.SetSecondPoint) { - ZoomWindow(); - CancelAction(); + ZoomAndFinish(); } } + private void ZoomAndFinish() + { + ZoomWindow(); + plateView.SetAction(typeof(ActionSelect)); + } + private void plateView_Paint(object sender, PaintEventArgs e) { if (!Point1.IsValid() || !Point2.IsValid())