fix: improve fill progress reporting and engine pipeline

- Strategies now promote results to IsOverallBest when they beat the
  pipeline best, so the UI updates immediately on improvement rather
  than waiting for each phase to complete
- PlateView only updates the main view on overall-best results, fixing
  intermediate angle-sweep layouts leaking to the plate display
- Skip Row/Column strategies for rectangle parts (redundant with Linear)
- Intercept Escape key at MainForm level via ProcessCmdKey so it always
  reaches the active PlateView regardless of focus state
- Restore keyboard focus to PlateView after fill progress form closes
- Remnant engines use SelectBestFitPair for orientation-aware pair
  selection; DefaultNestEngine tries both landscape and portrait pairs
- RemnantFiller preserves more parts during topmost-part removal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-05 18:30:07 -04:00
parent 37130e8a28
commit f78cc78a65
10 changed files with 135 additions and 23 deletions

View File

@@ -412,6 +412,16 @@ namespace OpenNest.Controls
}
}
public void ProcessEscapeKey()
{
if (currentAction.IsBusy())
currentAction.CancelAction();
else if (currentAction is ActionSelect && previousAction != null)
RestorePreviousAction();
else
SetAction(typeof(ActionSelect));
}
protected override bool ProcessDialogKey(Keys keyData)
{
// Only handle TAB, RETURN, ESC, and ARROW KEYS here.
@@ -420,12 +430,7 @@ namespace OpenNest.Controls
switch (keyData)
{
case Keys.Escape:
if (currentAction.IsBusy())
currentAction.CancelAction();
else if (currentAction is ActionSelect && previousAction != null)
RestorePreviousAction();
else
SetAction(typeof(ActionSelect));
ProcessEscapeKey();
break;
case Keys.Left:
@@ -791,9 +796,11 @@ namespace OpenNest.Controls
progressForm.UpdateProgress(p);
if (p.IsOverallBest)
{
progressForm.UpdatePreview(p.BestParts);
SetActiveParts(p.BestParts);
}
SetActiveParts(p.BestParts);
ActiveWorkArea = p.ActiveWorkArea;
});
@@ -837,6 +844,7 @@ namespace OpenNest.Controls
ActiveWorkArea = null;
progressForm.Close();
cts.Dispose();
Focus();
}
}

View File

@@ -29,6 +29,17 @@ namespace OpenNest.Forms
private const float ZoomInFactor = 1.5f;
private const float ZoomOutFactor = 1.0f / ZoomInFactor;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Escape && activeForm?.PlateView != null)
{
activeForm.PlateView.ProcessEscapeKey();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
public MainForm()
{
InitializeComponent();