mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 15:16:38 +09:00
Merge remote-tracking branch 'origin/master' into user-registration
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -11,7 +13,6 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input.Events;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
@ -20,9 +21,20 @@ namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
private const int fade_duration = 1000;
|
||||
|
||||
private readonly Bindable<IEnumerable<Mod>> mods = new Bindable<IEnumerable<Mod>>();
|
||||
private readonly Bindable<IEnumerable<Mod>> current = new Bindable<IEnumerable<Mod>>();
|
||||
|
||||
public Bindable<IEnumerable<Mod>> Current => mods;
|
||||
public Bindable<IEnumerable<Mod>> Current
|
||||
{
|
||||
get => current;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
|
||||
current.UnbindBindings();
|
||||
current.BindTo(value);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly FillFlowContainer<ModIcon> iconsContainer;
|
||||
private readonly OsuSpriteText unrankedText;
|
||||
@ -50,7 +62,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
}
|
||||
};
|
||||
|
||||
mods.ValueChanged += mods =>
|
||||
Current.ValueChanged += mods =>
|
||||
{
|
||||
iconsContainer.Clear();
|
||||
foreach (Mod mod in mods)
|
||||
@ -66,7 +78,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
mods.UnbindAll();
|
||||
Current.UnbindAll();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -77,7 +89,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
private void appearTransform()
|
||||
{
|
||||
if (mods.Value.Any(m => !m.Ranked))
|
||||
if (Current.Value.Any(m => !m.Ranked))
|
||||
unrankedText.FadeInFromZero(fade_duration, Easing.OutQuint);
|
||||
else
|
||||
unrankedText.Hide();
|
||||
|
@ -28,7 +28,6 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
|
||||
@ -288,7 +287,7 @@ namespace osu.Game.Screens.Play
|
||||
if (RulesetContainer.Replay == null)
|
||||
scoreManager.Import(score, true);
|
||||
|
||||
Push(new Results(score));
|
||||
Push(new SoloResults(score));
|
||||
|
||||
onCompletionEvent = null;
|
||||
});
|
||||
|
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Types;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class SoloResults : Results
|
||||
{
|
||||
public SoloResults(ScoreInfo score)
|
||||
: base(score)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
|
||||
{
|
||||
new ScoreOverviewPageInfo(Score, Beatmap),
|
||||
new BeatmapLeaderboardPageInfo(Score, Beatmap)
|
||||
};
|
||||
}
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public enum ResultMode
|
||||
public interface IResultPageInfo
|
||||
{
|
||||
Summary,
|
||||
Ranking,
|
||||
Share
|
||||
FontAwesome Icon { get; }
|
||||
|
||||
string Name { get; }
|
||||
|
||||
ResultsPage CreatePage();
|
||||
}
|
||||
}
|
@ -3,18 +3,19 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osuTK;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class ResultsPageRanking : ResultsPage
|
||||
public class RankingResultsPage : ResultsPage
|
||||
{
|
||||
public ResultsPageRanking(ScoreInfo score, WorkingBeatmap beatmap = null) : base(score, beatmap)
|
||||
public RankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap = null)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ namespace osu.Game.Screens.Ranking
|
||||
Colour = colours.GrayE,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new Leaderboard
|
||||
new BeatmapLeaderboard
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
@ -4,36 +4,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class ResultsPageScore : ResultsPage
|
||||
public class ScoreResultsPage : ResultsPage
|
||||
{
|
||||
private Container scoreContainer;
|
||||
private ScoreCounter scoreCounter;
|
||||
|
||||
public ResultsPageScore(ScoreInfo score, WorkingBeatmap beatmap) : base(score, beatmap) { }
|
||||
public ScoreResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private FillFlowContainer<DrawableScoreStatistic> statisticsContainer;
|
||||
|
@ -5,6 +5,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
@ -13,27 +14,18 @@ using osu.Framework.Graphics.Shapes;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeButton : TabItem<ResultMode>
|
||||
public class ResultModeButton : TabItem<IResultPageInfo>, IHasTooltip
|
||||
{
|
||||
private readonly FontAwesome icon;
|
||||
private Color4 activeColour;
|
||||
private Color4 inactiveColour;
|
||||
private CircularContainer colouredPart;
|
||||
|
||||
public ResultModeButton(ResultMode mode) : base(mode)
|
||||
public ResultModeButton(IResultPageInfo mode)
|
||||
: base(mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case ResultMode.Summary:
|
||||
icon = FontAwesome.fa_asterisk;
|
||||
break;
|
||||
case ResultMode.Ranking:
|
||||
icon = FontAwesome.fa_list;
|
||||
break;
|
||||
case ResultMode.Share:
|
||||
icon = FontAwesome.fa_camera;
|
||||
break;
|
||||
}
|
||||
icon = mode.Icon;
|
||||
TooltipText = mode.Name;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -95,5 +87,7 @@ namespace osu.Game.Screens.Ranking
|
||||
protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, Easing.OutQuint);
|
||||
|
||||
protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint);
|
||||
|
||||
public string TooltipText { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeTabControl : TabControl<ResultMode>
|
||||
public class ResultModeTabControl : TabControl<IResultPageInfo>
|
||||
{
|
||||
public ResultModeTabControl()
|
||||
{
|
||||
@ -19,9 +19,9 @@ namespace osu.Game.Screens.Ranking
|
||||
TabContainer.Padding = new MarginPadding(5);
|
||||
}
|
||||
|
||||
protected override Dropdown<ResultMode> CreateDropdown() => null;
|
||||
protected override Dropdown<IResultPageInfo> CreateDropdown() => null;
|
||||
|
||||
protected override TabItem<ResultMode> CreateTabItem(ResultMode value) => new ResultModeButton(value)
|
||||
protected override TabItem<IResultPageInfo> CreateTabItem(IResultPageInfo value) => new ResultModeButton(value)
|
||||
{
|
||||
Anchor = TabContainer.Anchor,
|
||||
Origin = TabContainer.Origin
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
@ -21,9 +22,8 @@ using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class Results : OsuScreen
|
||||
public abstract class Results : OsuScreen
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private Container circleOuterBackground;
|
||||
private Container circleOuter;
|
||||
private Container circleInner;
|
||||
@ -34,6 +34,8 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
public override bool AllowBeatmapRulesetChange => false;
|
||||
|
||||
protected readonly ScoreInfo Score;
|
||||
|
||||
private Container currentPage;
|
||||
|
||||
private static readonly Vector2 background_blur = new Vector2(20);
|
||||
@ -44,9 +46,9 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
private const float circle_outer_scale = 0.96f;
|
||||
|
||||
public Results(ScoreInfo score)
|
||||
protected Results(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
Score = score;
|
||||
}
|
||||
|
||||
private const float transition_time = 800;
|
||||
@ -67,7 +69,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
backgroundParallax.FadeOut();
|
||||
modeChangeButtons.FadeOut();
|
||||
currentPage.FadeOut();
|
||||
currentPage?.FadeOut();
|
||||
|
||||
circleOuterBackground
|
||||
.FadeIn(transition_time, Easing.OutQuint)
|
||||
@ -90,7 +92,7 @@ namespace osu.Game.Screens.Ranking
|
||||
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
||||
{
|
||||
modeChangeButtons.FadeIn(transition_time, Easing.OutQuint);
|
||||
currentPage.FadeIn(transition_time, Easing.OutQuint);
|
||||
currentPage?.FadeIn(transition_time, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,7 +190,7 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = $"{score.MaxCombo}x",
|
||||
Text = $"{Score.MaxCombo}x",
|
||||
TextSize = 40,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Font = @"Exo2.0-Bold",
|
||||
@ -209,7 +211,7 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = $"{score.Accuracy:P2}",
|
||||
Text = $"{Score.Accuracy:P2}",
|
||||
TextSize = 40,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Font = @"Exo2.0-Bold",
|
||||
@ -262,30 +264,22 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
};
|
||||
|
||||
modeChangeButtons.AddItem(ResultMode.Summary);
|
||||
modeChangeButtons.AddItem(ResultMode.Ranking);
|
||||
//modeChangeButtons.AddItem(ResultMode.Share);
|
||||
foreach (var t in CreateResultPages())
|
||||
modeChangeButtons.AddItem(t);
|
||||
modeChangeButtons.Current.Value = modeChangeButtons.Items.FirstOrDefault();
|
||||
|
||||
modeChangeButtons.Current.ValueChanged += mode =>
|
||||
modeChangeButtons.Current.BindValueChanged(m =>
|
||||
{
|
||||
currentPage?.FadeOut();
|
||||
currentPage?.Expire();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ResultMode.Summary:
|
||||
currentPage = new ResultsPageScore(score, Beatmap.Value);
|
||||
break;
|
||||
case ResultMode.Ranking:
|
||||
currentPage = new ResultsPageRanking(score, Beatmap.Value);
|
||||
break;
|
||||
}
|
||||
currentPage = m?.CreatePage();
|
||||
|
||||
if (currentPage != null)
|
||||
circleInner.Add(currentPage);
|
||||
};
|
||||
|
||||
modeChangeButtons.Current.TriggerChange();
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<IResultPageInfo> CreateResultPages();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultsPage : Container
|
||||
public abstract class ResultsPage : Container
|
||||
{
|
||||
protected readonly ScoreInfo Score;
|
||||
protected readonly WorkingBeatmap Beatmap;
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
protected ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
Score = score;
|
||||
Beatmap = beatmap;
|
||||
|
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class BeatmapLeaderboardPageInfo : IResultPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public BeatmapLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public FontAwesome Icon => FontAwesome.fa_list;
|
||||
|
||||
public string Name => @"Beatmap Leaderboard";
|
||||
|
||||
public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap);
|
||||
}
|
||||
}
|
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class ScoreOverviewPageInfo : IResultPageInfo
|
||||
{
|
||||
public FontAwesome Icon => FontAwesome.fa_asterisk;
|
||||
|
||||
public string Name => "Overview";
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public ScoreOverviewPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public ResultsPage CreatePage()
|
||||
{
|
||||
return new ScoreResultsPage(score, beatmap);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public readonly BeatmapDetails Details;
|
||||
public readonly Leaderboard Leaderboard;
|
||||
public readonly BeatmapLeaderboard Leaderboard;
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
public WorkingBeatmap Beatmap
|
||||
@ -52,7 +52,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
default:
|
||||
Details.Hide();
|
||||
Leaderboard.Scope = (LeaderboardScope)tab - 1;
|
||||
Leaderboard.Scope = (BeatmapLeaderboardScope)tab - 1;
|
||||
Leaderboard.Show();
|
||||
break;
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Select
|
||||
Alpha = 0,
|
||||
Margin = new MarginPadding { Top = details_padding },
|
||||
},
|
||||
Leaderboard = new Leaderboard
|
||||
Leaderboard = new BeatmapLeaderboard
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
|
@ -24,12 +24,12 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
{
|
||||
base.Filter(criteria);
|
||||
|
||||
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps;
|
||||
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || (Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
|
||||
|
||||
if (!string.IsNullOrEmpty(criteria.SearchText))
|
||||
foreach (var criteriaTerm in criteria.SearchTerms)
|
||||
match &=
|
||||
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
|
||||
Beatmap.Version.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0;
|
||||
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
|
||||
Beatmap.Version.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0;
|
||||
|
||||
Filtered.Value = !match;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
|
||||
@ -10,8 +12,22 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
public GroupMode Group;
|
||||
public SortMode Sort;
|
||||
public string SearchText;
|
||||
|
||||
public string[] SearchTerms = Array.Empty<string>();
|
||||
|
||||
public RulesetInfo Ruleset;
|
||||
public bool AllowConvertedBeatmaps;
|
||||
|
||||
private string searchText;
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get { return searchText; }
|
||||
set
|
||||
{
|
||||
searchText = value;
|
||||
SearchTerms = searchText.Split(',', ' ', '!').Where(s => !string.IsNullOrEmpty(s)).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class BeatmapLeaderboard : Leaderboard<BeatmapLeaderboardScope, ScoreInfo>
|
||||
{
|
||||
public Action<ScoreInfo> ScoreSelected;
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
if (beatmap == value)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
Scores = null;
|
||||
|
||||
UpdateScores();
|
||||
}
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private APIAccess api { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ruleset.ValueChanged += _ => UpdateScores();
|
||||
}
|
||||
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||
{
|
||||
if (Scope == BeatmapLeaderboardScope.Local)
|
||||
{
|
||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Beatmap?.OnlineBeatmapID == null)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.Unavailable;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Scope != BeatmapLeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotSupporter;
|
||||
return null;
|
||||
}
|
||||
|
||||
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||
|
||||
req.Success += r => scoresCallback?.Invoke(r.Scores);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override LeaderboardScore CreateDrawableScore(ScoreInfo model, int index) => new LeaderboardScore(model, index)
|
||||
{
|
||||
Action = () => ScoreSelected?.Invoke(model)
|
||||
};
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public enum LeaderboardScope
|
||||
public enum BeatmapLeaderboardScope
|
||||
{
|
||||
Local,
|
||||
Country,
|
@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class DrawableRank : Container
|
||||
{
|
||||
private readonly Sprite rankSprite;
|
||||
private TextureStore textures;
|
||||
|
||||
public ScoreRank Rank { get; private set; }
|
||||
|
||||
public DrawableRank(ScoreRank rank)
|
||||
{
|
||||
Rank = rank;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
rankSprite = new Sprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fit
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
this.textures = textures;
|
||||
updateTexture();
|
||||
}
|
||||
|
||||
private void updateTexture()
|
||||
{
|
||||
rankSprite.Texture = textures.Get($@"Grades/{Rank.GetDescription()}");
|
||||
}
|
||||
|
||||
public void UpdateRank(ScoreRank newRank)
|
||||
{
|
||||
Rank = newRank;
|
||||
|
||||
if (LoadState >= LoadState.Ready)
|
||||
updateTexture();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,348 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class Leaderboard : Container
|
||||
{
|
||||
private const double fade_duration = 300;
|
||||
|
||||
private readonly ScrollContainer scrollContainer;
|
||||
private readonly Container placeholderContainer;
|
||||
|
||||
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
||||
|
||||
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
public Action<ScoreInfo> ScoreSelected;
|
||||
|
||||
private readonly LoadingAnimation loading;
|
||||
|
||||
private ScheduledDelegate showScoresDelegate;
|
||||
|
||||
private bool scoresLoadedOnce;
|
||||
|
||||
private IEnumerable<ScoreInfo> scores;
|
||||
|
||||
public IEnumerable<ScoreInfo> Scores
|
||||
{
|
||||
get { return scores; }
|
||||
set
|
||||
{
|
||||
scores = value;
|
||||
|
||||
scoresLoadedOnce = true;
|
||||
|
||||
scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire();
|
||||
scrollFlow = null;
|
||||
|
||||
loading.Hide();
|
||||
|
||||
if (scores == null || !scores.Any())
|
||||
return;
|
||||
|
||||
// ensure placeholder is hidden when displaying scores
|
||||
PlaceholderState = PlaceholderState.Successful;
|
||||
|
||||
var flow = scrollFlow = new FillFlowContainer<LeaderboardScore>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||
ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) })
|
||||
};
|
||||
|
||||
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||
showScoresDelegate?.Cancel();
|
||||
if (!IsLoaded)
|
||||
showScoresDelegate = Schedule(showScores);
|
||||
else
|
||||
showScores();
|
||||
|
||||
void showScores() => LoadComponentAsync(flow, _ =>
|
||||
{
|
||||
scrollContainer.Add(flow);
|
||||
|
||||
int i = 0;
|
||||
foreach (var s in flow.Children)
|
||||
{
|
||||
using (s.BeginDelayedSequence(i++ * 50, true))
|
||||
s.Show();
|
||||
}
|
||||
|
||||
scrollContainer.ScrollTo(0f, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardScope scope;
|
||||
|
||||
public LeaderboardScope Scope
|
||||
{
|
||||
get { return scope; }
|
||||
set
|
||||
{
|
||||
if (value == scope)
|
||||
return;
|
||||
|
||||
scope = value;
|
||||
updateScores();
|
||||
}
|
||||
}
|
||||
|
||||
private PlaceholderState placeholderState;
|
||||
|
||||
/// <summary>
|
||||
/// Update the placeholder visibility.
|
||||
/// Setting this to anything other than PlaceholderState.Successful will cancel all existing retrieval requests and hide scores.
|
||||
/// </summary>
|
||||
protected PlaceholderState PlaceholderState
|
||||
{
|
||||
get { return placeholderState; }
|
||||
set
|
||||
{
|
||||
if (value != PlaceholderState.Successful)
|
||||
{
|
||||
getScoresRequest?.Cancel();
|
||||
getScoresRequest = null;
|
||||
Scores = null;
|
||||
}
|
||||
|
||||
if (value == placeholderState)
|
||||
return;
|
||||
|
||||
switch (placeholderState = value)
|
||||
{
|
||||
case PlaceholderState.NetworkFailure:
|
||||
replacePlaceholder(new RetrievalFailurePlaceholder
|
||||
{
|
||||
OnRetry = updateScores,
|
||||
});
|
||||
break;
|
||||
case PlaceholderState.Unavailable:
|
||||
replacePlaceholder(new MessagePlaceholder(@"Leaderboards are not available for this beatmap!"));
|
||||
break;
|
||||
case PlaceholderState.NoScores:
|
||||
replacePlaceholder(new MessagePlaceholder(@"No records yet!"));
|
||||
break;
|
||||
case PlaceholderState.NotLoggedIn:
|
||||
replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!"));
|
||||
break;
|
||||
case PlaceholderState.NotSupporter:
|
||||
replacePlaceholder(new MessagePlaceholder(@"Please invest in an osu!supporter tag to view this leaderboard!"));
|
||||
break;
|
||||
default:
|
||||
replacePlaceholder(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Leaderboard()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
scrollContainer = new OsuScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ScrollbarVisible = false,
|
||||
},
|
||||
loading = new LoadingAnimation(),
|
||||
placeholderContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private APIAccess api;
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; }
|
||||
|
||||
private ScheduledDelegate pendingUpdateScores;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
if (beatmap == value)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
Scores = null;
|
||||
|
||||
updateScores();
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(APIAccess api, IBindable<RulesetInfo> parentRuleset)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
ruleset.BindTo(parentRuleset);
|
||||
ruleset.ValueChanged += _ => updateScores();
|
||||
|
||||
if (api != null)
|
||||
api.OnStateChange += handleApiStateChange;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (api != null)
|
||||
api.OnStateChange -= handleApiStateChange;
|
||||
}
|
||||
|
||||
public void RefreshScores() => updateScores();
|
||||
|
||||
private GetScoresRequest getScoresRequest;
|
||||
|
||||
private void handleApiStateChange(APIState oldState, APIState newState)
|
||||
{
|
||||
if (Scope == LeaderboardScope.Local)
|
||||
// No need to respond to API state change while current scope is local
|
||||
return;
|
||||
|
||||
if (newState == APIState.Online)
|
||||
updateScores();
|
||||
}
|
||||
|
||||
private void updateScores()
|
||||
{
|
||||
// don't display any scores or placeholder until the first Scores_Set has been called.
|
||||
// this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished.
|
||||
if (!scoresLoadedOnce) return;
|
||||
|
||||
getScoresRequest?.Cancel();
|
||||
getScoresRequest = null;
|
||||
|
||||
pendingUpdateScores?.Cancel();
|
||||
pendingUpdateScores = Schedule(() =>
|
||||
{
|
||||
if (Scope == LeaderboardScope.Local)
|
||||
{
|
||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Beatmap?.OnlineBeatmapID == null)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.Unavailable;
|
||||
return;
|
||||
}
|
||||
|
||||
if (api?.IsLoggedIn != true)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotSupporter;
|
||||
return;
|
||||
}
|
||||
|
||||
PlaceholderState = PlaceholderState.Retrieving;
|
||||
loading.Show();
|
||||
|
||||
getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||
getScoresRequest.Success += r => Schedule(() =>
|
||||
{
|
||||
Scores = r.Scores;
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
});
|
||||
|
||||
getScoresRequest.Failure += e => Schedule(() =>
|
||||
{
|
||||
if (e is OperationCanceledException)
|
||||
return;
|
||||
|
||||
PlaceholderState = PlaceholderState.NetworkFailure;
|
||||
});
|
||||
|
||||
api.Queue(getScoresRequest);
|
||||
});
|
||||
}
|
||||
|
||||
private Placeholder currentPlaceholder;
|
||||
|
||||
private void replacePlaceholder(Placeholder placeholder)
|
||||
{
|
||||
if (placeholder != null && placeholder.Equals(currentPlaceholder))
|
||||
return;
|
||||
|
||||
currentPlaceholder?.FadeOut(150, Easing.OutQuint).Expire();
|
||||
|
||||
if (placeholder == null)
|
||||
{
|
||||
currentPlaceholder = null;
|
||||
return;
|
||||
}
|
||||
|
||||
placeholderContainer.Child = placeholder;
|
||||
|
||||
placeholder.ScaleTo(0.8f).Then().ScaleTo(1, fade_duration * 3, Easing.OutQuint);
|
||||
placeholder.FadeInFromZero(fade_duration, Easing.OutQuint);
|
||||
|
||||
currentPlaceholder = placeholder;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight;
|
||||
|
||||
if (!scrollContainer.IsScrolledToEnd())
|
||||
fadeStart -= LeaderboardScore.HEIGHT;
|
||||
|
||||
if (scrollFlow == null)
|
||||
return;
|
||||
|
||||
foreach (var c in scrollFlow.Children)
|
||||
{
|
||||
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
|
||||
var bottomY = topY + LeaderboardScore.HEIGHT;
|
||||
|
||||
if (bottomY < fadeStart)
|
||||
c.Colour = Color4.White;
|
||||
else if (topY > fadeStart + LeaderboardScore.HEIGHT)
|
||||
c.Colour = Color4.Transparent;
|
||||
else
|
||||
{
|
||||
c.Colour = ColourInfo.GradientVertical(
|
||||
Color4.White.Opacity(Math.Min(1 - (topY - fadeStart) / LeaderboardScore.HEIGHT, 1)),
|
||||
Color4.White.Opacity(Math.Min(1 - (bottomY - fadeStart) / LeaderboardScore.HEIGHT, 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,373 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class LeaderboardScore : OsuClickableContainer
|
||||
{
|
||||
public static readonly float HEIGHT = 60;
|
||||
|
||||
public readonly int RankPosition;
|
||||
public readonly ScoreInfo Score;
|
||||
|
||||
private const float corner_radius = 5;
|
||||
private const float edge_margin = 5;
|
||||
private const float background_alpha = 0.25f;
|
||||
private const float rank_width = 30;
|
||||
|
||||
private Box background;
|
||||
private Container content;
|
||||
private Drawable avatar;
|
||||
private DrawableRank scoreRank;
|
||||
private OsuSpriteText nameLabel;
|
||||
private GlowingSpriteText scoreLabel;
|
||||
private ScoreComponentLabel maxCombo;
|
||||
private ScoreComponentLabel accuracy;
|
||||
private Container flagBadgeContainer;
|
||||
private FillFlowContainer<ModIcon> modsContainer;
|
||||
|
||||
public LeaderboardScore(ScoreInfo score, int rank)
|
||||
{
|
||||
Score = score;
|
||||
RankPosition = rank;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = HEIGHT;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = rank_width,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
TextSize = 22,
|
||||
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
||||
Text = RankPosition.ToString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = rank_width, },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = corner_radius,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = background_alpha,
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(edge_margin),
|
||||
Children = new[]
|
||||
{
|
||||
avatar = new DelayedLoadWrapper(
|
||||
new Avatar(Score.User)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = corner_radius,
|
||||
Masking = true,
|
||||
OnLoadComplete = d => d.FadeInFromZero(200),
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 1,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
},
|
||||
})
|
||||
{
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2),
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Position = new Vector2(HEIGHT - edge_margin, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
nameLabel = new OsuSpriteText
|
||||
{
|
||||
Text = Score.User.Username,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
TextSize = 23,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
flagBadgeContainer = new Container
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Size = new Vector2(87f, 20f),
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableFlag(Score.User?.Country)
|
||||
{
|
||||
Width = 30,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
},
|
||||
},
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0f),
|
||||
Margin = new MarginPadding { Left = edge_margin },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(40f, 20f),
|
||||
Children = new[]
|
||||
{
|
||||
scoreRank = new DrawableRank(Score.Rank)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(40f),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modsContainer = new FillFlowContainer<ModIcon>
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
ChildrenEnumerable = Score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
|
||||
d.FadeOut();
|
||||
|
||||
Alpha = 0;
|
||||
|
||||
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(HoverEvent e)
|
||||
{
|
||||
background.FadeTo(0.5f, 300, Easing.OutQuint);
|
||||
return base.OnHover(e);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
background.FadeTo(background_alpha, 200, Easing.OutQuint);
|
||||
base.OnHoverLost(e);
|
||||
}
|
||||
|
||||
private class GlowingSpriteText : Container
|
||||
{
|
||||
public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new BufferedContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
BlurSigma = new Vector2(4),
|
||||
CacheDrawnFrameBuffer = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Blending = BlendingMode.Additive,
|
||||
Size = new Vector2(3f),
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = font,
|
||||
FixedWidth = true,
|
||||
TextSize = textSize,
|
||||
Text = text,
|
||||
Colour = glowColour,
|
||||
Shadow = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = font,
|
||||
FixedWidth = true,
|
||||
TextSize = textSize,
|
||||
Text = text,
|
||||
Colour = textColour,
|
||||
Shadow = false,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class ScoreComponentLabel : Container, IHasTooltip
|
||||
{
|
||||
private const float icon_size = 20;
|
||||
|
||||
private readonly string name;
|
||||
private readonly FillFlowContainer content;
|
||||
|
||||
public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos);
|
||||
|
||||
public string TooltipText => name;
|
||||
|
||||
public ScoreComponentLabel(FontAwesome icon, string value, string name)
|
||||
{
|
||||
this.name = name;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Width = 60;
|
||||
|
||||
Child = content = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(icon_size),
|
||||
Rotation = 45,
|
||||
Colour = OsuColour.FromHex(@"3087ac"),
|
||||
Icon = FontAwesome.fa_square,
|
||||
Shadow = true,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(icon_size - 6),
|
||||
Colour = OsuColour.FromHex(@"a4edff"),
|
||||
Icon = icon,
|
||||
},
|
||||
},
|
||||
},
|
||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class MessagePlaceholder : Placeholder
|
||||
{
|
||||
private readonly string message;
|
||||
|
||||
public MessagePlaceholder(string message)
|
||||
{
|
||||
AddIcon(FontAwesome.fa_exclamation_circle, cp =>
|
||||
{
|
||||
cp.TextSize = TEXT_SIZE;
|
||||
cp.Padding = new MarginPadding { Right = 10 };
|
||||
});
|
||||
|
||||
AddText(this.message = message);
|
||||
}
|
||||
|
||||
public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
|
||||
{
|
||||
protected const float TEXT_SIZE = 22;
|
||||
|
||||
protected Placeholder()
|
||||
: base(cp => cp.TextSize = TEXT_SIZE)
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
TextAnchor = Anchor.TopCentre;
|
||||
|
||||
Padding = new MarginPadding(20);
|
||||
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
}
|
||||
|
||||
public virtual bool Equals(Placeholder other) => GetType() == other?.GetType();
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public enum PlaceholderState
|
||||
{
|
||||
Successful,
|
||||
Retrieving,
|
||||
NetworkFailure,
|
||||
Unavailable,
|
||||
NoScores,
|
||||
NotLoggedIn,
|
||||
NotSupporter,
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class RetrievalFailurePlaceholder : Placeholder
|
||||
{
|
||||
public Action OnRetry;
|
||||
|
||||
public RetrievalFailurePlaceholder()
|
||||
{
|
||||
AddArbitraryDrawable(new RetryButton
|
||||
{
|
||||
Action = () => OnRetry?.Invoke(),
|
||||
Padding = new MarginPadding { Right = 10 }
|
||||
});
|
||||
|
||||
AddText(@"Couldn't retrieve scores!");
|
||||
}
|
||||
|
||||
public class RetryButton : OsuHoverContainer
|
||||
{
|
||||
private readonly SpriteIcon icon;
|
||||
|
||||
public new Action Action;
|
||||
|
||||
public RetryButton()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Child = new OsuClickableContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Action = () => Action?.Invoke(),
|
||||
Child = icon = new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(TEXT_SIZE),
|
||||
Shadow = true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
icon.ScaleTo(0.8f, 4000, Easing.OutQuint);
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
icon.ScaleTo(1, 1000, Easing.OutElastic);
|
||||
return base.OnMouseUp(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Options;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select
|
||||
});
|
||||
}
|
||||
|
||||
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new Results(s));
|
||||
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new SoloResults(s));
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
|
Reference in New Issue
Block a user