mirror of
https://github.com/ppy/osu.git
synced 2026-06-06 22:45:53 +08:00
Merge pull request #33142 from frenzibyte/ssv2-score-opens-results
SongSelectV2: Open results screen when clicking leaderboard scores
This commit is contained in:
@@ -15,10 +15,12 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Toolbar;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Footer;
|
||||
using osu.Game.Screens.Menu;
|
||||
@@ -33,6 +35,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
protected BeatmapManager Beatmaps { get; private set; } = null!;
|
||||
protected RealmRulesetStore Rulesets { get; private set; } = null!;
|
||||
protected OsuConfigManager Config { get; private set; } = null!;
|
||||
protected ScoreManager ScoreManager { get; private set; } = null!;
|
||||
|
||||
private RealmDetachedBeatmapStore beatmapStore = null!;
|
||||
|
||||
@@ -51,6 +54,9 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Cached(typeof(INotificationOverlay))]
|
||||
private readonly INotificationOverlay notificationOverlay = new NotificationOverlay();
|
||||
|
||||
[Cached]
|
||||
protected readonly LeaderboardManager LeaderboardManager = new LeaderboardManager();
|
||||
|
||||
protected SongSelectTestScene()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
@@ -60,6 +66,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
LeaderboardManager,
|
||||
new Toolbar
|
||||
{
|
||||
State = { Value = Visibility.Visible },
|
||||
@@ -90,6 +97,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
dependencies.Cache(Realm);
|
||||
dependencies.Cache(Beatmaps = new BeatmapManager(LocalStorage, Realm, null, Dependencies.Get<AudioManager>(), Resources, Dependencies.Get<GameHost>(), Beatmap.Default));
|
||||
dependencies.Cache(Config = new OsuConfigManager(LocalStorage));
|
||||
dependencies.Cache(ScoreManager = new ScoreManager(Rulesets, () => Beatmaps, LocalStorage, Realm, API, Config));
|
||||
|
||||
dependencies.CacheAs<BeatmapStore>(beatmapStore = new RealmDetachedBeatmapStore());
|
||||
|
||||
|
||||
@@ -8,12 +8,19 @@ using NUnit.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
using osuTK.Input;
|
||||
using FooterButtonMods = osu.Game.Screens.SelectV2.FooterButtonMods;
|
||||
using FooterButtonOptions = osu.Game.Screens.SelectV2.FooterButtonOptions;
|
||||
@@ -22,6 +29,55 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
public partial class TestSceneSongSelect : SongSelectTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestResultsScreenWhenClickingLeaderboardScore()
|
||||
{
|
||||
LoadSongSelect();
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
AddAssert("beatmap imported", () => Beatmaps.GetAllUsableBeatmapSets().Any(), () => Is.True);
|
||||
|
||||
// song select should automatically select the beatmap for us but this is not implemented yet.
|
||||
// todo: remove when that's the case.
|
||||
AddAssert("no beatmap selected", () => Beatmap.IsDefault);
|
||||
AddStep("select beatmap", () => Beatmap.Value = Beatmaps.GetWorkingBeatmap(Beatmaps.GetAllUsableBeatmapSets().Single().Beatmaps.First()));
|
||||
AddAssert("beatmap selected", () => !Beatmap.IsDefault);
|
||||
|
||||
AddStep("import score", () =>
|
||||
{
|
||||
var beatmapInfo = Beatmaps.GetAllUsableBeatmapSets().Single().Beatmaps.First();
|
||||
ScoreManager.Import(new ScoreInfo
|
||||
{
|
||||
Hash = Guid.NewGuid().ToString(),
|
||||
BeatmapHash = beatmapInfo.Hash,
|
||||
BeatmapInfo = beatmapInfo,
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
User = new GuestUser(),
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("select ranking tab", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(SongSelect.ChildrenOfType<BeatmapDetailsArea.WedgeSelector<BeatmapDetailsArea.Header.Selection>>().Last());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
// probably should be done via dropdown menu instead of forcing this way?
|
||||
AddStep("set local scope", () =>
|
||||
{
|
||||
var current = LeaderboardManager.CurrentCriteria!;
|
||||
LeaderboardManager.FetchWithCriteria(new LeaderboardCriteria(current.Beatmap, current.Ruleset, BeatmapLeaderboardScope.Local, null));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for score panel", () => SongSelect.ChildrenOfType<BeatmapLeaderboardScore>().Any());
|
||||
AddStep("click score panel", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(SongSelect.ChildrenOfType<BeatmapLeaderboardScore>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("wait for results screen", () => Stack.CurrentScreen is ResultsScreen);
|
||||
}
|
||||
|
||||
#region Hotkeys
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -50,6 +50,9 @@ namespace osu.Game.Screens.SelectV2
|
||||
[Resolved]
|
||||
private OverlayColourProvider colourProvider { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private ISongSelect? songSelect { get; set; }
|
||||
|
||||
private Container<Placeholder> placeholderContainer = null!;
|
||||
private Placeholder? placeholder;
|
||||
|
||||
@@ -244,6 +247,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
Rank = i + 1,
|
||||
IsPersonalBest = s.OnlineID == userScore?.OnlineID,
|
||||
SelectedMods = { BindTarget = mods },
|
||||
Action = () => onLeaderboardScoreClicked(s),
|
||||
}), loadedScores =>
|
||||
{
|
||||
int delay = 200;
|
||||
@@ -279,6 +283,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
IsPersonalBest = true,
|
||||
Rank = userScore.Position,
|
||||
SelectedMods = { BindTarget = mods },
|
||||
Action = () => onLeaderboardScoreClicked(userScore),
|
||||
};
|
||||
|
||||
scoresScroll.TransformTo(nameof(scoresScroll.Padding), new MarginPadding { Bottom = personal_best_height }, 300, Easing.OutQuint);
|
||||
@@ -308,6 +313,8 @@ namespace osu.Game.Screens.SelectV2
|
||||
scoresScroll.TransformTo(nameof(scoresScroll.Padding), new MarginPadding(), 300, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private void onLeaderboardScoreClicked(ScoreInfo score) => songSelect?.PresentScore(score);
|
||||
|
||||
private LeaderboardState displayedState;
|
||||
|
||||
protected void SetState(LeaderboardState state)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private ISongSelectBeatmapActions? beatmapActions { get; set; }
|
||||
private ISongSelect? songSelect { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour)
|
||||
@@ -51,7 +51,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
public Framework.Graphics.UserInterface.Popover GetPopover() => new Popover(this, beatmap.Value)
|
||||
{
|
||||
ColourProvider = colourProvider,
|
||||
BeatmapActions = beatmapActions
|
||||
SongSelect = songSelect
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
// Can't use DI for these due to popover being initialised from a footer button which ends up being on the global
|
||||
// PopoverContainer.
|
||||
public ISongSelectBeatmapActions? BeatmapActions { get; init; }
|
||||
public ISongSelect? SongSelect { get; init; }
|
||||
public required OverlayColourProvider ColourProvider { get; init; }
|
||||
|
||||
public Popover(FooterButtonOptions footerButton, WorkingBeatmap beatmap)
|
||||
@@ -59,20 +59,20 @@ namespace osu.Game.Screens.SelectV2
|
||||
};
|
||||
|
||||
addHeader(CommonStrings.General);
|
||||
addButton(SongSelectStrings.ManageCollections, FontAwesome.Solid.Book, () => BeatmapActions?.ManageCollections());
|
||||
addButton(SongSelectStrings.ManageCollections, FontAwesome.Solid.Book, () => SongSelect?.ManageCollections());
|
||||
|
||||
addHeader(SongSelectStrings.ForAllDifficulties, beatmap.BeatmapSetInfo.ToString());
|
||||
addButton(SongSelectStrings.DeleteBeatmap, FontAwesome.Solid.Trash, () => BeatmapActions?.Delete(beatmap.BeatmapSetInfo), colours.Red1);
|
||||
addButton(SongSelectStrings.DeleteBeatmap, FontAwesome.Solid.Trash, () => SongSelect?.Delete(beatmap.BeatmapSetInfo), colours.Red1);
|
||||
|
||||
addHeader(SongSelectStrings.ForSelectedDifficulty, beatmap.BeatmapInfo.DifficultyName);
|
||||
// TODO: replace with "remove from played" button when beatmap is already played.
|
||||
addButton(SongSelectStrings.MarkAsPlayed, FontAwesome.Regular.TimesCircle, () => BeatmapActions?.MarkPlayed(beatmap.BeatmapInfo));
|
||||
addButton(SongSelectStrings.ClearAllLocalScores, FontAwesome.Solid.Eraser, () => BeatmapActions?.ClearScores(beatmap.BeatmapInfo), colours.Red1);
|
||||
addButton(SongSelectStrings.MarkAsPlayed, FontAwesome.Regular.TimesCircle, () => SongSelect?.MarkPlayed(beatmap.BeatmapInfo));
|
||||
addButton(SongSelectStrings.ClearAllLocalScores, FontAwesome.Solid.Eraser, () => SongSelect?.ClearScores(beatmap.BeatmapInfo), colours.Red1);
|
||||
|
||||
if (BeatmapActions?.EditingAllowed == true)
|
||||
addButton(SongSelectStrings.EditBeatmap, FontAwesome.Solid.PencilAlt, () => BeatmapActions.Edit(beatmap.BeatmapInfo));
|
||||
if (SongSelect?.EditingAllowed == true)
|
||||
addButton(SongSelectStrings.EditBeatmap, FontAwesome.Solid.PencilAlt, () => SongSelect.Edit(beatmap.BeatmapInfo));
|
||||
|
||||
addButton(WebCommonStrings.ButtonsHide.ToSentence(), FontAwesome.Solid.Magic, () => BeatmapActions?.Hide(beatmap.BeatmapInfo));
|
||||
addButton(WebCommonStrings.ButtonsHide.ToSentence(), FontAwesome.Solid.Magic, () => SongSelect?.Hide(beatmap.BeatmapInfo));
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
||||
+7
-1
@@ -2,13 +2,14 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
/// <summary>
|
||||
/// Actions exposed by song select which are used by subcomponents to perform top-level operations.
|
||||
/// </summary>
|
||||
public interface ISongSelectBeatmapActions
|
||||
public interface ISongSelect
|
||||
{
|
||||
/// <summary>
|
||||
/// Requests the user for confirmation to delete the given beatmap set.
|
||||
@@ -44,5 +45,10 @@ namespace osu.Game.Screens.SelectV2
|
||||
/// Hides a beatmap from user's vision.
|
||||
/// </summary>
|
||||
void Hide(BeatmapInfo beatmap);
|
||||
|
||||
/// <summary>
|
||||
/// Present the provided score at the results screen.
|
||||
/// </summary>
|
||||
void PresentScore(ScoreInfo score);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@@ -23,9 +24,11 @@ using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Overlays.Volume;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Footer;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Utils;
|
||||
@@ -39,8 +42,8 @@ namespace osu.Game.Screens.SelectV2
|
||||
/// This screen is intended to house all components introduced in the new song select design to add transitions and examine the overall look.
|
||||
/// This will be gradually built upon and ultimately replace <see cref="Select.SongSelect"/> once everything is in place.
|
||||
/// </summary>
|
||||
[Cached(typeof(ISongSelectBeatmapActions))]
|
||||
public abstract partial class SongSelect : OsuScreen, IKeyBindingHandler<GlobalAction>, ISongSelectBeatmapActions
|
||||
[Cached(typeof(ISongSelect))]
|
||||
public abstract partial class SongSelect : OsuScreen, IKeyBindingHandler<GlobalAction>, ISongSelect
|
||||
{
|
||||
private const float logo_scale = 0.4f;
|
||||
private const double fade_duration = 300;
|
||||
@@ -401,6 +404,18 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Opens results screen with the given score.
|
||||
/// This assumes active beatmap and ruleset selection matches the score.
|
||||
/// </summary>
|
||||
public void PresentScore(ScoreInfo score)
|
||||
{
|
||||
Debug.Assert(Beatmap.Value.BeatmapInfo.Equals(score.BeatmapInfo));
|
||||
Debug.Assert(Ruleset.Value.Equals(score.Ruleset));
|
||||
|
||||
this.Push(new SoloResultsScreen(score));
|
||||
}
|
||||
|
||||
#region Beatmap management
|
||||
|
||||
public virtual bool EditingAllowed => false;
|
||||
|
||||
Reference in New Issue
Block a user