feat: add CuttingParametersForm dialog for lead-in/lead-out configuration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 13:36:41 -04:00
parent ab4f806820
commit 7f8c708d3f
2 changed files with 503 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
namespace OpenNest.Forms
{
partial class CuttingParametersForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabControl = new System.Windows.Forms.TabControl();
this.tabExternal = new System.Windows.Forms.TabPage();
this.tabInternal = new System.Windows.Forms.TabPage();
this.tabArcCircle = new System.Windows.Forms.TabPage();
this.acceptButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.bottomPanel = new OpenNest.Controls.BottomPanel();
this.tabControl.SuspendLayout();
this.bottomPanel.SuspendLayout();
this.SuspendLayout();
//
// tabControl
//
this.tabControl.Controls.Add(this.tabExternal);
this.tabControl.Controls.Add(this.tabInternal);
this.tabControl.Controls.Add(this.tabArcCircle);
this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl.Location = new System.Drawing.Point(0, 0);
this.tabControl.Margin = new System.Windows.Forms.Padding(4);
this.tabControl.Name = "tabControl";
this.tabControl.SelectedIndex = 0;
this.tabControl.Size = new System.Drawing.Size(368, 290);
this.tabControl.TabIndex = 0;
//
// tabExternal
//
this.tabExternal.Location = new System.Drawing.Point(4, 25);
this.tabExternal.Margin = new System.Windows.Forms.Padding(4);
this.tabExternal.Name = "tabExternal";
this.tabExternal.Padding = new System.Windows.Forms.Padding(8);
this.tabExternal.Size = new System.Drawing.Size(360, 261);
this.tabExternal.TabIndex = 0;
this.tabExternal.Text = "External";
this.tabExternal.UseVisualStyleBackColor = true;
//
// tabInternal
//
this.tabInternal.Location = new System.Drawing.Point(4, 25);
this.tabInternal.Margin = new System.Windows.Forms.Padding(4);
this.tabInternal.Name = "tabInternal";
this.tabInternal.Padding = new System.Windows.Forms.Padding(8);
this.tabInternal.Size = new System.Drawing.Size(360, 261);
this.tabInternal.TabIndex = 1;
this.tabInternal.Text = "Internal";
this.tabInternal.UseVisualStyleBackColor = true;
//
// tabArcCircle
//
this.tabArcCircle.Location = new System.Drawing.Point(4, 25);
this.tabArcCircle.Margin = new System.Windows.Forms.Padding(4);
this.tabArcCircle.Name = "tabArcCircle";
this.tabArcCircle.Padding = new System.Windows.Forms.Padding(8);
this.tabArcCircle.Size = new System.Drawing.Size(360, 261);
this.tabArcCircle.TabIndex = 2;
this.tabArcCircle.Text = "Arc / Circle";
this.tabArcCircle.UseVisualStyleBackColor = true;
//
// acceptButton
//
this.acceptButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.acceptButton.DialogResult = System.Windows.Forms.DialogResult.OK;
this.acceptButton.Location = new System.Drawing.Point(165, 11);
this.acceptButton.Margin = new System.Windows.Forms.Padding(4);
this.acceptButton.Name = "acceptButton";
this.acceptButton.Size = new System.Drawing.Size(90, 28);
this.acceptButton.TabIndex = 8;
this.acceptButton.Text = "OK";
this.acceptButton.UseVisualStyleBackColor = true;
//
// cancelButton
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(263, 11);
this.cancelButton.Margin = new System.Windows.Forms.Padding(4);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(90, 28);
this.cancelButton.TabIndex = 9;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
//
// bottomPanel
//
this.bottomPanel.Controls.Add(this.acceptButton);
this.bottomPanel.Controls.Add(this.cancelButton);
this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.bottomPanel.Location = new System.Drawing.Point(0, 290);
this.bottomPanel.Name = "bottomPanel";
this.bottomPanel.Size = new System.Drawing.Size(368, 50);
this.bottomPanel.TabIndex = 1;
//
// CuttingParametersForm
//
this.AcceptButton = this.acceptButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(368, 340);
this.Controls.Add(this.tabControl);
this.Controls.Add(this.bottomPanel);
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Margin = new System.Windows.Forms.Padding(4);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "CuttingParametersForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Cutting Parameters";
this.tabControl.ResumeLayout(false);
this.bottomPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl;
private System.Windows.Forms.TabPage tabExternal;
private System.Windows.Forms.TabPage tabInternal;
private System.Windows.Forms.TabPage tabArcCircle;
private Controls.BottomPanel bottomPanel;
private System.Windows.Forms.Button acceptButton;
private System.Windows.Forms.Button cancelButton;
}
}

View File

@@ -0,0 +1,347 @@
using OpenNest.CNC.CuttingStrategy;
using System;
using System.Windows.Forms;
namespace OpenNest.Forms
{
public partial class CuttingParametersForm : Form
{
private static readonly string[] LeadInTypes =
{ "None", "Line", "Arc", "Line + Arc", "Clean Hole", "Line + Line" };
private static readonly string[] LeadOutTypes =
{ "None", "Line", "Arc", "Microtab" };
private ComboBox cboExternalLeadIn, cboExternalLeadOut;
private ComboBox cboInternalLeadIn, cboInternalLeadOut;
private ComboBox cboArcCircleLeadIn, cboArcCircleLeadOut;
private Panel pnlExternalParams, pnlInternalParams, pnlArcCircleParams;
public CuttingParameters Parameters { get; set; } = new CuttingParameters();
public CuttingParametersForm()
{
InitializeComponent();
SetupTab(tabExternal, out cboExternalLeadIn, out cboExternalLeadOut, out pnlExternalParams);
SetupTab(tabInternal, out cboInternalLeadIn, out cboInternalLeadOut, out pnlInternalParams);
SetupTab(tabArcCircle, out cboArcCircleLeadIn, out cboArcCircleLeadOut, out pnlArcCircleParams);
PopulateDropdowns();
cboExternalLeadIn.SelectedIndexChanged += OnLeadInTypeChanged;
cboInternalLeadIn.SelectedIndexChanged += OnLeadInTypeChanged;
cboArcCircleLeadIn.SelectedIndexChanged += OnLeadInTypeChanged;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
LoadFromParameters(Parameters);
}
private static void SetupTab(TabPage tab, out ComboBox leadInCombo,
out ComboBox leadOutCombo, out Panel paramPanel)
{
var y = 12;
var lblLeadIn = new Label
{
Text = "Lead-In:",
Location = new System.Drawing.Point(8, y + 3),
AutoSize = true
};
tab.Controls.Add(lblLeadIn);
leadInCombo = new ComboBox
{
DropDownStyle = ComboBoxStyle.DropDownList,
Location = new System.Drawing.Point(100, y),
Size = new System.Drawing.Size(240, 24)
};
tab.Controls.Add(leadInCombo);
y += 32;
var lblLeadOut = new Label
{
Text = "Lead-Out:",
Location = new System.Drawing.Point(8, y + 3),
AutoSize = true
};
tab.Controls.Add(lblLeadOut);
leadOutCombo = new ComboBox
{
DropDownStyle = ComboBoxStyle.DropDownList,
Location = new System.Drawing.Point(100, y),
Size = new System.Drawing.Size(240, 24)
};
tab.Controls.Add(leadOutCombo);
y += 40;
paramPanel = new Panel
{
Location = new System.Drawing.Point(8, y),
Size = new System.Drawing.Size(332, 170),
AutoScroll = true
};
tab.Controls.Add(paramPanel);
}
private void PopulateDropdowns()
{
foreach (var combo in new[] { cboExternalLeadIn, cboInternalLeadIn, cboArcCircleLeadIn })
{
combo.Items.AddRange(LeadInTypes);
combo.SelectedIndex = 0;
}
foreach (var combo in new[] { cboExternalLeadOut, cboInternalLeadOut, cboArcCircleLeadOut })
{
combo.Items.AddRange(LeadOutTypes);
combo.SelectedIndex = 0;
}
}
private void OnLeadInTypeChanged(object sender, EventArgs e)
{
var combo = (ComboBox)sender;
var panel = GetParamPanel(combo);
if (panel != null)
BuildParamControls(panel, combo.SelectedIndex);
}
private Panel GetParamPanel(ComboBox combo)
{
if (combo == cboExternalLeadIn) return pnlExternalParams;
if (combo == cboInternalLeadIn) return pnlInternalParams;
if (combo == cboArcCircleLeadIn) return pnlArcCircleParams;
return null;
}
private static void BuildParamControls(Panel panel, int typeIndex)
{
panel.Controls.Clear();
var y = 0;
switch (typeIndex)
{
case 1: // Line
AddNumericField(panel, "Length:", 0.25, ref y, "Length");
AddNumericField(panel, "Approach Angle:", 90, ref y, "ApproachAngle");
break;
case 2: // Arc
AddNumericField(panel, "Radius:", 0.25, ref y, "Radius");
break;
case 3: // Line + Arc
AddNumericField(panel, "Line Length:", 0.25, ref y, "LineLength");
AddNumericField(panel, "Arc Radius:", 0.125, ref y, "ArcRadius");
AddNumericField(panel, "Approach Angle:", 135, ref y, "ApproachAngle");
break;
case 4: // Clean Hole
AddNumericField(panel, "Line Length:", 0.25, ref y, "LineLength");
AddNumericField(panel, "Arc Radius:", 0.125, ref y, "ArcRadius");
AddNumericField(panel, "Kerf:", 0.06, ref y, "Kerf");
break;
case 5: // Line + Line
AddNumericField(panel, "Length 1:", 0.25, ref y, "Length1");
AddNumericField(panel, "Angle 1:", 90, ref y, "Angle1");
AddNumericField(panel, "Length 2:", 0.25, ref y, "Length2");
AddNumericField(panel, "Angle 2:", 90, ref y, "Angle2");
break;
}
}
private static void AddNumericField(Panel panel, string label, double defaultValue,
ref int y, string tag)
{
var lbl = new Label
{
Text = label,
Location = new System.Drawing.Point(0, y + 3),
AutoSize = true
};
panel.Controls.Add(lbl);
var nud = new System.Windows.Forms.NumericUpDown
{
Location = new System.Drawing.Point(130, y),
Size = new System.Drawing.Size(120, 22),
DecimalPlaces = 4,
Increment = 0.0625m,
Minimum = 0,
Maximum = 9999,
Value = (decimal)defaultValue,
Tag = tag
};
panel.Controls.Add(nud);
y += 30;
}
private void LoadFromParameters(CuttingParameters p)
{
LoadLeadIn(cboExternalLeadIn, pnlExternalParams, p.ExternalLeadIn);
LoadLeadOut(cboExternalLeadOut, p.ExternalLeadOut);
LoadLeadIn(cboInternalLeadIn, pnlInternalParams, p.InternalLeadIn);
LoadLeadOut(cboInternalLeadOut, p.InternalLeadOut);
LoadLeadIn(cboArcCircleLeadIn, pnlArcCircleParams, p.ArcCircleLeadIn);
LoadLeadOut(cboArcCircleLeadOut, p.ArcCircleLeadOut);
}
private static void LoadLeadIn(ComboBox combo, Panel panel, LeadIn leadIn)
{
switch (leadIn)
{
case LineLeadIn line:
combo.SelectedIndex = 1;
SetParam(panel, "Length", line.Length);
SetParam(panel, "ApproachAngle", line.ApproachAngle);
break;
case ArcLeadIn arc:
combo.SelectedIndex = 2;
SetParam(panel, "Radius", arc.Radius);
break;
case LineArcLeadIn lineArc:
combo.SelectedIndex = 3;
SetParam(panel, "LineLength", lineArc.LineLength);
SetParam(panel, "ArcRadius", lineArc.ArcRadius);
SetParam(panel, "ApproachAngle", lineArc.ApproachAngle);
break;
case CleanHoleLeadIn cleanHole:
combo.SelectedIndex = 4;
SetParam(panel, "LineLength", cleanHole.LineLength);
SetParam(panel, "ArcRadius", cleanHole.ArcRadius);
SetParam(panel, "Kerf", cleanHole.Kerf);
break;
case LineLineLeadIn lineLine:
combo.SelectedIndex = 5;
SetParam(panel, "Length1", lineLine.Length1);
SetParam(panel, "Angle1", lineLine.ApproachAngle1);
SetParam(panel, "Length2", lineLine.Length2);
SetParam(panel, "Angle2", lineLine.ApproachAngle2);
break;
default:
combo.SelectedIndex = 0;
break;
}
}
private static void LoadLeadOut(ComboBox combo, LeadOut leadOut)
{
switch (leadOut)
{
case LineLeadOut _:
combo.SelectedIndex = 1;
break;
case ArcLeadOut _:
combo.SelectedIndex = 2;
break;
case MicrotabLeadOut _:
combo.SelectedIndex = 3;
break;
default:
combo.SelectedIndex = 0;
break;
}
}
public CuttingParameters BuildParameters()
{
var p = new CuttingParameters
{
ExternalLeadIn = BuildLeadIn(cboExternalLeadIn, pnlExternalParams),
ExternalLeadOut = BuildLeadOut(cboExternalLeadOut),
InternalLeadIn = BuildLeadIn(cboInternalLeadIn, pnlInternalParams),
InternalLeadOut = BuildLeadOut(cboInternalLeadOut),
ArcCircleLeadIn = BuildLeadIn(cboArcCircleLeadIn, pnlArcCircleParams),
ArcCircleLeadOut = BuildLeadOut(cboArcCircleLeadOut)
};
return p;
}
private static LeadIn BuildLeadIn(ComboBox combo, Panel panel)
{
switch (combo.SelectedIndex)
{
case 1:
return new LineLeadIn
{
Length = GetParam(panel, "Length", 0.25),
ApproachAngle = GetParam(panel, "ApproachAngle", 90)
};
case 2:
return new ArcLeadIn
{
Radius = GetParam(panel, "Radius", 0.25)
};
case 3:
return new LineArcLeadIn
{
LineLength = GetParam(panel, "LineLength", 0.25),
ArcRadius = GetParam(panel, "ArcRadius", 0.125),
ApproachAngle = GetParam(panel, "ApproachAngle", 135)
};
case 4:
return new CleanHoleLeadIn
{
LineLength = GetParam(panel, "LineLength", 0.25),
ArcRadius = GetParam(panel, "ArcRadius", 0.125),
Kerf = GetParam(panel, "Kerf", 0.06)
};
case 5:
return new LineLineLeadIn
{
Length1 = GetParam(panel, "Length1", 0.25),
ApproachAngle1 = GetParam(panel, "Angle1", 90),
Length2 = GetParam(panel, "Length2", 0.25),
ApproachAngle2 = GetParam(panel, "Angle2", 90)
};
default:
return new NoLeadIn();
}
}
private static LeadOut BuildLeadOut(ComboBox combo)
{
switch (combo.SelectedIndex)
{
case 1:
return new LineLeadOut { Length = 0.25, ApproachAngle = 90 };
case 2:
return new ArcLeadOut { Radius = 0.25 };
case 3:
return new MicrotabLeadOut();
default:
return new NoLeadOut();
}
}
private static void SetParam(Panel panel, string tag, double value)
{
foreach (Control c in panel.Controls)
{
if (c is System.Windows.Forms.NumericUpDown nud && (string)nud.Tag == tag)
{
nud.Value = (decimal)value;
return;
}
}
}
private static double GetParam(Panel panel, string tag, double defaultValue)
{
foreach (Control c in panel.Controls)
{
if (c is System.Windows.Forms.NumericUpDown nud && (string)nud.Tag == tag)
return (double)nud.Value;
}
return defaultValue;
}
}
}