diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunSetupOverlay.cs b/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunSetupOverlay.cs deleted file mode 100644 index c9aba315eb..0000000000 --- a/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunSetupOverlay.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Framework.Graphics.Containers; -using osu.Framework.Testing; -using osu.Game.Overlays; -using osu.Game.Overlays.FirstRunSetup; - -namespace osu.Game.Tests.Visual.Navigation -{ - public class TestSceneFirstRunSetupOverlay : OsuTestScene - { - private FirstRunSetupOverlay overlay; - - [SetUpSteps] - public void SetUpSteps() - { - AddStep("add overlay", () => - { - Child = overlay = new FirstRunSetupOverlay(); - }); - } - - [Test] - public void TestOverlayRunsToFinish() - { - AddUntilStep("step through", () => - { - if (overlay.CurrentScreen?.IsLoaded != false) - overlay.NextButton.TriggerClick(); - - return overlay.State.Value == Visibility.Hidden; - }); - } - - [Test] - public void TestBackButton() - { - AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value); - - AddUntilStep("step to last", () => - { - var nextButton = overlay.NextButton; - - if (overlay.CurrentScreen?.IsLoaded != false) - nextButton.TriggerClick(); - - return nextButton.Text.ToString() == "Finish"; - }); - - AddUntilStep("step back to start", () => - { - if (overlay.CurrentScreen?.IsLoaded != false) - overlay.BackButton.TriggerClick(); - - return overlay.CurrentScreen is ScreenWelcome; - }); - - AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value); - } - } -} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs new file mode 100644 index 0000000000..5ca09b34aa --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Screens; +using osu.Game.Overlays.FirstRunSetup; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene + { + public TestSceneFirstRunScreenUIScale() + { + AddStep("load screen", () => + { + Child = new ScreenStack(new ScreenUIScale()); + }); + } + } +} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs new file mode 100644 index 0000000000..d892301a81 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs @@ -0,0 +1,111 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using Moq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Screens; +using osu.Framework.Testing; +using osu.Game.Overlays; +using osu.Game.Overlays.Dialog; +using osu.Game.Overlays.FirstRunSetup; +using osu.Game.Screens; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneFirstRunSetupOverlay : OsuManualInputManagerTestScene + { + private FirstRunSetupOverlay overlay; + + private readonly Mock perfomer = new Mock(); + private readonly Mock dialogOverlay = new Mock(); + + [BackgroundDependencyLoader] + private void load() + { + Dependencies.CacheAs(perfomer.Object); + Dependencies.CacheAs(dialogOverlay.Object); + + perfomer.Setup(g => g.PerformFromScreen(It.IsAny>(), It.IsAny>())) + .Callback((Action action, IEnumerable types) => action(null)); + + dialogOverlay.Setup(d => d.Push(It.IsAny())) + .Callback((PopupDialog dialog) => dialog.PerformOkAction()); + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("add overlay", () => + { + Child = overlay = new FirstRunSetupOverlay + { + State = { Value = Visibility.Visible } + }; + }); + } + + [Test] + public void TestOverlayRunsToFinish() + { + AddUntilStep("step through", () => + { + if (overlay.CurrentScreen?.IsLoaded != false) + overlay.NextButton.TriggerClick(); + + return overlay.State.Value == Visibility.Hidden; + }); + } + + [Test] + public void TestBackButton() + { + AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value); + + AddUntilStep("step to last", () => + { + var nextButton = overlay.NextButton; + + if (overlay.CurrentScreen?.IsLoaded != false) + nextButton.TriggerClick(); + + return nextButton.Text.ToString() == "Finish"; + }); + + AddUntilStep("step back to start", () => + { + if (overlay.CurrentScreen?.IsLoaded != false) + overlay.BackButton.TriggerClick(); + + return overlay.CurrentScreen is ScreenWelcome; + }); + + AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value); + } + + [Test] + public void TestClickAwayToExit() + { + AddStep("click inside content", () => + { + InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.Centre); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("overlay not dismissed", () => overlay.State.Value == Visibility.Visible); + + AddStep("click outside content", () => + { + InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.TopLeft - new Vector2(1)); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden); + } + } +} diff --git a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs index 5cf3d562a9..2d025d46ef 100644 --- a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs +++ b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs @@ -1,26 +1,21 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Input.Events; using osu.Framework.Screens; namespace osu.Game.Overlays.FirstRunSetup { public abstract class FirstRunSetupScreen : Screen { - [Resolved] - protected FirstRunSetupOverlay Overlay { get; private set; } - - protected override bool OnClick(ClickEvent e) => true; + private const float offset = 100; public override void OnEntering(IScreen last) { base.OnEntering(last); this .FadeInFromZero(500) - .MoveToX(100) + .MoveToX(offset) .MoveToX(0, 500, Easing.OutQuint); } @@ -32,12 +27,22 @@ namespace osu.Game.Overlays.FirstRunSetup .MoveToX(0, 500, Easing.OutQuint); } - public override void OnSuspending(IScreen next) + public override bool OnExiting(IScreen next) { - base.OnSuspending(next); this .FadeOut(100) - .MoveToX(-100, 500, Easing.OutQuint); + .MoveToX(offset, 500, Easing.OutQuint); + + return base.OnExiting(next); + } + + public override void OnSuspending(IScreen next) + { + this + .FadeOut(100) + .MoveToX(-offset, 500, Easing.OutQuint); + + base.OnSuspending(next); } } } diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenSetupUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenSetupUIScale.cs deleted file mode 100644 index 1a8ef0338c..0000000000 --- a/osu.Game/Overlays/FirstRunSetup/ScreenSetupUIScale.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Localisation; -using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; -using osu.Game.Localisation; -using osu.Game.Overlays.Settings; -using osu.Game.Screens; -using osu.Game.Screens.Menu; -using osu.Game.Screens.OnlinePlay.Match.Components; -using osu.Game.Screens.Select; -using osuTK; - -namespace osu.Game.Overlays.FirstRunSetup -{ - public class ScreenSetupUIScale : FirstRunSetupScreen - { - [Resolved] - private OsuConfigManager osuConfig { get; set; } - - [Cached] - private OsuLogo osuLogo = new OsuLogo(); - - [BackgroundDependencyLoader] - private void load() - { - OsuScreenStack stack; - Content.Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(20), - Children = new Drawable[] - { - new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 32)) - { - Text = "The osu! user interface size can be adjusted to your liking.", - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y - }, - new SettingsSlider - { - LabelText = GraphicsSettingsStrings.UIScaling, - TransferValueOnCommit = true, - Current = osuConfig.GetBindable(OsuSetting.UIScale), - KeyboardStep = 0.01f, - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new ScalingContainer(ScalingMode.Off) - { - Masking = true, - RelativeSizeAxes = Axes.Both, - Child = stack = new OsuScreenStack() - }, - new ScalingContainer(ScalingMode.Off) - { - Masking = true, - RelativeSizeAxes = Axes.Both, - Child = stack = new OsuScreenStack() - } - }, - new Drawable[] - { - new ScalingContainer(ScalingMode.Off) - { - Masking = true, - RelativeSizeAxes = Axes.Both, - Child = stack = new OsuScreenStack() - }, - new ScalingContainer(ScalingMode.Off) - { - Masking = true, - RelativeSizeAxes = Axes.Both, - Child = stack = new OsuScreenStack() - } - } - } - } - } - }, - new PurpleTriangleButton - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding(10), - Text = "Finish", - Action = () => Overlay.Hide() - } - }; - - stack.Push(new PlaySongSelect()); - } - - private class UIScaleSlider : OsuSliderBar - { - public override LocalisableString TooltipText => base.TooltipText + "x"; - } - } -} diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs new file mode 100644 index 0000000000..5070856087 --- /dev/null +++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs @@ -0,0 +1,146 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; +using osu.Framework.Screens; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; +using osu.Game.Overlays.Settings; +using osu.Game.Screens; +using osu.Game.Screens.Menu; +using osu.Game.Screens.Select; +using osu.Game.Tests.Visual; +using osuTK; + +namespace osu.Game.Overlays.FirstRunSetup +{ + public class ScreenUIScale : FirstRunSetupScreen + { + [Resolved] + private OsuConfigManager osuConfig { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension() + }, + Content = new[] + { + new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(20), + Children = new Drawable[] + { + new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 24)) + { + Text = "The osu! user interface size can be adjusted to your liking.", + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + }, + new SettingsSlider + { + LabelText = GraphicsSettingsStrings.UIScaling, + Current = osuConfig.GetBindable(OsuSetting.UIScale), + KeyboardStep = 0.01f, + }, + } + } + }, + new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new SampleScreenContainer(new MainMenu()), + new SampleScreenContainer(new PlaySongSelect()), + }, + new Drawable[] + { + new SampleScreenContainer(new MainMenu()), + new SampleScreenContainer(new MainMenu()), + } + } + } + }, + } + } + }; + } + + private class SampleScreenContainer : CompositeDrawable + { + public override bool HandlePositionalInput => false; + public override bool HandleNonPositionalInput => false; + public override bool PropagatePositionalInputSubTree => false; + public override bool PropagateNonPositionalInputSubTree => false; + + public SampleScreenContainer(Screen screen) + { + OsuScreenStack stack; + RelativeSizeAxes = Axes.Both; + + OsuLogo logo; + + InternalChildren = new Drawable[] + { + new DependencyProvidingContainer + { + CachedDependencies = new (Type, object)[] + { + (typeof(OsuLogo), logo = new OsuLogo + { + RelativePositionAxes = Axes.Both, + Position = new Vector2(0.5f), + }) + }, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new ScalingContainer(ScalingMode.Off) + { + Masking = true, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + stack = new OsuScreenStack(), + logo + }, + }, + } + }, + }; + + stack.Push(screen); + } + } + + private class UIScaleSlider : OsuSliderBar + { + public override LocalisableString TooltipText => base.TooltipText + "x"; + } + } +} diff --git a/osu.Game/Overlays/FirstRunSetupOverlay.cs b/osu.Game/Overlays/FirstRunSetupOverlay.cs index 0efeded062..b391f71437 100644 --- a/osu.Game/Overlays/FirstRunSetupOverlay.cs +++ b/osu.Game/Overlays/FirstRunSetupOverlay.cs @@ -21,6 +21,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Overlays.Dialog; using osu.Game.Overlays.FirstRunSetup; +using osu.Game.Screens; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Match.Components; using osuTK; @@ -33,16 +34,17 @@ namespace osu.Game.Overlays { protected override bool StartHidden => true; - [Resolved(canBeNull: true)] - private DialogOverlay? dialogOverlay { get; set; } + [Resolved] + private IDialogOverlay dialogOverlay { get; set; } = null!; - [Resolved(canBeNull: true)] - private OsuGame? osuGame { get; set; } + [Resolved] + private IPerformFromScreenRunner performer { get; set; } = null!; private ScreenStack stack = null!; public PurpleTriangleButton NextButton = null!; public DangerousTriangleButton BackButton = null!; + private Container mainContent = null!; [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); @@ -57,11 +59,9 @@ namespace osu.Game.Overlays private readonly FirstRunStep[] steps = { new FirstRunStep(typeof(ScreenWelcome), "Welcome"), - new FirstRunStep(typeof(ScreenSetupUIScale), "UI Scale"), + new FirstRunStep(typeof(ScreenUIScale), "UI Scale"), }; - private Container mainContent; - public FirstRunSetupOverlay() { RelativeSizeAxes = Axes.Both; @@ -91,7 +91,7 @@ namespace osu.Game.Overlays new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background5, + Colour = colourProvider.Background6, }, new GridContainer { @@ -114,7 +114,7 @@ namespace osu.Game.Overlays { new Box { - Colour = colourProvider.Background6, + Colour = colourProvider.Background5, RelativeSizeAxes = Axes.Both, }, new FillFlowContainer @@ -214,27 +214,15 @@ namespace osu.Game.Overlays { base.LoadComplete(); - if (osuGame != null) - { - // if we are valid for display, only do so after reaching the main menu. - osuGame.PerformFromScreen(_ => - { - Show(); - }, new[] { typeof(MainMenu) }); - } - else - { - Show(); - } + // if we are valid for display, only do so after reaching the main menu. + performer.PerformFromScreen(_ => { Show(); }, new[] { typeof(MainMenu) }); } protected override bool OnClick(ClickEvent e) { - if (!mainContent.IsHovered && dialogOverlay?.CurrentDialog == null) + if (!mainContent.IsHovered && dialogOverlay.CurrentDialog == null) { - dialogOverlay?.Push(new ConfirmDialog("Are you sure you want to exit the setup process?", - Hide, - () => { })); + dialogOverlay.Push(new ConfirmDialog("Are you sure you want to exit the setup process?", Hide, () => { })); } return base.OnClick(e);