fix(scoreboard): the strip and the social bar now really share the frame
Reported: the ticker was painting OVER the socials. The coupling rule existed and was tested (ScoreboardLayout.ResolveEdges) but nothing ever CALLED it — the strip's Y still came from its own preference, so both bars landed on the south edge. Now the resolution runs at publish time: the social bar keeps its side, the scoreboard takes the other one, and its Y follows from that edge. The pair re-sorts whenever the social bar moves (the preview click-toggle) or shows/hides, because the rule is "resolve from what is visible", not a stored pairing. The layer also gains an Edge preference (Top/Bottom) in its properties, labelled "socials take the other" — a preference, never a claim on an occupied edge. Also stabilised the opacity assertion: it samples a plate-only pixel 5px from the left edge instead of the first semi-transparent pixel it finds (which could be anti-aliased text).
This commit is contained in:
@@ -27,6 +27,22 @@ public partial class MainViewModel
|
||||
|
||||
/// <summary>Gap between the strip and the frame edge.</summary>
|
||||
private const double ScoreboardEdgeMargin = 8;
|
||||
|
||||
private BarEdge _scoreboardPreferredEdge = BarEdge.Bottom;
|
||||
|
||||
/// <summary>The edge the creator asked for. It is only a PREFERENCE: the resolver gives the
|
||||
/// scoreboard the edge the social bar does not hold (creator ruling, resolved at render time).</summary>
|
||||
public BarEdge ScoreboardEdge
|
||||
{
|
||||
get => _scoreboardPreferredEdge;
|
||||
set
|
||||
{
|
||||
if (!SetProperty(ref _scoreboardPreferredEdge, value)) return;
|
||||
RefreshScoreboardPreviews();
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<BarEdge> ScoreboardEdgeOptions { get; } = new[] { BarEdge.Top, BarEdge.Bottom };
|
||||
private Source? _scoreboardPreviewSource;
|
||||
|
||||
internal ScoreboardRecorder ScoreboardRecorder => _scoreboard;
|
||||
@@ -219,16 +235,18 @@ public partial class MainViewModel
|
||||
frame.BgraPixels, frame.Width * 4, 0);
|
||||
source.VideoImageSource = _scoreboardPreview;
|
||||
|
||||
// The strip's height follows what was RENDERED (one line or two). A fixed 56px box
|
||||
// squashed a wrapped strip instead of showing it, and its Y follows from the edge.
|
||||
if (Math.Abs(source.Height - frame.Height) > 0.5)
|
||||
{
|
||||
source.Width = frame.Width;
|
||||
source.Height = frame.Height;
|
||||
source.Y = _scoreboardStyle is var _ && source.Y > 540
|
||||
? 1080 - frame.Height - ScoreboardEdgeMargin
|
||||
: ScoreboardEdgeMargin;
|
||||
}
|
||||
// The strip's box follows what was RENDERED (one or two lines), and its edge comes
|
||||
// from the SHARED rule: the social bar keeps its side, the scoreboard takes the other.
|
||||
var socialEdge = _socials?.BarPosition == SocialBarPosition.Top ? BarEdge.Top : BarEdge.Bottom;
|
||||
var (_, resolved) = ScoreboardLayout.ResolveEdges(
|
||||
socialVisible: SocialBarVisible, socialPreferred: socialEdge,
|
||||
scoreboardVisible: true, scoreboardPreferred: _scoreboardPreferredEdge);
|
||||
|
||||
source.Width = frame.Width;
|
||||
source.Height = frame.Height;
|
||||
source.Y = resolved == BarEdge.Top
|
||||
? ScoreboardEdgeMargin
|
||||
: 1080 - frame.Height - ScoreboardEdgeMargin;
|
||||
_scoreboardPreviewSource = source;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user