The creator: "under Live->Layers->webcam->Properties->border color: in the drop down box, the #hex values are good, but add a corresponding color name/label next to the value." Each row now reads "#e94560 Crimson" - the hex stays exactly as it was, the colour's name goes next to it (dimmed #a0a0b0 so the hex reads first), and the tooltip becomes "Crimson (#e94560)". The 14 colours were a hard-coded string[] inside the click handler - a list of bare strings cannot carry a name, and a list hidden in UI code cannot be asserted on. They now live in Models/BorderColorPalette.cs: NamedColor(Hex, Name) + BorderColorPalette.All (the single source of truth) + NameOf(hex), which answers case-insensitively and falls back to the hex for a colour outside the palette. The picker builds its menu from the catalogue and no longer knows any colour by heart. The names are chosen not to collide - the palette has two greens, two blues and two warm colours: #00FF00 is Lime and #22c55e Emerald, #0000FF is Blue and #3b82f6 Azure, #FF8800 is Orange and #f59e0b Amber. Guard: ytLive.Tests/BorderColorPaletteTests.cs - every entry valid + named, no hex or name repeated, the 14 legacy colours all still offered, NameOf answers, and the old list is gone from the handler. 433/433 green, 0 warnings.
2.6 KiB
TASK 60 — The border-colour drop-down names every colour
Status: ✅ Done — shipped 2026-10-21.
What it is
The creator (2026-10-21), on Live → Layers → webcam → Properties → Border Color:
in the drop down box, the #hex values are good, but add a corresponding color name/label next to the value
So each row of the drop-down now reads #e94560 Crimson: the hex stays exactly as
it was, the colour's name goes next to it (dimmed, so the hex reads first), and the
tooltip becomes Crimson (#e94560).
The palette is the single source of truth
The 14 colours were a hard-coded string[] inside the click handler
(WebcamBorderColorPicker_Click in Controls/LeftPanel.xaml.cs) — a list that could not
carry a name, and a second place to edit if a colour were added. They now live in
Models/BorderColorPalette.cs:
public readonly record struct NamedColor(string Hex, string Name);
public static class BorderColorPalette
{
public static IReadOnlyList<NamedColor> All { get; } = new NamedColor[]
{
new("#FFFFFF", "White"), new("#000000", "Black"), new("#FF0000", "Red"),
new("#00FF00", "Lime"), new("#0000FF", "Blue"), new("#FFFF00", "Yellow"),
new("#FF00FF", "Magenta"), new("#00FFFF", "Cyan"), new("#FF8800", "Orange"),
new("#8800FF", "Violet"), new("#e94560", "Crimson"),new("#22c55e", "Emerald"),
new("#3b82f6", "Azure"), new("#f59e0b", "Amber"),
};
public static string NameOf(string hex); // case-insensitive; an unknown hex stays as-is
}
The names are chosen to be unambiguous next to each other (the palette has two greens,
two blues and two warm colours: #00FF00 is Lime and #22c55e Emerald;
#0000FF is Blue and #3b82f6 Azure; #FF8800 is Orange and #f59e0b
Amber).
NameOf also answers for a hex the creator typed into the field — the colours
outside the palette simply keep their hex as the "name".
The menu row
The MenuItem's Header is a horizontal StackPanel (the theme's MenuItem template
presents the header through a ContentPresenter, so any content works): the hex in the
normal foreground, the name dimmed (#a0a0b0) with a 10px gap. The swatch Icon is
unchanged.
Tests
ytLive.Tests/BorderColorPaletteTests.cs — the ONE test for this change: every entry has
a valid hex and a name, no hex or name repeats, the 14 colours the picker used to offer
are all still offered, NameOf answers in any case and falls back to the hex, and the
picker builds its menu from the palette (no second list left in the code-behind).