From e2de5bb8f940e71fcf9cfefa8fe504966c5e00bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 2 Jan 2021 22:05:41 +0900 Subject: [PATCH 1/6] Fix the beatmap carousel not returning to centre correctly after resizing window --- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index d76f0abb9e..c83c89bb7f 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Pooling; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Layout; using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -567,6 +568,15 @@ namespace osu.Game.Screens.Select #endregion + protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source) + { + // handles the vertical size of the carousel changing (ie. on window resize when aspect ratio has changed). + if ((invalidation & Invalidation.Layout) > 0) + itemsCache.Invalidate(); + + return base.OnInvalidate(invalidation, source); + } + protected override void Update() { base.Update(); From caa5109e3a0e1e526c789024d2ecbc9d57767e76 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jan 2021 12:18:35 +0900 Subject: [PATCH 2/6] Add precautionary null checks to update methods in SongSelect --- osu.Game/Screens/Select/SongSelect.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a5252fdc96..8ad1ace36a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -428,7 +428,7 @@ namespace osu.Game.Screens.Select private void updateSelectedBeatmap(BeatmapInfo beatmap) { - if (beatmap?.Equals(beatmapNoDebounce) == true) + if (beatmap == null || beatmap.Equals(beatmapNoDebounce)) return; beatmapNoDebounce = beatmap; @@ -438,7 +438,7 @@ namespace osu.Game.Screens.Select private void updateSelectedRuleset(RulesetInfo ruleset) { - if (ruleset?.Equals(rulesetNoDebounce) == true) + if (ruleset == null || ruleset.Equals(rulesetNoDebounce)) return; rulesetNoDebounce = ruleset; From a6d49929978a2617ef2f180d3e3e868513e8737e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jan 2021 12:53:25 +0900 Subject: [PATCH 3/6] Ensure SelectionChanged events are only sent once when selection is null --- osu.Game/Screens/Select/BeatmapCarousel.cs | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index c83c89bb7f..37213c6003 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -125,6 +125,8 @@ namespace osu.Game.Screens.Select { BeatmapSetsChanged?.Invoke(); BeatmapSetsLoaded = true; + + itemsCache.Invalidate(); }); } @@ -731,6 +733,12 @@ namespace osu.Game.Screens.Select private const float panel_padding = 5; + /// + /// After loading, we want to invoke a selection changed event at least once. + /// This handles the case where this event is potentially sending a null selection. + /// + private bool sentInitialSelectionEvent; + /// /// Computes the target Y positions for every item in the carousel. /// @@ -787,13 +795,21 @@ namespace osu.Game.Screens.Select Scroll.ScrollContent.Height = currentY; - if (BeatmapSetsLoaded && (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) - { - selectedBeatmapSet = null; - SelectionChanged?.Invoke(null); - } - itemsCache.Validate(); + + // update and let external consumers know about selection loss. + if (BeatmapSetsLoaded) + { + bool selectionLost = selectedBeatmapSet != null && selectedBeatmapSet.State.Value != CarouselItemState.Selected; + + if (selectionLost || !sentInitialSelectionEvent) + { + selectedBeatmapSet = null; + SelectionChanged?.Invoke(null); + + sentInitialSelectionEvent = true; + } + } } private bool firstScroll = true; @@ -816,14 +832,13 @@ namespace osu.Game.Screens.Select break; case PendingScrollOperation.Immediate: + // in order to simplify animation logic, rather than using the animated version of ScrollTo, // we take the difference in scroll height and apply to all visible panels. // this avoids edge cases like when the visible panels is reduced suddenly, causing ScrollContainer // to enter clamp-special-case mode where it animates completely differently to normal. float scrollChange = scrollTarget.Value - Scroll.Current; - Scroll.ScrollTo(scrollTarget.Value, false); - foreach (var i in Scroll.Children) i.Y += scrollChange; break; From efb71713efdde039ab6a3d0fce58476e6ef6d575 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jan 2021 22:43:02 +0900 Subject: [PATCH 4/6] Fix null condition inhibiting deselection events --- osu.Game/Screens/Select/SongSelect.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8ad1ace36a..e3036c662b 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -428,7 +428,10 @@ namespace osu.Game.Screens.Select private void updateSelectedBeatmap(BeatmapInfo beatmap) { - if (beatmap == null || beatmap.Equals(beatmapNoDebounce)) + if (beatmap == null && beatmapNoDebounce == null) + return; + + if (beatmap?.Equals(beatmapNoDebounce) == true) return; beatmapNoDebounce = beatmap; From 53e6a349bbed8492c62b66ff8b47333da8101230 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jan 2021 22:44:30 +0900 Subject: [PATCH 5/6] Fix incorrect initial conditional Turns out this wasn't actually required. --- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 37213c6003..36f8fbedb3 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -733,12 +733,6 @@ namespace osu.Game.Screens.Select private const float panel_padding = 5; - /// - /// After loading, we want to invoke a selection changed event at least once. - /// This handles the case where this event is potentially sending a null selection. - /// - private bool sentInitialSelectionEvent; - /// /// Computes the target Y positions for every item in the carousel. /// @@ -802,12 +796,10 @@ namespace osu.Game.Screens.Select { bool selectionLost = selectedBeatmapSet != null && selectedBeatmapSet.State.Value != CarouselItemState.Selected; - if (selectionLost || !sentInitialSelectionEvent) + if (selectionLost) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); - - sentInitialSelectionEvent = true; } } } From 4b539b01c1862bfb0a29ad69dc6b400f3719e99b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jan 2021 20:38:58 +0900 Subject: [PATCH 6/6] Match code between updateSelectedBeatmap/Ruleset --- osu.Game/Screens/Select/SongSelect.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e3036c662b..7e217ca7a4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -435,13 +435,15 @@ namespace osu.Game.Screens.Select return; beatmapNoDebounce = beatmap; - performUpdateSelected(); } private void updateSelectedRuleset(RulesetInfo ruleset) { - if (ruleset == null || ruleset.Equals(rulesetNoDebounce)) + if (ruleset == null && rulesetNoDebounce == null) + return; + + if (ruleset?.Equals(rulesetNoDebounce) == true) return; rulesetNoDebounce = ruleset;