feat(shapes): generate unique drawing names from parameters and add toolbar button
Shape library drawings now get descriptive names based on their parameters (e.g. "Rectangle 12x6", "Circle 8 Dia") instead of generic type names, preventing silent duplicates in the DrawingCollection HashSet. Added a Shape Library button to the Drawings tab toolbar and removed separators between toolbar buttons for a cleaner look. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,8 @@ namespace OpenNest.Shapes
|
||||
{
|
||||
public double Diameter { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Circle {Dim(Diameter)} Dia";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Diameter = 8;
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace OpenNest.Shapes
|
||||
public double Base { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Isosceles Triangle {Dim(Base)}x{Dim(Height)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Base = 8;
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace OpenNest.Shapes
|
||||
public double LegWidth { get; set; }
|
||||
public double LegHeight { get; set; }
|
||||
|
||||
public override string GenerateName() => $"L {Dim(Width)}x{Dim(Height)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Width = 8;
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace OpenNest.Shapes
|
||||
public int Sides { get; set; }
|
||||
public double Width { get; set; }
|
||||
|
||||
public override string GenerateName() => $"{Sides}-Sided Polygon {Dim(Width)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Sides = 8;
|
||||
|
||||
@@ -13,6 +13,14 @@ namespace OpenNest.Shapes
|
||||
public double PipeClearance { get; set; }
|
||||
public bool Blind { get; set; }
|
||||
|
||||
public override string GenerateName()
|
||||
{
|
||||
var name = $"Pipe Flange {Dim(OD)} OD";
|
||||
if (!string.IsNullOrEmpty(PipeSize))
|
||||
name += $" {PipeSize} Pipe";
|
||||
return name;
|
||||
}
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
OD = 7.5;
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace OpenNest.Shapes
|
||||
public double Length { get; set; }
|
||||
public double Width { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Rectangle {Dim(Length)}x{Dim(Width)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Length = 12;
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace OpenNest.Shapes
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Right Triangle {Dim(Width)}x{Dim(Height)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Width = 8;
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace OpenNest.Shapes
|
||||
public double OuterDiameter { get; set; }
|
||||
public double InnerDiameter { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Ring {Dim(OuterDiameter)}x{Dim(InnerDiameter)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
OuterDiameter = 10;
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace OpenNest.Shapes
|
||||
public double Width { get; set; }
|
||||
public double Radius { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Rounded Rectangle {Dim(Length)}x{Dim(Width)} R{Dim(Radius)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Length = 12;
|
||||
|
||||
@@ -26,6 +26,14 @@ namespace OpenNest.Shapes
|
||||
|
||||
public abstract Drawing GetDrawing();
|
||||
|
||||
public virtual string GenerateName()
|
||||
{
|
||||
var typeName = GetType().Name;
|
||||
return typeName.EndsWith("Shape")
|
||||
? typeName.Substring(0, typeName.Length - 5)
|
||||
: typeName;
|
||||
}
|
||||
|
||||
public virtual void SetPreviewDefaults() { }
|
||||
|
||||
public static List<T> LoadFromJson<T>(string path) where T : ShapeDefinition
|
||||
@@ -34,6 +42,8 @@ namespace OpenNest.Shapes
|
||||
return JsonSerializer.Deserialize<List<T>>(json, JsonOptions);
|
||||
}
|
||||
|
||||
protected static string Dim(double value) => value.ToString("0.###");
|
||||
|
||||
protected Drawing CreateDrawing(List<Entity> entities)
|
||||
{
|
||||
var pgm = ConvertGeometry.ToProgram(entities);
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace OpenNest.Shapes
|
||||
public double StemWidth { get; set; }
|
||||
public double BarHeight { get; set; }
|
||||
|
||||
public override string GenerateName() => $"T {Dim(Width)}x{Dim(Height)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
Width = 10;
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace OpenNest.Shapes
|
||||
public double BottomWidth { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public override string GenerateName() => $"Trapezoid {Dim(TopWidth)}x{Dim(BottomWidth)}x{Dim(Height)}";
|
||||
|
||||
public override void SetPreviewDefaults()
|
||||
{
|
||||
TopWidth = 6;
|
||||
|
||||
Generated
+18
-27
@@ -47,11 +47,9 @@
|
||||
drawingListBox1 = new OpenNest.Controls.DrawingListBox();
|
||||
toolStrip2 = new System.Windows.Forms.ToolStrip();
|
||||
toolStripButton2 = new System.Windows.Forms.ToolStripButton();
|
||||
toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
shapeLibraryButton = new System.Windows.Forms.ToolStripButton();
|
||||
editDrawingsButton = new System.Windows.Forms.ToolStripButton();
|
||||
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
toolStripButton3 = new System.Windows.Forms.ToolStripButton();
|
||||
toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
hideNestedButton = new System.Windows.Forms.ToolStripButton();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||
splitContainer.Panel1.SuspendLayout();
|
||||
@@ -219,7 +217,7 @@
|
||||
//
|
||||
toolStrip2.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
toolStrip2.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripButton2, toolStripSeparator4, editDrawingsButton, toolStripSeparator1, toolStripButton3, toolStripSeparator2, hideNestedButton });
|
||||
toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripButton2, shapeLibraryButton, editDrawingsButton, toolStripButton3, hideNestedButton });
|
||||
toolStrip2.Location = new System.Drawing.Point(4, 3);
|
||||
toolStrip2.Name = "toolStrip2";
|
||||
toolStrip2.Size = new System.Drawing.Size(265, 27);
|
||||
@@ -237,14 +235,19 @@
|
||||
toolStripButton2.Size = new System.Drawing.Size(34, 24);
|
||||
toolStripButton2.Text = "Import Drawings";
|
||||
toolStripButton2.Click += ImportDrawings_Click;
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
toolStripSeparator4.Size = new System.Drawing.Size(6, 27);
|
||||
//
|
||||
//
|
||||
// shapeLibraryButton
|
||||
//
|
||||
shapeLibraryButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
shapeLibraryButton.Image = Properties.Resources.shapes;
|
||||
shapeLibraryButton.Name = "shapeLibraryButton";
|
||||
shapeLibraryButton.Padding = new System.Windows.Forms.Padding(5, 0, 5, 0);
|
||||
shapeLibraryButton.Size = new System.Drawing.Size(34, 24);
|
||||
shapeLibraryButton.Text = "Shape Library";
|
||||
shapeLibraryButton.Click += ShapeLibrary_Click;
|
||||
//
|
||||
// editDrawingsButton
|
||||
//
|
||||
//
|
||||
editDrawingsButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
editDrawingsButton.Image = (System.Drawing.Image)resources.GetObject("editDrawingsButton.Image");
|
||||
editDrawingsButton.Name = "editDrawingsButton";
|
||||
@@ -252,14 +255,9 @@
|
||||
editDrawingsButton.Size = new System.Drawing.Size(34, 24);
|
||||
editDrawingsButton.Text = "Edit Drawings in Converter";
|
||||
editDrawingsButton.Click += EditDrawingsInConverter_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
toolStripSeparator1.Size = new System.Drawing.Size(6, 27);
|
||||
//
|
||||
//
|
||||
// toolStripButton3
|
||||
//
|
||||
//
|
||||
toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
toolStripButton3.Image = (System.Drawing.Image)resources.GetObject("toolStripButton3.Image");
|
||||
toolStripButton3.Name = "toolStripButton3";
|
||||
@@ -268,12 +266,7 @@
|
||||
toolStripButton3.Size = new System.Drawing.Size(34, 24);
|
||||
toolStripButton3.Text = "Cleanup unused Drawings";
|
||||
toolStripButton3.Click += CleanUnusedDrawings_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
toolStripSeparator2.Size = new System.Drawing.Size(6, 27);
|
||||
//
|
||||
//
|
||||
// hideNestedButton
|
||||
//
|
||||
hideNestedButton.CheckOnClick = true;
|
||||
@@ -329,11 +322,9 @@
|
||||
private System.Windows.Forms.ColumnHeader utilColumn;
|
||||
private System.Windows.Forms.ToolStrip toolStrip2;
|
||||
private System.Windows.Forms.ToolStripButton toolStripButton2;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
|
||||
private System.Windows.Forms.ToolStripButton shapeLibraryButton;
|
||||
private System.Windows.Forms.ToolStripButton editDrawingsButton;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||
private System.Windows.Forms.ToolStripButton toolStripButton3;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripButton hideNestedButton;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
|
||||
private System.Windows.Forms.ToolStripButton toolStripLabel1;
|
||||
|
||||
@@ -875,6 +875,18 @@ namespace OpenNest.Forms
|
||||
Import();
|
||||
}
|
||||
|
||||
private void ShapeLibrary_Click(object sender, EventArgs e)
|
||||
{
|
||||
var form = new ShapeLibraryForm(Nest.Drawings.Select(d => d.Name));
|
||||
form.ShowDialog();
|
||||
|
||||
var drawings = form.GetDrawings();
|
||||
if (drawings.Count == 0) return;
|
||||
|
||||
drawings.ForEach(d => Nest.Drawings.Add(d));
|
||||
UpdateDrawingList();
|
||||
}
|
||||
|
||||
private void EditDrawingsInConverter_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Nest.Drawings.Count == 0)
|
||||
|
||||
@@ -837,7 +837,7 @@ namespace OpenNest.Forms
|
||||
{
|
||||
if (activeForm == null) return;
|
||||
|
||||
var form = new ShapeLibraryForm();
|
||||
var form = new ShapeLibraryForm(activeForm.Nest.Drawings.Select(d => d.Name));
|
||||
form.ShowDialog();
|
||||
|
||||
var drawings = form.GetDrawings();
|
||||
|
||||
@@ -21,12 +21,17 @@ namespace OpenNest.Forms
|
||||
private readonly List<Drawing> addedDrawings = new List<Drawing>();
|
||||
private readonly List<ShapeEntry> shapeEntries = new List<ShapeEntry>();
|
||||
private readonly List<ParameterBinding> parameterBindings = new List<ParameterBinding>();
|
||||
private readonly HashSet<string> existingNames;
|
||||
|
||||
private ShapeEntry selectedEntry;
|
||||
private bool suppressPreview;
|
||||
|
||||
public ShapeLibraryForm()
|
||||
public ShapeLibraryForm(IEnumerable<string> existingDrawingNames = null)
|
||||
{
|
||||
existingNames = existingDrawingNames != null
|
||||
? new HashSet<string>(existingDrawingNames, StringComparer.OrdinalIgnoreCase)
|
||||
: new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
InitializeComponent();
|
||||
DiscoverShapes();
|
||||
PopulateShapeList();
|
||||
@@ -259,6 +264,7 @@ namespace OpenNest.Forms
|
||||
if (shape == null) return;
|
||||
|
||||
var drawing = shape.GetDrawing();
|
||||
nameTextBox.Text = shape.GenerateName();
|
||||
previewBox.ShowDrawing(drawing);
|
||||
|
||||
if (drawing?.Program != null)
|
||||
@@ -405,10 +411,12 @@ namespace OpenNest.Forms
|
||||
if (shape == null) return;
|
||||
|
||||
var drawing = shape.GetDrawing();
|
||||
drawing.Name = GetUniqueName(drawing.Name);
|
||||
drawing.Color = Drawing.GetNextColor();
|
||||
drawing.Quantity.Required = (int)quantityUpDown.Value;
|
||||
|
||||
addedDrawings.Add(drawing);
|
||||
existingNames.Add(drawing.Name);
|
||||
DialogResult = DialogResult.OK;
|
||||
|
||||
addButton.Text = $"Added ({addedDrawings.Count})";
|
||||
@@ -423,6 +431,19 @@ namespace OpenNest.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private string GetUniqueName(string baseName)
|
||||
{
|
||||
if (!existingNames.Contains(baseName))
|
||||
return baseName;
|
||||
|
||||
for (var i = 2; ; i++)
|
||||
{
|
||||
var candidate = $"{baseName} ({i})";
|
||||
if (!existingNames.Contains(candidate))
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FriendlyName(string name)
|
||||
{
|
||||
if (name.EndsWith("Shape"))
|
||||
|
||||
+11
-1
@@ -249,7 +249,17 @@ namespace OpenNest.Properties {
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap shapes {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("shapes", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
||||
@@ -187,4 +187,7 @@
|
||||
<data name="delete" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="shapes" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\shapes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user