TASK 60: the border-colour drop-down names every colour

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.
This commit is contained in:
2026-10-21 20:03:19 -07:00
parent 89f6aa3a67
commit 6271bf34c9
10 changed files with 231 additions and 16 deletions
+57
View File
@@ -0,0 +1,57 @@
# 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`**:
```csharp
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).