The creator asked why the Stream Alerts "Display" drop-down was not in the same
style as the other drop-downs. It was never given the theme's YtComboBox style -
only a hand-painted Background/Foreground. Setting colours changes the paint, not
the template, so WPF still drew the light system ComboBox (grey border, system
arrow, white popup list) on top of the dark panel. The chat Font drop-down was a
copy of the same mistake, and every check box was the light system one.
The sweep of the whole properties panel (then the app):
- ComboBox x2 (chat Font, alert Display) -> YtComboBox, hand-painted colours gone
- TextBox x16 in the properties panel -> YtTextBoxCompact (new, BasedOn YtTextBox:
11px / padding 4,2 - the panel is dense, the full 13px box would double it)
- CheckBox x2 (chat) + x3 (preview broadcast) + x1 (socials dialog) -> YtCheckBox
(new: a 14x14 rounded box + tick path, accent fill when checked)
- the layer-rename field -> YtTextBoxCompact via BasedOn, still borderless
- buttons, pills, sliders: already themed, untouched
The sweep also killed a typo'd foreground (#e0d0e0 for #e0e0e0) and the only
remaining hand-painted colour is the deliberate dimming of the two read-only path
fields.
Guard: ytLive.Tests/PropertiesStyleTests.cs (the ONE Good Dog test) parses the app
XAML and fails if an unstyled drop-down, check box or properties field comes back.
431/431 green, 0 warnings.
85 lines
4.0 KiB
C#
85 lines
4.0 KiB
C#
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
using Xunit;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>TASK 58 — the creator's style audit (2026-10-21): "in the Live scene, for the
|
|
/// layer Stream Alerts, the properties → display — why is the drop-down box not in the same
|
|
/// style as the others?" It was never given the theme's <c>YtComboBox</c> style — only a
|
|
/// hand-painted Background/Foreground — so WPF fell back to the light system template, and
|
|
/// the chat Font drop-down (copied from it) was the same. The sweep found the same smell in
|
|
/// every check box and every properties field.
|
|
///
|
|
/// <para>This test is the guard: every drop-down and check box in the app carries the theme's
|
|
/// style, and every field in the properties panel carries the compact theme style and paints
|
|
/// no colour of its own — the theme owns the look, so it cannot drift back.</para></summary>
|
|
public class PropertiesStyleTests
|
|
{
|
|
private static readonly XNamespace Xaml = "http://schemas.microsoft.com/winfx/2006/xaml";
|
|
|
|
[Fact]
|
|
public void Every_drop_down_check_box_and_properties_field_carries_the_theme_style()
|
|
{
|
|
// 1. The theme defines the styles the app relies on.
|
|
var theme = XDocument.Load(SourceAssert.RepoPath("Themes", "Controls.xaml"));
|
|
var keys = theme.Descendants()
|
|
.Where(e => e.Name.LocalName == "Style")
|
|
.Select(e => (string?)e.Attribute(Xaml + "Key"))
|
|
.Where(k => k != null)
|
|
.ToHashSet();
|
|
foreach (var required in new[] { "YtComboBox", "YtCheckBox", "YtTextBox", "YtTextBoxCompact" })
|
|
Assert.Contains(required, keys);
|
|
|
|
// 2. Every drop-down and check box in the app carries the theme style — an unstyled
|
|
// one falls back to the light WPF system template.
|
|
foreach (var file in AppXamlFiles())
|
|
{
|
|
var doc = XDocument.Load(file);
|
|
var where = Path.GetFileName(file);
|
|
|
|
foreach (var combo in doc.Descendants().Where(e => e.Name.LocalName == "ComboBox"))
|
|
AssertStyled(combo, "YtComboBox",
|
|
$"{where}: a ComboBox is not styled with YtComboBox — it renders with the light system template");
|
|
|
|
foreach (var check in doc.Descendants().Where(e => e.Name.LocalName == "CheckBox"))
|
|
AssertStyled(check, "YtCheckBox",
|
|
$"{where}: a CheckBox is not styled with YtCheckBox — it renders with the light system template");
|
|
}
|
|
|
|
// 3. Every field in the properties panel carries the compact theme style and paints
|
|
// no colours of its own.
|
|
var left = XDocument.Load(SourceAssert.RepoPath("Controls", "LeftPanel.xaml"));
|
|
var properties = left.Descendants().Single(e => e.Name.LocalName == "StackPanel"
|
|
&& (string?)e.Attribute(Xaml + "Name") == "ElementsPanel");
|
|
|
|
var fields = properties.Descendants().Where(e => e.Name.LocalName == "TextBox").ToList();
|
|
Assert.NotEmpty(fields);
|
|
foreach (var box in fields)
|
|
{
|
|
AssertStyled(box, "YtTextBoxCompact",
|
|
"a properties field is not styled with YtTextBoxCompact");
|
|
Assert.Null(box.Attribute("Background"));
|
|
Assert.Null(box.Attribute("BorderBrush"));
|
|
}
|
|
}
|
|
|
|
/// <summary>The app's XAML: the windows at the repo root plus the carved-up controls.</summary>
|
|
private static string[] AppXamlFiles()
|
|
{
|
|
var root = Path.GetDirectoryName(SourceAssert.RepoPath("ytLive.csproj"))!;
|
|
return Directory.GetFiles(root, "*.xaml", SearchOption.TopDirectoryOnly)
|
|
.Concat(Directory.GetFiles(Path.Combine(root, "Controls"), "*.xaml", SearchOption.TopDirectoryOnly))
|
|
.OrderBy(f => f)
|
|
.ToArray();
|
|
}
|
|
|
|
/// <summary>Asserts the element carries the named theme style.</summary>
|
|
private static void AssertStyled(XElement element, string key, string message)
|
|
{
|
|
var style = (string?)element.Attribute("Style");
|
|
Assert.True(style is not null && style.Contains(key, StringComparison.Ordinal), message);
|
|
}
|
|
}
|