mirror of
https://github.com/osukey/osukey.git
synced 2025-05-30 01:47:30 +09:00
Merge pull request #9370 from peppy/song-select-key-repeat
This commit is contained in:
commit
a4254802c1
@ -17,11 +17,12 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
using osu.Game.Screens.Select.Carousel;
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneBeatmapCarousel : OsuTestScene
|
public class TestSceneBeatmapCarousel : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
private TestBeatmapCarousel carousel;
|
private TestBeatmapCarousel carousel;
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
@ -39,6 +40,43 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyRepeat()
|
||||||
|
{
|
||||||
|
loadBeatmaps();
|
||||||
|
advanceSelection(false);
|
||||||
|
|
||||||
|
AddStep("press down arrow", () => InputManager.PressKey(Key.Down));
|
||||||
|
|
||||||
|
BeatmapInfo selection = null;
|
||||||
|
|
||||||
|
checkSelectionIterating(true);
|
||||||
|
|
||||||
|
AddStep("press up arrow", () => InputManager.PressKey(Key.Up));
|
||||||
|
|
||||||
|
checkSelectionIterating(true);
|
||||||
|
|
||||||
|
AddStep("release down arrow", () => InputManager.ReleaseKey(Key.Down));
|
||||||
|
|
||||||
|
checkSelectionIterating(true);
|
||||||
|
|
||||||
|
AddStep("release up arrow", () => InputManager.ReleaseKey(Key.Up));
|
||||||
|
|
||||||
|
checkSelectionIterating(false);
|
||||||
|
|
||||||
|
void checkSelectionIterating(bool isIterating)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
AddStep("store selection", () => selection = carousel.SelectedBeatmap);
|
||||||
|
if (isIterating)
|
||||||
|
AddUntilStep("selection changed", () => carousel.SelectedBeatmap != selection);
|
||||||
|
else
|
||||||
|
AddUntilStep("selection not changed", () => carousel.SelectedBeatmap == selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRecommendedSelection()
|
public void TestRecommendedSelection()
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
|||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
@ -301,6 +302,9 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private void selectNextDifficulty(int direction)
|
private void selectNextDifficulty(int direction)
|
||||||
{
|
{
|
||||||
|
if (selectedBeatmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
var unfilteredDifficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList();
|
var unfilteredDifficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList();
|
||||||
|
|
||||||
int index = unfilteredDifficulties.IndexOf(selectedBeatmap);
|
int index = unfilteredDifficulties.IndexOf(selectedBeatmap);
|
||||||
@ -452,32 +456,49 @@ namespace osu.Game.Screens.Select
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ScrollToSelected() => scrollPositionCache.Invalidate();
|
public void ScrollToSelected() => scrollPositionCache.Invalidate();
|
||||||
|
|
||||||
|
#region Key / button selection logic
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
{
|
{
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
case Key.Left:
|
case Key.Left:
|
||||||
SelectNext(-1, true);
|
if (!e.Repeat)
|
||||||
|
beginRepeatSelection(() => SelectNext(-1, true), e.Key);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Key.Right:
|
case Key.Right:
|
||||||
SelectNext(1, true);
|
if (!e.Repeat)
|
||||||
|
beginRepeatSelection(() => SelectNext(1, true), e.Key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case GlobalAction.SelectNext:
|
case GlobalAction.SelectNext:
|
||||||
SelectNext(1, false);
|
beginRepeatSelection(() => SelectNext(1, false), action);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.SelectPrevious:
|
case GlobalAction.SelectPrevious:
|
||||||
SelectNext(-1, false);
|
beginRepeatSelection(() => SelectNext(-1, false), action);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,8 +507,44 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
public void OnReleased(GlobalAction action)
|
public void OnReleased(GlobalAction action)
|
||||||
{
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GlobalAction.SelectNext:
|
||||||
|
case GlobalAction.SelectPrevious:
|
||||||
|
endRepeatSelection(action);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
repeatDelegate = this.BeginKeyRepeat(Scheduler, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user