diff --git a/OpenNest/Controls/FilterPanel.cs b/OpenNest/Controls/FilterPanel.cs index 9901011..ceddf6d 100644 --- a/OpenNest/Controls/FilterPanel.cs +++ b/OpenNest/Controls/FilterPanel.cs @@ -16,7 +16,7 @@ namespace OpenNest.Controls private readonly CollapsiblePanel bendLinesPanel; private readonly CheckedListBox layersList; - private readonly CheckedListBox colorsList; + private readonly ListBox colorsList; private readonly CheckedListBox lineTypesList; private readonly ListBox bendLinesList; private readonly LinkLabel bendAddLink; @@ -91,7 +91,7 @@ namespace OpenNest.Controls HeaderText = "Line Types (0)", Dock = DockStyle.Top, ExpandedHeight = 100, - IsExpanded = false + IsExpanded = true }; lineTypesList = CreateCheckedList(); lineTypesPanel.ContentPanel.Controls.Add(lineTypesList); @@ -102,12 +102,19 @@ namespace OpenNest.Controls HeaderText = "Colors (0)", Dock = DockStyle.Top, ExpandedHeight = 100, - IsExpanded = false + IsExpanded = true + }; + colorsList = new ListBox + { + Dock = DockStyle.Fill, + BorderStyle = BorderStyle.None, + Font = new Font("Segoe UI", 9f), + DrawMode = DrawMode.OwnerDrawFixed, + ItemHeight = 20, + SelectionMode = SelectionMode.None }; - colorsList = CreateCheckedList(); - colorsList.DrawMode = DrawMode.OwnerDrawFixed; - colorsList.ItemHeight = 20; colorsList.DrawItem += ColorsList_DrawItem; + colorsList.MouseClick += ColorsList_MouseClick; colorsPanel.ContentPanel.Controls.Add(colorsList); // Layers (always expanded) @@ -174,7 +181,7 @@ namespace OpenNest.Controls .Distinct() .Select(argb => new ColorItem(Color.FromArgb(argb))); foreach (var color in colors) - colorsList.Items.Add(color, true); // checked = visible + colorsList.Items.Add(color); colorsPanel.HeaderText = $"Colors ({colorsList.Items.Count})"; @@ -213,8 +220,9 @@ namespace OpenNest.Controls var hiddenColors = new HashSet(); for (var i = 0; i < colorsList.Items.Count; i++) { - if (!colorsList.GetItemChecked(i)) - hiddenColors.Add(((ColorItem)colorsList.Items[i]).Argb); + var item = (ColorItem)colorsList.Items[i]; + if (!item.IsChecked) + hiddenColors.Add(item.Argb); } var hiddenLineTypes = new HashSet(); @@ -242,20 +250,39 @@ namespace OpenNest.Controls list.SetItemChecked(i, isChecked); } + private void ColorsList_MouseClick(object sender, MouseEventArgs e) + { + var index = colorsList.IndexFromPoint(e.Location); + if (index < 0) return; + var item = (ColorItem)colorsList.Items[index]; + item.IsChecked = !item.IsChecked; + colorsList.Invalidate(colorsList.GetItemRectangle(index)); + FilterChanged?.Invoke(this, EventArgs.Empty); + } + private void ColorsList_DrawItem(object sender, DrawItemEventArgs e) { if (e.Index < 0) return; - e.DrawBackground(); + e.Graphics.FillRectangle(Brushes.White, e.Bounds); var colorItem = (ColorItem)colorsList.Items[e.Index]; - var swatchRect = new Rectangle(e.Bounds.Left + 20, e.Bounds.Top + 2, 16, e.Bounds.Height - 4); + var checkSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, + System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal); + var checkY = e.Bounds.Top + (e.Bounds.Height - checkSize.Height) / 2; + var checkState = colorItem.IsChecked + ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal + : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal; + CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(e.Bounds.Left + 2, checkY), checkState); + var swatchX = e.Bounds.Left + checkSize.Width + 6; + var swatchRect = new Rectangle(swatchX, e.Bounds.Top + 2, 16, e.Bounds.Height - 4); using (var brush = new SolidBrush(colorItem.Color)) e.Graphics.FillRectangle(brush, swatchRect); e.Graphics.DrawRectangle(Pens.Gray, swatchRect); - e.DrawFocusRectangle(); + TextRenderer.DrawText(e.Graphics, colorItem.ToString(), e.Font, + new Point(swatchRect.Right + 4, e.Bounds.Top + 1), SystemColors.WindowText); } public void SetPickMode(bool active) @@ -269,6 +296,7 @@ namespace OpenNest.Controls { public int Argb { get; } public Color Color { get; } + public bool IsChecked { get; set; } = true; public ColorItem(Color color) { diff --git a/OpenNest/Controls/ProgramEditorControl.cs b/OpenNest/Controls/ProgramEditorControl.cs index 041f865..191597f 100644 --- a/OpenNest/Controls/ProgramEditorControl.cs +++ b/OpenNest/Controls/ProgramEditorControl.cs @@ -50,14 +50,6 @@ namespace OpenNest.Controls contours = ContourInfo.Classify(shapes); - // Assign contour-type colors once so the CAD view also picks them up - foreach (var contour in contours) - { - var color = GetContourColor(contour.Type, false); - foreach (var entity in contour.Shape.Entities) - entity.Color = color; - } - Program = BuildProgram(contours); isDirty = false; isLoaded = true; @@ -144,33 +136,38 @@ namespace OpenNest.Controls preview.ClearPenCache(); preview.Entities.Clear(); - // Restore base colors first (undo any selection highlight) - foreach (var contour in contours) - { - var baseColor = GetContourColor(contour.Type, false); - foreach (var entity in contour.Shape.Entities) - entity.Color = baseColor; - } - for (var i = 0; i < contours.Count; i++) { var contour = contours[i]; var selected = contourList.SelectedIndices.Contains(i); + var color = GetContourColor(contour.Type, selected); - if (selected) + foreach (var entity in contour.Shape.Entities) { - var selColor = GetContourColor(contour.Type, true); - foreach (var entity in contour.Shape.Entities) - entity.Color = selColor; + var clone = CloneEntity(entity, color); + if (clone != null) + preview.Entities.Add(clone); } - - preview.Entities.AddRange(contour.Shape.Entities); } preview.ZoomToFit(); preview.Invalidate(); } + private static Entity CloneEntity(Entity entity, Color color) + { + Entity clone = entity switch + { + Line line => new Line(line.StartPoint, line.EndPoint) { Layer = line.Layer, IsVisible = line.IsVisible }, + Arc arc => new Arc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsReversed) { Layer = arc.Layer, IsVisible = arc.IsVisible }, + Circle circle => new Circle(circle.Center, circle.Radius) { Layer = circle.Layer, IsVisible = circle.IsVisible }, + _ => null, + }; + if (clone != null) + clone.Color = color; + return clone; + } + private static Color GetContourColor(ContourClassification type, bool selected) { if (selected) diff --git a/OpenNest/Forms/CadConverterForm.Designer.cs b/OpenNest/Forms/CadConverterForm.Designer.cs index 1f27f4a..50dda1e 100644 --- a/OpenNest/Forms/CadConverterForm.Designer.cs +++ b/OpenNest/Forms/CadConverterForm.Designer.cs @@ -17,14 +17,12 @@ namespace OpenNest.Forms { mainSplit = new System.Windows.Forms.SplitContainer(); fileList = new OpenNest.Controls.FileListControl(); + viewTabs = new System.Windows.Forms.TabControl(); + tabCadView = new System.Windows.Forms.TabPage(); cadViewSplit = new System.Windows.Forms.SplitContainer(); filterPanel = new OpenNest.Controls.FilterPanel(); entityView1 = new OpenNest.Controls.EntityView(); detailBar = new System.Windows.Forms.FlowLayoutPanel(); - viewTabs = new System.Windows.Forms.TabControl(); - tabCadView = new System.Windows.Forms.TabPage(); - tabProgram = new System.Windows.Forms.TabPage(); - programEditor = new OpenNest.Controls.ProgramEditorControl(); lblQty = new System.Windows.Forms.Label(); numQuantity = new System.Windows.Forms.NumericUpDown(); lblCust = new System.Windows.Forms.Label(); @@ -38,6 +36,8 @@ namespace OpenNest.Forms chkLabels = new System.Windows.Forms.CheckBox(); lblDetect = new System.Windows.Forms.Label(); cboBendDetector = new System.Windows.Forms.ComboBox(); + tabProgram = new System.Windows.Forms.TabPage(); + programEditor = new OpenNest.Controls.ProgramEditorControl(); bottomPanel1 = new OpenNest.Controls.BottomPanel(); cancelButton = new System.Windows.Forms.Button(); acceptButton = new System.Windows.Forms.Button(); @@ -45,40 +45,40 @@ namespace OpenNest.Forms mainSplit.Panel1.SuspendLayout(); mainSplit.Panel2.SuspendLayout(); mainSplit.SuspendLayout(); + viewTabs.SuspendLayout(); + tabCadView.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)cadViewSplit).BeginInit(); cadViewSplit.Panel1.SuspendLayout(); cadViewSplit.Panel2.SuspendLayout(); cadViewSplit.SuspendLayout(); detailBar.SuspendLayout(); - viewTabs.SuspendLayout(); - tabCadView.SuspendLayout(); - tabProgram.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)numQuantity).BeginInit(); + tabProgram.SuspendLayout(); bottomPanel1.SuspendLayout(); SuspendLayout(); - // + // // mainSplit - // + // mainSplit.Dock = System.Windows.Forms.DockStyle.Fill; mainSplit.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; mainSplit.Location = new System.Drawing.Point(0, 0); mainSplit.Name = "mainSplit"; - // + // // mainSplit.Panel1 - // + // mainSplit.Panel1.Controls.Add(fileList); mainSplit.Panel1MinSize = 200; - // + // // mainSplit.Panel2 - // + // mainSplit.Panel2.Controls.Add(viewTabs); mainSplit.Size = new System.Drawing.Size(1024, 670); mainSplit.SplitterDistance = 260; mainSplit.SplitterWidth = 5; mainSplit.TabIndex = 2; - // + // // fileList - // + // fileList.AllowDrop = true; fileList.BackColor = System.Drawing.Color.White; fileList.Dock = System.Windows.Forms.DockStyle.Fill; @@ -87,30 +87,51 @@ namespace OpenNest.Forms fileList.Name = "fileList"; fileList.Size = new System.Drawing.Size(260, 670); fileList.TabIndex = 0; - // + // + // viewTabs + // + viewTabs.Controls.Add(tabCadView); + viewTabs.Controls.Add(tabProgram); + viewTabs.Dock = System.Windows.Forms.DockStyle.Fill; + viewTabs.Location = new System.Drawing.Point(0, 0); + viewTabs.Name = "viewTabs"; + viewTabs.SelectedIndex = 0; + viewTabs.Size = new System.Drawing.Size(759, 670); + viewTabs.TabIndex = 0; + // + // tabCadView + // + tabCadView.Controls.Add(cadViewSplit); + tabCadView.Location = new System.Drawing.Point(4, 24); + tabCadView.Name = "tabCadView"; + tabCadView.Size = new System.Drawing.Size(751, 642); + tabCadView.TabIndex = 0; + tabCadView.Text = "CAD View"; + tabCadView.UseVisualStyleBackColor = true; + // // cadViewSplit - // + // cadViewSplit.Dock = System.Windows.Forms.DockStyle.Fill; cadViewSplit.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; cadViewSplit.Location = new System.Drawing.Point(0, 0); cadViewSplit.Name = "cadViewSplit"; - // - // cadViewSplit.Panel1 — filter panel - // + // + // cadViewSplit.Panel1 + // cadViewSplit.Panel1.Controls.Add(filterPanel); cadViewSplit.Panel1MinSize = 150; - // - // cadViewSplit.Panel2 — entity view + detail bar - // + // + // cadViewSplit.Panel2 + // cadViewSplit.Panel2.Controls.Add(entityView1); cadViewSplit.Panel2.Controls.Add(detailBar); cadViewSplit.Size = new System.Drawing.Size(751, 642); cadViewSplit.SplitterDistance = 200; cadViewSplit.SplitterWidth = 5; cadViewSplit.TabIndex = 0; - // + // // filterPanel - // + // filterPanel.AutoScroll = true; filterPanel.BackColor = System.Drawing.Color.White; filterPanel.Dock = System.Windows.Forms.DockStyle.Fill; @@ -118,6 +139,7 @@ namespace OpenNest.Forms filterPanel.Name = "filterPanel"; filterPanel.Size = new System.Drawing.Size(200, 642); filterPanel.TabIndex = 0; + filterPanel.Paint += filterPanel_Paint; // // entityView1 // @@ -128,6 +150,7 @@ namespace OpenNest.Forms entityView1.Location = new System.Drawing.Point(0, 0); entityView1.Name = "entityView1"; entityView1.OriginalEntities = null; + entityView1.PaintOverlay = null; entityView1.ShowEntityLabels = false; entityView1.SimplifierHighlight = null; entityView1.SimplifierPreview = null; @@ -153,7 +176,7 @@ namespace OpenNest.Forms detailBar.Controls.Add(lblDetect); detailBar.Controls.Add(cboBendDetector); detailBar.Dock = System.Windows.Forms.DockStyle.Bottom; - detailBar.Location = new System.Drawing.Point(0, 634); + detailBar.Location = new System.Drawing.Point(0, 606); detailBar.Name = "detailBar"; detailBar.Padding = new System.Windows.Forms.Padding(4, 6, 4, 4); detailBar.Size = new System.Drawing.Size(546, 36); @@ -308,6 +331,24 @@ namespace OpenNest.Forms cboBendDetector.Size = new System.Drawing.Size(90, 23); cboBendDetector.TabIndex = 8; // + // tabProgram + // + tabProgram.Controls.Add(programEditor); + tabProgram.Location = new System.Drawing.Point(4, 24); + tabProgram.Name = "tabProgram"; + tabProgram.Size = new System.Drawing.Size(751, 642); + tabProgram.TabIndex = 1; + tabProgram.Text = "Program"; + tabProgram.UseVisualStyleBackColor = true; + // + // programEditor + // + programEditor.Dock = System.Windows.Forms.DockStyle.Fill; + programEditor.Location = new System.Drawing.Point(0, 0); + programEditor.Name = "programEditor"; + programEditor.Size = new System.Drawing.Size(751, 642); + programEditor.TabIndex = 0; + // // bottomPanel1 // bottomPanel1.Controls.Add(cancelButton); @@ -341,50 +382,9 @@ namespace OpenNest.Forms acceptButton.Size = new System.Drawing.Size(90, 28); acceptButton.TabIndex = 1; acceptButton.Text = "Accept"; - // - // viewTabs - // - viewTabs.Controls.Add(tabCadView); - viewTabs.Controls.Add(tabProgram); - viewTabs.Dock = System.Windows.Forms.DockStyle.Fill; - viewTabs.Location = new System.Drawing.Point(0, 0); - viewTabs.Name = "viewTabs"; - viewTabs.SelectedIndex = 0; - viewTabs.Size = new System.Drawing.Size(759, 670); - viewTabs.TabIndex = 0; - // - // tabCadView - // - tabCadView.Controls.Add(cadViewSplit); - tabCadView.Location = new System.Drawing.Point(4, 24); - tabCadView.Name = "tabCadView"; - tabCadView.Padding = new System.Windows.Forms.Padding(0); - tabCadView.Size = new System.Drawing.Size(751, 642); - tabCadView.TabIndex = 0; - tabCadView.Text = "CAD View"; - tabCadView.UseVisualStyleBackColor = true; - // - // tabProgram - // - tabProgram.Controls.Add(programEditor); - tabProgram.Location = new System.Drawing.Point(4, 24); - tabProgram.Name = "tabProgram"; - tabProgram.Padding = new System.Windows.Forms.Padding(0); - tabProgram.Size = new System.Drawing.Size(751, 642); - tabProgram.TabIndex = 1; - tabProgram.Text = "Program"; - tabProgram.UseVisualStyleBackColor = true; - // - // programEditor - // - programEditor.Dock = System.Windows.Forms.DockStyle.Fill; - programEditor.Location = new System.Drawing.Point(0, 0); - programEditor.Name = "programEditor"; - programEditor.Size = new System.Drawing.Size(751, 642); - programEditor.TabIndex = 0; - // + // // CadConverterForm - // + // AllowDrop = true; AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; ClientSize = new System.Drawing.Size(1024, 720); @@ -402,6 +402,8 @@ namespace OpenNest.Forms mainSplit.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)mainSplit).EndInit(); mainSplit.ResumeLayout(false); + viewTabs.ResumeLayout(false); + tabCadView.ResumeLayout(false); cadViewSplit.Panel1.ResumeLayout(false); cadViewSplit.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)cadViewSplit).EndInit(); @@ -409,8 +411,6 @@ namespace OpenNest.Forms detailBar.ResumeLayout(false); detailBar.PerformLayout(); ((System.ComponentModel.ISupportInitialize)numQuantity).EndInit(); - viewTabs.ResumeLayout(false); - tabCadView.ResumeLayout(false); tabProgram.ResumeLayout(false); bottomPanel1.ResumeLayout(false); ResumeLayout(false); diff --git a/OpenNest/Forms/CadConverterForm.cs b/OpenNest/Forms/CadConverterForm.cs index 2ad71a3..1adbcf5 100644 --- a/OpenNest/Forms/CadConverterForm.cs +++ b/OpenNest/Forms/CadConverterForm.cs @@ -161,8 +161,6 @@ namespace OpenNest.Forms item.Entities.ForEach(e => e.Layer.IsVisible = true); ReHidePromotedEntities(item.Bends); - ApplyContourColors(item.Entities); - filterPanel.LoadItem(item.Entities, item.Bends); numQuantity.Value = item.Quantity; @@ -178,30 +176,6 @@ namespace OpenNest.Forms CheckSimplifiable(item); } - private static void ApplyContourColors(List entities) - { - var visible = entities.Where(e => e.IsVisible && e.Layer != null && e.Layer.IsVisible).ToList(); - if (visible.Count == 0) return; - - var shapes = ShapeBuilder.GetShapes(visible); - if (shapes.Count == 0) return; - - var contours = ContourInfo.Classify(shapes); - foreach (var contour in contours) - { - var color = contour.Type switch - { - ContourClassification.Perimeter => System.Drawing.Color.FromArgb(80, 180, 120), - ContourClassification.Hole => System.Drawing.Color.FromArgb(100, 140, 255), - ContourClassification.Etch => System.Drawing.Color.FromArgb(255, 170, 50), - ContourClassification.Open => System.Drawing.Color.FromArgb(200, 200, 100), - _ => System.Drawing.Color.Gray, - }; - foreach (var entity in contour.Shape.Entities) - entity.Color = color; - } - } - private void CheckSimplifiable(FileListItem item) { ResetSimplifyButton(); @@ -293,10 +267,6 @@ namespace OpenNest.Forms var normalized = ShapeProfile.NormalizeEntities(entities); programEditor.LoadEntities(normalized); staleProgram = false; - - // Refresh CAD view to show contour-type colors - entityView1.ClearPenCache(); - entityView1.Invalidate(); } private void OnBendLineSelected(object sender, int index) @@ -728,5 +698,10 @@ namespace OpenNest.Forms } #endregion + + private void filterPanel_Paint(object sender, PaintEventArgs e) + { + + } } } diff --git a/OpenNest/Forms/SplitDrawingForm.cs b/OpenNest/Forms/SplitDrawingForm.cs index 6512c80..756edfe 100644 --- a/OpenNest/Forms/SplitDrawingForm.cs +++ b/OpenNest/Forms/SplitDrawingForm.cs @@ -474,7 +474,7 @@ public partial class SplitDrawingForm : Form } // Placement preview line - if (_placingLine && _placingCursor != null) + if (_placingLine) { var isVert = _currentAxis == CutOffAxis.Vertical; var snapped = _placingCursor;