mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-26 22:01:06 -04:00
feat(ui): replace status bar plate labels with nest material
The status bar's "Plate N of M" counted the trailing empty plate, and its plate number and size repeated what the plate view header already shows. Drop Plate, Size and Qty from the status bar. Show the plate quantity in the header as "×N" when it is above one, and keep Util in the status bar so it stays visible while the Drawings tab is open. Add a Material label (name and thickness) that opens Nest Info when clicked. Nest Info remains the only place to edit material, and the label refreshes after the dialog closes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d1270a860
commit
be8d1443e3
9 files changed
+94
-64
No files matched your search
@@ -48,17 +48,24 @@ namespace OpenNest
|
||||
return plate != null && plate.Parts.Count == 0;
|
||||
}
|
||||
|
||||
/// <summary>Header text for the plate at <paramref name="storageIndex"/>.</summary>
|
||||
public static string FormatHeader(IList<Plate> plates, int storageIndex, string plateSizeText)
|
||||
/// <summary>
|
||||
/// Header text for the plate at <paramref name="storageIndex"/>. A quantity above one is
|
||||
/// appended as "×N"; a single sheet shows no quantity.
|
||||
/// </summary>
|
||||
public static string FormatHeader(IList<Plate> plates, int storageIndex, string plateSizeText, int quantity = 1)
|
||||
{
|
||||
var displayed = DisplayedPlateNumber(plates, storageIndex);
|
||||
if (displayed == null)
|
||||
return IsTrailingSentinel(plates, storageIndex)
|
||||
? "New plate (empty)"
|
||||
: "No plates";
|
||||
return string.IsNullOrEmpty(plateSizeText)
|
||||
? string.Format("Plate {0} of {1}", displayed.Value, DisplayedPlateCount(plates))
|
||||
: string.Format("Plate {0} of {1} | {2}", displayed.Value, DisplayedPlateCount(plates), plateSizeText);
|
||||
|
||||
var text = string.Format("Plate {0} of {1}", displayed.Value, DisplayedPlateCount(plates));
|
||||
if (!string.IsNullOrEmpty(plateSizeText))
|
||||
text += " | " + plateSizeText;
|
||||
if (quantity > 1)
|
||||
text += " | ×" + quantity;
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,18 @@ public class PlateDisplayNumberingTests
|
||||
Assert.Equal("New plate (empty)", PlateDisplayNumbering.FormatHeader(nest.Plates, sentinel, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Header_ShowsSizeAndQuantityAboveOne()
|
||||
{
|
||||
var nest = CreateNest();
|
||||
nest.Plates.Add(WithPart());
|
||||
|
||||
Assert.Equal("Plate 1 of 1 | 60 x 120", PlateDisplayNumbering.FormatHeader(nest.Plates, 0, "60 x 120"));
|
||||
Assert.Equal("Plate 1 of 1 | 60 x 120", PlateDisplayNumbering.FormatHeader(nest.Plates, 0, "60 x 120", 1));
|
||||
Assert.Equal("Plate 1 of 1 | 60 x 120 | ×4", PlateDisplayNumbering.FormatHeader(nest.Plates, 0, "60 x 120", 4));
|
||||
Assert.Equal("Plate 1 of 1 | ×2", PlateDisplayNumbering.FormatHeader(nest.Plates, 0, null, 2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoRealPlatesThenSentinel_TotalIsTwo()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Globalization;
|
||||
using OpenNest.Forms;
|
||||
|
||||
namespace OpenNest.WinForms.Tests.Forms;
|
||||
|
||||
public class MainStatusBarTests
|
||||
{
|
||||
[Fact]
|
||||
public void FormatMaterial_ShowsNameAndThicknessWithUnits()
|
||||
{
|
||||
var previous = CultureInfo.CurrentCulture;
|
||||
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
try
|
||||
{
|
||||
Assert.Equal("Material: A36 · 0.25 in", MainStatusBar.FormatMaterial("A36", 0.25, Units.Inches));
|
||||
Assert.Equal("Material: 304 SS · 3 mm", MainStatusBar.FormatMaterial(" 304 SS ", 3, Units.Millimeters));
|
||||
Assert.Equal("Material: A36", MainStatusBar.FormatMaterial("A36", 0, Units.Inches));
|
||||
Assert.Equal("Material: 0.1875 in", MainStatusBar.FormatMaterial(null, 0.1875, Units.Inches));
|
||||
Assert.Equal("Material: (none)", MainStatusBar.FormatMaterial("", 0, Units.Inches));
|
||||
}
|
||||
finally
|
||||
{
|
||||
CultureInfo.CurrentCulture = previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -995,7 +995,7 @@ namespace OpenNest.Forms
|
||||
// Display-only numbering: the trailing empty new-plate sentinel is excluded from the
|
||||
// total (and labeled as such); navigation and storage indexes are untouched.
|
||||
plateInfoLabel.Text = PlateDisplayNumbering.FormatHeader(
|
||||
Nest.Plates, PlateManager.CurrentIndex, plate.Size.ToString());
|
||||
Nest.Plates, PlateManager.CurrentIndex, plate.Size.ToString(), plate.Quantity);
|
||||
|
||||
btnFirstPlate.Enabled = !PlateManager.IsFirst;
|
||||
btnPreviousPlate.Enabled = !PlateManager.IsFirst;
|
||||
|
||||
Generated
+13
-31
@@ -167,9 +167,7 @@ namespace OpenNest.Forms
|
||||
statusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
locationStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
spacerLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
plateIndexStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
plateSizeStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
plateQtyStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
materialStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
plateUtilStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
selectionStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
toolStrip1 = new System.Windows.Forms.ToolStrip();
|
||||
@@ -1094,7 +1092,7 @@ namespace OpenNest.Forms
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { statusLabel1, locationStatusLabel, selectionStatusLabel, spacerLabel, plateIndexStatusLabel, plateSizeStatusLabel, plateQtyStatusLabel, plateUtilStatusLabel });
|
||||
statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { statusLabel1, locationStatusLabel, selectionStatusLabel, spacerLabel, materialStatusLabel, plateUtilStatusLabel });
|
||||
statusStrip1.Location = new System.Drawing.Point(0, 630);
|
||||
statusStrip1.Name = "statusStrip1";
|
||||
statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0);
|
||||
@@ -1130,30 +1128,16 @@ namespace OpenNest.Forms
|
||||
spacerLabel.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
spacerLabel.Size = new System.Drawing.Size(931, 19);
|
||||
spacerLabel.Spring = true;
|
||||
//
|
||||
// plateIndexStatusLabel
|
||||
//
|
||||
plateIndexStatusLabel.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
|
||||
plateIndexStatusLabel.Name = "plateIndexStatusLabel";
|
||||
plateIndexStatusLabel.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
plateIndexStatusLabel.Size = new System.Drawing.Size(85, 19);
|
||||
plateIndexStatusLabel.Text = "Plate : 0 of 0";
|
||||
//
|
||||
// plateSizeStatusLabel
|
||||
//
|
||||
plateSizeStatusLabel.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
|
||||
plateSizeStatusLabel.Name = "plateSizeStatusLabel";
|
||||
plateSizeStatusLabel.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
plateSizeStatusLabel.Size = new System.Drawing.Size(67, 19);
|
||||
plateSizeStatusLabel.Text = "Size : 0x0";
|
||||
//
|
||||
// plateQtyStatusLabel
|
||||
//
|
||||
plateQtyStatusLabel.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
|
||||
plateQtyStatusLabel.Name = "plateQtyStatusLabel";
|
||||
plateQtyStatusLabel.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
plateQtyStatusLabel.Size = new System.Drawing.Size(55, 19);
|
||||
plateQtyStatusLabel.Text = "Qty : 0";
|
||||
//
|
||||
// materialStatusLabel
|
||||
//
|
||||
materialStatusLabel.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
|
||||
materialStatusLabel.Name = "materialStatusLabel";
|
||||
materialStatusLabel.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
materialStatusLabel.Size = new System.Drawing.Size(85, 19);
|
||||
materialStatusLabel.Text = "Material: (none)";
|
||||
materialStatusLabel.ToolTipText = "Click to edit nest info";
|
||||
materialStatusLabel.Click += MaterialStatusLabel_Click;
|
||||
//
|
||||
// plateUtilStatusLabel
|
||||
//
|
||||
@@ -1374,11 +1358,10 @@ namespace OpenNest.Forms
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPlateRotate180;
|
||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||
private System.Windows.Forms.ToolStripStatusLabel plateSizeStatusLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel locationStatusLabel;
|
||||
private System.Windows.Forms.ToolStrip toolStrip1;
|
||||
private System.Windows.Forms.ToolStripButton btnOpen;
|
||||
private System.Windows.Forms.ToolStripStatusLabel plateIndexStatusLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel materialStatusLabel;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuWindow;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuWindowCascade;
|
||||
@@ -1386,7 +1369,6 @@ namespace OpenNest.Forms
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuWindowTileHorizontal;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem10;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuCloseAll;
|
||||
private System.Windows.Forms.ToolStripStatusLabel plateQtyStatusLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel plateUtilStatusLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuFileExportAll;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuFileExportNestReport;
|
||||
|
||||
@@ -47,8 +47,10 @@ namespace OpenNest.Forms
|
||||
|
||||
private async void EditNest_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (activeForm != null)
|
||||
await activeForm.ShowNestInfoEditorAsync();
|
||||
if (activeForm == null)
|
||||
return;
|
||||
await activeForm.ShowNestInfoEditorAsync();
|
||||
statusBar.UpdatePlate(); // Material and thickness may have changed.
|
||||
}
|
||||
|
||||
private void Clamps_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace OpenNest.Forms
|
||||
private void LocationStatusLabel_Click(object sender, EventArgs e) =>
|
||||
statusBar.ToggleLocationMode();
|
||||
|
||||
private void MaterialStatusLabel_Click(object sender, EventArgs e) =>
|
||||
EditNest_Click(sender, e);
|
||||
|
||||
#endregion Statusbar Events
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace OpenNest.Forms
|
||||
storage.StateChanged += Storage_StateChanged;
|
||||
InitializeComponent();
|
||||
statusBar = new MainStatusBar(statusLabel1, locationStatusLabel, selectionStatusLabel,
|
||||
plateIndexStatusLabel, plateSizeStatusLabel, plateQtyStatusLabel, plateUtilStatusLabel);
|
||||
materialStatusLabel, plateUtilStatusLabel);
|
||||
toolStrip1.Items.Add(CreateActionButton("btnCutPlanner", "Plan Cutting",
|
||||
Resources.cut_planner, PlatePlanCutting_Click));
|
||||
toolStrip1.Items.Add(CreateActionButton("btnSimulateCutting", "Simulate Cutting",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Collections;
|
||||
@@ -10,7 +12,8 @@ namespace OpenNest.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// The main window's status labels for the active nest document: status text, cursor
|
||||
/// location, selection bounds and plate index/size/quantity/utilization. The location
|
||||
/// location, selection bounds, nest material and plate utilization. Plate number, size and
|
||||
/// quantity live in the plate view header instead. The location
|
||||
/// follows the mouse (the default, throttled), or only left clicks while click mode is on;
|
||||
/// the mode persists as a user setting.
|
||||
/// </summary>
|
||||
@@ -22,9 +25,7 @@ namespace OpenNest.Forms
|
||||
private readonly ToolStripStatusLabel status;
|
||||
private readonly ToolStripStatusLabel location;
|
||||
private readonly ToolStripStatusLabel selection;
|
||||
private readonly ToolStripStatusLabel plateIndex;
|
||||
private readonly ToolStripStatusLabel plateSize;
|
||||
private readonly ToolStripStatusLabel plateQty;
|
||||
private readonly ToolStripStatusLabel material;
|
||||
private readonly ToolStripStatusLabel plateUtil;
|
||||
private readonly Timer locationTimer;
|
||||
|
||||
@@ -33,15 +34,12 @@ namespace OpenNest.Forms
|
||||
private bool locationPending;
|
||||
|
||||
public MainStatusBar(ToolStripStatusLabel status, ToolStripStatusLabel location,
|
||||
ToolStripStatusLabel selection, ToolStripStatusLabel plateIndex, ToolStripStatusLabel plateSize,
|
||||
ToolStripStatusLabel plateQty, ToolStripStatusLabel plateUtil)
|
||||
ToolStripStatusLabel selection, ToolStripStatusLabel material, ToolStripStatusLabel plateUtil)
|
||||
{
|
||||
this.status = status;
|
||||
this.location = location;
|
||||
this.selection = selection;
|
||||
this.plateIndex = plateIndex;
|
||||
this.plateSize = plateSize;
|
||||
this.plateQty = plateQty;
|
||||
this.material = material;
|
||||
this.plateUtil = plateUtil;
|
||||
|
||||
locationTimer = new Timer { Interval = LocationRefreshIntervalMs };
|
||||
@@ -126,25 +124,13 @@ namespace OpenNest.Forms
|
||||
{
|
||||
if (form == null)
|
||||
{
|
||||
plateIndex.Text = string.Empty;
|
||||
plateSize.Text = string.Empty;
|
||||
plateQty.Text = string.Empty;
|
||||
material.Text = string.Empty;
|
||||
plateUtil.Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
plateIndex.Text = string.Format(
|
||||
"Plate: {0} of {1}",
|
||||
form.PlateManager.CurrentIndex + 1,
|
||||
form.PlateManager.Count
|
||||
);
|
||||
|
||||
plateSize.Text = string.Format("Size: {0}", form.PlateView.Plate.Size);
|
||||
|
||||
plateQty.Text = string.Format(
|
||||
"Qty: {0}",
|
||||
form.PlateView.Plate.Quantity
|
||||
);
|
||||
var nest = form.Nest;
|
||||
material.Text = FormatMaterial(nest.Material?.Name, nest.Thickness, nest.Units);
|
||||
|
||||
plateUtil.Text = string.Format(
|
||||
"Util: {0:P1}",
|
||||
@@ -152,6 +138,18 @@ namespace OpenNest.Forms
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>Status text for the nest's material and thickness, e.g. "Material: A36 · 0.25 in".</summary>
|
||||
internal static string FormatMaterial(string name, double thickness, Units units)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
parts.Add(name.Trim());
|
||||
if (thickness > 0)
|
||||
parts.Add(thickness.ToString("0.####", CultureInfo.CurrentCulture) + " " + UnitsHelper.GetShortString(units));
|
||||
|
||||
return "Material: " + (parts.Count == 0 ? "(none)" : string.Join(" · ", parts));
|
||||
}
|
||||
|
||||
public void UpdateSelection()
|
||||
{
|
||||
if (form == null || form.PlateView.SelectedParts.Count == 0)
|
||||
|
||||
Reference in new issue
Block a user