From 5f8d180b5ec5acdff86933d7deeb5e0c3bcff6ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Mar 2020 11:51:26 +0900 Subject: [PATCH] Fix carousel scrolling being inoperable during beatmap import --- osu.Game/Screens/Select/BeatmapCarousel.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 04c08cdbd2..2dc063012f 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -191,7 +191,9 @@ namespace osu.Game.Screens.Select root.AddChild(newSet); - applyActiveCriteria(false); + // only reset scroll position if already near the scroll target. + // without this, during a large beatmap import it is impossible to navigate the carousel. + applyActiveCriteria(false, alwaysResetScrollPosition: false); //check if we can/need to maintain our current selection. if (previouslySelectedID != null) @@ -411,7 +413,7 @@ namespace osu.Game.Screens.Select applyActiveCriteria(debounce); } - private void applyActiveCriteria(bool debounce) + private void applyActiveCriteria(bool debounce, bool alwaysResetScrollPosition = true) { if (root.Children.Any() != true) return; @@ -421,7 +423,9 @@ namespace osu.Game.Screens.Select root.Filter(activeCriteria); itemsCache.Invalidate(); - scrollPositionCache.Invalidate(); + + if (alwaysResetScrollPosition || isAtScrollTarget) + ScrollToSelected(); } PendingFilter?.Cancel(); @@ -435,6 +439,9 @@ namespace osu.Game.Screens.Select private float? scrollTarget; + /// + /// Scroll to the current . + /// public void ScrollToSelected() => scrollPositionCache.Invalidate(); protected override bool OnKeyDown(KeyDownEvent e) @@ -601,7 +608,7 @@ namespace osu.Game.Screens.Select SelectionChanged?.Invoke(c.Beatmap); itemsCache.Invalidate(); - scrollPositionCache.Invalidate(); + ScrollToSelected(); } }; } @@ -688,6 +695,11 @@ namespace osu.Game.Screens.Select itemsCache.Validate(); } + /// + /// Denotes whether the current scroll position is roughly at the scroll target (the current selection). + /// + private bool isAtScrollTarget => scrollTarget != null && Precision.AlmostEquals(scrollTarget.Value, scroll.Current, 150); + private bool firstScroll = true; private void updateScrollPosition()