From fc5832ce67d7af1b32f88109b705788c4bf07e07 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Wed, 5 Feb 2025 04:44:06 -0500 Subject: [PATCH] Support variable spacing between carousel items --- osu.Game/Screens/SelectV2/BeatmapCarousel.cs | 11 +++++++ osu.Game/Screens/SelectV2/Carousel.cs | 33 +++++++++++++------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/SelectV2/BeatmapCarousel.cs b/osu.Game/Screens/SelectV2/BeatmapCarousel.cs index 9f62780dda..12660d8642 100644 --- a/osu.Game/Screens/SelectV2/BeatmapCarousel.cs +++ b/osu.Game/Screens/SelectV2/BeatmapCarousel.cs @@ -20,12 +20,23 @@ namespace osu.Game.Screens.SelectV2 [Cached] public partial class BeatmapCarousel : Carousel { + public const float SPACING = 5f; + private IBindableList detachedBeatmaps = null!; private readonly LoadingLayer loading; private readonly BeatmapCarouselFilterGrouping grouping; + protected override float GetSpacingBetweenPanels(CarouselItem top, CarouselItem bottom) + { + if (top.Model is BeatmapInfo || bottom.Model is BeatmapInfo) + // Beatmap difficulty panels do not overlap with themselves or any other panel. + return SPACING; + + return -SPACING; + } + public BeatmapCarousel() { DebounceDelay = 100; diff --git a/osu.Game/Screens/SelectV2/Carousel.cs b/osu.Game/Screens/SelectV2/Carousel.cs index 608ef207d9..d7b6f251c3 100644 --- a/osu.Game/Screens/SelectV2/Carousel.cs +++ b/osu.Game/Screens/SelectV2/Carousel.cs @@ -50,11 +50,6 @@ namespace osu.Game.Screens.SelectV2 /// public float DistanceOffscreenToPreload { get; set; } - /// - /// Vertical space between panel layout. Negative value can be used to create an overlapping effect. - /// - protected float SpacingBetweenPanels { get; set; } = -5; - /// /// When a new request arrives to change filtering, the number of milliseconds to wait before performing the filter. /// Regardless of any external debouncing, this is a safety measure to avoid triggering too many threaded operations. @@ -116,6 +111,11 @@ namespace osu.Game.Screens.SelectV2 } } + /// + /// Returns the vertical spacing between two given carousel items. Negative value can be used to create an overlapping effect. + /// + protected virtual float GetSpacingBetweenPanels(CarouselItem top, CarouselItem bottom) => 0f; + #endregion #region Properties and methods concerning implementations @@ -260,7 +260,7 @@ namespace osu.Game.Screens.SelectV2 } log("Updating Y positions"); - updateYPositions(items, visibleHalfHeight, SpacingBetweenPanels); + updateYPositions(items, visibleHalfHeight); } catch (OperationCanceledException) { @@ -283,17 +283,26 @@ namespace osu.Game.Screens.SelectV2 void log(string text) => Logger.Log($"Carousel[op {cts.GetHashCode().ToString()}] {stopwatch.ElapsedMilliseconds} ms: {text}"); } - private static void updateYPositions(IEnumerable carouselItems, float offset, float spacing) + private void updateYPositions(IEnumerable carouselItems, float offset) { + CarouselItem? previousVisible = null; + foreach (var item in carouselItems) - updateItemYPosition(item, ref offset, spacing); + updateItemYPosition(item, ref previousVisible, ref offset); } - private static void updateItemYPosition(CarouselItem item, ref float offset, float spacing) + private void updateItemYPosition(CarouselItem item, ref CarouselItem? previousVisible, ref float offset) { + float spacing = previousVisible == null || !item.IsVisible ? 0 : GetSpacingBetweenPanels(previousVisible, item); + + offset += spacing; item.CarouselYPosition = offset; + if (item.IsVisible) - offset += item.DrawHeight + spacing; + { + offset += item.DrawHeight; + previousVisible = item; + } } #endregion @@ -470,7 +479,7 @@ namespace osu.Game.Screens.SelectV2 return; } - float spacing = SpacingBetweenPanels; + CarouselItem? lastVisible = null; int count = carouselItems.Count; Selection prevKeyboard = currentKeyboardSelection; @@ -482,7 +491,7 @@ namespace osu.Game.Screens.SelectV2 { var item = carouselItems[i]; - updateItemYPosition(item, ref yPos, spacing); + updateItemYPosition(item, ref lastVisible, ref yPos); if (ReferenceEquals(item.Model, currentKeyboardSelection.Model)) currentKeyboardSelection = new Selection(item.Model, item, item.CarouselYPosition, i);