1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 00:42:55 +08:00

Add key/press repeat support to carousel

This commit is contained in:
Dean Herbert 2020-06-25 19:47:23 +09:00
parent 41d3de3fab
commit d7742766d0

View File

@ -452,32 +452,49 @@ namespace osu.Game.Screens.Select
/// </summary>
public void ScrollToSelected() => scrollPositionCache.Invalidate();
#region Key / button selection logic
protected override bool OnKeyDown(KeyDownEvent e)
{
switch (e.Key)
{
case Key.Left:
SelectNext(-1, true);
if (!e.Repeat)
beginRepeatSelection(() => SelectNext(-1, true), e.Key);
return true;
case Key.Right:
SelectNext(1, true);
if (!e.Repeat)
beginRepeatSelection(() => SelectNext(1, true), e.Key);
return true;
}
return false;
}
protected override void OnKeyUp(KeyUpEvent e)
{
switch (e.Key)
{
case Key.Left:
case Key.Right:
endRepeatSelection(e.Key);
break;
}
base.OnKeyUp(e);
}
public bool OnPressed(GlobalAction action)
{
switch (action)
{
case GlobalAction.SelectNext:
SelectNext(1, false);
beginRepeatSelection(() => SelectNext(1, false), action);
return true;
case GlobalAction.SelectPrevious:
SelectNext(-1, false);
beginRepeatSelection(() => SelectNext(-1, false), action);
return true;
}
@ -486,8 +503,46 @@ namespace osu.Game.Screens.Select
public void OnReleased(GlobalAction action)
{
switch (action)
{
case GlobalAction.SelectNext:
case GlobalAction.SelectPrevious:
endRepeatSelection(action);
break;
}
}
private const double repeat_interval = 120;
private ScheduledDelegate repeatDelegate;
private object lastRepeatSource;
/// <summary>
/// Begin repeating the specified selection action.
/// </summary>
/// <param name="action">The action to perform.</param>
/// <param name="source">The source of the action. Used in conjunction with <see cref="endRepeatSelection"/> to only cancel the correct action (most recently pressed key).</param>
private void beginRepeatSelection(Action action, object source)
{
endRepeatSelection();
lastRepeatSource = source;
Scheduler.Add(repeatDelegate = new ScheduledDelegate(action, Time.Current, repeat_interval));
}
private void endRepeatSelection(object source = null)
{
// only the most recent source should be able to cancel the current action.
if (source != null && !EqualityComparer<object>.Default.Equals(lastRepeatSource, source))
return;
repeatDelegate?.Cancel();
repeatDelegate = null;
lastRepeatSource = null;
}
#endregion
protected override void Update()
{
base.Update();