diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs index 81b692004b..3b38343f04 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs @@ -9,6 +9,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Overlays.Dialog; @@ -19,11 +20,15 @@ namespace osu.Game.Tests.Visual.UserInterface { private DialogOverlay overlay; + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay()); + } + [Test] public void TestBasic() { - AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay()); - TestPopupDialog firstDialog = null; TestPopupDialog secondDialog = null; @@ -84,7 +89,7 @@ namespace osu.Game.Tests.Visual.UserInterface })); AddAssert("second dialog displayed", () => overlay.CurrentDialog == secondDialog); - AddAssert("first dialog is not part of hierarchy", () => firstDialog.Parent == null); + AddUntilStep("first dialog is not part of hierarchy", () => firstDialog.Parent == null); } [Test] @@ -92,7 +97,7 @@ namespace osu.Game.Tests.Visual.UserInterface { PopupDialog dialog = null; - AddStep("create dialog overlay", () => overlay = new SlowLoadingDialogOverlay()); + AddStep("create slow loading dialog overlay", () => overlay = new SlowLoadingDialogOverlay()); AddStep("start loading overlay", () => LoadComponentAsync(overlay, Add)); @@ -128,8 +133,6 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestDismissBeforePush() { - AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay()); - TestPopupDialog testDialog = null; AddStep("dismissed dialog push", () => { @@ -146,8 +149,6 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestDismissBeforePushViaButtonPress() { - AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay()); - TestPopupDialog testDialog = null; AddStep("dismissed dialog push", () => { @@ -163,7 +164,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddAssert("no dialog pushed", () => overlay.CurrentDialog == null); - AddAssert("dialog is not part of hierarchy", () => testDialog.Parent == null); + AddUntilStep("dialog is not part of hierarchy", () => testDialog.Parent == null); } private partial class TestPopupDialog : PopupDialog diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index db81bc991d..c920597a95 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -25,7 +25,7 @@ namespace osu.Game.Graphics.UserInterface private const float idle_width = 0.8f; private const float hover_width = 0.9f; - private const float hover_duration = 500; + private const float hover_duration = 300; private const float click_duration = 200; public event Action? StateChanged; @@ -54,7 +54,7 @@ namespace osu.Game.Graphics.UserInterface private readonly Box rightGlow; private readonly Box background; private readonly SpriteText spriteText; - private Vector2 hoverSpacing => new Vector2(3f, 0f); + private Vector2 hoverSpacing => new Vector2(1.4f, 0f); public DialogButton(HoverSampleSet sampleSet = HoverSampleSet.Button) : base(sampleSet) @@ -279,15 +279,15 @@ namespace osu.Game.Graphics.UserInterface if (newState == SelectionState.Selected) { - spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutElastic); - ColourContainer.ResizeWidthTo(hover_width, hover_duration, Easing.OutElastic); + spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutQuint); + ColourContainer.ResizeWidthTo(hover_width, hover_duration, Easing.OutQuint); glowContainer.FadeIn(hover_duration, Easing.OutQuint); } else { - ColourContainer.ResizeWidthTo(idle_width, hover_duration, Easing.OutElastic); - spriteText.TransformSpacingTo(Vector2.Zero, hover_duration, Easing.OutElastic); - glowContainer.FadeOut(hover_duration, Easing.OutQuint); + ColourContainer.ResizeWidthTo(idle_width, hover_duration / 2, Easing.OutQuint); + spriteText.TransformSpacingTo(Vector2.Zero, hover_duration / 2, Easing.OutQuint); + glowContainer.FadeOut(hover_duration / 2, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 36a9baac67..663c2e78ce 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osuTK; @@ -25,11 +26,10 @@ namespace osu.Game.Overlays.Dialog public abstract partial class PopupDialog : VisibilityContainer { public const float ENTER_DURATION = 500; - public const float EXIT_DURATION = 200; + public const float EXIT_DURATION = 500; private readonly Vector2 ringSize = new Vector2(100f); private readonly Vector2 ringMinifiedSize = new Vector2(20f); - private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f); private readonly Box flashLayer; private Sample flashSample = null!; @@ -108,13 +108,20 @@ namespace osu.Game.Overlays.Dialog protected PopupDialog() { - RelativeSizeAxes = Axes.Both; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; Children = new Drawable[] { content = new Container { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Alpha = 0f, Children = new Drawable[] { @@ -122,11 +129,13 @@ namespace osu.Game.Overlays.Dialog { RelativeSizeAxes = Axes.Both, Masking = true, + CornerRadius = 20, + CornerExponent = 2.5f, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.5f), - Radius = 8, + Colour = Color4.Black.Opacity(0.2f), + Radius = 14, }, Children = new Drawable[] { @@ -142,23 +151,29 @@ namespace osu.Game.Overlays.Dialog ColourDark = Color4Extensions.FromHex(@"1e171e"), TriangleScale = 4, }, + flashLayer = new Box + { + Alpha = 0, + RelativeSizeAxes = Axes.Both, + Blending = BlendingParameters.Additive, + Colour = Color4Extensions.FromHex(@"221a21"), + }, }, }, new FillFlowContainer { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Spacing = new Vector2(0f, 10f), - Padding = new MarginPadding { Bottom = 10 }, + Padding = new MarginPadding { Vertical = 60 }, Children = new Drawable[] { new Container { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, + Padding = new MarginPadding { Bottom = 30 }, Size = ringSize, Children = new Drawable[] { @@ -181,6 +196,7 @@ namespace osu.Game.Overlays.Dialog Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = FontAwesome.Solid.TimesCircle, + Y = -2, Size = new Vector2(50), }, }, @@ -202,25 +218,18 @@ namespace osu.Game.Overlays.Dialog TextAnchor = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(5), + }, + buttonsContainer = new FillFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Top = 30 }, }, }, }, - buttonsContainer = new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - }, - flashLayer = new Box - { - Alpha = 0, - RelativeSizeAxes = Axes.Both, - Blending = BlendingParameters.Additive, - Colour = Color4Extensions.FromHex(@"221a21"), - }, }, }, }; @@ -231,7 +240,7 @@ namespace osu.Game.Overlays.Dialog } [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(AudioManager audio, OsuColour colours) { flashSample = audio.Samples.Get(@"UI/default-select-disabled"); } @@ -288,15 +297,15 @@ namespace osu.Game.Overlays.Dialog // Reset various animations but only if the dialog animation fully completed if (content.Alpha == 0) { - buttonsContainer.TransformSpacingTo(buttonsEnterSpacing); - buttonsContainer.MoveToY(buttonsEnterSpacing.Y); + content.ScaleTo(0.7f); ring.ResizeTo(ringMinifiedSize); } - content.FadeIn(ENTER_DURATION, Easing.OutQuint); - ring.ResizeTo(ringSize, ENTER_DURATION, Easing.OutQuint); - buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, Easing.OutQuint); - buttonsContainer.MoveToY(0, ENTER_DURATION, Easing.OutQuint); + content + .ScaleTo(1, 750, Easing.OutElasticHalf) + .FadeIn(ENTER_DURATION, Easing.OutQuint); + + ring.ResizeTo(ringSize, ENTER_DURATION * 1.5f, Easing.OutQuint); } protected override void PopOut() @@ -306,7 +315,9 @@ namespace osu.Game.Overlays.Dialog // This is presumed to always be a sane default "cancel" action. buttonsContainer.Last().TriggerClick(); - content.FadeOut(EXIT_DURATION, Easing.InSine); + content + .ScaleTo(0.7f, EXIT_DURATION, Easing.Out) + .FadeOut(EXIT_DURATION, Easing.OutQuint); } private void pressButtonAtIndex(int index) diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index 005162bbcc..a85f1ecbcd 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -29,16 +29,18 @@ namespace osu.Game.Overlays public DialogOverlay() { - RelativeSizeAxes = Axes.Both; + AutoSizeAxes = Axes.Y; Child = dialogContainer = new Container { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, }; - Width = 0.4f; - Anchor = Anchor.BottomCentre; - Origin = Anchor.BottomCentre; + Width = 500; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; } [BackgroundDependencyLoader]