feat(ui): rewrite NestProgressForm with grouped panels, stepper, density bar, and Accept button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 17:34:50 -04:00
parent 60a557bd37
commit b5af5a118d
2 changed files with 399 additions and 233 deletions
+244 -188
View File
@@ -2,15 +2,8 @@ namespace OpenNest.Forms
{ {
partial class NestProgressForm partial class NestProgressForm
{ {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; 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) protected override void Dispose(bool disposing)
{ {
if (disposing && (components != null)) if (disposing && (components != null))
@@ -22,284 +15,342 @@ namespace OpenNest.Forms
#region Windows Form Designer generated code #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() private void InitializeComponent()
{ {
table = new System.Windows.Forms.TableLayoutPanel(); phaseStepper = new Controls.PhaseStepperControl();
phaseLabel = new System.Windows.Forms.Label(); resultsPanel = new System.Windows.Forms.Panel();
phaseValue = new System.Windows.Forms.Label(); resultsHeader = new System.Windows.Forms.Label();
plateLabel = new System.Windows.Forms.Label(); resultsTable = new System.Windows.Forms.TableLayoutPanel();
plateValue = new System.Windows.Forms.Label();
partsLabel = new System.Windows.Forms.Label(); partsLabel = new System.Windows.Forms.Label();
partsValue = new System.Windows.Forms.Label(); partsValue = new System.Windows.Forms.Label();
densityLabel = new System.Windows.Forms.Label(); densityLabel = new System.Windows.Forms.Label();
densityPanel = new System.Windows.Forms.FlowLayoutPanel();
densityValue = new System.Windows.Forms.Label(); densityValue = new System.Windows.Forms.Label();
densityBar = new Controls.DensityBar();
nestedAreaLabel = new System.Windows.Forms.Label(); nestedAreaLabel = new System.Windows.Forms.Label();
nestedAreaValue = new System.Windows.Forms.Label(); nestedAreaValue = new System.Windows.Forms.Label();
remnantLabel = new System.Windows.Forms.Label(); statusPanel = new System.Windows.Forms.Panel();
remnantValue = new System.Windows.Forms.Label(); statusHeader = new System.Windows.Forms.Label();
statusTable = new System.Windows.Forms.TableLayoutPanel();
plateLabel = new System.Windows.Forms.Label();
plateValue = new System.Windows.Forms.Label();
elapsedLabel = new System.Windows.Forms.Label(); elapsedLabel = new System.Windows.Forms.Label();
elapsedValue = new System.Windows.Forms.Label(); elapsedValue = new System.Windows.Forms.Label();
descriptionLabel = new System.Windows.Forms.Label(); descriptionLabel = new System.Windows.Forms.Label();
descriptionValue = new System.Windows.Forms.Label(); descriptionValue = new System.Windows.Forms.Label();
stopButton = new System.Windows.Forms.Button();
buttonPanel = new System.Windows.Forms.FlowLayoutPanel(); buttonPanel = new System.Windows.Forms.FlowLayoutPanel();
table.SuspendLayout(); acceptButton = new System.Windows.Forms.Button();
stopButton = new System.Windows.Forms.Button();
resultsPanel.SuspendLayout();
resultsTable.SuspendLayout();
densityPanel.SuspendLayout();
statusPanel.SuspendLayout();
statusTable.SuspendLayout();
buttonPanel.SuspendLayout(); buttonPanel.SuspendLayout();
SuspendLayout(); SuspendLayout();
// //
// table // phaseStepper
// //
table.AutoSize = true; phaseStepper.Dock = System.Windows.Forms.DockStyle.Top;
table.ColumnCount = 2; phaseStepper.Height = 60;
table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F)); phaseStepper.Name = "phaseStepper";
table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); phaseStepper.TabIndex = 0;
table.Controls.Add(phaseLabel, 0, 0);
table.Controls.Add(phaseValue, 1, 0);
table.Controls.Add(plateLabel, 0, 1);
table.Controls.Add(plateValue, 1, 1);
table.Controls.Add(partsLabel, 0, 2);
table.Controls.Add(partsValue, 1, 2);
table.Controls.Add(densityLabel, 0, 3);
table.Controls.Add(densityValue, 1, 3);
table.Controls.Add(nestedAreaLabel, 0, 4);
table.Controls.Add(nestedAreaValue, 1, 4);
table.Controls.Add(remnantLabel, 0, 5);
table.Controls.Add(remnantValue, 1, 5);
table.Controls.Add(elapsedLabel, 0, 6);
table.Controls.Add(elapsedValue, 1, 6);
table.Controls.Add(descriptionLabel, 0, 7);
table.Controls.Add(descriptionValue, 1, 7);
table.Dock = System.Windows.Forms.DockStyle.Top;
table.Location = new System.Drawing.Point(0, 45);
table.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
table.Name = "table";
table.Padding = new System.Windows.Forms.Padding(9, 9, 9, 9);
table.RowCount = 8;
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.RowStyles.Add(new System.Windows.Forms.RowStyle());
table.Size = new System.Drawing.Size(425, 218);
table.TabIndex = 0;
// //
// phaseLabel // resultsPanel
// //
phaseLabel.AutoSize = true; resultsPanel.BackColor = System.Drawing.Color.White;
phaseLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); resultsPanel.Controls.Add(resultsTable);
phaseLabel.Location = new System.Drawing.Point(14, 14); resultsPanel.Controls.Add(resultsHeader);
phaseLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); resultsPanel.Dock = System.Windows.Forms.DockStyle.Top;
phaseLabel.Name = "phaseLabel"; resultsPanel.Location = new System.Drawing.Point(0, 60);
phaseLabel.Size = new System.Drawing.Size(46, 13); resultsPanel.Margin = new System.Windows.Forms.Padding(10, 4, 10, 4);
phaseLabel.TabIndex = 0; resultsPanel.Name = "resultsPanel";
phaseLabel.Text = "Phase:"; resultsPanel.Padding = new System.Windows.Forms.Padding(14, 10, 14, 10);
resultsPanel.Size = new System.Drawing.Size(450, 105);
resultsPanel.TabIndex = 1;
// //
// phaseValue // resultsHeader
// //
phaseValue.AutoSize = true; resultsHeader.AutoSize = true;
phaseValue.Location = new System.Drawing.Point(107, 14); resultsHeader.Dock = System.Windows.Forms.DockStyle.Top;
phaseValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); resultsHeader.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
phaseValue.Name = "phaseValue"; resultsHeader.ForeColor = System.Drawing.Color.FromArgb(85, 85, 85);
phaseValue.Size = new System.Drawing.Size(19, 15); resultsHeader.Name = "resultsHeader";
phaseValue.TabIndex = 1; resultsHeader.Padding = new System.Windows.Forms.Padding(0, 0, 0, 4);
phaseValue.Text = "—"; resultsHeader.Size = new System.Drawing.Size(63, 19);
resultsHeader.TabIndex = 0;
resultsHeader.Text = "RESULTS";
// //
// plateLabel // resultsTable
// //
plateLabel.AutoSize = true; resultsTable.AutoSize = true;
plateLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); resultsTable.ColumnCount = 2;
plateLabel.Location = new System.Drawing.Point(14, 39); resultsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
plateLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); resultsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
plateLabel.Name = "plateLabel"; resultsTable.Controls.Add(partsLabel, 0, 0);
plateLabel.Size = new System.Drawing.Size(40, 13); resultsTable.Controls.Add(partsValue, 1, 0);
plateLabel.TabIndex = 2; resultsTable.Controls.Add(densityLabel, 0, 1);
plateLabel.Text = "Plate:"; resultsTable.Controls.Add(densityPanel, 1, 1);
// resultsTable.Controls.Add(nestedAreaLabel, 0, 2);
// plateValue resultsTable.Controls.Add(nestedAreaValue, 1, 2);
// resultsTable.Dock = System.Windows.Forms.DockStyle.Top;
plateValue.AutoSize = true; resultsTable.Name = "resultsTable";
plateValue.Location = new System.Drawing.Point(107, 39); resultsTable.RowCount = 3;
plateValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); resultsTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
plateValue.Name = "plateValue"; resultsTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
plateValue.Size = new System.Drawing.Size(19, 15); resultsTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
plateValue.TabIndex = 3; resultsTable.TabIndex = 1;
plateValue.Text = "—";
// //
// partsLabel // partsLabel
// //
partsLabel.AutoSize = true; partsLabel.AutoSize = true;
partsLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); partsLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
partsLabel.Location = new System.Drawing.Point(14, 64); partsLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
partsLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); partsLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
partsLabel.Name = "partsLabel"; partsLabel.Name = "partsLabel";
partsLabel.Size = new System.Drawing.Size(40, 13);
partsLabel.TabIndex = 4;
partsLabel.Text = "Parts:"; partsLabel.Text = "Parts:";
// //
// partsValue // partsValue
// //
partsValue.AutoSize = true; partsValue.AutoSize = true;
partsValue.Location = new System.Drawing.Point(107, 64); partsValue.Font = new System.Drawing.Font("Consolas", 8.25F);
partsValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); partsValue.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
partsValue.Name = "partsValue"; partsValue.Name = "partsValue";
partsValue.Size = new System.Drawing.Size(19, 15); partsValue.Text = "\u2014";
partsValue.TabIndex = 5;
partsValue.Text = "—";
// //
// densityLabel // densityLabel
// //
densityLabel.AutoSize = true; densityLabel.AutoSize = true;
densityLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); densityLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
densityLabel.Location = new System.Drawing.Point(14, 89); densityLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
densityLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); densityLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
densityLabel.Name = "densityLabel"; densityLabel.Name = "densityLabel";
densityLabel.Size = new System.Drawing.Size(53, 13);
densityLabel.TabIndex = 6;
densityLabel.Text = "Density:"; densityLabel.Text = "Density:";
//
// densityPanel
//
densityPanel.AutoSize = true;
densityPanel.Controls.Add(densityValue);
densityPanel.Controls.Add(densityBar);
densityPanel.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
densityPanel.Margin = new System.Windows.Forms.Padding(0);
densityPanel.Name = "densityPanel";
densityPanel.WrapContents = false;
// //
// densityValue // densityValue
// //
densityValue.AutoSize = true; densityValue.AutoSize = true;
densityValue.Location = new System.Drawing.Point(107, 89); densityValue.Font = new System.Drawing.Font("Consolas", 8.25F);
densityValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); densityValue.Margin = new System.Windows.Forms.Padding(0, 3, 8, 3);
densityValue.Name = "densityValue"; densityValue.Name = "densityValue";
densityValue.Size = new System.Drawing.Size(19, 15); densityValue.Text = "\u2014";
densityValue.TabIndex = 7;
densityValue.Text = "—"; //
// densityBar
//
densityBar.Margin = new System.Windows.Forms.Padding(0, 5, 0, 0);
densityBar.Name = "densityBar";
densityBar.Size = new System.Drawing.Size(60, 8);
// //
// nestedAreaLabel // nestedAreaLabel
// //
nestedAreaLabel.AutoSize = true; nestedAreaLabel.AutoSize = true;
nestedAreaLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); nestedAreaLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
nestedAreaLabel.Location = new System.Drawing.Point(14, 114); nestedAreaLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
nestedAreaLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); nestedAreaLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
nestedAreaLabel.Name = "nestedAreaLabel"; nestedAreaLabel.Name = "nestedAreaLabel";
nestedAreaLabel.Size = new System.Drawing.Size(51, 13);
nestedAreaLabel.TabIndex = 8;
nestedAreaLabel.Text = "Nested:"; nestedAreaLabel.Text = "Nested:";
// //
// nestedAreaValue // nestedAreaValue
// //
nestedAreaValue.AutoSize = true; nestedAreaValue.AutoSize = true;
nestedAreaValue.Location = new System.Drawing.Point(107, 114); nestedAreaValue.Font = new System.Drawing.Font("Consolas", 8.25F);
nestedAreaValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); nestedAreaValue.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
nestedAreaValue.Name = "nestedAreaValue"; nestedAreaValue.Name = "nestedAreaValue";
nestedAreaValue.Size = new System.Drawing.Size(19, 15); nestedAreaValue.Text = "\u2014";
nestedAreaValue.TabIndex = 9;
nestedAreaValue.Text = "—";
// //
// remnantLabel // statusPanel
// //
remnantLabel.AutoSize = true; statusPanel.BackColor = System.Drawing.Color.White;
remnantLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); statusPanel.Controls.Add(statusTable);
remnantLabel.Location = new System.Drawing.Point(14, 139); statusPanel.Controls.Add(statusHeader);
remnantLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); statusPanel.Dock = System.Windows.Forms.DockStyle.Top;
remnantLabel.Name = "remnantLabel"; statusPanel.Location = new System.Drawing.Point(0, 169);
remnantLabel.Size = new System.Drawing.Size(54, 13); statusPanel.Name = "statusPanel";
remnantLabel.TabIndex = 10; statusPanel.Padding = new System.Windows.Forms.Padding(14, 10, 14, 10);
remnantLabel.Text = "Unused:"; statusPanel.Size = new System.Drawing.Size(450, 100);
statusPanel.TabIndex = 2;
// //
// remnantValue // statusHeader
// //
remnantValue.AutoSize = true; statusHeader.AutoSize = true;
remnantValue.Location = new System.Drawing.Point(107, 139); statusHeader.Dock = System.Windows.Forms.DockStyle.Top;
remnantValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); statusHeader.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
remnantValue.Name = "remnantValue"; statusHeader.ForeColor = System.Drawing.Color.FromArgb(85, 85, 85);
remnantValue.Size = new System.Drawing.Size(19, 15); statusHeader.Name = "statusHeader";
remnantValue.TabIndex = 11; statusHeader.Padding = new System.Windows.Forms.Padding(0, 0, 0, 4);
remnantValue.Text = "—"; statusHeader.Size = new System.Drawing.Size(55, 19);
statusHeader.TabIndex = 0;
statusHeader.Text = "STATUS";
//
// statusTable
//
statusTable.AutoSize = true;
statusTable.ColumnCount = 2;
statusTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
statusTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
statusTable.Controls.Add(plateLabel, 0, 0);
statusTable.Controls.Add(plateValue, 1, 0);
statusTable.Controls.Add(elapsedLabel, 0, 1);
statusTable.Controls.Add(elapsedValue, 1, 1);
statusTable.Controls.Add(descriptionLabel, 0, 2);
statusTable.Controls.Add(descriptionValue, 1, 2);
statusTable.Dock = System.Windows.Forms.DockStyle.Top;
statusTable.Name = "statusTable";
statusTable.RowCount = 3;
statusTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
statusTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
statusTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
statusTable.TabIndex = 1;
//
// plateLabel
//
plateLabel.AutoSize = true;
plateLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
plateLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
plateLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
plateLabel.Name = "plateLabel";
plateLabel.Text = "Plate:";
//
// plateValue
//
plateValue.AutoSize = true;
plateValue.Font = new System.Drawing.Font("Consolas", 8.25F);
plateValue.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
plateValue.Name = "plateValue";
plateValue.Text = "\u2014";
// //
// elapsedLabel // elapsedLabel
// //
elapsedLabel.AutoSize = true; elapsedLabel.AutoSize = true;
elapsedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); elapsedLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
elapsedLabel.Location = new System.Drawing.Point(14, 164); elapsedLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
elapsedLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); elapsedLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
elapsedLabel.Name = "elapsedLabel"; elapsedLabel.Name = "elapsedLabel";
elapsedLabel.Size = new System.Drawing.Size(56, 13);
elapsedLabel.TabIndex = 12;
elapsedLabel.Text = "Elapsed:"; elapsedLabel.Text = "Elapsed:";
// //
// elapsedValue // elapsedValue
// //
elapsedValue.AutoSize = true; elapsedValue.AutoSize = true;
elapsedValue.Location = new System.Drawing.Point(107, 164); elapsedValue.Font = new System.Drawing.Font("Consolas", 8.25F);
elapsedValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); elapsedValue.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
elapsedValue.Name = "elapsedValue"; elapsedValue.Name = "elapsedValue";
elapsedValue.Size = new System.Drawing.Size(28, 15);
elapsedValue.TabIndex = 13;
elapsedValue.Text = "0:00"; elapsedValue.Text = "0:00";
// //
// descriptionLabel // descriptionLabel
// //
descriptionLabel.AutoSize = true; descriptionLabel.AutoSize = true;
descriptionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); descriptionLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold);
descriptionLabel.Location = new System.Drawing.Point(14, 189); descriptionLabel.ForeColor = System.Drawing.Color.FromArgb(51, 51, 51);
descriptionLabel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); descriptionLabel.Margin = new System.Windows.Forms.Padding(0, 3, 5, 3);
descriptionLabel.Name = "descriptionLabel"; descriptionLabel.Name = "descriptionLabel";
descriptionLabel.Size = new System.Drawing.Size(44, 13);
descriptionLabel.TabIndex = 14;
descriptionLabel.Text = "Detail:"; descriptionLabel.Text = "Detail:";
// //
// descriptionValue // descriptionValue
// //
descriptionValue.AutoSize = true; descriptionValue.AutoSize = true;
descriptionValue.Location = new System.Drawing.Point(107, 189); descriptionValue.Font = new System.Drawing.Font("Segoe UI", 8.25F);
descriptionValue.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); descriptionValue.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
descriptionValue.Name = "descriptionValue"; descriptionValue.Name = "descriptionValue";
descriptionValue.Size = new System.Drawing.Size(19, 15); descriptionValue.Text = "\u2014";
descriptionValue.TabIndex = 15;
descriptionValue.Text = "—"; //
// buttonPanel
//
buttonPanel.AutoSize = true;
buttonPanel.Controls.Add(stopButton);
buttonPanel.Controls.Add(acceptButton);
buttonPanel.Dock = System.Windows.Forms.DockStyle.Top;
buttonPanel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
buttonPanel.Name = "buttonPanel";
buttonPanel.Padding = new System.Windows.Forms.Padding(9, 6, 9, 6);
buttonPanel.Size = new System.Drawing.Size(450, 45);
buttonPanel.TabIndex = 3;
//
// acceptButton
//
acceptButton.Enabled = false;
acceptButton.Font = new System.Drawing.Font("Segoe UI", 8.25F);
acceptButton.Margin = new System.Windows.Forms.Padding(6, 3, 0, 3);
acceptButton.Name = "acceptButton";
acceptButton.Size = new System.Drawing.Size(93, 27);
acceptButton.TabIndex = 1;
acceptButton.Text = "Accept";
acceptButton.UseVisualStyleBackColor = true;
acceptButton.Click += AcceptButton_Click;
// //
// stopButton // stopButton
// //
stopButton.Anchor = System.Windows.Forms.AnchorStyles.None; stopButton.Enabled = false;
stopButton.Location = new System.Drawing.Point(314, 9); stopButton.Font = new System.Drawing.Font("Segoe UI", 8.25F);
stopButton.Margin = new System.Windows.Forms.Padding(0, 9, 0, 9); stopButton.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
stopButton.Name = "stopButton"; stopButton.Name = "stopButton";
stopButton.Size = new System.Drawing.Size(93, 27); stopButton.Size = new System.Drawing.Size(93, 27);
stopButton.TabIndex = 0; stopButton.TabIndex = 0;
stopButton.Text = "Stop"; stopButton.Text = "Stop";
stopButton.UseVisualStyleBackColor = true; stopButton.UseVisualStyleBackColor = true;
stopButton.Click += StopButton_Click; stopButton.Click += StopButton_Click;
//
// buttonPanel
//
buttonPanel.AutoSize = true;
buttonPanel.Controls.Add(stopButton);
buttonPanel.Dock = System.Windows.Forms.DockStyle.Top;
buttonPanel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
buttonPanel.Location = new System.Drawing.Point(0, 0);
buttonPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
buttonPanel.Name = "buttonPanel";
buttonPanel.Padding = new System.Windows.Forms.Padding(9, 0, 9, 0);
buttonPanel.Size = new System.Drawing.Size(425, 45);
buttonPanel.TabIndex = 1;
// //
// NestProgressForm // NestProgressForm
// //
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(425, 266); ClientSize = new System.Drawing.Size(450, 315);
Controls.Add(table);
Controls.Add(buttonPanel); Controls.Add(buttonPanel);
Controls.Add(statusPanel);
Controls.Add(resultsPanel);
Controls.Add(phaseStepper);
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
MaximizeBox = false; MaximizeBox = false;
MinimizeBox = false; MinimizeBox = false;
Name = "NestProgressForm"; Name = "NestProgressForm";
ShowInTaskbar = false; ShowInTaskbar = false;
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
Text = "Nesting Progress"; Text = "Nesting Progress";
table.ResumeLayout(false); resultsPanel.ResumeLayout(false);
table.PerformLayout(); resultsPanel.PerformLayout();
resultsTable.ResumeLayout(false);
resultsTable.PerformLayout();
densityPanel.ResumeLayout(false);
densityPanel.PerformLayout();
statusPanel.ResumeLayout(false);
statusPanel.PerformLayout();
statusTable.ResumeLayout(false);
statusTable.PerformLayout();
buttonPanel.ResumeLayout(false); buttonPanel.ResumeLayout(false);
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
@@ -307,24 +358,29 @@ namespace OpenNest.Forms
#endregion #endregion
private System.Windows.Forms.TableLayoutPanel table; private Controls.PhaseStepperControl phaseStepper;
private System.Windows.Forms.Label phaseLabel; private System.Windows.Forms.Panel resultsPanel;
private System.Windows.Forms.Label phaseValue; private System.Windows.Forms.Label resultsHeader;
private System.Windows.Forms.Label plateLabel; private System.Windows.Forms.TableLayoutPanel resultsTable;
private System.Windows.Forms.Label plateValue;
private System.Windows.Forms.Label partsLabel; private System.Windows.Forms.Label partsLabel;
private System.Windows.Forms.Label partsValue; private System.Windows.Forms.Label partsValue;
private System.Windows.Forms.Label densityLabel; private System.Windows.Forms.Label densityLabel;
private System.Windows.Forms.FlowLayoutPanel densityPanel;
private System.Windows.Forms.Label densityValue; private System.Windows.Forms.Label densityValue;
private Controls.DensityBar densityBar;
private System.Windows.Forms.Label nestedAreaLabel; private System.Windows.Forms.Label nestedAreaLabel;
private System.Windows.Forms.Label nestedAreaValue; private System.Windows.Forms.Label nestedAreaValue;
private System.Windows.Forms.Label remnantLabel; private System.Windows.Forms.Panel statusPanel;
private System.Windows.Forms.Label remnantValue; private System.Windows.Forms.Label statusHeader;
private System.Windows.Forms.TableLayoutPanel statusTable;
private System.Windows.Forms.Label plateLabel;
private System.Windows.Forms.Label plateValue;
private System.Windows.Forms.Label elapsedLabel; private System.Windows.Forms.Label elapsedLabel;
private System.Windows.Forms.Label elapsedValue; private System.Windows.Forms.Label elapsedValue;
private System.Windows.Forms.Label descriptionLabel; private System.Windows.Forms.Label descriptionLabel;
private System.Windows.Forms.Label descriptionValue; private System.Windows.Forms.Label descriptionValue;
private System.Windows.Forms.Button stopButton;
private System.Windows.Forms.FlowLayoutPanel buttonPanel; private System.Windows.Forms.FlowLayoutPanel buttonPanel;
private System.Windows.Forms.Button acceptButton;
private System.Windows.Forms.Button stopButton;
} }
} }
+119 -9
View File
@@ -1,5 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
@@ -7,9 +10,22 @@ namespace OpenNest.Forms
{ {
public partial class NestProgressForm : Form public partial class NestProgressForm : Form
{ {
private static readonly Color DefaultFlashColor = Color.FromArgb(0, 160, 0);
private static readonly Color DensityLowColor = Color.FromArgb(200, 40, 40);
private static readonly Color DensityMidColor = Color.FromArgb(200, 160, 0);
private static readonly Color DensityHighColor = Color.FromArgb(0, 160, 0);
private const int FadeSteps = 20;
private const int FadeIntervalMs = 50;
private readonly CancellationTokenSource cts; private readonly CancellationTokenSource cts;
private readonly Stopwatch stopwatch = Stopwatch.StartNew(); private readonly Stopwatch stopwatch = Stopwatch.StartNew();
private readonly System.Windows.Forms.Timer elapsedTimer; private readonly System.Windows.Forms.Timer elapsedTimer;
private readonly System.Windows.Forms.Timer fadeTimer;
private readonly Dictionary<Label, (int remaining, Color flashColor)> fadeCounters = new();
private bool hasReceivedProgress;
public bool Accepted { get; private set; }
public NestProgressForm(CancellationTokenSource cts, bool showPlateRow = true) public NestProgressForm(CancellationTokenSource cts, bool showPlateRow = true)
{ {
@@ -25,6 +41,9 @@ namespace OpenNest.Forms
elapsedTimer = new System.Windows.Forms.Timer { Interval = 1000 }; elapsedTimer = new System.Windows.Forms.Timer { Interval = 1000 };
elapsedTimer.Tick += (s, e) => UpdateElapsed(); elapsedTimer.Tick += (s, e) => UpdateElapsed();
elapsedTimer.Start(); elapsedTimer.Start();
fadeTimer = new System.Windows.Forms.Timer { Interval = FadeIntervalMs };
fadeTimer.Tick += FadeTimer_Tick;
} }
public void UpdateProgress(NestProgress progress) public void UpdateProgress(NestProgress progress)
@@ -32,14 +51,29 @@ namespace OpenNest.Forms
if (IsDisposed || !IsHandleCreated) if (IsDisposed || !IsHandleCreated)
return; return;
phaseValue.Text = FormatPhase(progress.Phase); if (!hasReceivedProgress)
plateValue.Text = progress.PlateNumber.ToString(); {
partsValue.Text = progress.BestPartCount.ToString(); hasReceivedProgress = true;
densityValue.Text = progress.BestDensity.ToString("P1"); acceptButton.Enabled = true;
nestedAreaValue.Text = $"{progress.NestedWidth:F1} x {progress.NestedLength:F1} ({progress.NestedArea:F1} sq in)"; stopButton.Enabled = true;
}
if (!string.IsNullOrEmpty(progress.Description)) phaseStepper.ActivePhase = progress.Phase;
descriptionValue.Text = progress.Description;
SetValueWithFlash(plateValue, progress.PlateNumber.ToString());
SetValueWithFlash(partsValue, progress.BestPartCount.ToString());
var densityText = progress.BestDensity.ToString("P1");
var densityFlashColor = GetDensityColor(progress.BestDensity);
SetValueWithFlash(densityValue, densityText, densityFlashColor);
densityBar.Value = progress.BestDensity;
SetValueWithFlash(nestedAreaValue,
$"{progress.NestedWidth:F1} x {progress.NestedLength:F1} ({progress.NestedArea:F1} sq in)");
descriptionValue.Text = !string.IsNullOrEmpty(progress.Description)
? progress.Description
: FormatPhase(progress.Phase);
} }
public void ShowCompleted() public void ShowCompleted()
@@ -51,8 +85,10 @@ namespace OpenNest.Forms
elapsedTimer.Stop(); elapsedTimer.Stop();
UpdateElapsed(); UpdateElapsed();
phaseValue.Text = "Done"; phaseStepper.IsComplete = true;
descriptionValue.Text = "\u2014"; descriptionValue.Text = "\u2014";
acceptButton.Visible = false;
stopButton.Text = "Close"; stopButton.Text = "Close";
stopButton.Enabled = true; stopButton.Enabled = true;
stopButton.Click -= StopButton_Click; stopButton.Click -= StopButton_Click;
@@ -70,15 +106,28 @@ namespace OpenNest.Forms
: elapsed.ToString(@"m\:ss"); : elapsed.ToString(@"m\:ss");
} }
private void AcceptButton_Click(object sender, EventArgs e)
{
Accepted = true;
cts.Cancel();
acceptButton.Enabled = false;
stopButton.Enabled = false;
acceptButton.Text = "Accepted";
stopButton.Text = "Stopping...";
}
private void StopButton_Click(object sender, EventArgs e) private void StopButton_Click(object sender, EventArgs e)
{ {
cts.Cancel(); cts.Cancel();
stopButton.Text = "Stopping..."; acceptButton.Enabled = false;
stopButton.Enabled = false; stopButton.Enabled = false;
stopButton.Text = "Stopping...";
} }
protected override void OnFormClosing(FormClosingEventArgs e) protected override void OnFormClosing(FormClosingEventArgs e)
{ {
fadeTimer.Stop();
fadeTimer.Dispose();
elapsedTimer.Stop(); elapsedTimer.Stop();
elapsedTimer.Dispose(); elapsedTimer.Dispose();
stopwatch.Stop(); stopwatch.Stop();
@@ -89,6 +138,65 @@ namespace OpenNest.Forms
base.OnFormClosing(e); base.OnFormClosing(e);
} }
private void SetValueWithFlash(Label label, string text, Color? flashColor = null)
{
if (label.Text == text)
return;
var color = flashColor ?? DefaultFlashColor;
label.Text = text;
label.ForeColor = color;
fadeCounters[label] = (FadeSteps, color);
if (!fadeTimer.Enabled)
fadeTimer.Start();
}
private void FadeTimer_Tick(object sender, EventArgs e)
{
if (IsDisposed || !IsHandleCreated)
{
fadeTimer.Stop();
return;
}
var defaultColor = SystemColors.ControlText;
var labels = fadeCounters.Keys.ToList();
foreach (var label in labels)
{
var (remaining, flashColor) = fadeCounters[label];
remaining--;
if (remaining <= 0)
{
label.ForeColor = defaultColor;
fadeCounters.Remove(label);
}
else
{
var ratio = (float)remaining / FadeSteps;
var r = (int)(defaultColor.R + (flashColor.R - defaultColor.R) * ratio);
var g = (int)(defaultColor.G + (flashColor.G - defaultColor.G) * ratio);
var b = (int)(defaultColor.B + (flashColor.B - defaultColor.B) * ratio);
label.ForeColor = Color.FromArgb(r, g, b);
fadeCounters[label] = (remaining, flashColor);
}
}
if (fadeCounters.Count == 0)
fadeTimer.Stop();
}
private static Color GetDensityColor(double density)
{
if (density < 0.5)
return DensityLowColor;
if (density < 0.7)
return DensityMidColor;
return DensityHighColor;
}
private static string FormatPhase(NestPhase phase) private static string FormatPhase(NestPhase phase)
{ {
switch (phase) switch (phase)
@@ -96,6 +204,8 @@ namespace OpenNest.Forms
case NestPhase.Linear: return "Trying rotations..."; case NestPhase.Linear: return "Trying rotations...";
case NestPhase.RectBestFit: return "Trying best fit..."; case NestPhase.RectBestFit: return "Trying best fit...";
case NestPhase.Pairs: return "Trying pairs..."; case NestPhase.Pairs: return "Trying pairs...";
case NestPhase.Extents: return "Trying extents...";
case NestPhase.Nfp: return "Trying NFP...";
default: return phase.ToString(); default: return phase.ToString();
} }
} }