fix(scoreboard): the defaults were never applied — a record struct zero-initialises

Creator's defaults: white text, Background ON (black, 20%), speed capped at 200 px/s, text size shown
in real pixels, and "plate" dropped from the label.

The important find is underneath those: `ScoreboardStyle` is a record STRUCT, and `new
ScoreboardStyle()` zero-initialises — it does NOT run the constructor's parameter defaults. So the
shipped strip had null text colour, NO background and zero opacity, whatever the source said. That is
why the Background checkbox and the opacity slider looked like they had no code behind them: the
renderer was faithfully drawing the zeros it was handed.

An explicit parameterless constructor now carries the real defaults, and the renderer test asserts
them (white / on / black / 0.20 / max speed 200) so this class of silent-zero cannot return.

Readouts fixed too: the opacity and text-size setters never raised their own property, so the numbers
never moved while the render did. Text size now reads "24 px" instead of a bare slider value, and
snaps to whole pixels.
This commit is contained in:
2026-10-30 15:24:14 -07:00
parent 28525c90aa
commit c03acd0aa0
6 changed files with 43 additions and 9 deletions
+10 -1
View File
@@ -25,13 +25,22 @@ public class ScoreboardPropertiesTests
Assert.Contains("Sign in to YouTube to use the scoreboard.", block);
Assert.Contains("CanUseScoreboard, Converter={StaticResource InverseBoolToVis}", block);
// Defaults the creator asked for, and readouts that actually move.
Assert.Contains("Background", block);
Assert.DoesNotContain("Background plate", block);
Assert.Contains("ScoreboardFontSizeLabel", block); // "24 px", not a bare number
var vm = SourceAssert.Text("ViewModels", "MainViewModel.Scoreboard.cs");
Assert.Contains("OnPropertyChanged(nameof(ScoreboardBackgroundOpacity));", vm);
Assert.Contains("OnPropertyChanged(nameof(ScoreboardFontSize));", vm);
// Dev-only labels are ORANGE, so a development affordance cannot pass for product.
Assert.Contains("Simulate (dev)", block);
Assert.Contains("Brush.Attention", block);
// Scroll speed: a real dial, persisted, with its range owned by the presenter.
Assert.Contains("ScoreboardScrollSpeed", block);
Assert.Contains("Minimum=\"20\" Maximum=\"400\"", block);
Assert.Contains("Minimum=\"20\" Maximum=\"200\"", block);
Assert.Contains("Scoreboard.ScrollSpeed", SourceAssert.Text("Services", "LayoutStore.Settings.cs"));
// The master switch sits in the same panel: off hides the strip and stops the polling.