From 007de10e2b48a2d092c117e379acc15de16bba53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 2 Oct 2025 14:21:34 +0200 Subject: [PATCH] Attempt to scroll carousel to nearest expanded panel when the current selection is filtered out Addresses https://github.com/ppy/osu/issues/33443, maybe. I considered adding tests but they'd likely be janky and take a long time to write, so decided against until there's a demand for it. --- osu.Game/Graphics/Carousel/Carousel.cs | 9 +++++++-- osu.Game/Screens/SelectV2/BeatmapCarousel.cs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Carousel/Carousel.cs b/osu.Game/Graphics/Carousel/Carousel.cs index b605efc69d..a63fee6914 100644 --- a/osu.Game/Graphics/Carousel/Carousel.cs +++ b/osu.Game/Graphics/Carousel/Carousel.cs @@ -876,13 +876,18 @@ namespace osu.Game.Graphics.Carousel if (!scrollToSelection.IsValid) { - if (currentKeyboardSelection.YPosition != null) - Scroll.ScrollTo(currentKeyboardSelection.YPosition.Value - visibleHalfHeight + BleedTop); + if (GetScrollTarget() is double scrollTarget) + Scroll.ScrollTo(scrollTarget - visibleHalfHeight + BleedTop); scrollToSelection.Validate(); } } + /// + /// Returns the Y position to scroll to in order to show the most relevant carousel item(s). + /// + protected virtual double? GetScrollTarget() => currentKeyboardSelection.YPosition; + protected virtual float GetPanelXOffset(Drawable panel) { Vector2 posInScroll = Scroll.ToLocalSpace(panel.ScreenSpaceDrawQuad.Centre); diff --git a/osu.Game/Screens/SelectV2/BeatmapCarousel.cs b/osu.Game/Screens/SelectV2/BeatmapCarousel.cs index 780b5155fd..804987a6d0 100644 --- a/osu.Game/Screens/SelectV2/BeatmapCarousel.cs +++ b/osu.Game/Screens/SelectV2/BeatmapCarousel.cs @@ -661,6 +661,24 @@ namespace osu.Game.Screens.SelectV2 } } + protected override double? GetScrollTarget() + { + double? target = base.GetScrollTarget(); + + // if the base implementation returned null, it means that the keyboard selection has been filtered out and is no longer visible + // attempt a fallback to other possibly expanded panels (set first, then group) + if (target == null) + { + var items = GetCarouselItems(); + var targetItem = items?.FirstOrDefault(i => CheckModelEquality(i.Model, ExpandedBeatmapSet)) + ?? items?.FirstOrDefault(i => CheckModelEquality(i.Model, ExpandedGroup)); + + target = targetItem?.CarouselYPosition; + } + + return target; + } + #endregion #region Audio