From 0cae9e88e780d431095da8f63f9a39db146491dd Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Tue, 31 Mar 2026 21:56:53 -0400 Subject: [PATCH] fix: improve program editor formatting, file switching, and entity colors - Replace Program.ToString() with Cincinnati-style formatter (spaced coordinates, blank lines between contours, trailing zero suppression) - Fix empty Program tab when switching files while on the tab by loading immediately instead of only marking stale - Set contour-type colors on entities at load time and restore base colors before selection highlight to prevent color bleed to CAD view Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest/Controls/ProgramEditorControl.cs | 71 ++++++++++++++++++++--- OpenNest/Forms/CadConverterForm.cs | 38 +++++++++--- 2 files changed, 91 insertions(+), 18 deletions(-) diff --git a/OpenNest/Controls/ProgramEditorControl.cs b/OpenNest/Controls/ProgramEditorControl.cs index 48ffa74..d58f7ed 100644 --- a/OpenNest/Controls/ProgramEditorControl.cs +++ b/OpenNest/Controls/ProgramEditorControl.cs @@ -44,6 +44,15 @@ namespace OpenNest.Controls } contours = ContourInfo.Classify(shapes); + + // Assign contour-type colors once so the CAD view also picks them up + foreach (var contour in contours) + { + var color = GetContourColor(contour.Type, false); + foreach (var entity in contour.Shape.Entities) + entity.Color = color; + } + Program = BuildProgram(contours); isDirty = false; isLoaded = true; @@ -86,7 +95,43 @@ namespace OpenNest.Controls private void UpdateGcodeText() { - gcodeEditor.Text = Program?.ToString() ?? string.Empty; + gcodeEditor.Text = Program != null ? FormatProgram(Program) : string.Empty; + } + + private static string FormatProgram(Program pgm) + { + var sb = new System.Text.StringBuilder(); + sb.AppendLine(pgm.Mode == Mode.Absolute ? "G90" : "G91"); + + var lastWasRapid = false; + foreach (var code in pgm.Codes) + { + if (code is RapidMove rapid) + { + if (!lastWasRapid && sb.Length > 0) + sb.AppendLine(); + sb.AppendLine($"G00 X{FormatCoord(rapid.EndPoint.X)} Y{FormatCoord(rapid.EndPoint.Y)}"); + lastWasRapid = true; + } + else if (code is ArcMove arc) + { + var g = arc.Rotation == RotationType.CW ? "G02" : "G03"; + sb.AppendLine($"{g} X{FormatCoord(arc.EndPoint.X)} Y{FormatCoord(arc.EndPoint.Y)} I{FormatCoord(arc.CenterPoint.X)} J{FormatCoord(arc.CenterPoint.Y)}"); + lastWasRapid = false; + } + else if (code is LinearMove linear) + { + sb.AppendLine($"G01 X{FormatCoord(linear.EndPoint.X)} Y{FormatCoord(linear.EndPoint.Y)}"); + lastWasRapid = false; + } + } + + return sb.ToString(); + } + + private static string FormatCoord(double value) + { + return System.Math.Round(value, 4).ToString("0.####", System.Globalization.CultureInfo.InvariantCulture); } private void RefreshPreview() @@ -94,20 +139,28 @@ namespace OpenNest.Controls preview.ClearPenCache(); preview.Entities.Clear(); + // Restore base colors first (undo any selection highlight) + foreach (var contour in contours) + { + var baseColor = GetContourColor(contour.Type, false); + foreach (var entity in contour.Shape.Entities) + entity.Color = baseColor; + } + for (var i = 0; i < contours.Count; i++) { var contour = contours[i]; var selected = contourList.SelectedIndices.Contains(i); - var color = GetContourColor(contour.Type, selected); - - foreach (var entity in contour.Shape.Entities) - { - entity.Color = color; - preview.Entities.Add(entity); - } if (selected) - AddDirectionArrows(contour.Shape, color); + { + var selColor = GetContourColor(contour.Type, true); + foreach (var entity in contour.Shape.Entities) + entity.Color = selColor; + AddDirectionArrows(contour.Shape, selColor); + } + + preview.Entities.AddRange(contour.Shape.Entities); } preview.ZoomToFit(); diff --git a/OpenNest/Forms/CadConverterForm.cs b/OpenNest/Forms/CadConverterForm.cs index 69a8662..5b0c394 100644 --- a/OpenNest/Forms/CadConverterForm.cs +++ b/OpenNest/Forms/CadConverterForm.cs @@ -137,7 +137,10 @@ namespace OpenNest.Forms LoadItem(item); staleProgram = true; - programEditor.Clear(); + if (viewTabs.SelectedTab == tabProgram) + LoadProgramTab(); + else + programEditor.Clear(); } private void LoadItem(FileListItem item) @@ -240,17 +243,34 @@ namespace OpenNest.Forms private void OnViewTabChanged(object sender, EventArgs e) { if (viewTabs.SelectedTab == tabProgram && staleProgram) + LoadProgramTab(); + } + + private void LoadProgramTab() + { + var item = CurrentItem; + if (item == null) { - var item = CurrentItem; - if (item == null) return; - - var entities = item.Entities.Where(en => en.Layer.IsVisible && en.IsVisible).ToList(); - if (entities.Count == 0) return; - - var normalized = ShapeProfile.NormalizeEntities(entities); - programEditor.LoadEntities(normalized); + programEditor.Clear(); staleProgram = false; + return; } + + var entities = item.Entities.Where(en => en.Layer.IsVisible && en.IsVisible).ToList(); + if (entities.Count == 0) + { + programEditor.Clear(); + staleProgram = false; + return; + } + + var normalized = ShapeProfile.NormalizeEntities(entities); + programEditor.LoadEntities(normalized); + staleProgram = false; + + // Refresh CAD view to show contour-type colors + entityView1.ClearPenCache(); + entityView1.Invalidate(); } private void OnBendLineSelected(object sender, int index)