1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-19 21:02:55 +08:00

Support variable spacing between carousel items

This commit is contained in:
Salman Alshamrani 2025-02-05 04:44:06 -05:00
parent c37fa261c3
commit fc5832ce67
2 changed files with 32 additions and 12 deletions

View File

@ -20,12 +20,23 @@ namespace osu.Game.Screens.SelectV2
[Cached] [Cached]
public partial class BeatmapCarousel : Carousel<BeatmapInfo> public partial class BeatmapCarousel : Carousel<BeatmapInfo>
{ {
public const float SPACING = 5f;
private IBindableList<BeatmapSetInfo> detachedBeatmaps = null!; private IBindableList<BeatmapSetInfo> detachedBeatmaps = null!;
private readonly LoadingLayer loading; private readonly LoadingLayer loading;
private readonly BeatmapCarouselFilterGrouping grouping; 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() public BeatmapCarousel()
{ {
DebounceDelay = 100; DebounceDelay = 100;

View File

@ -50,11 +50,6 @@ namespace osu.Game.Screens.SelectV2
/// </summary> /// </summary>
public float DistanceOffscreenToPreload { get; set; } public float DistanceOffscreenToPreload { get; set; }
/// <summary>
/// Vertical space between panel layout. Negative value can be used to create an overlapping effect.
/// </summary>
protected float SpacingBetweenPanels { get; set; } = -5;
/// <summary> /// <summary>
/// When a new request arrives to change filtering, the number of milliseconds to wait before performing the filter. /// 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. /// 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
} }
} }
/// <summary>
/// Returns the vertical spacing between two given carousel items. Negative value can be used to create an overlapping effect.
/// </summary>
protected virtual float GetSpacingBetweenPanels(CarouselItem top, CarouselItem bottom) => 0f;
#endregion #endregion
#region Properties and methods concerning implementations #region Properties and methods concerning implementations
@ -260,7 +260,7 @@ namespace osu.Game.Screens.SelectV2
} }
log("Updating Y positions"); log("Updating Y positions");
updateYPositions(items, visibleHalfHeight, SpacingBetweenPanels); updateYPositions(items, visibleHalfHeight);
} }
catch (OperationCanceledException) 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}"); void log(string text) => Logger.Log($"Carousel[op {cts.GetHashCode().ToString()}] {stopwatch.ElapsedMilliseconds} ms: {text}");
} }
private static void updateYPositions(IEnumerable<CarouselItem> carouselItems, float offset, float spacing) private void updateYPositions(IEnumerable<CarouselItem> carouselItems, float offset)
{ {
CarouselItem? previousVisible = null;
foreach (var item in carouselItems) 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; item.CarouselYPosition = offset;
if (item.IsVisible) if (item.IsVisible)
offset += item.DrawHeight + spacing; {
offset += item.DrawHeight;
previousVisible = item;
}
} }
#endregion #endregion
@ -470,7 +479,7 @@ namespace osu.Game.Screens.SelectV2
return; return;
} }
float spacing = SpacingBetweenPanels; CarouselItem? lastVisible = null;
int count = carouselItems.Count; int count = carouselItems.Count;
Selection prevKeyboard = currentKeyboardSelection; Selection prevKeyboard = currentKeyboardSelection;
@ -482,7 +491,7 @@ namespace osu.Game.Screens.SelectV2
{ {
var item = carouselItems[i]; var item = carouselItems[i];
updateItemYPosition(item, ref yPos, spacing); updateItemYPosition(item, ref lastVisible, ref yPos);
if (ReferenceEquals(item.Model, currentKeyboardSelection.Model)) if (ReferenceEquals(item.Model, currentKeyboardSelection.Model))
currentKeyboardSelection = new Selection(item.Model, item, item.CarouselYPosition, i); currentKeyboardSelection = new Selection(item.Model, item, item.CarouselYPosition, i);