Merge remote-tracking branch 'peppy/leaderboard-modularity' into timeshift-wip

# Conflicts:
#	osu.Game/Online/Leaderboards/Leaderboard.cs
#	osu.Game/Online/Leaderboards/LeaderboardScore.cs
#	osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs
#	osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
This commit is contained in:
smoogipoo
2018-12-22 15:33:26 +09:00
3 changed files with 46 additions and 40 deletions

View File

@ -18,14 +18,14 @@ using osuTK.Graphics;
namespace osu.Game.Online.Leaderboards namespace osu.Game.Online.Leaderboards
{ {
public abstract class Leaderboard<TScope, TScoreModel> : Container public abstract class Leaderboard<TScope, ScoreInfo> : Container
{ {
private const double fade_duration = 300; private const double fade_duration = 300;
private readonly ScrollContainer scrollContainer; private readonly ScrollContainer scrollContainer;
private readonly Container placeholderContainer; private readonly Container placeholderContainer;
private FillFlowContainer<LeaderboardScore<TScoreModel>> scrollFlow; private FillFlowContainer<LeaderboardScore> scrollFlow;
private readonly LoadingAnimation loading; private readonly LoadingAnimation loading;
@ -33,9 +33,9 @@ namespace osu.Game.Online.Leaderboards
private bool scoresLoadedOnce; private bool scoresLoadedOnce;
private IEnumerable<TScoreModel> scores; private IEnumerable<ScoreInfo> scores;
public IEnumerable<TScoreModel> Scores public IEnumerable<ScoreInfo> Scores
{ {
get { return scores; } get { return scores; }
set set
@ -55,13 +55,13 @@ namespace osu.Game.Online.Leaderboards
// ensure placeholder is hidden when displaying scores // ensure placeholder is hidden when displaying scores
PlaceholderState = PlaceholderState.Successful; PlaceholderState = PlaceholderState.Successful;
var flow = scrollFlow = new FillFlowContainer<LeaderboardScore<TScoreModel>> var flow = scrollFlow = new FillFlowContainer<LeaderboardScore>
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 5f), Spacing = new Vector2(0f, 5f),
Padding = new MarginPadding { Top = 10, Bottom = 5 }, Padding = new MarginPadding { Top = 10, Bottom = 5 },
ChildrenEnumerable = scores.Select((s, index) => CreateScoreVisualiser(s, index + 1)) ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1))
}; };
// schedule because we may not be loaded yet (LoadComponentAsync complains). // schedule because we may not be loaded yet (LoadComponentAsync complains).
@ -240,7 +240,7 @@ namespace osu.Game.Online.Leaderboards
}); });
} }
protected abstract APIRequest FetchScores(Action<IEnumerable<TScoreModel>> scoresCallback); protected abstract APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback);
private Placeholder currentPlaceholder; private Placeholder currentPlaceholder;
@ -295,6 +295,6 @@ namespace osu.Game.Online.Leaderboards
} }
} }
protected abstract LeaderboardScore<TScoreModel> CreateScoreVisualiser(TScoreModel model, int index); protected abstract LeaderboardScore CreateDrawableScore(ScoreInfo model, int index);
} }
} }

View File

@ -13,7 +13,6 @@ using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Users; using osu.Game.Users;
@ -22,15 +21,12 @@ using osuTK.Graphics;
namespace osu.Game.Online.Leaderboards namespace osu.Game.Online.Leaderboards
{ {
public static class LeaderboardScore public class LeaderboardScore : OsuClickableContainer
{
public const float HEIGHT = 60;
}
public abstract class LeaderboardScore<TScoreModel> : OsuClickableContainer
{ {
public readonly int RankPosition; public readonly int RankPosition;
public const float HEIGHT = 60;
private const float corner_radius = 5; private const float corner_radius = 5;
private const float edge_margin = 5; private const float edge_margin = 5;
private const float background_alpha = 0.25f; private const float background_alpha = 0.25f;
@ -38,7 +34,7 @@ namespace osu.Game.Online.Leaderboards
protected Container RankContainer { get; private set; } protected Container RankContainer { get; private set; }
private readonly TScoreModel score; private readonly ScoreInfo score;
private Box background; private Box background;
private Container content; private Container content;
@ -51,21 +47,21 @@ namespace osu.Game.Online.Leaderboards
private List<ScoreComponentLabel> statisticsLabels; private List<ScoreComponentLabel> statisticsLabels;
protected LeaderboardScore(TScoreModel score, int rank) public LeaderboardScore(ScoreInfo score, int rank)
{ {
this.score = score; this.score = score;
RankPosition = rank; RankPosition = rank;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = LeaderboardScore.HEIGHT; Height = HEIGHT;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
var user = GetUser(score); var user = score.User;
statisticsLabels = GetStatistics(score).Select(s => new ScoreComponentLabel(s.icon, s.value, s.name)).ToList(); statisticsLabels = GetStatistics(score).Select(s => new ScoreComponentLabel(s)).ToList();
Children = new Drawable[] Children = new Drawable[]
{ {
@ -129,13 +125,13 @@ namespace osu.Game.Online.Leaderboards
}) })
{ {
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Size = new Vector2(LeaderboardScore.HEIGHT - edge_margin * 2, LeaderboardScore.HEIGHT - edge_margin * 2), Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2),
}, },
new Container new Container
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
Position = new Vector2(LeaderboardScore.HEIGHT - edge_margin, 0f), Position = new Vector2(HEIGHT - edge_margin, 0f),
Children = new Drawable[] Children = new Drawable[]
{ {
nameLabel = new OsuSpriteText nameLabel = new OsuSpriteText
@ -191,13 +187,13 @@ namespace osu.Game.Online.Leaderboards
Spacing = new Vector2(5f, 0f), Spacing = new Vector2(5f, 0f),
Children = new Drawable[] Children = new Drawable[]
{ {
scoreLabel = new GlowingSpriteText(GetTotalScore(score).ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")), scoreLabel = new GlowingSpriteText(score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
RankContainer = new Container RankContainer = new Container
{ {
Size = new Vector2(40f, 20f), Size = new Vector2(40f, 20f),
Children = new[] Children = new[]
{ {
scoreRank = new DrawableRank(GetRank(score)) scoreRank = new DrawableRank(score.Rank)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -213,7 +209,7 @@ namespace osu.Game.Online.Leaderboards
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
ChildrenEnumerable = GetMods(score).Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) }) ChildrenEnumerable = score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
}, },
}, },
}, },
@ -259,6 +255,12 @@ namespace osu.Game.Online.Leaderboards
} }
} }
protected virtual IEnumerable<LeaderboardScoreStatistic> GetStatistics(ScoreInfo model) => new[]
{
new LeaderboardScoreStatistic(FontAwesome.fa_link, "Max Combo", model.MaxCombo.ToString()),
new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy))
};
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)
{ {
background.FadeTo(0.5f, 300, Easing.OutQuint); background.FadeTo(0.5f, 300, Easing.OutQuint);
@ -271,16 +273,6 @@ namespace osu.Game.Online.Leaderboards
base.OnHoverLost(e); base.OnHoverLost(e);
} }
protected abstract User GetUser(TScoreModel model);
protected abstract IEnumerable<Mod> GetMods(TScoreModel model);
protected abstract IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(TScoreModel model);
protected abstract int GetTotalScore(TScoreModel model);
protected abstract ScoreRank GetRank(TScoreModel model);
private class GlowingSpriteText : Container private class GlowingSpriteText : Container
{ {
public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour) public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour)
@ -339,9 +331,9 @@ namespace osu.Game.Online.Leaderboards
public string TooltipText => name; public string TooltipText => name;
public ScoreComponentLabel(FontAwesome icon, string value, string name) public ScoreComponentLabel(LeaderboardScoreStatistic statistic)
{ {
this.name = name; name = statistic.Name;
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
Child = content = new FillFlowContainer Child = content = new FillFlowContainer
@ -373,11 +365,11 @@ namespace osu.Game.Online.Leaderboards
Origin = Anchor.Centre, Origin = Anchor.Centre,
Size = new Vector2(icon_size - 6), Size = new Vector2(icon_size - 6),
Colour = OsuColour.FromHex(@"a4edff"), Colour = OsuColour.FromHex(@"a4edff"),
Icon = icon, Icon = statistic.Icon,
}, },
}, },
}, },
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa")) new GlowingSpriteText(statistic.Value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
@ -386,5 +378,19 @@ namespace osu.Game.Online.Leaderboards
}; };
} }
} }
public class LeaderboardScoreStatistic
{
public FontAwesome Icon;
public string Value;
public string Name;
public LeaderboardScoreStatistic(FontAwesome icon, string name, string value)
{
Icon = icon;
Name = name;
Value = value;
}
}
} }
} }

View File

@ -79,7 +79,7 @@ namespace osu.Game.Screens.Select.Leaderboards
return req; return req;
} }
protected override LeaderboardScore<ScoreInfo> CreateScoreVisualiser(ScoreInfo model, int index) => new BeatmapLeaderboardScore(model, index) protected override LeaderboardScore CreateDrawableScore(ScoreInfo model, int index) => new LeaderboardScore(model, index)
{ {
Action = () => ScoreSelected?.Invoke(model) Action = () => ScoreSelected?.Invoke(model)
}; };