mirror of
https://github.com/ppy/osu.git
synced 2025-01-06 21:12:55 +08:00
Optimise leaderboard display
Adds async loading support and cleans up the code quite a bit in the process.
This commit is contained in:
parent
f6bdfa9876
commit
6c40cf08cc
@ -7,7 +7,7 @@ using OpenTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Graphics.Containers
|
namespace osu.Game.Graphics.Containers
|
||||||
{
|
{
|
||||||
internal class OsuScrollContainer : ScrollContainer
|
public class OsuScrollContainer : ScrollContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows controlling the scroll bar from any position in the container using the right mouse button.
|
/// Allows controlling the scroll bar from any position in the container using the right mouse button.
|
||||||
|
@ -17,19 +17,21 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
public class Leaderboard : Container
|
public class Leaderboard : Container
|
||||||
{
|
{
|
||||||
private readonly ScrollContainer scrollContainer;
|
private readonly ScrollContainer scrollContainer;
|
||||||
private readonly FillFlowContainer<LeaderboardScore> scrollFlow;
|
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
||||||
|
|
||||||
public Action<Score> ScoreSelected;
|
public Action<Score> ScoreSelected;
|
||||||
|
|
||||||
private readonly LoadingAnimation loading;
|
private readonly LoadingAnimation loading;
|
||||||
|
|
||||||
private IEnumerable<Score> scores;
|
private IEnumerable<Score> scores;
|
||||||
|
|
||||||
public IEnumerable<Score> Scores
|
public IEnumerable<Score> Scores
|
||||||
{
|
{
|
||||||
get { return scores; }
|
get { return scores; }
|
||||||
@ -41,33 +43,43 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
int i = 150;
|
int i = 150;
|
||||||
if (scores == null)
|
if (scores == null)
|
||||||
{
|
{
|
||||||
foreach (var c in scrollFlow.Children)
|
if (scrollFlow != null)
|
||||||
c.FadeOut(i += 10);
|
{
|
||||||
|
foreach (var c in scrollFlow.Children)
|
||||||
|
c.FadeOut(i += 10);
|
||||||
|
|
||||||
foreach (var c in scrollFlow.Children)
|
foreach (var c in scrollFlow.Children)
|
||||||
c.LifetimeEnd = Time.Current + i;
|
c.LifetimeEnd = Time.Current + i;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollFlow.Clear();
|
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||||
|
Schedule(() =>
|
||||||
i = 0;
|
|
||||||
foreach (var s in scores)
|
|
||||||
{
|
{
|
||||||
var ls = new LeaderboardScore(s, 1 + i)
|
LoadComponentAsync(new FillFlowContainer<LeaderboardScore>
|
||||||
{
|
{
|
||||||
AlwaysPresent = true,
|
RelativeSizeAxes = Axes.X,
|
||||||
Action = () => ScoreSelected?.Invoke(s),
|
AutoSizeAxes = Axes.Y,
|
||||||
State = Visibility.Hidden,
|
Spacing = new Vector2(0f, 5f),
|
||||||
};
|
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||||
scrollFlow.Add(ls);
|
ChildrenEnumerable = scores.Select(s => new LeaderboardScore(s, 1 + i) { Action = () => ScoreSelected?.Invoke(s) })
|
||||||
|
}, f =>
|
||||||
|
{
|
||||||
|
scrollFlow?.Expire();
|
||||||
|
scrollContainer.Add(scrollFlow = f);
|
||||||
|
|
||||||
using (BeginDelayedSequence(i++ * 50, true))
|
i = 0;
|
||||||
ls.Show();
|
foreach (var s in f.Children)
|
||||||
}
|
{
|
||||||
|
using (s.BeginDelayedSequence(i++ * 50, true))
|
||||||
|
s.Show();
|
||||||
|
}
|
||||||
|
|
||||||
scrollContainer.ScrollTo(0f, false);
|
scrollContainer.ScrollTo(0f, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,16 +91,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
ScrollbarVisible = false,
|
ScrollbarVisible = false,
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
scrollFlow = new FillFlowContainer<LeaderboardScore>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Spacing = new Vector2(0f, 5f),
|
|
||||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
loading = new LoadingAnimation()
|
loading = new LoadingAnimation()
|
||||||
};
|
};
|
||||||
@ -152,6 +154,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
if (!scrollContainer.IsScrolledToEnd())
|
if (!scrollContainer.IsScrolledToEnd())
|
||||||
fadeStart -= LeaderboardScore.HEIGHT;
|
fadeStart -= LeaderboardScore.HEIGHT;
|
||||||
|
|
||||||
|
if (scrollFlow == null) return;
|
||||||
|
|
||||||
foreach (var c in scrollFlow.Children)
|
foreach (var c in scrollFlow.Children)
|
||||||
{
|
{
|
||||||
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
|
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -13,14 +14,13 @@ using osu.Framework.Input;
|
|||||||
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.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
public class LeaderboardScore : OsuClickableContainer, IStateful<Visibility>
|
public class LeaderboardScore : OsuClickableContainer
|
||||||
{
|
{
|
||||||
public static readonly float HEIGHT = 60;
|
public static readonly float HEIGHT = 60;
|
||||||
|
|
||||||
@ -34,72 +34,16 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
private const float background_alpha = 0.25f;
|
private const float background_alpha = 0.25f;
|
||||||
private const float rank_width = 30;
|
private const float rank_width = 30;
|
||||||
|
|
||||||
private readonly Box background;
|
private Box background;
|
||||||
private readonly Container content;
|
private Container content;
|
||||||
private readonly Container avatar;
|
private Container avatar;
|
||||||
private readonly DrawableRank scoreRank;
|
private DrawableRank scoreRank;
|
||||||
private readonly OsuSpriteText nameLabel;
|
private OsuSpriteText nameLabel;
|
||||||
private readonly GlowingSpriteText scoreLabel;
|
private GlowingSpriteText scoreLabel;
|
||||||
private readonly ScoreComponentLabel maxCombo;
|
private ScoreComponentLabel maxCombo;
|
||||||
private readonly ScoreComponentLabel accuracy;
|
private ScoreComponentLabel accuracy;
|
||||||
private readonly Container flagBadgeContainer;
|
private Container flagBadgeContainer;
|
||||||
private readonly FillFlowContainer<ModIcon> modsContainer;
|
private FillFlowContainer<ModIcon> modsContainer;
|
||||||
|
|
||||||
private Visibility state;
|
|
||||||
|
|
||||||
public Visibility State
|
|
||||||
{
|
|
||||||
get { return state; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (state == value)
|
|
||||||
return;
|
|
||||||
state = value;
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case Visibility.Hidden:
|
|
||||||
foreach (var d in new Drawable[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
|
|
||||||
d.FadeOut();
|
|
||||||
|
|
||||||
Alpha = 0;
|
|
||||||
|
|
||||||
content.MoveToY(75);
|
|
||||||
avatar.MoveToX(75);
|
|
||||||
nameLabel.MoveToX(150);
|
|
||||||
break;
|
|
||||||
case Visibility.Visible:
|
|
||||||
this.FadeIn(200);
|
|
||||||
content.MoveToY(0, 800, Easing.OutQuint);
|
|
||||||
|
|
||||||
using (BeginDelayedSequence(100, true))
|
|
||||||
{
|
|
||||||
avatar.FadeIn(300, Easing.OutQuint);
|
|
||||||
nameLabel.FadeIn(350, Easing.OutQuint);
|
|
||||||
|
|
||||||
avatar.MoveToX(0, 300, Easing.OutQuint);
|
|
||||||
nameLabel.MoveToX(0, 350, Easing.OutQuint);
|
|
||||||
|
|
||||||
using (BeginDelayedSequence(250, true))
|
|
||||||
{
|
|
||||||
scoreLabel.FadeIn(200);
|
|
||||||
scoreRank.FadeIn(200);
|
|
||||||
|
|
||||||
using (BeginDelayedSequence(50, true))
|
|
||||||
{
|
|
||||||
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
|
|
||||||
for (int i = 0; i < drawables.Length; i++)
|
|
||||||
drawables[i].FadeIn(100 + i * 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChanged?.Invoke(State);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LeaderboardScore(Score score, int rank)
|
public LeaderboardScore(Score score, int rank)
|
||||||
{
|
{
|
||||||
@ -108,7 +52,11 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = HEIGHT;
|
Height = HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
new Container
|
||||||
@ -255,23 +203,51 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
|
ChildrenEnumerable = Score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Mod mod in Score.Mods)
|
|
||||||
{
|
|
||||||
modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.375f) });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleVisibility() => State = State == Visibility.Visible ? Visibility.Hidden : Visibility.Visible;
|
public override void Show()
|
||||||
|
{
|
||||||
|
foreach (var d in new Drawable[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
|
||||||
|
d.FadeOut();
|
||||||
|
|
||||||
public override void Hide() => State = Visibility.Hidden;
|
Alpha = 0;
|
||||||
public override void Show() => State = Visibility.Visible;
|
|
||||||
|
content.MoveToY(75);
|
||||||
|
avatar.MoveToX(75);
|
||||||
|
nameLabel.MoveToX(150);
|
||||||
|
|
||||||
|
this.FadeIn(200);
|
||||||
|
content.MoveToY(0, 800, Easing.OutQuint);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(100, true))
|
||||||
|
{
|
||||||
|
avatar.FadeIn(300, Easing.OutQuint);
|
||||||
|
nameLabel.FadeIn(350, Easing.OutQuint);
|
||||||
|
|
||||||
|
avatar.MoveToX(0, 300, Easing.OutQuint);
|
||||||
|
nameLabel.MoveToX(0, 350, Easing.OutQuint);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(250, true))
|
||||||
|
{
|
||||||
|
scoreLabel.FadeIn(200);
|
||||||
|
scoreRank.FadeIn(200);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(50, true))
|
||||||
|
{
|
||||||
|
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
|
||||||
|
for (int i = 0; i < drawables.Length; i++)
|
||||||
|
drawables[i].FadeIn(100 + i * 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnHover(InputState state)
|
protected override bool OnHover(InputState state)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user