From 287023d802048f733f3d66e24dd8cb8163caff29 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Thu, 2 Apr 2026 08:38:14 -0400 Subject: [PATCH] feat: add syntax highlighting to gcode editor Switch gcodeEditor from TextBox to RichTextBox and colorize G-code tokens: rapids (amber), linear cuts (green), arcs (blue), comments (dim gray), and mode codes (purple). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Controls/ProgramEditorControl.Designer.cs | 7 ++- OpenNest/Controls/ProgramEditorControl.cs | 44 ++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/OpenNest/Controls/ProgramEditorControl.Designer.cs b/OpenNest/Controls/ProgramEditorControl.Designer.cs index 2ca3e05..71060d4 100644 --- a/OpenNest/Controls/ProgramEditorControl.Designer.cs +++ b/OpenNest/Controls/ProgramEditorControl.Designer.cs @@ -28,7 +28,7 @@ namespace OpenNest.Controls rightSplit = new System.Windows.Forms.SplitContainer(); preview = new EntityView(); editorPanel = new System.Windows.Forms.Panel(); - gcodeEditor = new System.Windows.Forms.TextBox(); + gcodeEditor = new System.Windows.Forms.RichTextBox(); editorToolbar = new System.Windows.Forms.Panel(); lblGcode = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)mainSplit).BeginInit(); @@ -185,10 +185,9 @@ namespace OpenNest.Controls gcodeEditor.Font = new System.Drawing.Font("Consolas", 10F); gcodeEditor.ForeColor = System.Drawing.Color.FromArgb(180, 200, 180); gcodeEditor.Location = new System.Drawing.Point(0, 30); - gcodeEditor.Multiline = true; gcodeEditor.Name = "gcodeEditor"; - gcodeEditor.ScrollBars = System.Windows.Forms.ScrollBars.Both; gcodeEditor.ReadOnly = true; + gcodeEditor.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Both; gcodeEditor.Size = new System.Drawing.Size(260, 470); gcodeEditor.TabIndex = 1; gcodeEditor.WordWrap = false; @@ -251,7 +250,7 @@ namespace OpenNest.Controls private System.Windows.Forms.Panel editorPanel; private System.Windows.Forms.Panel editorToolbar; private System.Windows.Forms.Label lblGcode; - private System.Windows.Forms.TextBox gcodeEditor; + private System.Windows.Forms.RichTextBox gcodeEditor; private System.Windows.Forms.ContextMenuStrip contourMenu; private System.Windows.Forms.ToolStripMenuItem menuReverse; private System.Windows.Forms.ToolStripMenuItem menuMoveUp; diff --git a/OpenNest/Controls/ProgramEditorControl.cs b/OpenNest/Controls/ProgramEditorControl.cs index d6d037f..0941463 100644 --- a/OpenNest/Controls/ProgramEditorControl.cs +++ b/OpenNest/Controls/ProgramEditorControl.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using System.Text.RegularExpressions; using System.Windows.Forms; namespace OpenNest.Controls @@ -90,7 +91,9 @@ namespace OpenNest.Controls private void UpdateGcodeText() { - gcodeEditor.Text = Program != null ? FormatProgram(Program, contours) : string.Empty; + var text = Program != null ? FormatProgram(Program, contours) : string.Empty; + gcodeEditor.Text = text; + ApplyHighlighting(); } private static string FormatProgram(Program pgm, List contours) @@ -142,6 +145,45 @@ namespace OpenNest.Controls return System.Math.Round(value, 4).ToString("0.####", System.Globalization.CultureInfo.InvariantCulture); } + private void ApplyHighlighting() + { + var text = gcodeEditor.Text; + if (string.IsNullOrEmpty(text)) return; + + gcodeEditor.SuspendLayout(); + + var rapidColor = Color.FromArgb(230, 180, 80); + var linearColor = Color.FromArgb(130, 200, 140); + var arcColor = Color.FromArgb(120, 160, 255); + var commentColor = Color.FromArgb(120, 120, 140); + var modeColor = Color.FromArgb(200, 140, 220); + var coordColor = Color.FromArgb(180, 200, 180); + + gcodeEditor.SelectAll(); + gcodeEditor.SelectionColor = coordColor; + + var rules = new (Regex pattern, Color color)[] + { + (new Regex(@"^;.*$", RegexOptions.Multiline), commentColor), + (new Regex(@"^G9[01]\b", RegexOptions.Multiline), modeColor), + (new Regex(@"^G00\b", RegexOptions.Multiline), rapidColor), + (new Regex(@"^G01\b", RegexOptions.Multiline), linearColor), + (new Regex(@"^G0[23]\b", RegexOptions.Multiline), arcColor), + }; + + foreach (var (pattern, color) in rules) + { + foreach (Match match in pattern.Matches(text)) + { + gcodeEditor.Select(match.Index, match.Length); + gcodeEditor.SelectionColor = color; + } + } + + gcodeEditor.Select(0, 0); + gcodeEditor.ResumeLayout(); + } + private void RefreshPreview() { preview.ClearPenCache();