diff --git a/.idea/.idea.osu.Desktop/.idea/misc.xml b/.idea/.idea.osu.Desktop/.idea/misc.xml index 1d8c84d0af..4e1d56f4dd 100644 --- a/.idea/.idea.osu.Desktop/.idea/misc.xml +++ b/.idea/.idea.osu.Desktop/.idea/misc.xml @@ -1,5 +1,10 @@ + + + diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs new file mode 100644 index 0000000000..5d554719a5 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs @@ -0,0 +1,114 @@ +// 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.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; +using osu.Game.Graphics.Containers; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.UserInterface +{ + [TestFixture] + public class TestSceneScalingContainer : OsuTestScene + { + private OsuConfigManager osuConfigManager { get; set; } + + private ScalingContainer scaling1; + private ScalingContainer scaling2; + private Box scaleTarget; + + [BackgroundDependencyLoader] + private void load() + { + osuConfigManager = new OsuConfigManager(LocalStorage); + + Dependencies.CacheAs(osuConfigManager); + + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + scaling1 = new ScalingContainer(ScalingMode.Everything) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.8f), + Children = new Drawable[] + { + scaling2 = new ScalingContainer(ScalingMode.Everything) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.8f), + Children = new Drawable[] + { + new Box + { + Colour = Color4.Purple, + RelativeSizeAxes = Axes.Both, + }, + scaleTarget = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Color4.White, + Size = new Vector2(100), + }, + } + } + } + } + } + }, + }; + } + + [Test] + public void TestScaling() + { + AddStep("adjust scale", () => osuConfigManager.SetValue(OsuSetting.UIScale, 2f)); + + checkForCorrectness(); + + AddStep("adjust scale", () => osuConfigManager.SetValue(OsuSetting.UIScale, 0.5f)); + + checkForCorrectness(); + } + + private void checkForCorrectness() + { + Quad? scaling1LastQuad = null; + Quad? scaling2LastQuad = null; + Quad? scalingTargetLastQuad = null; + + AddUntilStep("ensure dimensions don't change", () => + { + if (scaling1LastQuad.HasValue && scaling2LastQuad.HasValue) + { + // check inter-frame changes to make sure they match expectations. + Assert.That(scaling1.ScreenSpaceDrawQuad.AlmostEquals(scaling1LastQuad.Value), Is.True); + Assert.That(scaling2.ScreenSpaceDrawQuad.AlmostEquals(scaling2LastQuad.Value), Is.True); + } + + scaling1LastQuad = scaling1.ScreenSpaceDrawQuad; + scaling2LastQuad = scaling2.ScreenSpaceDrawQuad; + + // wait for scaling to stop. + bool scalingFinished = scalingTargetLastQuad.HasValue && scaleTarget.ScreenSpaceDrawQuad.AlmostEquals(scalingTargetLastQuad.Value); + + scalingTargetLastQuad = scaleTarget.ScreenSpaceDrawQuad; + + return scalingFinished; + }); + } + } +} diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 58d18e1b21..ca8b6f388f 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -21,6 +21,8 @@ namespace osu.Game.Graphics.Containers /// public class ScalingContainer : Container { + private const float duration = 500; + private Bindable sizeX; private Bindable sizeY; private Bindable posX; @@ -82,6 +84,8 @@ namespace osu.Game.Graphics.Containers private readonly bool applyUIScale; private Bindable uiScale; + private float currentScale = 1; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public ScalingDrawSizePreservingFillContainer(bool applyUIScale) @@ -95,14 +99,16 @@ namespace osu.Game.Graphics.Containers if (applyUIScale) { uiScale = osuConfig.GetBindable(OsuSetting.UIScale); - uiScale.BindValueChanged(scaleChanged, true); + uiScale.BindValueChanged(args => this.TransformTo(nameof(currentScale), args.NewValue, duration, Easing.OutQuart), true); } } - private void scaleChanged(ValueChangedEvent args) + protected override void Update() { - this.ScaleTo(new Vector2(args.NewValue), 500, Easing.Out); - this.ResizeTo(new Vector2(1 / args.NewValue), 500, Easing.Out); + Scale = new Vector2(currentScale); + Size = new Vector2(1 / currentScale); + + base.Update(); } } @@ -140,8 +146,6 @@ namespace osu.Game.Graphics.Containers private void updateSize() { - const float duration = 500; - if (targetMode == ScalingMode.Everything) { // the top level scaling container manages the background to be displayed while scaling.