fix(cutting-ui): navigate selected source plate in planner

This commit is contained in:
aj committed 2026-10-11 22:45:54 -04:00
1 parent d6ae706098
commit 9bd5d0dfa7
3 files changed
+61 -7

No files matched your search

@@ -175,6 +175,7 @@ public class CuttingInspectionPanelTests
Assert.False(Field<Button>(panel, "applyButton").Enabled);
Assert.True(editor.PlateView.HasProposalDisplay);
Field<Button>(panel, "nextButton").PerformClick();
Assert.Same(second, editor.PlateView.Plate); // Refusal shows the requested live plate, not the opening plate.
Assert.False(editor.PlateView.HasProposalDisplay);
Assert.Contains("no current preview", Field<Label>(panel, "previewLabel").Text);
var grid = Field<DataGridView>(panel, "warningGrid");
@@ -188,6 +189,40 @@ public class CuttingInspectionPanelTests
Assert.Same(original, editor.PlateView.Plate);
});
[Fact]
public void NextAndPreviousShowTheSelectedReadyPlateNotTheOpeningPlate() => RunSta(() =>
{
using var editor = Editor();
var first = editor.Nest.Plates[0];
var second = editor.Nest.Plates[^1]; // Fill the managed sentinel.
second.Size = new OpenNest.Geometry.Size(100, 100);
second.Parts.Add(Square("other plate", 40));
editor.Show();
editor.PlateManager.LoadAt(0);
OpenAll(editor);
var panel = editor.CuttingInspection!;
PumpUntil(() => panel.Proposal != null && !panel.IsPlanning);
Assert.Equal(2, panel.Proposal.Plates.Count);
Assert.Same(first, editor.PlateView.Plate);
Assert.True(editor.PlateView.HasProposalDisplay);
Assert.Contains(editor.PlateView.DisplayPlate.Parts, part => part.BaseDrawing.Name == "near");
Field<Button>(panel, "nextButton").PerformClick();
Assert.Same(second, editor.PlateView.Plate);
Assert.True(editor.PlateView.HasProposalDisplay);
Assert.NotSame(second, editor.PlateView.DisplayPlate);
Assert.Single(editor.PlateView.DisplayPlate.Parts);
Assert.Equal("other plate", editor.PlateView.DisplayPlate.Parts[0].BaseDrawing.Name);
Assert.Contains("Plate 2", Field<Label>(panel, "previewLabel").Text);
Field<Button>(panel, "previousButton").PerformClick();
Assert.Same(first, editor.PlateView.Plate);
Assert.True(editor.PlateView.HasProposalDisplay);
Assert.Contains(editor.PlateView.DisplayPlate.Parts, part => part.BaseDrawing.Name == "near");
panel.RequestClose();
Assert.Same(first, editor.PlateView.Plate);
});
[Fact]
public void WarningAcceptanceResetsOnReplanAndSettingsOrderChange() => RunSta(() =>
{
+18 -1
View File
@@ -436,7 +436,7 @@ internal sealed class CuttingInspectionPanel : UserControl
private bool IsPreviewCurrent()
{
if (!closed && !invalidated && ReferenceEquals(view.Plate, plate)
if (!closed && !invalidated && ReferenceEquals(view.Plate, plates[selectedPlate])
&& inspection.RefreshPreview(selectedPlate) != null)
return true;
invalidated = true;
@@ -454,6 +454,23 @@ internal sealed class CuttingInspectionPanel : UserControl
selectedPlate = index;
view.ClearProposalDisplay();
view.ClearValidationFinding();
// Keep the authoritative editor plate on the selected live source even when
// no safe detached proposal can be rendered for that plate.
var sourceIndex = editor.Nest.Plates.IndexOf(plates[index]);
if (sourceIndex < 0)
{
ClearResult();
resultLabel.Text = "The selected plate changed after capture. Replan to continue.";
return;
}
if (!ReferenceEquals(view.Plate, plates[index]))
editor.PlateManager.LoadAt(sourceIndex);
if (!ReferenceEquals(view.Plate, plates[index]))
{
ClearResult();
resultLabel.Text = "The selected plate is no longer current. Replan to continue.";
return;
}
if (plates[index].Parts.Count == 0)
{
preview = null;
+8 -6
View File
@@ -399,12 +399,14 @@ panel is wired in the editor. Non-editor callers still use the shared analyzer.
- The docked panel keeps the batch outcome and plate headings above a
read-only, unsorted warning grid with Plate, source Part, With, and full finding text. Every
overlap issue/pair and every planner finding has its own selectable row, including findings
hidden by the compact blocked-plate summary. Selecting a row switches to that plate's
detached preview and zooms to the affected part extent (or both parts for a pair), mapping
source positions to the proposed cutting order. This is not an exact contact marker: most
findings do not carry a geometric witness. If a plate cannot produce a current, supported
preview, no geometry is cloned or focused; the row still identifies its source part in the
editor. Replanning, cancellation and stale Apply clear old warning targets.
hidden by the compact blocked-plate summary. **Previous**/**Next** and warning selection
navigate the editor to that plate's live source sheet, then display its detached proposal
when available. Warning selection zooms to the affected part extent (or both parts for a
pair), mapping source positions to proposed cutting order. This is not an exact contact
marker: most findings do not carry a geometric witness. If a plate cannot produce a
current, supported proposal preview, its own live sheet remains visible; no unsupported
geometry is cloned or focused. Replanning, cancellation and stale Apply clear old warning
targets.
- The summary lists every plate: ready plates with part counts and rapid travel, others
with their status and findings. Unverified proposals retain every overlap and route
warning in the selectable grid before the acceptance checkbox is used; they do