1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00

Fix song select navigation with home/end keys (#36879)

It's a continuation of https://github.com/ppy/osu/pull/36293, but for
the home and end keys.

Now when using home or end keys, it selects respectively the first or
last item in the carousel, instead of just scrolling.

## Before: 


https://github.com/user-attachments/assets/6ab08d2f-1da4-4740-9d9e-574d7a8a10c9

## After:


https://github.com/user-attachments/assets/30bab836-0006-4830-b4e9-2d85017a15e6
This commit is contained in:
Rudi Herouard
2026-03-10 06:20:59 +01:00
committed by GitHub
Unverified
parent 277d53a4f1
commit 14bde85263
2 changed files with 51 additions and 1 deletions
@@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
@@ -31,10 +32,12 @@ namespace osu.Game.Graphics.Carousel
/// Implementation of scroll container which handles very large vertical lists by internally using <c>double</c> precision
/// for pre-display Y values.
/// </summary>
protected partial class ScrollContainer : UserTrackingScrollContainer, IKeyBindingHandler<GlobalAction>
protected partial class ScrollContainer : UserTrackingScrollContainer, IKeyBindingHandler<GlobalAction>, IKeyBindingHandler<PlatformAction>
{
public Action? OnPageUp { get; init; }
public Action? OnPageDown { get; init; }
public Action? OnListStart { get; init; }
public Action? OnListEnd { get; init; }
public readonly Container Panels;
@@ -146,6 +149,25 @@ namespace osu.Game.Graphics.Carousel
return base.OnKeyDown(e);
}
public new bool OnPressed(KeyBindingPressEvent<PlatformAction> e)
{
if (IsHandlingKeyboardScrolling)
{
switch (e.Action)
{
case PlatformAction.MoveBackwardLine:
OnListStart?.Invoke();
return true;
case PlatformAction.MoveForwardLine:
OnListEnd?.Invoke();
return true;
}
}
return base.OnPressed(e);
}
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
switch (e.Action)
+28
View File
@@ -319,6 +319,8 @@ namespace osu.Game.Graphics.Carousel
RelativeSizeAxes = Axes.Both,
OnPageUp = () => Scheduler.AddOnce(traverseFromKey, new TraversalOperation(TraversalType.Page, -1)),
OnPageDown = () => Scheduler.AddOnce(traverseFromKey, new TraversalOperation(TraversalType.Page, 1)),
OnListStart = () => Scheduler.AddOnce(traverseFromKey, new TraversalOperation(TraversalType.Edge, -1)),
OnListEnd = () => Scheduler.AddOnce(traverseFromKey, new TraversalOperation(TraversalType.Edge, 1)),
};
Items.BindCollectionChanged((_, args) =>
@@ -554,6 +556,10 @@ namespace osu.Game.Graphics.Carousel
traverseKeyboardPage(traversal.Direction);
break;
case TraversalType.Edge:
traverseKeyboardEdge(traversal.Direction);
break;
case TraversalType.Set:
traverseSetSelection(traversal.Direction);
break;
@@ -572,6 +578,7 @@ namespace osu.Game.Graphics.Carousel
Keyboard,
Set,
Page,
Edge,
Group
}
@@ -682,6 +689,27 @@ namespace osu.Game.Graphics.Carousel
}
}
/// <summary>
/// Select the first or last item in the carousel.
/// </summary>
/// <param name="direction">Positive for last item, negative for first item.</param>
private void traverseKeyboardEdge(int direction)
{
if (carouselItems == null || carouselItems.Count == 0)
return;
var item = direction > 0
? carouselItems.LastOrDefault(x => x.IsVisible)
: carouselItems.FirstOrDefault(x => x.IsVisible);
if (item != null && !CheckModelEquality(item.Model, currentKeyboardSelection.Model))
{
setKeyboardSelection(item.Model);
ScrollToSelection();
playTraversalSound();
}
}
/// <summary>
/// Select the next valid group selection relative to a current selection.
/// This is generally for keyboard based traversal.