Remove and re-add backbutton instead and add tests

This commit is contained in:
David Zhao 2019-07-29 14:30:46 +09:00
parent 2318402292
commit 2e242075b4
3 changed files with 196 additions and 18 deletions

View File

@ -0,0 +1,152 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Select;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Menus
{
public class TestSceneExitingScreens : ManualInputManagerTestScene
{
private readonly TestOsuGame osuGame = new TestOsuGame();
[BackgroundDependencyLoader]
private void load(GameHost gameHost)
{
osuGame.SetHost(gameHost);
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
osuGame
};
}
[SetUpSteps]
public void SetUpSteps()
{
AddUntilStep("wait for load", () => osuGame.IsLoaded);
AddUntilStep("wait for main menu", () =>
{
var current = osuGame.ScreenStack?.CurrentScreen;
switch (current)
{
case null:
case Intro _:
case Disclaimer _:
return false;
case MainMenu _:
return true;
default:
current.Exit();
return false;
}
});
}
[Test]
public void TestExitingSongSelectWithEscape()
{
TestSongSelect songSelect = null;
AddStep("Push songselect", () => osuGame.ScreenStack.Push(songSelect = new TestSongSelect()));
AddUntilStep("Wait for song select", () => songSelect.IsCurrentScreen());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
AddStep("Press escape", () => pressAndRelease(Key.Escape));
AddAssert("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);
exitViaEscapeAndConfirm();
}
[Test]
public void TestExitingSongSelectWithClick()
{
TestSongSelect songSelect = null;
AddStep("Push songselect", () => osuGame.ScreenStack.Push(songSelect = new TestSongSelect()));
AddUntilStep("Wait for song select", () => songSelect.IsCurrentScreen());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(osuGame.BackButton));
// BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered.
AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == osuGame.BackButton));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
AddAssert("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);
exitViaBackButtonAndConfirm();
}
[Test]
public void TestExitMultiWithEscape()
{
Screens.Multi.Multiplayer multiplayer = null;
AddStep("Push songselect", () => osuGame.ScreenStack.Push(multiplayer = new Screens.Multi.Multiplayer()));
AddUntilStep("Wait for song select", () => multiplayer.IsCurrentScreen());
exitViaEscapeAndConfirm();
}
[Test]
public void TestExitMultiWithBackButton()
{
Screens.Multi.Multiplayer multiplayer = null;
AddStep("Push songselect", () => osuGame.ScreenStack.Push(multiplayer = new Screens.Multi.Multiplayer()));
AddUntilStep("Wait for song select", () => multiplayer.IsCurrentScreen());
exitViaBackButtonAndConfirm();
}
private void exitViaEscapeAndConfirm()
{
AddStep("Press escape", () => pressAndRelease(Key.Escape));
AddUntilStep("Wait for main menu", () => osuGame.ScreenStack.CurrentScreen is MainMenu);
}
private void exitViaBackButtonAndConfirm()
{
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(osuGame.BackButton));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
AddUntilStep("Wait for main menu", () => osuGame.ScreenStack.CurrentScreen is MainMenu);
}
private void pressAndRelease(Key key)
{
InputManager.PressKey(key);
InputManager.ReleaseKey(key);
}
private class TestOsuGame : OsuGame
{
public new ScreenStack ScreenStack => base.ScreenStack;
public new BackButton BackButton => base.BackButton;
}
private class TestSongSelect : PlaySongSelect
{
public ModSelectOverlay ModSelectOverlay => ModSelect;
}
}
}

View File

@ -7,6 +7,7 @@
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Input.Bindings
{
@ -55,8 +56,32 @@ public GlobalActionContainer(OsuGameBase game)
new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed),
};
protected override IEnumerable<Drawable> KeyBindingInputQueue =>
handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler);
protected override IEnumerable<Drawable> KeyBindingInputQueue
{
get
{
var queue = base.KeyBindingInputQueue.ToList();
if (handler != null)
yield return handler;
BackButton backButton = null;
foreach (var drawable in queue)
{
if (drawable is BackButton button)
{
backButton = button;
continue;
}
yield return drawable;
}
if (backButton != null)
yield return backButton;
}
}
}
public enum GlobalAction

View File

@ -81,10 +81,11 @@ public class OsuGame : OsuGameBase, IKeyBindingHandler<GlobalAction>
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
private OsuScreenStack screenStack;
protected OsuScreenStack ScreenStack;
protected BackButton BackButton;
private VolumeOverlay volume;
private OsuLogo osuLogo;
private BackButton backButton;
private MainMenu menuScreen;
private Intro introScreen;
@ -325,7 +326,7 @@ private void performFromMainMenu(Action action, string taskName, Type targetScre
performFromMainMenuTask?.Cancel();
// if the current screen does not allow screen changing, give the user an option to try again later.
if (!bypassScreenAllowChecks && (screenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange == false)
if (!bypassScreenAllowChecks && (ScreenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange == false)
{
notifications.Post(new SimpleNotification
{
@ -343,7 +344,7 @@ private void performFromMainMenu(Action action, string taskName, Type targetScre
CloseAllOverlays(false);
// we may already be at the target screen type.
if (targetScreen != null && screenStack.CurrentScreen?.GetType() == targetScreen)
if (targetScreen != null && ScreenStack.CurrentScreen?.GetType() == targetScreen)
{
action();
return;
@ -406,15 +407,15 @@ protected override void LoadComplete()
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both },
backButton = new BackButton
ScreenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both },
BackButton = new BackButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Action = () =>
{
if ((screenStack.CurrentScreen as IOsuScreen)?.AllowBackButton == true)
screenStack.Exit();
if ((ScreenStack.CurrentScreen as IOsuScreen)?.AllowBackButton == true)
ScreenStack.Exit();
}
},
logoContainer = new Container { RelativeSizeAxes = Axes.Both },
@ -427,15 +428,15 @@ protected override void LoadComplete()
idleTracker
});
screenStack.ScreenPushed += screenPushed;
screenStack.ScreenExited += screenExited;
ScreenStack.ScreenPushed += screenPushed;
ScreenStack.ScreenExited += screenExited;
loadComponentSingleFile(osuLogo, logo =>
{
logoContainer.Add(logo);
// Loader has to be created after the logo has finished loading as Loader performs logo transformations on entering.
screenStack.Push(new Loader
ScreenStack.Push(new Loader
{
RelativeSizeAxes = Axes.Both
});
@ -755,13 +756,13 @@ private void updateActiveState(bool isActive)
protected override bool OnExiting()
{
if (screenStack.CurrentScreen is Loader)
if (ScreenStack.CurrentScreen is Loader)
return false;
if (introScreen == null)
return true;
if (!introScreen.DidLoadMenu || !(screenStack.CurrentScreen is Intro))
if (!introScreen.DidLoadMenu || !(ScreenStack.CurrentScreen is Intro))
{
Scheduler.Add(introScreen.MakeCurrent);
return true;
@ -789,7 +790,7 @@ protected override void UpdateAfterChildren()
screenContainer.Padding = new MarginPadding { Top = ToolbarOffset };
overlayContent.Padding = new MarginPadding { Top = ToolbarOffset };
MenuCursorContainer.CanShowCursor = (screenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false;
MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false;
}
protected virtual void ScreenChanged(IScreen current, IScreen newScreen)
@ -815,9 +816,9 @@ protected virtual void ScreenChanged(IScreen current, IScreen newScreen)
Toolbar.Show();
if (newOsuScreen.AllowBackButton)
backButton.Show();
BackButton.Show();
else
backButton.Hide();
BackButton.Hide();
}
}