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:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
@@ -59,6 +60,76 @@ public partial class MainViewModel
|
||||
/// (unit 7) — kept here so the panel binds one object instead of six primitives.</summary>
|
||||
internal ScoreboardStyle ScoreboardStyleState => _scoreboardStyle;
|
||||
|
||||
// ─── Properties panel surface (per layout: one scoreboard look) ────────────
|
||||
|
||||
public string ScoreboardTextColor
|
||||
{
|
||||
get => _scoreboardStyle.TextColor;
|
||||
set { _scoreboardStyle = _scoreboardStyle with { TextColor = value }; PushStyle(); }
|
||||
}
|
||||
|
||||
public bool ScoreboardBackgroundEnabled
|
||||
{
|
||||
get => _scoreboardStyle.BackgroundEnabled;
|
||||
set { _scoreboardStyle = _scoreboardStyle with { BackgroundEnabled = value }; PushStyle(); }
|
||||
}
|
||||
|
||||
public string ScoreboardBackgroundColor
|
||||
{
|
||||
get => _scoreboardStyle.BackgroundColor;
|
||||
set { _scoreboardStyle = _scoreboardStyle with { BackgroundColor = value }; PushStyle(); }
|
||||
}
|
||||
|
||||
public double ScoreboardBackgroundOpacity
|
||||
{
|
||||
get => _scoreboardStyle.BackgroundOpacity;
|
||||
set
|
||||
{
|
||||
_scoreboardStyle = _scoreboardStyle with { BackgroundOpacity = Math.Clamp(value, 0, 1) };
|
||||
PushStyle();
|
||||
}
|
||||
}
|
||||
|
||||
public double ScoreboardFontSize
|
||||
{
|
||||
get => _scoreboardStyle.FontSize;
|
||||
set
|
||||
{
|
||||
_scoreboardStyle = _scoreboardStyle with
|
||||
{
|
||||
FontSize = Math.Clamp(value, ScoreboardLayout.FloorFontSize, ScoreboardLayout.MaxFontSize),
|
||||
};
|
||||
PushStyle();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The colours offered for text and plate: the app's one palette.</summary>
|
||||
public IReadOnlyList<NamedColor> ScoreboardColorOptions => BorderColorPalette.All;
|
||||
|
||||
public bool ScoreboardShowSubscribers { get => _scoreboardTiles.Subscribers; set => SetTile(t => t.Subscribers = value); }
|
||||
public bool ScoreboardShowWatchHours { get => _scoreboardTiles.WatchHours; set => SetTile(t => t.WatchHours = value); }
|
||||
public bool ScoreboardShowSuperChats { get => _scoreboardTiles.SuperChats; set => SetTile(t => t.SuperChats = value); }
|
||||
public bool ScoreboardShowNewMembers { get => _scoreboardTiles.NewMembers; set => SetTile(t => t.NewMembers = value); }
|
||||
public bool ScoreboardShowMilestones { get => _scoreboardTiles.Milestones; set => SetTile(t => t.Milestones = value); }
|
||||
public bool ScoreboardShowLastMember { get => _scoreboardTiles.LastMember; set => SetTile(t => t.LastMember = value); }
|
||||
public bool ScoreboardShowLastSuperChat { get => _scoreboardTiles.LastSuperChat; set => SetTile(t => t.LastSuperChat = value); }
|
||||
public bool ScoreboardShowLastGift { get => _scoreboardTiles.LastGift; set => SetTile(t => t.LastGift = value); }
|
||||
|
||||
private void SetTile(Action<ScoreboardTiles> change)
|
||||
{
|
||||
change(_scoreboardTiles);
|
||||
_scoreboardPresenter?.SetTiles(_scoreboardTiles);
|
||||
RefreshScoreboardPreviews();
|
||||
OnPropertyChanged(nameof(ScoreboardTilesState));
|
||||
}
|
||||
|
||||
private void PushStyle()
|
||||
{
|
||||
_scoreboardPresenter?.SetStyle(_scoreboardStyle);
|
||||
RefreshScoreboardPreviews();
|
||||
OnPropertyChanged(nameof(ScoreboardStyleState));
|
||||
}
|
||||
|
||||
/// <summary>Publishes the strip to every scoreboard layer's preview element. The pump thread
|
||||
/// must never touch a WriteableBitmap, so this runs on the UI thread only.</summary>
|
||||
private void RefreshScoreboardPreviews()
|
||||
|
||||
Reference in New Issue
Block a user