From 9773449563f3d167f80c6367f82c5bf987637701 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Fri, 13 Mar 2026 08:39:30 -0400 Subject: [PATCH] feat(ui): add FillWithProgress to PlateView, use from ActionClone Moves async fill+progress orchestration into PlateView so ActionClone's Ctrl+F fill shows the NestProgressForm dialog. Co-Authored-By: Claude Opus 4.6 --- OpenNest/Actions/ActionClone.cs | 13 ++------- OpenNest/Controls/PlateView.cs | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/OpenNest/Actions/ActionClone.cs b/OpenNest/Actions/ActionClone.cs index f3cd60d..9abb583 100644 --- a/OpenNest/Actions/ActionClone.cs +++ b/OpenNest/Actions/ActionClone.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Windows.Forms; using OpenNest.Controls; @@ -171,19 +170,14 @@ namespace OpenNest.Actions private void Fill() { - var sw = Stopwatch.StartNew(); - var plate = plateView.Plate; - var engine = new NestEngine(plate); var groupParts = parts.Select(p => p.BasePart).ToList(); var bounds = plate.WorkArea(); if (plate.Parts.Count == 0) { - engine.Fill(groupParts); - sw.Stop(); - plateView.Status = $"Fill: {plate.Parts.Count} parts in {sw.ElapsedMilliseconds} ms"; + plateView.FillWithProgress(groupParts, bounds); return; } @@ -202,10 +196,7 @@ namespace OpenNest.Actions if (bestArea == Box.Empty) return; - var before = plate.Parts.Count; - engine.Fill(groupParts, bestArea); - sw.Stop(); - plateView.Status = $"Fill: {plate.Parts.Count - before} parts in {sw.ElapsedMilliseconds} ms"; + plateView.FillWithProgress(groupParts, bestArea); } } } diff --git a/OpenNest/Controls/PlateView.cs b/OpenNest/Controls/PlateView.cs index 7b17514..368e2aa 100644 --- a/OpenNest/Controls/PlateView.cs +++ b/OpenNest/Controls/PlateView.cs @@ -2,14 +2,18 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; using OpenNest.Actions; using OpenNest.CNC; using OpenNest.Collections; using OpenNest.Converters; +using OpenNest.Forms; using OpenNest.Geometry; using OpenNest.Math; using Action = OpenNest.Actions.Action; @@ -834,6 +838,50 @@ namespace OpenNest.Controls return count; } + public async void FillWithProgress(List groupParts, Box workArea) + { + var sw = Stopwatch.StartNew(); + var cts = new CancellationTokenSource(); + var progressForm = new NestProgressForm(cts, showPlateRow: false); + + var progress = new Progress(p => + { + progressForm.UpdateProgress(p); + SetTemporaryParts(p.BestParts); + }); + + progressForm.Show(FindForm()); + + try + { + var engine = new NestEngine(Plate); + var parts = await Task.Run(() => + engine.Fill(groupParts, workArea, progress, cts.Token)); + + if (parts.Count > 0) + { + AcceptTemporaryParts(); + sw.Stop(); + Status = $"Fill: {parts.Count} parts in {sw.ElapsedMilliseconds} ms"; + } + else + { + ClearTemporaryParts(); + } + + progressForm.ShowCompleted(); + } + catch (Exception) + { + ClearTemporaryParts(); + } + finally + { + progressForm.Close(); + cts.Dispose(); + } + } + public void RemoveSelectedParts() { foreach (var part in SelectedParts)