From 1edbdc5aac9f3d44e099f294991dced7a8ce43de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 May 2025 14:51:54 +0900 Subject: [PATCH] Update filter control's status text with beatmap displayed count This also fixes code running in `Update` which shouldn't be, by consuming the new `NewItemsPresented` callback. Fields and properties are renamed to knock some sense into things (was previously called two or three different things). --- .../TestSceneSongSelectFiltering.cs | 38 ++++++++++++++++-- .../TestSceneShearedSearchTextBox.cs | 2 +- .../UserInterface/ShearedFilterTextBox.cs | 10 ++--- osu.Game/Screens/SelectV2/FilterControl.cs | 6 +-- osu.Game/Screens/SelectV2/SongSelect.cs | 39 +++++++++++++------ 5 files changed, 71 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelectV2/TestSceneSongSelectFiltering.cs b/osu.Game.Tests/Visual/SongSelectV2/TestSceneSongSelectFiltering.cs index da78f19dc5..e88b47a287 100644 --- a/osu.Game.Tests/Visual/SongSelectV2/TestSceneSongSelectFiltering.cs +++ b/osu.Game.Tests/Visual/SongSelectV2/TestSceneSongSelectFiltering.cs @@ -31,6 +31,9 @@ using osu.Game.Screens.Menu; using osu.Game.Screens.Select.Filter; using osu.Game.Screens.SelectV2; using osu.Game.Tests.Resources; +using BeatmapCarousel = osu.Game.Screens.SelectV2.BeatmapCarousel; +using FilterControl = osu.Game.Screens.SelectV2.FilterControl; +using NoResultsPlaceholder = osu.Game.Screens.SelectV2.NoResultsPlaceholder; namespace osu.Game.Tests.Visual.SongSelectV2 { @@ -266,7 +269,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2 } [Test] - public void TestPlaceholderBeatmapPresence() + public void TestPlaceholderVisibleAfterDeleteAll() { loadSongSelect(); @@ -280,7 +283,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2 } [Test] - public void TestPlaceholderStarDifficulty() + public void TestPlaceholderVisibleAfterStarDifficultyFilter() { importBeatmapForRuleset(0); AddStep("change star filter", () => config.SetValue(OsuSetting.DisplayStarsMinimum, 10.0)); @@ -296,7 +299,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2 } [Test] - public void TestPlaceholderConvertSetting() + public void TestPlaceholderVisibleWithConvertSetting() { importBeatmapForRuleset(0); AddStep("change convert setting", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, false)); @@ -313,6 +316,32 @@ namespace osu.Game.Tests.Visual.SongSelectV2 AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Hidden); } + [Test] + public void TestCorrectMatchCountAfterDeleteAll() + { + loadSongSelect(); + checkMatchedBeatmaps(0); + + importBeatmapForRuleset(0); + checkMatchedBeatmaps(3); + + AddStep("delete all beatmaps", () => manager.Delete()); + checkMatchedBeatmaps(0); + } + + [Test] + public void TestCorrectMatchCountAfterHardDelete() + { + loadSongSelect(); + checkMatchedBeatmaps(0); + + importBeatmapForRuleset(0); + checkMatchedBeatmaps(3); + + AddStep("hard delete beatmap", () => Realm.Write(r => r.RemoveRange(r.All().Where(s => !s.Protected)))); + checkMatchedBeatmaps(0); + } + private void loadSongSelect() { AddStep("load screen", () => Stack.Push(songSelect = new SoloSongSelect())); @@ -364,6 +393,9 @@ namespace osu.Game.Tests.Visual.SongSelectV2 }); } + private void checkMatchedBeatmaps(int expected) => + AddUntilStep($"{expected} matching shown", () => carousel.MatchedBeatmapsCount, () => Is.EqualTo(expected)); + private void waitForSuspension() => AddUntilStep("wait for not current", () => !songSelect.AsNonNull().IsCurrentScreen()); private void updateFooter(IScreen? _, IScreen? newScreen) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs index d4141f2b64..0ecaf4900a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.UserInterface Anchor = Anchor.Centre, RelativeSizeAxes = Axes.X, Width = 0.5f, - FilterText = "12345 matches", + StatusText = "12345 matches", }, } }, diff --git a/osu.Game/Graphics/UserInterface/ShearedFilterTextBox.cs b/osu.Game/Graphics/UserInterface/ShearedFilterTextBox.cs index cffe34650c..635990ec9c 100644 --- a/osu.Game/Graphics/UserInterface/ShearedFilterTextBox.cs +++ b/osu.Game/Graphics/UserInterface/ShearedFilterTextBox.cs @@ -12,10 +12,10 @@ namespace osu.Game.Graphics.UserInterface { private const float filter_text_size = 12; - public LocalisableString FilterText + public LocalisableString StatusText { - get => ((InnerFilterTextBox)TextBox).FilterText.Text; - set => Schedule(() => ((InnerFilterTextBox)TextBox).FilterText.Text = value); + get => ((InnerFilterTextBox)TextBox).StatusText.Text; + set => Schedule(() => ((InnerFilterTextBox)TextBox).StatusText.Text = value); } public ShearedFilterTextBox() @@ -27,12 +27,12 @@ namespace osu.Game.Graphics.UserInterface protected partial class InnerFilterTextBox : InnerSearchTextBox { - public OsuSpriteText FilterText { get; private set; } = null!; + public OsuSpriteText StatusText { get; private set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours) { - TextContainer.Add(FilterText = new OsuSpriteText + TextContainer.Add(StatusText = new OsuSpriteText { Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, diff --git a/osu.Game/Screens/SelectV2/FilterControl.cs b/osu.Game/Screens/SelectV2/FilterControl.cs index 5eda47391a..69029cd131 100644 --- a/osu.Game/Screens/SelectV2/FilterControl.cs +++ b/osu.Game/Screens/SelectV2/FilterControl.cs @@ -47,10 +47,10 @@ namespace osu.Game.Screens.SelectV2 [Resolved] private OsuConfigManager config { get; set; } = null!; - public LocalisableString InformationalNote + public LocalisableString StatusText { - get => searchTextBox.FilterText; - set => searchTextBox.FilterText = value; + get => searchTextBox.StatusText; + set => searchTextBox.StatusText = value; } public event Action? CriteriaChanged; diff --git a/osu.Game/Screens/SelectV2/SongSelect.cs b/osu.Game/Screens/SelectV2/SongSelect.cs index 062d7cff2c..d0749c8e6f 100644 --- a/osu.Game/Screens/SelectV2/SongSelect.cs +++ b/osu.Game/Screens/SelectV2/SongSelect.cs @@ -128,6 +128,7 @@ namespace osu.Game.Screens.SelectV2 BleedTop = FilterControl.HEIGHT_FROM_SCREEN_TOP + 5, BleedBottom = ScreenFooter.HEIGHT + 5, RequestPresentBeatmap = _ => OnStart(), + NewItemsPresented = newItemsPresented, RelativeSizeAxes = Axes.Both, }, noResultsPlaceholder = new NoResultsPlaceholder(), @@ -151,6 +152,12 @@ namespace osu.Game.Screens.SelectV2 }); } + /// + /// Called when a selection is made. + /// + /// If a resultant action occurred that takes the user away from SongSelect. + protected abstract bool OnStart(); + public override IReadOnlyList CreateFooterButtons() => new ScreenFooterButton[] { new FooterButtonMods(modSelectOverlay) { Current = Mods }, @@ -171,6 +178,15 @@ namespace osu.Game.Screens.SelectV2 }, true); } + protected override void Update() + { + base.Update(); + + detailsArea.Height = wedgesContainer.DrawHeight - titleWedge.LayoutSize.Y - 4; + } + + #region Transitions + public override void OnEntering(ScreenTransitionEvent e) { base.OnEntering(e); @@ -250,12 +266,6 @@ namespace osu.Game.Screens.SelectV2 }; } - /// - /// Called when a selection is made. - /// - /// If a resultant action occurred that takes the user away from SongSelect. - protected abstract bool OnStart(); - protected override void LogoSuspending(OsuLogo logo) { base.LogoSuspending(logo); @@ -270,6 +280,8 @@ namespace osu.Game.Screens.SelectV2 logo.FadeOut(120, Easing.Out); } + #endregion + #region Filtering private const double filter_delay = 250; @@ -292,14 +304,17 @@ namespace osu.Game.Screens.SelectV2 }, filter_delay); } - #endregion - - protected override void Update() + private void newItemsPresented() { - base.Update(); + int count = carousel.MatchedBeatmapsCount; - detailsArea.Height = wedgesContainer.DrawHeight - titleWedge.LayoutSize.Y - 4; - noResultsPlaceholder.State.Value = carousel.MatchedBeatmapsCount == 0 ? Visibility.Visible : Visibility.Hidden; + noResultsPlaceholder.State.Value = count == 0 ? Visibility.Visible : Visibility.Hidden; + + // 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"; } + + #endregion } }