From 87b6d7ee903a11d9adfb1befeb4673d6e66cedcd Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 18 Oct 2026 20:14:18 -0400 Subject: [PATCH] Revert "fix(ui): make part fills, labels and the cut trail easier to read" This reverts commit 66afea5a51c2dde84ba36e530ec244995bc98047. --- .../ClassicPaletteTests.cs | 78 ------------------- OpenNest/ColorScheme.cs | 2 +- OpenNest/ColorSchemeRegistry.cs | 29 ++++--- OpenNest/Controls/CutSimulationOverlay.cs | 3 +- OpenNest/Forms/MainStatusBar.cs | 11 ++- OpenNest/LayoutPart.cs | 24 +----- 6 files changed, 24 insertions(+), 123 deletions(-) delete mode 100644 OpenNest.WinForms.Tests/ClassicPaletteTests.cs diff --git a/OpenNest.WinForms.Tests/ClassicPaletteTests.cs b/OpenNest.WinForms.Tests/ClassicPaletteTests.cs deleted file mode 100644 index 4c007e36..00000000 --- a/OpenNest.WinForms.Tests/ClassicPaletteTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Drawing; - -namespace OpenNest.WinForms.Tests; - -public class ClassicPaletteTests -{ - private static double Linear(byte channel) - { - var value = channel / 255.0; - return value <= 0.04045 ? value / 12.92 : System.Math.Pow((value + 0.055) / 1.055, 2.4); - } - - private static double Luminance(Color c) => 0.2126 * Linear(c.R) + 0.7152 * Linear(c.G) + 0.0722 * Linear(c.B); - - private static double Contrast(Color a, Color b) - { - var (hi, lo) = (System.Math.Max(Luminance(a), Luminance(b)), System.Math.Min(Luminance(a), Luminance(b))); - return (hi + 0.05) / (lo + 0.05); - } - - // CIE76 distance in Lab, D65. - private static (double L, double A, double B) Lab(Color c) - { - var r = Linear(c.R); - var g = Linear(c.G); - var b = Linear(c.B); - var x = (0.4124 * r + 0.3576 * g + 0.1805 * b) / 0.95047; - var y = 0.2126 * r + 0.7152 * g + 0.0722 * b; - var z = (0.0193 * r + 0.1192 * g + 0.9505 * b) / 1.08883; - static double F(double t) => t > 0.008856 ? System.Math.Cbrt(t) : 7.787 * t + 16.0 / 116; - return (116 * F(y) - 16, 500 * (F(x) - F(y)), 200 * (F(y) - F(z))); - } - - private static double DeltaE(Color a, Color b) - { - var (l1, a1, b1) = Lab(a); - var (l2, a2, b2) = Lab(b); - return System.Math.Sqrt((l1 - l2) * (l1 - l2) + (a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2)); - } - - [Fact] - public void ClassicFillsAreClearlyDistinctFromEachOther() - { - var colors = ColorSchemeRegistry.Get("Classic").PartColors; - Assert.Equal(12, colors.Length); - for (var i = 0; i < colors.Length; i++) - { - for (var j = i + 1; j < colors.Length; j++) - Assert.True(DeltaE(colors[i], colors[j]) >= 30, - $"Classic colors {i} and {j} are too similar ({DeltaE(colors[i], colors[j]):F1})."); - } - } - - [Fact] - public void ClassicFillsStayReadableAndClearOfEtchGreenAndTheSheet() - { - var scheme = ColorSchemeRegistry.Get("Classic"); - Assert.All(scheme.PartColors, color => - { - Assert.True(Contrast(color, Color.Black) >= 4.5, $"{color} is too dark for black part IDs."); - Assert.True(DeltaE(color, scheme.EtchColor) >= 50, $"{color} is too close to the etch color."); - Assert.True(DeltaE(color, scheme.LayoutFillColor) >= 25, $"{color} blends into the sheet."); - Assert.True(DeltaE(color, scheme.BackgroundColor) >= 25, $"{color} blends into the canvas."); - }); - } - - [Theory] - [InlineData(255, 255, 255, false)] - [InlineData(206, 153, 85, false)] - [InlineData(104, 113, 230, false)] - [InlineData(30, 30, 34, true)] - [InlineData(60, 60, 140, true)] - public void LabelIsWhiteOnDarkFillsAndBlackOnLightOnes(int r, int g, int b, bool expectWhite) - { - var brush = LayoutPart.LabelBrushFor(Color.FromArgb(r, g, b)); - Assert.Same(expectWhite ? Brushes.White : Brushes.Black, brush); - } -} diff --git a/OpenNest/ColorScheme.cs b/OpenNest/ColorScheme.cs index 30ece670..b80d5bfc 100644 --- a/OpenNest/ColorScheme.cs +++ b/OpenNest/ColorScheme.cs @@ -33,7 +33,7 @@ namespace OpenNest public static readonly ColorScheme Default = new ColorScheme { Name = "Classic", - BackgroundColor = Color.FromArgb(104, 108, 114), + BackgroundColor = Color.DarkGray, LayoutOutlineColor = Color.Gray, LayoutFillColor = Color.WhiteSmoke, BoundingBoxColor = Color.FromArgb(128, 128, 255), diff --git a/OpenNest/ColorSchemeRegistry.cs b/OpenNest/ColorSchemeRegistry.cs index f431db4d..11dd54f8 100644 --- a/OpenNest/ColorSchemeRegistry.cs +++ b/OpenNest/ColorSchemeRegistry.cs @@ -231,7 +231,7 @@ namespace OpenNest new ColorScheme { Name = "Classic", - BackgroundColor = Color.FromArgb(104, 108, 114), + BackgroundColor = Color.DarkGray, LayoutOutlineColor = Color.Gray, LayoutFillColor = Color.WhiteSmoke, BoundingBoxColor = Color.FromArgb(128, 128, 255), @@ -239,23 +239,20 @@ namespace OpenNest OriginColor = Color.Gray, EdgeSpacingColor = Color.FromArgb(180, 180, 180), PreviewPartColor = Color.FromArgb(255, 140, 0), - // Twelve fills at least ~35 CIE76 apart from each other (the old set had near-duplicate - // teals and purples under 10), each readable with black part IDs and clear of etch green. - // Ordered so neighboring drawings contrast. PartColors = new[] { - Color.FromArgb(206, 153, 85), - Color.FromArgb(196, 66, 221), - Color.FromArgb(196, 220, 67), - Color.FromArgb(104, 113, 230), - Color.FromArgb(62, 223, 145), - Color.FromArgb(223, 67, 118), - Color.FromArgb(135, 231, 224), - Color.FromArgb(219, 91, 64), - Color.FromArgb(82, 166, 223), - Color.FromArgb(194, 217, 148), - Color.FromArgb(212, 147, 220), - Color.FromArgb(204, 132, 135), + Color.FromArgb(205, 92, 92), + Color.FromArgb(148, 103, 189), + Color.FromArgb(75, 180, 175), + Color.FromArgb(210, 190, 75), + Color.FromArgb(190, 85, 175), + Color.FromArgb(185, 115, 85), + Color.FromArgb(120, 100, 190), + Color.FromArgb(200, 100, 140), + Color.FromArgb(80, 175, 155), + Color.FromArgb(195, 160, 85), + Color.FromArgb(175, 95, 160), + Color.FromArgb(215, 130, 130), }, }; diff --git a/OpenNest/Controls/CutSimulationOverlay.cs b/OpenNest/Controls/CutSimulationOverlay.cs index d681efa1..10f7e6ef 100644 --- a/OpenNest/Controls/CutSimulationOverlay.cs +++ b/OpenNest/Controls/CutSimulationOverlay.cs @@ -484,8 +484,7 @@ internal sealed class CutSimulationOverlay : IDisposable private sealed class TrailPens(float dpi) : IDisposable { public Pen Rapid { get; } = new(Color.FromArgb(150, 70, 150, 255), 1 * dpi) { DashStyle = DashStyle.Dash }; - // A pale casing under the orange core keeps the trail visible on red, orange and brown parts. - public Pen Glow { get; } = new(Color.FromArgb(210, 255, 255, 255), 5 * dpi) { LineJoin = LineJoin.Round }; + public Pen Glow { get; } = new(Color.FromArgb(70, 255, 140, 0), 6 * dpi) { LineJoin = LineJoin.Round }; public Pen Cut { get; } = new(Color.OrangeRed, 2 * dpi) { LineJoin = LineJoin.Round }; public Pen Scribe { get; } = new(Color.MediumOrchid, 1.5f * dpi); diff --git a/OpenNest/Forms/MainStatusBar.cs b/OpenNest/Forms/MainStatusBar.cs index 047bd61c..a0d95a87 100644 --- a/OpenNest/Forms/MainStatusBar.cs +++ b/OpenNest/Forms/MainStatusBar.cs @@ -133,12 +133,11 @@ namespace OpenNest.Forms return; } - // Same numbering as the plate header: the trailing empty "new plate" workspace isn't counted. - var plates = form.Nest.Plates; - var shown = PlateDisplayNumbering.DisplayedPlateNumber(plates, form.PlateManager.CurrentIndex); - plateIndex.Text = shown == null - ? "Plate: new" - : string.Format("Plate: {0} of {1}", shown.Value, PlateDisplayNumbering.DisplayedPlateCount(plates)); + 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); diff --git a/OpenNest/LayoutPart.cs b/OpenNest/LayoutPart.cs index 89e58ec6..d7b6c887 100644 --- a/OpenNest/LayoutPart.cs +++ b/OpenNest/LayoutPart.cs @@ -35,7 +35,7 @@ namespace OpenNest static LayoutPart() { - programIdFont = new Font(SystemFonts.DefaultFont, FontStyle.Bold); + programIdFont = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); SelectedColor = Color.FromArgb(90, 150, 200, 255); leadInPen = new Pen(Color.OrangeRed, 1.5f); } @@ -110,10 +110,10 @@ namespace OpenNest DrawDisplay(g, muted); DrawEtch(g, muted); // Keep real cuts visible even where an etch overlaps them. - g.DrawPath(muted ? Pens.DimGray : IsSelected && colorScheme.PartOutlineColor.IsEmpty ? selectedPen : pen, Path); + g.DrawPath(muted ? Pens.Gray : IsSelected && colorScheme.PartOutlineColor.IsEmpty ? selectedPen : pen, Path); if (LeadInPath != null) - g.DrawPath(muted ? Pens.DimGray : leadInPen, LeadInPath); + g.DrawPath(muted ? Pens.Gray : leadInPen, LeadInPath); } public void Draw(Graphics g, string id) => Draw(g, id, false); @@ -130,29 +130,13 @@ namespace OpenNest g.DrawString( id, programIdFont, - muted ? Brushes.DimGray : LabelBrushFor(color), + muted ? Brushes.DimGray : Brushes.Black, _labelScreenPoint.X, _labelScreenPoint.Y, sf ); } - /// - /// Black or white, whichever contrasts more with (WCAG relative - /// luminance; the two are equal at a luminance of about 0.179). - /// - internal static Brush LabelBrushFor(Color fill) - { - static double Linear(byte channel) - { - var value = channel / 255.0; - return value <= 0.04045 ? value / 12.92 : System.Math.Pow((value + 0.055) / 1.055, 2.4); - } - - var luminance = 0.2126 * Linear(fill.R) + 0.7152 * Linear(fill.G) + 0.0722 * Linear(fill.B); - return luminance > 0.179 ? Brushes.Black : Brushes.White; - } - internal void ReleaseDisplayResources() { brush?.Dispose();