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()