This PR converts the leaderboard into a full-fledged skinnable component
that can be manipulated by users at will.
Notably, this finally allows https://github.com/ppy/osu/issues/20422 to
be fixed - although it's a very mixed bag, for several reasons:
- Because of taiko players' refusal to see reason^W^W^W^Winsistence on
keeping stable behaviours related to aspect ratio treatment, I have to
assume the worst case scenario, which means than on typical
resolutions like 16:9 (or even worse, 4:3), the leaderboard will
likely not occupy as much vertical space as it probably could.
- Additionally, there's the problem of where to put the spectator list.
I settled on putting it to the right of the leaderboard, but that's
kind of janky, because the leaderboard sometimes collapses and
sometimes fully hides, leading to a very awkward space left behind. If
we had the capability to anchor elements to other elements, maybe this
could be resolved, but for now, I'm not sure what to do. I think if
some users are bothered by it they can move it where they want it. Or
delete it.
I'm not sure why this condition was written this obtusely, but
importantly it was also wrong. It fires when the selection contains
multiple items and only some are removed from it, like when
ctrl-click-unselecting an item from a multiple selection.
Closes https://github.com/ppy/osu/issues/32920.
I don't know if there's going to be other cases of breakage, but from
what I can tell these settings *not* showing infinite precision
representations was a bug with the previous implementation of number
formatting.
The rationale for this change is that the return value was mostly
useless, and at worst, misleading.
When using `LeaderboardManager`, it's assumed that a consumer will bind
to the global `Scores` list to ensure they receive updates for things
like local score changes via the internal realm subscription. If one
decides to instead use the return value of the task, it will be a static
snapshot that potentially becomes stale in the future.
I fell into this trap when refactoring the new leaderboard component
(while attempting to assert correctness that the values we are
displaying were in fact from the fetch operation we requested).
In the interest of keeping things simple, removing the return value
seems to be the best path forward.
Closes https://github.com/ppy/osu/issues/32908.
Have you ever been in a situation wherein you find out you fixed a bug
that you didn't know existed, but that makes *another* bug appear
because it was relying on the other bug? This is where I'm at right now.
But, to start from the top.
`TextFlowContainer.Text` (the setter) is a convenience property that you
use to set the text in one go. Internally it uses `AddText()`:
https://github.com/ppy/osu-framework/blob/681900ffb70adfeede4e3fa32a69da66252691ee/osu.Framework/Graphics/Containers/TextFlowContainer.cs#L81-L94
`AddText()`'s xmldoc says:
The \n character will create a new paragraph, not just a line break.
If you need \n to be a line break, use <see cref="AddParagraph{TSpriteText}(LocalisableString, Action{TSpriteText})"/> instead.
https://github.com/ppy/osu-framework/blob/681900ffb70adfeede4e3fa32a69da66252691ee/osu.Framework/Graphics/Containers/TextFlowContainer.cs#L226-L239
That's right. This portion of xmldoc was *straight up false* and
*silently broken* before https://github.com/ppy/osu-framework/pull/6556.
If you want to check that out yourself, apply the following patch to
framework:
diff --git a/osu.Framework.Tests/Visual/Containers/TestSceneTextFlowContainer.cs b/osu.Framework.Tests/Visual/Containers/TestSceneTextFlowContainer.cs
index 464f47c2c..e1ad521a7 100644
--- a/osu.Framework.Tests/Visual/Containers/TestSceneTextFlowContainer.cs
+++ b/osu.Framework.Tests/Visual/Containers/TestSceneTextFlowContainer.cs
@@ -180,6 +180,22 @@ public void TestAlignmentIsCorrectWhenLineBreaksAtLastWordOfParagraph(Anchor tex
});
}
+ [Test]
+ public void TestSetTextWithNewLine()
+ {
+ AddStep("set text", () => textContainer.Text = "this text\nhas a newline");
+ AddStep("clear and add text", () =>
+ {
+ textContainer.Clear();
+ textContainer.AddText("this text\nhas a newline");
+ });
+ AddStep("clear and add paragraph", () =>
+ {
+ textContainer.Clear();
+ textContainer.AddParagraph("this text\nhas a newline");
+ });
+ }
+
private void assertSpriteTextCount(int count)
=> AddAssert($"text flow has {count} sprite texts", () => textContainer.ChildrenOfType<SpriteText>().Count() == count);
On `master`, there will be a difference between the first two steps, and
the third. On 2025.321.0, *there will be none*.
My working theory as to why this was always busted is that the
corresponding code that was there before in
https://github.com/bdach/osu-framework/blob/c31a48178889ca2f9b4d257d2d64915eee90338a/osu.Framework/Graphics/Containers/TextFlowContainer.cs#L454-L458
just straight up ran too late. *The height of the container is being
changed after the flow has laid itself out, without adjusting subsequent
children in any way.*
There is potentially a discussion to be had as to whether the emergent
behaviour of `TextFlowContainer.Text` with respect to `\n` character is
correct, but I'm just going to start with this diff and see what the
reaction is.