1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 11:42:56 +08:00

Add keyboard traversal support for first run dialog (and tidy up step traversal logic)

This commit is contained in:
Dean Herbert 2022-04-19 14:46:01 +09:00
parent e67cc293b8
commit 6d534046ff
2 changed files with 103 additions and 52 deletions

View File

@ -60,13 +60,19 @@ namespace osu.Game.Tests.Visual.UserInterface
});
}
[Test]
public void TestOverlayRunsToFinish()
[TestCase(false)]
[TestCase(true)]
public void TestOverlayRunsToFinish(bool keyboard)
{
AddUntilStep("step through", () =>
{
if (overlay.CurrentScreen?.IsLoaded != false)
overlay.NextButton.TriggerClick();
{
if (keyboard)
InputManager.Key(Key.Enter);
else
overlay.NextButton.TriggerClick();
}
return overlay.State.Value == Visibility.Hidden;
});
@ -80,8 +86,9 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("back at start", () => overlay.CurrentScreen is ScreenWelcome);
}
[Test]
public void TestBackButton()
[TestCase(false)]
[TestCase(true)]
public void TestBackButton(bool keyboard)
{
AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);
@ -98,12 +105,23 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("step back to start", () =>
{
if (overlay.CurrentScreen?.IsLoaded != false)
overlay.BackButton.TriggerClick();
{
if (keyboard)
InputManager.Key(Key.Escape);
else
overlay.BackButton.TriggerClick();
}
return overlay.CurrentScreen is ScreenWelcome;
});
AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);
if (keyboard)
{
AddStep("exit via keyboard", () => InputManager.Key(Key.Escape));
AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
}
}
[Test]

View File

@ -12,12 +12,14 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Framework.Screens;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Game.Localisation;
using osu.Game.Overlays.FirstRunSetup;
using osu.Game.Overlays.Notifications;
@ -215,57 +217,30 @@ namespace osu.Game.Overlays
performer.PerformFromScreen(_ => { Show(); }, new[] { typeof(MainMenu) });
}
private void showLastStep()
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
Debug.Assert(currentStepIndex > 0);
Debug.Assert(stack != null);
stack.CurrentScreen.Exit();
currentStepIndex--;
BackButton.Enabled.Value = currentStepIndex != 0;
updateButtonText();
}
private void showNextStep()
{
if (currentStepIndex == null)
if (!e.Repeat)
{
stackContainer.Child = stack = new ScreenStack
switch (e.Action)
{
RelativeSizeAxes = Axes.Both,
};
case GlobalAction.Select:
NextButton.TriggerClick();
return true;
currentStepIndex = 0;
case GlobalAction.Back:
if (BackButton.Enabled.Value)
{
BackButton.TriggerClick();
return true;
}
// If back button is disabled, we are at the first step.
// The base call will handle dismissal of the overlay.
break;
}
}
else
currentStepIndex++;
Debug.Assert(currentStepIndex != null);
Debug.Assert(stack != null);
BackButton.Enabled.Value = currentStepIndex > 0;
if (currentStepIndex < steps.Length)
{
stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value].ScreenType));
updateButtonText();
}
else
{
currentStepIndex = null;
Hide();
}
}
private void updateButtonText()
{
Debug.Assert(currentStepIndex != null);
NextButton.Text = currentStepIndex + 1 < steps.Length
? FirstRunSetupOverlayStrings.Next(steps[currentStepIndex.Value + 1].Description)
: CommonStrings.Finish;
return base.OnPressed(e);
}
protected override void PopIn()
@ -278,7 +253,7 @@ namespace osu.Game.Overlays
this.FadeIn(400, Easing.OutQuint);
if (currentStepIndex == null)
showNextStep();
showFirstStep();
}
protected override void PopOut()
@ -308,6 +283,64 @@ namespace osu.Game.Overlays
this.FadeOut(200, Easing.OutQuint);
}
private void showFirstStep()
{
Debug.Assert(currentStepIndex == null);
stackContainer.Child = stack = new ScreenStack
{
RelativeSizeAxes = Axes.Both,
};
currentStepIndex = -1;
showNextStep();
}
private void showLastStep()
{
if (currentStepIndex == 0)
return;
Debug.Assert(stack != null);
stack.CurrentScreen.Exit();
currentStepIndex--;
BackButton.Enabled.Value = currentStepIndex != 0;
updateButtonText();
}
private void showNextStep()
{
Debug.Assert(currentStepIndex != null);
Debug.Assert(stack != null);
currentStepIndex++;
BackButton.Enabled.Value = currentStepIndex > 0;
if (currentStepIndex < steps.Length)
{
stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value].ScreenType));
updateButtonText();
}
else
{
currentStepIndex = null;
Hide();
}
}
private void updateButtonText()
{
Debug.Assert(currentStepIndex != null);
NextButton.Text = currentStepIndex + 1 < steps.Length
? FirstRunSetupOverlayStrings.Next(steps[currentStepIndex.Value + 1].Description)
: CommonStrings.Finish;
}
private class FirstRunStep
{
public readonly Type ScreenType;