diff --git a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs index e05fb2b306..e56156752b 100644 --- a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs @@ -9,7 +9,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Input.States; @@ -54,8 +53,6 @@ namespace osu.Game.Tests.Visual.Background private BeatmapManager manager; private RulesetStore rulesets; - private ScreenStackCacheContainer screenStackContainer; - [BackgroundDependencyLoader] private void load(GameHost host) { @@ -82,8 +79,10 @@ namespace osu.Game.Tests.Visual.Background [SetUp] public virtual void SetUp() => Schedule(() => { - Child = screenStackContainer = new ScreenStackCacheContainer { RelativeSizeAxes = Axes.Both }; - screenStackContainer.ScreenStack.Push(songSelect = new DummySongSelect()); + Child = new OsuScreenStack(songSelect = new DummySongSelect()) + { + RelativeSizeAxes = Axes.Both + }; }); /// @@ -373,20 +372,6 @@ namespace osu.Game.Tests.Visual.Background } } - private class ScreenStackCacheContainer : Container - { - [Cached] - private BackgroundScreenStack backgroundScreenStack; - - public readonly ScreenStack ScreenStack; - - public ScreenStackCacheContainer() - { - Add(backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }); - Add(ScreenStack = new ScreenStack { RelativeSizeAxes = Axes.Both }); - } - } - private class TestPlayerLoader : PlayerLoader { public VisualSettings VisualSettingsPos => VisualSettings; diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index bcedcb10a6..be2a21d23d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -14,15 +14,11 @@ namespace osu.Game.Tests.Visual.Gameplay public class TestCasePlayerLoader : ManualInputManagerTestCase { private PlayerLoader loader; - private readonly ScreenStack stack; - - [Cached] - private BackgroundScreenStack backgroundStack; + private readonly OsuScreenStack stack; public TestCasePlayerLoader() { - InputManager.Add(backgroundStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }); - InputManager.Add(stack = new ScreenStack { RelativeSizeAxes = Axes.Both }); + InputManager.Add(stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }); } [BackgroundDependencyLoader] diff --git a/osu.Game.Tests/Visual/Multiplayer/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestCaseMultiHeader.cs index b74c303726..b49bb7fd84 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestCaseMultiHeader.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestCaseMultiHeader.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { int index = 0; - ScreenStack screenStack = new ScreenStack(new TestMultiplayerSubScreen(index)) { RelativeSizeAxes = Axes.Both }; + OsuScreenStack screenStack = new OsuScreenStack(new TestMultiplayerSubScreen(index)) { RelativeSizeAxes = Axes.Both }; Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/TestCaseOsuScreenStack.cs b/osu.Game.Tests/Visual/TestCaseOsuScreenStack.cs new file mode 100644 index 0000000000..0831228681 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseOsuScreenStack.cs @@ -0,0 +1,82 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Screens; +using osu.Framework.Testing; +using osu.Game.Screens; +using osu.Game.Screens.Play; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseOsuScreenStack : OsuTestCase + { + private TestOsuScreenStack stack; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("Create new screen stack", () => { Child = stack = new TestOsuScreenStack { RelativeSizeAxes = Axes.Both }; }); + } + + [Test] + public void ParallaxAssignmentTest() + { + NoParallaxTestScreen noParallaxScreen = null; + TestScreen parallaxScreen = null; + + AddStep("Push no parallax", () => stack.Push(noParallaxScreen = new NoParallaxTestScreen("NO PARALLAX"))); + AddUntilStep("Wait for current", () => noParallaxScreen.IsLoaded); + AddAssert("Parallax is off", () => stack.ParallaxAmount == 0); + + AddStep("Push parallax", () => noParallaxScreen.Push(parallaxScreen = new TestScreen("PARALLAX"))); + AddUntilStep("Wait for current", () => parallaxScreen.IsLoaded); + AddAssert("Parallax is on", () => stack.ParallaxAmount > 0); + + AddStep("Exit from new screen", () => { noParallaxScreen.MakeCurrent(); }); + AddAssert("Parallax is off", () => stack.ParallaxAmount == 0); + } + + private class TestScreen : ScreenWithBeatmapBackground + { + private readonly string screenText; + + public TestScreen(string screenText) + { + this.screenText = screenText; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new SpriteText + { + Text = screenText, + Colour = Color4.White, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } + } + + private class NoParallaxTestScreen : TestScreen + { + public NoParallaxTestScreen(string screenText) + : base(screenText) + { + } + + public override float BackgroundParallaxAmount => 0.0f; + } + + private class TestOsuScreenStack : OsuScreenStack + { + public new float ParallaxAmount => base.ParallaxAmount; + } + } +} diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseScreenBreadcrumbControl.cs index b4b24ae4df..c92072eb71 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseScreenBreadcrumbControl.cs @@ -19,14 +19,14 @@ namespace osu.Game.Tests.Visual.UserInterface public class TestCaseScreenBreadcrumbControl : OsuTestCase { private readonly ScreenBreadcrumbControl breadcrumbs; - private readonly ScreenStack screenStack; + private readonly OsuScreenStack screenStack; public TestCaseScreenBreadcrumbControl() { OsuSpriteText titleText; IScreen startScreen = new TestScreenOne(); - screenStack = new ScreenStack(startScreen) { RelativeSizeAxes = Axes.Both }; + screenStack = new OsuScreenStack(startScreen) { RelativeSizeAxes = Axes.Both }; Children = new Drawable[] { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index cf231f19ce..7277990987 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -87,11 +87,7 @@ namespace osu.Game public readonly Bindable OverlayActivationMode = new Bindable(); - private BackgroundScreenStack backgroundStack; - - private ParallaxContainer backgroundParallax; - - private ScreenStack screenStack; + private OsuScreenStack screenStack; private VolumeOverlay volume; private OnScreenDisplay onscreenDisplay; private OsuLogo osuLogo; @@ -390,12 +386,7 @@ namespace osu.Game RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - backgroundParallax = new ParallaxContainer - { - RelativeSizeAxes = Axes.Both, - Child = backgroundStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }, - }, - screenStack = new ScreenStack { RelativeSizeAxes = Axes.Both }, + screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }, logoContainer = new Container { RelativeSizeAxes = Axes.Both }, } }, @@ -407,17 +398,19 @@ namespace osu.Game idleTracker = new GameIdleTracker(6000) }); - dependencies.Cache(backgroundStack); - screenStack.ScreenPushed += screenPushed; screenStack.ScreenExited += screenExited; - loadComponentSingleFile(osuLogo, logoContainer.Add); - - loadComponentSingleFile(new Loader + loadComponentSingleFile(osuLogo, logo => { - RelativeSizeAxes = Axes.Both - }, screenStack.Push); + 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 + { + RelativeSizeAxes = Axes.Both + }); + }); loadComponentSingleFile(Toolbar = new Toolbar { @@ -777,8 +770,6 @@ namespace osu.Game if (newScreen is IOsuScreen newOsuScreen) { - backgroundParallax.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * newOsuScreen.BackgroundParallaxAmount; - OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode; if (newOsuScreen.HideOverlaysOnEnter) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index f38fc4e3ff..5e019a7b3a 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = screenStack = new ScreenStack(loungeSubScreen = new LoungeSubScreen()) { RelativeSizeAxes = Axes.Both } + Child = screenStack = new OsuScreenStack(loungeSubScreen = new LoungeSubScreen()) { RelativeSizeAxes = Axes.Both } }, new Header(screenStack), createButton = new HeaderButton diff --git a/osu.Game/Screens/OsuScreenStack.cs b/osu.Game/Screens/OsuScreenStack.cs new file mode 100644 index 0000000000..0844e32d46 --- /dev/null +++ b/osu.Game/Screens/OsuScreenStack.cs @@ -0,0 +1,48 @@ +// 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.Screens; +using osu.Game.Graphics.Containers; + +namespace osu.Game.Screens +{ + public class OsuScreenStack : ScreenStack + { + [Cached] + private BackgroundScreenStack backgroundScreenStack; + + private ParallaxContainer parallaxContainer; + + protected float ParallaxAmount => parallaxContainer.ParallaxAmount; + + public OsuScreenStack() + { + initializeStack(); + } + + public OsuScreenStack(IScreen baseScreen) + : base(baseScreen) + { + initializeStack(); + } + + private void initializeStack() + { + InternalChild = parallaxContainer = new ParallaxContainer + { + RelativeSizeAxes = Axes.Both, + Child = backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }, + }; + + ScreenPushed += onScreenChange; + ScreenExited += onScreenChange; + } + + private void onScreenChange(IScreen prev, IScreen next) + { + parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; + } + } +} diff --git a/osu.Game/Tests/Visual/AllPlayersTestCase.cs b/osu.Game/Tests/Visual/AllPlayersTestCase.cs index 507848730f..03bd7b218a 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestCase.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestCase.cs @@ -73,15 +73,11 @@ namespace osu.Game.Tests.Visual Player?.Exit(); Player = null; - var player = CreatePlayer(r); + Player = CreatePlayer(r); - LoadComponentAsync(player, p => - { - Player = p; - LoadScreen(p); - }); + LoadScreen(Player); - return player; + return Player; } protected virtual Player CreatePlayer(Ruleset ruleset) => new Player diff --git a/osu.Game/Tests/Visual/EditorTestCase.cs b/osu.Game/Tests/Visual/EditorTestCase.cs index 67a1cb6de3..96e70e018e 100644 --- a/osu.Game/Tests/Visual/EditorTestCase.cs +++ b/osu.Game/Tests/Visual/EditorTestCase.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual { Beatmap.Value = new TestWorkingBeatmap(ruleset.RulesetInfo, null); - LoadComponentAsync(new Editor(), LoadScreen); + LoadScreen(new Editor()); } } } diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index ad01d82281..50cb839ed9 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -52,11 +52,8 @@ namespace osu.Game.Tests.Visual if (!AllowFail) Beatmap.Value.Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; - LoadComponentAsync(Player = CreatePlayer(ruleset), p => - { - Player = p; - LoadScreen(p); - }); + Player = CreatePlayer(ruleset); + LoadScreen(Player); } protected virtual Player CreatePlayer(Ruleset ruleset) => new Player diff --git a/osu.Game/Tests/Visual/ScreenTestCase.cs b/osu.Game/Tests/Visual/ScreenTestCase.cs index 79c57ad9f4..eec60d01c5 100644 --- a/osu.Game/Tests/Visual/ScreenTestCase.cs +++ b/osu.Game/Tests/Visual/ScreenTestCase.cs @@ -1,9 +1,7 @@ // 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.Screens; using osu.Game.Screens; namespace osu.Game.Tests.Visual @@ -13,18 +11,11 @@ namespace osu.Game.Tests.Visual /// public abstract class ScreenTestCase : OsuTestCase { - private readonly ScreenStack stack; - - [Cached] - private BackgroundScreenStack backgroundStack; + private readonly OsuScreenStack stack; protected ScreenTestCase() { - Children = new Drawable[] - { - backgroundStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }, - stack = new ScreenStack { RelativeSizeAxes = Axes.Both } - }; + Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; } protected void LoadScreen(OsuScreen screen)