diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardStatistic.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardStatistic.cs new file mode 100644 index 000000000000..7d1883833b8e --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardStatistic.cs @@ -0,0 +1,114 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Online.Leaderboards; +using osu.Game.Overlays; +using osuTK; + +namespace osu.Game.Tests.Visual.Online +{ + public partial class TestSceneLeaderboardStatistic : OsuTestScene + { + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine); + + [Cached] + private OsuColour colours = new OsuColour(); + + private FillFlowContainer container = null!; + private LeaderboardStatistic[] statistics = []; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create container", () => + { + Child = new Container + { + Masking = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = 50, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray3, + }, + container = new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Horizontal = 20 }, + Spacing = new Vector2(20, 0) + }, + }, + }; + }); + } + + [Test] + public void TestTwoElements() + { + AddStep("create content", () => + { + container.AddRange(statistics = new[] + { + new LeaderboardStatistic("COMBO", "123x", false), + new LeaderboardStatistic("ACCURACY", "100.00%", true), + }); + }); + AddStep("change to vertical", () => + { + container.Direction = FillDirection.Vertical; + container.ScaleTo(0.8f, 200, Easing.OutQuint); + }); + AddStep("change to horizontal", () => + { + container.Direction = FillDirection.Horizontal; + container.ScaleTo(1, 200, Easing.OutQuint); + }); + } + + [Test] + public void TestThreeElements() + { + AddStep("create content", () => + { + container.AddRange(statistics = new[] + { + new LeaderboardStatistic("COMBO", "123x", false), + new LeaderboardStatistic("ACCURACY", "100.00%", true), + new LeaderboardStatistic("TEST", "12345", false), + }); + }); + AddStep("change to vertical", () => + { + container.Direction = FillDirection.Vertical; + container.ScaleTo(0.8f, 200, Easing.OutQuint); + + foreach (var statistic in statistics) + statistic.Direction = Direction.Vertical; + }); + AddStep("change to horizontal", () => + { + container.Direction = FillDirection.Horizontal; + container.ScaleTo(1, 200, Easing.OutQuint); + + foreach (var statistic in statistics) + statistic.Direction = Direction.Horizontal; + }); + } + } +} diff --git a/osu.Game/Online/Leaderboards/LeaderboardStatistic.cs b/osu.Game/Online/Leaderboards/LeaderboardStatistic.cs new file mode 100644 index 000000000000..8eb33e7ca108 --- /dev/null +++ b/osu.Game/Online/Leaderboards/LeaderboardStatistic.cs @@ -0,0 +1,93 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Online.Leaderboards +{ + public partial class LeaderboardStatistic : Container + { + private readonly LocalisableString name; + private readonly LocalisableString value; + + private readonly bool perfect; + + private Direction direction; + + public Direction Direction + { + get => direction; + set + { + direction = value; + + if (IsLoaded) + recreateText(); + } + } + + [Resolved] + private OsuColour colours { get; set; } = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + private readonly Container content; + private readonly OsuTextFlowContainer textFlow; + + public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos); + + public LeaderboardStatistic(LocalisableString name, LocalisableString value, bool perfect, float? minWidth = null) + { + this.name = name; + this.value = value; + this.perfect = perfect; + + AutoSizeAxes = Axes.Both; + Child = content = new Container + { + AutoSizeAxes = Axes.Both, + Child = textFlow = new OsuTextFlowContainer + { + AutoSizeAxes = Axes.Both, + ParagraphSpacing = 0.1f, + }, + }; + + if (minWidth != null) + Add(Empty().With(d => d.Width = minWidth.Value)); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + recreateText(); + } + + private void recreateText() + { + textFlow.Clear(); + + textFlow.AddText($"{name}{(direction == Direction.Horizontal ? "\n" : "")}", t => + { + t.Font = OsuFont.Style.Caption2.With(weight: FontWeight.SemiBold); + t.Colour = colourProvider.Content2; + }); + + textFlow.AddText(value, t => + { + t.Font = OsuFont.Style.Body; + t.Colour = perfect ? colours.Lime1 : Color4.White; + t.Padding = new MarginPadding { Left = direction == Direction.Horizontal ? 0 : 5 }; + }); + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs b/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs index bb96c97d520a..16fce9a3cd75 100644 --- a/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs +++ b/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs @@ -324,9 +324,9 @@ private void load() Direction = FillDirection.Horizontal, Children = new Drawable[] { - new ScoreComponentLabel(BeatmapsetsStrings.ShowScoreboardHeadersCombo.ToUpper(), $"{Score.MaxCombo.ToString()}x", + new LeaderboardStatistic(BeatmapsetsStrings.ShowScoreboardHeadersCombo.ToUpper(), $"{Score.MaxCombo.ToString()}x", Score.MaxCombo == Score.GetMaximumAchievableCombo(), 60), - new ScoreComponentLabel(BeatmapsetsStrings.ShowScoreboardHeadersAccuracy.ToUpper(), Score.DisplayAccuracy, Score.Accuracy == 1, + new LeaderboardStatistic(BeatmapsetsStrings.ShowScoreboardHeadersAccuracy.ToUpper(), Score.DisplayAccuracy, Score.Accuracy == 1, 55), }, Alpha = 0, @@ -659,55 +659,6 @@ public DateLabel(DateTimeOffset date) protected override LocalisableString Format() => Date.ToShortRelativeTime(TimeSpan.FromSeconds(30)); } - private partial class ScoreComponentLabel : Container - { - private readonly LocalisableString name; - private readonly LocalisableString value; - private readonly bool perfect; - private readonly float minWidth; - - private FillFlowContainer content = null!; - public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos); - - public ScoreComponentLabel(LocalisableString name, LocalisableString value, bool perfect, float minWidth) - { - this.name = name; - this.value = value; - this.perfect = perfect; - this.minWidth = minWidth; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, OverlayColourProvider colourProvider) - { - AutoSizeAxes = Axes.Both; - Child = content = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new[] - { - new OsuSpriteText - { - Colour = colourProvider.Content2, - Text = name, - Font = OsuFont.Style.Caption2.With(weight: FontWeight.SemiBold), - }, - new OsuSpriteText - { - // We don't want the value setting the horizontal size, since it leads to wonky accuracy container length, - // since the accuracy is sometimes longer than its name. - BypassAutoSizeAxes = Axes.X, - Text = value, - Font = OsuFont.Style.Body, - Colour = perfect ? colours.Lime1 : Color4.White, - }, - Empty().With(d => d.Width = minWidth), - } - }; - } - } - private partial class RankLabel : Container, IHasTooltip { private readonly bool darkText;