feat(scoreboard): units 7+8 — the layer's properties panel (facts, colours, plate, size)
Selecting a Scoreboard layer now shows its settings, using the app's own widgets only: - eight fact checkboxes (subscribers, watch hours, Super Chats, new members, milestones, last member, last Super Chat, last gift) - text colour and plate colour via YtComboBox over BorderColorPalette (the app's one palette — TASK 63's rule: a picker IS the app's drop-down, never a hand-built menu) - plate on/off, plate opacity, text size 14-24 Every change pushes through the presenter (SetStyle/SetTiles) and repaints the strip, so the preview and the output follow immediately. One look per layout, stored on the view-model: the scoreboard is a single billboard, not eight independent widgets. Guard: ScoreboardPropertiesTests asserts the panel is gated on SelectedElement.IsScoreboard, binds all eight facts and the four look controls, uses YtComboBox/YtCheckBox only, and that the VM surface exists for each name (a typo would otherwise bind to nothing in silence).
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using System.Reflection;
|
||||
using Xunit;
|
||||
using ytLive.ViewModels;
|
||||
|
||||
namespace ytLive.Tests;
|
||||
|
||||
/// <summary>The scoreboard's look and its eight fact switches live in the LAYER PROPERTIES, and the
|
||||
/// panel must use the app's widgets — a hand-painted control is the TASK 58/63 defect, and the
|
||||
/// guard that catches it is here because the type-based sweep cannot see a bespoke picker.</summary>
|
||||
public class ScoreboardPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void The_scoreboard_properties_are_themed_controls_bound_to_the_layer_surface()
|
||||
{
|
||||
var panel = SourceAssert.Text("Controls", "LeftPanel.xaml");
|
||||
|
||||
// Gated on the selected layer being a scoreboard.
|
||||
Assert.Contains("SelectedElement.IsScoreboard", panel);
|
||||
|
||||
// The eight fact switches.
|
||||
foreach (var binding in new[]
|
||||
{
|
||||
"ScoreboardShowSubscribers", "ScoreboardShowWatchHours", "ScoreboardShowSuperChats",
|
||||
"ScoreboardShowNewMembers", "ScoreboardShowMilestones", "ScoreboardShowLastMember",
|
||||
"ScoreboardShowLastSuperChat", "ScoreboardShowLastGift",
|
||||
})
|
||||
Assert.Contains(binding, panel);
|
||||
|
||||
// Look controls: text colour, plate colour, plate opacity, text size.
|
||||
foreach (var binding in new[]
|
||||
{
|
||||
"ScoreboardTextColor", "ScoreboardBackgroundColor",
|
||||
"ScoreboardBackgroundOpacity", "ScoreboardFontSize",
|
||||
})
|
||||
Assert.Contains(binding, panel);
|
||||
|
||||
// Theme widgets only: the colour pickers are the app's drop-down (YtComboBox), never a
|
||||
// hand-built menu, and the toggles are YtCheckBox.
|
||||
var block = panel[panel.IndexOf("Scoreboard config", System.StringComparison.Ordinal)..];
|
||||
block = block[..block.IndexOf("<!-- Countdown config -->", System.StringComparison.Ordinal)];
|
||||
Assert.Contains("Style=\"{StaticResource YtComboBox}\"", block);
|
||||
Assert.Contains("Style=\"{StaticResource YtCheckBox}\"", block);
|
||||
Assert.DoesNotContain("ContextMenu", block);
|
||||
|
||||
// The VM surface exists for every binding above (a typo would bind to nothing silently).
|
||||
var type = typeof(MainViewModel);
|
||||
foreach (var name in new[]
|
||||
{
|
||||
"ScoreboardTextColor", "ScoreboardBackgroundColor", "ScoreboardBackgroundOpacity",
|
||||
"ScoreboardFontSize", "ScoreboardColorOptions", "ScoreboardShowSubscribers",
|
||||
})
|
||||
Assert.NotNull(type.GetProperty(name));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user