mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-02 01:11:36 -05:00
fix(plateview): keep nudged clones through dialogs
Windows reposts a mouse move when a dialog opens or closes, so Set Offset Increment threw away arrow-key nudges by snapping the previews back to the cursor. Only a real cursor move now moves them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bbdd51fabc
commit
45f5ce6954
2 files changed
+58
No files matched your search
@@ -74,4 +74,44 @@ public class ActionCloneTests
|
||||
view.SetAction(typeof(ActionSelect));
|
||||
Assert.False(view.ActionHandlesF1);
|
||||
}, TimeSpan.FromMinutes(1), "The STA test did not complete.");
|
||||
|
||||
[Fact]
|
||||
public void ADialogsFakeMouseMoveLeavesNudgedPreviewsInPlace() => StaTestThread.Run(() =>
|
||||
{
|
||||
using var view = new PlateView { Plate = new Plate(48, 96), Size = new System.Drawing.Size(600, 600) };
|
||||
view.ZoomToFit();
|
||||
view.SetAction(typeof(ActionClone), Square("new"));
|
||||
var preview = Assert.Single(view.SelectedParts);
|
||||
MoveMouse(view, new System.Drawing.Point(300, 300));
|
||||
var followed = preview.BasePart.BoundingBox.Location;
|
||||
|
||||
Nudge(view);
|
||||
var nudged = preview.BasePart.BoundingBox.Location;
|
||||
Assert.Equal(followed.X + view.OffsetIncrementDistance, nudged.X, 6);
|
||||
|
||||
// A repost of the last position, with no focus change.
|
||||
MoveMouse(view, new System.Drawing.Point(300, 300));
|
||||
Assert.Equal(nudged, preview.BasePart.BoundingBox.Location);
|
||||
|
||||
// Opening the dialog, then closing it: each post arrives where the cursor rests.
|
||||
var rest = view.PointToClient(Cursor.Position);
|
||||
Raise(view, "OnLostFocus", EventArgs.Empty);
|
||||
MoveMouse(view, rest);
|
||||
Assert.Equal(nudged, preview.BasePart.BoundingBox.Location);
|
||||
|
||||
Raise(view, "OnGotFocus", EventArgs.Empty);
|
||||
MoveMouse(view, rest);
|
||||
Assert.Equal(nudged, preview.BasePart.BoundingBox.Location);
|
||||
|
||||
// The next real move takes the previews back to the cursor.
|
||||
MoveMouse(view, new System.Drawing.Point(rest.X + 20, rest.Y + 20));
|
||||
Assert.NotEqual(nudged, preview.BasePart.BoundingBox.Location);
|
||||
}, TimeSpan.FromMinutes(1), "The STA test did not complete.");
|
||||
|
||||
private static void MoveMouse(PlateView view, System.Drawing.Point point) =>
|
||||
Raise(view, "OnMouseMove", new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
|
||||
|
||||
private static void Nudge(PlateView view) =>
|
||||
typeof(PlateView).GetMethod("ProcessDialogKey", BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||
.Invoke(view, new object[] { Keys.Right });
|
||||
}
|
||||
@@ -16,6 +16,7 @@ namespace OpenNest.Actions
|
||||
private readonly List<Part> sourceParts;
|
||||
|
||||
private double lastScale;
|
||||
private System.Drawing.Point? restingCursor;
|
||||
|
||||
public ActionClone(PlateView plateView, Drawing drawing)
|
||||
: this(plateView, new List<Part> { new Part(drawing) }) { }
|
||||
@@ -27,6 +28,8 @@ namespace OpenNest.Actions
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.Paint += plateView_Paint;
|
||||
plateView.GotFocus += plateView_FocusChanged;
|
||||
plateView.LostFocus += plateView_FocusChanged;
|
||||
|
||||
sourceParts = partsToClone;
|
||||
parts = new List<LayoutPart>();
|
||||
@@ -101,13 +104,24 @@ namespace OpenNest.Actions
|
||||
lastScale = plateView.ViewScale;
|
||||
}
|
||||
|
||||
// Windows posts a mouse move when a dialog opens or closes, though the mouse stayed
|
||||
// put. Following it would throw away arrow-key nudges, so only a real move counts.
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Location == restingCursor)
|
||||
return;
|
||||
|
||||
restingCursor = e.Location;
|
||||
var offset = plateView.CurrentPoint - parts.GetBoundingBox().Location;
|
||||
parts.ForEach(p => p.Offset(offset));
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
// The cursor may have been moved to the dialog's OK button, so measure the rest
|
||||
// position afresh whenever focus leaves or returns.
|
||||
private void plateView_FocusChanged(object sender, System.EventArgs e) =>
|
||||
restingCursor = plateView.PointToClient(Cursor.Position);
|
||||
|
||||
public override bool SurvivesPlateChange => true;
|
||||
|
||||
// F1 sets the part in place, as it always has; help stays on the Help menu.
|
||||
@@ -121,6 +135,8 @@ namespace OpenNest.Actions
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.Paint += plateView_Paint;
|
||||
plateView.GotFocus += plateView_FocusChanged;
|
||||
plateView.LostFocus += plateView_FocusChanged;
|
||||
|
||||
SelectPreviews();
|
||||
}
|
||||
@@ -131,6 +147,8 @@ namespace OpenNest.Actions
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
plateView.GotFocus -= plateView_FocusChanged;
|
||||
plateView.LostFocus -= plateView_FocusChanged;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.Invalidate();
|
||||
|
||||
Reference in new issue
Block a user