refactor: make ProgramEditorControl gcode editor read-only with contour comments
Remove the Apply button and OnApplyClicked handler since the gcode editor is now read-only. Add contour label comments (e.g. "; Hole 1 (CCW)") to the formatted gcode output so users can see which feature each group of codes belongs to. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
17
OpenNest/Controls/ProgramEditorControl.Designer.cs
generated
17
OpenNest/Controls/ProgramEditorControl.Designer.cs
generated
@@ -30,7 +30,6 @@ namespace OpenNest.Controls
|
|||||||
editorPanel = new System.Windows.Forms.Panel();
|
editorPanel = new System.Windows.Forms.Panel();
|
||||||
gcodeEditor = new System.Windows.Forms.TextBox();
|
gcodeEditor = new System.Windows.Forms.TextBox();
|
||||||
editorToolbar = new System.Windows.Forms.Panel();
|
editorToolbar = new System.Windows.Forms.Panel();
|
||||||
applyButton = new System.Windows.Forms.Button();
|
|
||||||
lblGcode = new System.Windows.Forms.Label();
|
lblGcode = new System.Windows.Forms.Label();
|
||||||
((System.ComponentModel.ISupportInitialize)mainSplit).BeginInit();
|
((System.ComponentModel.ISupportInitialize)mainSplit).BeginInit();
|
||||||
mainSplit.Panel1.SuspendLayout();
|
mainSplit.Panel1.SuspendLayout();
|
||||||
@@ -189,6 +188,7 @@ namespace OpenNest.Controls
|
|||||||
gcodeEditor.Multiline = true;
|
gcodeEditor.Multiline = true;
|
||||||
gcodeEditor.Name = "gcodeEditor";
|
gcodeEditor.Name = "gcodeEditor";
|
||||||
gcodeEditor.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
gcodeEditor.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||||
|
gcodeEditor.ReadOnly = true;
|
||||||
gcodeEditor.Size = new System.Drawing.Size(260, 470);
|
gcodeEditor.Size = new System.Drawing.Size(260, 470);
|
||||||
gcodeEditor.TabIndex = 1;
|
gcodeEditor.TabIndex = 1;
|
||||||
gcodeEditor.WordWrap = false;
|
gcodeEditor.WordWrap = false;
|
||||||
@@ -196,7 +196,6 @@ namespace OpenNest.Controls
|
|||||||
// editorToolbar
|
// editorToolbar
|
||||||
//
|
//
|
||||||
editorToolbar.BackColor = System.Drawing.Color.FromArgb(245, 245, 245);
|
editorToolbar.BackColor = System.Drawing.Color.FromArgb(245, 245, 245);
|
||||||
editorToolbar.Controls.Add(applyButton);
|
|
||||||
editorToolbar.Controls.Add(lblGcode);
|
editorToolbar.Controls.Add(lblGcode);
|
||||||
editorToolbar.Dock = System.Windows.Forms.DockStyle.Top;
|
editorToolbar.Dock = System.Windows.Forms.DockStyle.Top;
|
||||||
editorToolbar.Location = new System.Drawing.Point(0, 0);
|
editorToolbar.Location = new System.Drawing.Point(0, 0);
|
||||||
@@ -204,18 +203,7 @@ namespace OpenNest.Controls
|
|||||||
editorToolbar.Padding = new System.Windows.Forms.Padding(6, 4, 6, 4);
|
editorToolbar.Padding = new System.Windows.Forms.Padding(6, 4, 6, 4);
|
||||||
editorToolbar.Size = new System.Drawing.Size(260, 30);
|
editorToolbar.Size = new System.Drawing.Size(260, 30);
|
||||||
editorToolbar.TabIndex = 0;
|
editorToolbar.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// applyButton
|
|
||||||
//
|
|
||||||
applyButton.Dock = System.Windows.Forms.DockStyle.Right;
|
|
||||||
applyButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
||||||
applyButton.Font = new System.Drawing.Font("Segoe UI", 9F);
|
|
||||||
applyButton.Location = new System.Drawing.Point(184, 4);
|
|
||||||
applyButton.Name = "applyButton";
|
|
||||||
applyButton.Size = new System.Drawing.Size(70, 22);
|
|
||||||
applyButton.TabIndex = 1;
|
|
||||||
applyButton.Text = "Apply";
|
|
||||||
//
|
|
||||||
// lblGcode
|
// lblGcode
|
||||||
//
|
//
|
||||||
lblGcode.AutoSize = true;
|
lblGcode.AutoSize = true;
|
||||||
@@ -263,7 +251,6 @@ namespace OpenNest.Controls
|
|||||||
private System.Windows.Forms.Panel editorPanel;
|
private System.Windows.Forms.Panel editorPanel;
|
||||||
private System.Windows.Forms.Panel editorToolbar;
|
private System.Windows.Forms.Panel editorToolbar;
|
||||||
private System.Windows.Forms.Label lblGcode;
|
private System.Windows.Forms.Label lblGcode;
|
||||||
private System.Windows.Forms.Button applyButton;
|
|
||||||
private System.Windows.Forms.TextBox gcodeEditor;
|
private System.Windows.Forms.TextBox gcodeEditor;
|
||||||
private System.Windows.Forms.ContextMenuStrip contourMenu;
|
private System.Windows.Forms.ContextMenuStrip contourMenu;
|
||||||
private System.Windows.Forms.ToolStripMenuItem menuReverse;
|
private System.Windows.Forms.ToolStripMenuItem menuReverse;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using OpenNest.CNC;
|
using OpenNest.CNC;
|
||||||
using OpenNest.Converters;
|
using OpenNest.Converters;
|
||||||
using OpenNest.Geometry;
|
using OpenNest.Geometry;
|
||||||
using OpenNest.IO;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
@@ -29,7 +28,6 @@ namespace OpenNest.Controls
|
|||||||
menuMoveDown.Click += OnMoveDownClicked;
|
menuMoveDown.Click += OnMoveDownClicked;
|
||||||
menuSequence.Click += OnSequenceClicked;
|
menuSequence.Click += OnSequenceClicked;
|
||||||
contourMenu.Opening += OnContourMenuOpening;
|
contourMenu.Opening += OnContourMenuOpening;
|
||||||
applyButton.Click += OnApplyClicked;
|
|
||||||
preview.PaintOverlay = OnPreviewPaintOverlay;
|
preview.PaintOverlay = OnPreviewPaintOverlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,34 +90,47 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
private void UpdateGcodeText()
|
private void UpdateGcodeText()
|
||||||
{
|
{
|
||||||
gcodeEditor.Text = Program != null ? FormatProgram(Program) : string.Empty;
|
gcodeEditor.Text = Program != null ? FormatProgram(Program, contours) : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string FormatProgram(Program pgm)
|
private static string FormatProgram(Program pgm, List<ContourInfo> contours)
|
||||||
{
|
{
|
||||||
var sb = new System.Text.StringBuilder();
|
var sb = new System.Text.StringBuilder();
|
||||||
sb.AppendLine(pgm.Mode == Mode.Absolute ? "G90" : "G91");
|
sb.AppendLine(pgm.Mode == Mode.Absolute ? "G90" : "G91");
|
||||||
|
|
||||||
var lastWasRapid = false;
|
var codeIndex = 0;
|
||||||
foreach (var code in pgm.Codes)
|
var codes = pgm.Codes;
|
||||||
|
|
||||||
|
foreach (var contour in contours)
|
||||||
{
|
{
|
||||||
if (code is RapidMove rapid)
|
var sub = ConvertGeometry.ToProgram(contour.Shape);
|
||||||
|
if (sub == null) continue;
|
||||||
|
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.AppendLine($"; {contour.Label} ({contour.DirectionLabel})");
|
||||||
|
|
||||||
|
var lastWasRapid = false;
|
||||||
|
for (var i = 0; i < sub.Length && codeIndex < codes.Count; i++, codeIndex++)
|
||||||
{
|
{
|
||||||
if (!lastWasRapid && sb.Length > 0)
|
var code = codes[codeIndex];
|
||||||
sb.AppendLine();
|
if (code is RapidMove rapid)
|
||||||
sb.AppendLine($"G00 X{FormatCoord(rapid.EndPoint.X)} Y{FormatCoord(rapid.EndPoint.Y)}");
|
{
|
||||||
lastWasRapid = true;
|
if (!lastWasRapid)
|
||||||
}
|
sb.AppendLine();
|
||||||
else if (code is ArcMove arc)
|
sb.AppendLine($"G00 X{FormatCoord(rapid.EndPoint.X)} Y{FormatCoord(rapid.EndPoint.Y)}");
|
||||||
{
|
lastWasRapid = true;
|
||||||
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)}");
|
else if (code is ArcMove arc)
|
||||||
lastWasRapid = false;
|
{
|
||||||
}
|
var g = arc.Rotation == RotationType.CW ? "G02" : "G03";
|
||||||
else if (code is LinearMove linear)
|
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;
|
||||||
sb.AppendLine($"G01 X{FormatCoord(linear.EndPoint.X)} Y{FormatCoord(linear.EndPoint.Y)}");
|
}
|
||||||
lastWasRapid = false;
|
else if (code is LinearMove linear)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"G01 X{FormatCoord(linear.EndPoint.X)} Y{FormatCoord(linear.EndPoint.Y)}");
|
||||||
|
lastWasRapid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,50 +429,5 @@ namespace OpenNest.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnApplyClicked(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var text = gcodeEditor.Text;
|
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
|
||||||
{
|
|
||||||
MessageBox.Show("G-code is empty.", "Apply", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var stream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(text));
|
|
||||||
var reader = new ProgramReader(stream);
|
|
||||||
var parsed = reader.Read();
|
|
||||||
|
|
||||||
if (parsed == null || parsed.Length == 0)
|
|
||||||
{
|
|
||||||
MessageBox.Show("No valid G-code found.", "Apply", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuild shapes from the parsed program
|
|
||||||
var entities = ConvertProgram.ToGeometry(parsed);
|
|
||||||
var shapes = ShapeBuilder.GetShapes(entities);
|
|
||||||
|
|
||||||
if (shapes.Count == 0)
|
|
||||||
{
|
|
||||||
MessageBox.Show("No contours found in parsed G-code.", "Apply", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
contours = ContourInfo.Classify(shapes);
|
|
||||||
Program = parsed;
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
PopulateContourList();
|
|
||||||
RefreshPreview();
|
|
||||||
ProgramChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"Error parsing G-code: {ex.Message}", "Apply",
|
|
||||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user