mirror of
https://github.com/ppy/osu.git
synced 2026-05-28 03:53:45 +08:00
Merge pull request #33264 from peppy/song-select-v2-hookup
SongSelectV2: Hook up screen to carousel and move selection logic up one level
This commit is contained in:
@@ -107,8 +107,9 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
Carousel = new TestBeatmapCarousel
|
||||
{
|
||||
NewItemsPresented = () => NewItemsPresentedInvocationCount++,
|
||||
ChooseRecommendedBeatmap = beatmaps => BeatmapRecommendationFunction?.Invoke(beatmaps) ?? beatmaps.First(),
|
||||
NewItemsPresented = _ => NewItemsPresentedInvocationCount++,
|
||||
RequestSelection = b => Carousel.CurrentSelection = b,
|
||||
RequestRecommendedSelection = beatmaps => Carousel.CurrentSelection = BeatmapRecommendationFunction?.Invoke(beatmaps) ?? beatmaps.First(),
|
||||
BleedTop = 50,
|
||||
BleedBottom = 50,
|
||||
Anchor = Anchor.Centre,
|
||||
|
||||
@@ -8,6 +8,7 @@ using NUnit.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
using osu.Game.Overlays.Mods;
|
||||
@@ -36,10 +37,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
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", () =>
|
||||
@@ -90,11 +87,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
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("press shift-delete", () =>
|
||||
@@ -253,11 +245,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
LoadSongSelect();
|
||||
|
||||
// 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()));
|
||||
AddStep("press right", () => InputManager.Key(Key.Right)); // press right to select in carousel, also remove.
|
||||
AddAssert("beatmap selected", () => !Beatmap.IsDefault);
|
||||
|
||||
@@ -283,11 +270,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
LoadSongSelect();
|
||||
|
||||
// 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()));
|
||||
AddStep("press right", () => InputManager.Key(Key.Right)); // press right to select in carousel, also remove.
|
||||
AddAssert("beatmap selected", () => !Beatmap.IsDefault);
|
||||
|
||||
@@ -315,11 +297,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
LoadSongSelect();
|
||||
|
||||
// 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()));
|
||||
AddStep("press right", () => InputManager.Key(Key.Right)); // press right to select in carousel, also remove.
|
||||
AddAssert("beatmap selected", () => !Beatmap.IsDefault);
|
||||
|
||||
@@ -460,17 +437,56 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
LoadSongSelect();
|
||||
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
// 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("options enabled", () => this.ChildrenOfType<FooterButtonOptions>().Single().Enabled.Value);
|
||||
|
||||
AddStep("click", () => this.ChildrenOfType<FooterButtonOptions>().Single().TriggerClick());
|
||||
AddUntilStep("popover displayed", () => this.ChildrenOfType<FooterButtonOptions.Popover>().Any(p => p.IsPresent));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectionChangedFromProtectedToNone()
|
||||
{
|
||||
ImportBeatmapForRuleset(0);
|
||||
AddStep("set protected on import", () => Realm.Write(r => r.All<BeatmapSetInfo>().First(s => !s.DeletePending).Protected = true));
|
||||
|
||||
AddStep("selected protected", () => Beatmap.Value = Beatmaps.GetWorkingBeatmap(Beatmaps.GetAllUsableBeatmapSets().First(s => s.Protected).Beatmaps.First()));
|
||||
|
||||
LoadSongSelect();
|
||||
|
||||
AddUntilStep("beatmap deselected", () => Beatmap.IsDefault);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectionChangedFromProtectedToSomething()
|
||||
{
|
||||
ImportBeatmapForRuleset(0);
|
||||
AddStep("set protected on import", () => Realm.Write(r => r.All<BeatmapSetInfo>().First(s => !s.DeletePending).Protected = true));
|
||||
|
||||
AddStep("selected protected", () => Beatmap.Value = Beatmaps.GetWorkingBeatmap(Beatmaps.GetAllUsableBeatmapSets().First(s => s.Protected).Beatmaps.First()));
|
||||
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
LoadSongSelect();
|
||||
|
||||
AddUntilStep("beatmap selected", () => !Beatmap.IsDefault);
|
||||
AddUntilStep("selection not protected", () => !Beatmap.Value.BeatmapSetInfo.Protected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectAfterDeletion()
|
||||
{
|
||||
LoadSongSelect();
|
||||
|
||||
ImportBeatmapForRuleset(0);
|
||||
AddUntilStep("beatmap selected", () => !Beatmap.IsDefault);
|
||||
|
||||
AddStep("delete all beatmaps", () => Beatmaps.Delete());
|
||||
AddUntilStep("beatmap not selected", () => Beatmap.IsDefault);
|
||||
|
||||
AddStep("restore deleted", () => Beatmaps.UndeleteAll());
|
||||
AddUntilStep("beatmap selected", () => !Beatmap.IsDefault);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFooterOptionsState()
|
||||
{
|
||||
@@ -478,16 +494,9 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
ImportBeatmapForRuleset(0);
|
||||
|
||||
// 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("options enabled", () => this.ChildrenOfType<FooterButtonOptions>().Single().Enabled.Value);
|
||||
AddStep("delete all beatmaps", () => Beatmaps.Delete());
|
||||
|
||||
// song select should automatically select the beatmap for us but this is not implemented yet.
|
||||
// todo: remove when that's the case.
|
||||
AddAssert("beatmap selected", () => !Beatmap.IsDefault);
|
||||
AddStep("select no beatmap", () => Beatmap.SetDefault());
|
||||
|
||||
|
||||
@@ -254,11 +254,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
checkMatchedBeatmaps(3);
|
||||
|
||||
// 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()));
|
||||
|
||||
AddStep("hide", () => Beatmaps.Hide(Beatmap.Value.BeatmapInfo));
|
||||
|
||||
checkMatchedBeatmaps(2);
|
||||
|
||||
@@ -90,6 +90,12 @@ namespace osu.Game.Beatmaps
|
||||
return ID == other.ID;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// ReSharper disable once NonReadonlyMemberInGetHashCode
|
||||
return ID.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString() => Metadata.GetDisplayString();
|
||||
|
||||
public bool Equals(IBeatmapSetInfo? other) => other is BeatmapSetInfo b && Equals(b);
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace osu.Game.Graphics.Carousel
|
||||
/// <summary>
|
||||
/// Called after a filter operation or change in items results in the visible carousel items changing.
|
||||
/// </summary>
|
||||
public Action? NewItemsPresented { private get; init; }
|
||||
public Action<IEnumerable<CarouselItem>>? NewItemsPresented { private get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Height of the area above the carousel that should be treated as visible due to transparency of elements in front of it.
|
||||
@@ -318,7 +318,7 @@ namespace osu.Game.Graphics.Carousel
|
||||
if (!Scroll.UserScrolling)
|
||||
scrollToSelection();
|
||||
|
||||
NewItemsPresented?.Invoke();
|
||||
NewItemsPresented?.Invoke(carouselItems);
|
||||
});
|
||||
|
||||
return items;
|
||||
|
||||
@@ -27,9 +27,14 @@ namespace osu.Game.Screens.SelectV2
|
||||
public Action<BeatmapInfo>? RequestPresentBeatmap { private get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// From the provided beatmaps, return the most appropriate one for the user's skill.
|
||||
/// From the provided beatmaps, select the most appropriate one for the user's skill.
|
||||
/// </summary>
|
||||
public Func<IEnumerable<BeatmapInfo>, BeatmapInfo>? ChooseRecommendedBeatmap { private get; init; }
|
||||
public required Action<IEnumerable<BeatmapInfo>> RequestRecommendedSelection { private get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Selection requested for the provided beatmap.
|
||||
/// </summary>
|
||||
public required Action<BeatmapInfo> RequestSelection { private get; init; }
|
||||
|
||||
public const float SPACING = 3f;
|
||||
|
||||
@@ -139,7 +144,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
// TODO: should this exist in song select instead of here?
|
||||
// we need to ensure the global beatmap is also updated alongside changes.
|
||||
if (CurrentSelection != null && CheckModelEquality(beatmap, CurrentSelection))
|
||||
CurrentSelection = matchingNewBeatmap;
|
||||
RequestSelection(matchingNewBeatmap);
|
||||
|
||||
Items.ReplaceRange(previousIndex, 1, [matchingNewBeatmap]);
|
||||
newSetBeatmaps.Remove(matchingNewBeatmap);
|
||||
@@ -190,7 +195,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
if (grouping.SetItems.TryGetValue(setInfo, out var items))
|
||||
{
|
||||
var beatmaps = items.Select(i => i.Model).OfType<BeatmapInfo>();
|
||||
CurrentSelection = ChooseRecommendedBeatmap?.Invoke(beatmaps) ?? beatmaps.First();
|
||||
RequestRecommendedSelection(beatmaps);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -202,7 +207,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentSelection = beatmapInfo;
|
||||
RequestSelection(beatmapInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
var beatmap = (BeatmapInfo)Item.Model;
|
||||
|
||||
starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, starDifficultyCancellationSource.Token, 200);
|
||||
starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, starDifficultyCancellationSource.Token, SongSelect.SELECTION_DEBOUNCE);
|
||||
starDifficultyBindable.BindValueChanged(_ => updateDisplay(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
var beatmap = (BeatmapInfo)Item.Model;
|
||||
|
||||
starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, starDifficultyCancellationSource.Token, 200);
|
||||
starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, starDifficultyCancellationSource.Token, SongSelect.SELECTION_DEBOUNCE);
|
||||
starDifficultyBindable.BindValueChanged(_ => updateDisplay(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@@ -15,10 +16,12 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Graphics.Carousel;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
@@ -32,6 +35,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Footer;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Skinning;
|
||||
@@ -47,8 +51,12 @@ namespace osu.Game.Screens.SelectV2
|
||||
/// This will be gradually built upon and ultimately replace <see cref="Select.SongSelect"/> once everything is in place.
|
||||
/// </summary>
|
||||
[Cached(typeof(ISongSelect))]
|
||||
public abstract partial class SongSelect : OsuScreen, IKeyBindingHandler<GlobalAction>, ISongSelect
|
||||
public abstract partial class SongSelect : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>, ISongSelect
|
||||
{
|
||||
// this is intentionally slightly higher than key repeat, but low enough to not impede user experience.
|
||||
// this avoids rapid churn loading when iterating the carousel using keyboard.
|
||||
public const int SELECTION_DEBOUNCE = 100;
|
||||
|
||||
private const float logo_scale = 0.4f;
|
||||
private const double fade_duration = 300;
|
||||
|
||||
@@ -56,6 +64,12 @@ namespace osu.Game.Screens.SelectV2
|
||||
public const float CORNER_RADIUS_HIDE_OFFSET = 20f;
|
||||
public const float ENTER_DURATION = 600;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this song select instance should take control of the global track,
|
||||
/// applying looping and preview offsets.
|
||||
/// </summary>
|
||||
protected bool ControlGlobalMusic { get; init; } = true;
|
||||
|
||||
private readonly ModSelectOverlay modSelectOverlay = new UserModSelectOverlay(OverlayColourScheme.Aquamarine)
|
||||
{
|
||||
ShowPresets = true,
|
||||
@@ -177,9 +191,11 @@ namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
BleedTop = FilterControl.HEIGHT_FROM_SCREEN_TOP + 5,
|
||||
BleedBottom = ScreenFooter.HEIGHT + 5,
|
||||
RequestPresentBeatmap = SelectAndStart,
|
||||
NewItemsPresented = newItemsPresented,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RequestPresentBeatmap = _ => OnStart(),
|
||||
RequestSelection = selectBeatmap,
|
||||
RequestRecommendedSelection = selectRecommendedBeatmap,
|
||||
NewItemsPresented = newItemsPresented,
|
||||
},
|
||||
noResultsPlaceholder = new NoResultsPlaceholder(),
|
||||
}
|
||||
@@ -245,10 +261,107 @@ namespace osu.Game.Screens.SelectV2
|
||||
detailsArea.Height = wedgesContainer.DrawHeight - titleWedge.LayoutSize.Y - 4;
|
||||
}
|
||||
|
||||
#region Audio
|
||||
|
||||
[Resolved]
|
||||
private MusicController music { get; set; } = null!;
|
||||
|
||||
private readonly WeakReference<ITrack?> lastTrack = new WeakReference<ITrack?>(null);
|
||||
|
||||
/// <summary>
|
||||
/// Ensures some music is playing for the current track.
|
||||
/// Will resume playback from a manual user pause if the track has changed.
|
||||
/// </summary>
|
||||
private void ensurePlayingSelected()
|
||||
{
|
||||
if (!ControlGlobalMusic)
|
||||
return;
|
||||
|
||||
ITrack track = music.CurrentTrack;
|
||||
|
||||
bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track;
|
||||
|
||||
if (!track.IsRunning && (music.UserPauseRequested != true || isNewTrack))
|
||||
{
|
||||
Logger.Log($"Song select decided to {nameof(ensurePlayingSelected)}");
|
||||
music.Play(true);
|
||||
}
|
||||
|
||||
lastTrack.SetTarget(track);
|
||||
}
|
||||
|
||||
private bool isHandlingLooping;
|
||||
|
||||
private void beginLooping()
|
||||
{
|
||||
if (!ControlGlobalMusic)
|
||||
return;
|
||||
|
||||
Debug.Assert(!isHandlingLooping);
|
||||
|
||||
isHandlingLooping = true;
|
||||
|
||||
ensureTrackLooping(Beatmap.Value, TrackChangeDirection.None);
|
||||
|
||||
music.TrackChanged += ensureTrackLooping;
|
||||
}
|
||||
|
||||
private void endLooping()
|
||||
{
|
||||
// may be called multiple times during screen exit process.
|
||||
if (!isHandlingLooping)
|
||||
return;
|
||||
|
||||
music.CurrentTrack.Looping = isHandlingLooping = false;
|
||||
|
||||
music.TrackChanged -= ensureTrackLooping;
|
||||
}
|
||||
|
||||
private void ensureTrackLooping(IWorkingBeatmap beatmap, TrackChangeDirection changeDirection)
|
||||
=> beatmap.PrepareTrackForPreview(true);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Selection handling
|
||||
|
||||
private BeatmapInfo getRecommendedBeatmap(IEnumerable<BeatmapInfo> beatmaps)
|
||||
=> difficultyRecommender?.GetRecommendedBeatmap(beatmaps) ?? beatmaps.First();
|
||||
private ScheduledDelegate? selectionDebounce;
|
||||
|
||||
private void selectRecommendedBeatmap(IEnumerable<BeatmapInfo> beatmaps)
|
||||
{
|
||||
selectBeatmap(difficultyRecommender?.GetRecommendedBeatmap(beatmaps) ?? beatmaps.First());
|
||||
}
|
||||
|
||||
private void selectBeatmap(BeatmapInfo beatmap)
|
||||
{
|
||||
carousel.CurrentSelection = beatmap;
|
||||
|
||||
selectionDebounce?.Cancel();
|
||||
selectionDebounce = Scheduler.AddDelayed(() => selectBeatmap(beatmaps.GetWorkingBeatmap(beatmap)), SELECTION_DEBOUNCE);
|
||||
}
|
||||
|
||||
private void selectBeatmap(WorkingBeatmap beatmap)
|
||||
{
|
||||
if (beatmap.BeatmapInfo.BeatmapSet!.Protected)
|
||||
return;
|
||||
|
||||
carousel.CurrentSelection = beatmap.BeatmapInfo;
|
||||
|
||||
Beatmap.Value = beatmap;
|
||||
|
||||
if (this.IsCurrentScreen())
|
||||
ensurePlayingSelected();
|
||||
|
||||
// If not the current screen, this will be applied in OnResuming.
|
||||
if (this.IsCurrentScreen())
|
||||
{
|
||||
ApplyToBackground(backgroundModeBeatmap =>
|
||||
{
|
||||
backgroundModeBeatmap.Beatmap = beatmap;
|
||||
backgroundModeBeatmap.IgnoreUserSettings.Value = true;
|
||||
backgroundModeBeatmap.FadeColour(Color4.White, 250);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -266,6 +379,14 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
modSelectOverlay.Beatmap.BindTo(Beatmap);
|
||||
modSelectOverlay.SelectedMods.BindTo(Mods);
|
||||
|
||||
beginLooping();
|
||||
|
||||
// force reselection if entering song select with a protected beatmap
|
||||
if (Beatmap.Value.BeatmapInfo.BeatmapSet!.Protected)
|
||||
Beatmap.SetDefault();
|
||||
else
|
||||
selectBeatmap(Beatmap.Value);
|
||||
}
|
||||
|
||||
public override void OnResuming(ScreenTransitionEvent e)
|
||||
@@ -285,6 +406,13 @@ namespace osu.Game.Screens.SelectV2
|
||||
// required due to https://github.com/ppy/osu-framework/issues/3218
|
||||
modSelectOverlay.SelectedMods.Disabled = false;
|
||||
modSelectOverlay.SelectedMods.BindTo(Mods);
|
||||
|
||||
beginLooping();
|
||||
|
||||
if (Beatmap.Value.BeatmapInfo.BeatmapSet!.Protected)
|
||||
Beatmap.SetDefault();
|
||||
else
|
||||
selectBeatmap(Beatmap.Value);
|
||||
}
|
||||
|
||||
public override void OnSuspending(ScreenTransitionEvent e)
|
||||
@@ -300,6 +428,8 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
carousel.VisuallyFocusSelected = true;
|
||||
|
||||
endLooping();
|
||||
|
||||
base.OnSuspending(e);
|
||||
}
|
||||
|
||||
@@ -311,6 +441,8 @@ namespace osu.Game.Screens.SelectV2
|
||||
detailsArea.Hide();
|
||||
filterControl.Hide();
|
||||
|
||||
endLooping();
|
||||
|
||||
return base.OnExiting(e);
|
||||
}
|
||||
|
||||
@@ -368,13 +500,10 @@ namespace osu.Game.Screens.SelectV2
|
||||
private void criteriaChanged(FilterCriteria criteria)
|
||||
{
|
||||
filterDebounce?.Cancel();
|
||||
filterDebounce = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
carousel.Filter(criteria);
|
||||
}, filter_delay);
|
||||
filterDebounce = Scheduler.AddDelayed(() => { carousel.Filter(criteria); }, filter_delay);
|
||||
}
|
||||
|
||||
private void newItemsPresented()
|
||||
private void newItemsPresented(IEnumerable<CarouselItem> carouselItems)
|
||||
{
|
||||
int count = carousel.MatchedBeatmapsCount;
|
||||
|
||||
@@ -389,6 +518,16 @@ namespace osu.Game.Screens.SelectV2
|
||||
// Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918
|
||||
// but also in this case we want support for formatting a number within a string).
|
||||
filterControl.StatusText = count != 1 ? $"{count:#,0} matches" : $"{count:#,0} match";
|
||||
|
||||
if (!carouselItems.Any())
|
||||
{
|
||||
Beatmap.SetDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Beatmap.IsDefault || Beatmap.Value.BeatmapSetInfo?.DeletePending == true)
|
||||
// TODO: this should probably use random, not recommended like this.
|
||||
selectRecommendedBeatmap(carouselItems.Select(i => i.Model).OfType<BeatmapInfo>());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user