Revert "fix(ui): make part fills, labels and the cut trail easier to read"

This reverts commit 66afea5a51.
This commit is contained in:
aj committed 2026-10-18 20:14:18 -04:00
1 parent 9d68945e75
commit 87b6d7ee90
6 files changed
+24 -123

No files matched your search

@@ -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);
}
}
+1 -1
View File
@@ -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),
+13 -16
View File
@@ -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),
},
};
+1 -2
View File
@@ -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);
+5 -6
View File
@@ -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);
+4 -20
View File
@@ -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
);
}
/// <summary>
/// Black or white, whichever contrasts more with <paramref name="fill"/> (WCAG relative
/// luminance; the two are equal at a luminance of about 0.179).
/// </summary>
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();