Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update popup dialog design #26187

Merged
merged 4 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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;

Expand All @@ -19,11 +20,15 @@ public partial class TestSceneDialogOverlay : OsuTestScene
{
private DialogOverlay overlay;

[Test]
public void TestBasic()
[SetUpSteps]
public void SetUpSteps()
{
AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay());
}

[Test]
public void TestBasic()
{
TestPopupDialog firstDialog = null;
TestPopupDialog secondDialog = null;

Expand Down Expand Up @@ -84,15 +89,39 @@ public void TestBasic()
}));

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]
public void TestTooMuchText()
{
AddStep("dialog #1", () => overlay.Push(new TestPopupDialog
{
Icon = FontAwesome.Regular.TrashAlt,
HeaderText = @"Confirm deletion ofConfirm deletion ofConfirm deletion ofConfirm deletion ofConfirm deletion ofConfirm deletion of",
BodyText = @"Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver.Ayase Rie - Yuima-ru*World TVver. ",
Buttons = new PopupDialogButton[]
{
new PopupDialogOkButton
{
Text = @"I never want to see this again.",
Action = () => Console.WriteLine(@"OK"),
},
new PopupDialogCancelButton
{
Text = @"Firetruck, I still want quick ranks!",
Action = () => Console.WriteLine(@"Cancel"),
},
},
}));
}

[Test]
public void TestPushBeforeLoad()
{
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));

Expand Down Expand Up @@ -128,8 +157,6 @@ private void load()
[Test]
public void TestDismissBeforePush()
{
AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay());

TestPopupDialog testDialog = null;
AddStep("dismissed dialog push", () =>
{
Expand All @@ -146,8 +173,6 @@ public void TestDismissBeforePush()
[Test]
public void TestDismissBeforePushViaButtonPress()
{
AddStep("create dialog overlay", () => Child = overlay = new DialogOverlay());

TestPopupDialog testDialog = null;
AddStep("dismissed dialog push", () =>
{
Expand All @@ -163,7 +188,7 @@ public void TestDismissBeforePushViaButtonPress()
});

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
Expand Down
12 changes: 5 additions & 7 deletions osu.Game.Tests/Visual/UserInterface/TestScenePopupDialog.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// 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.

#nullable disable

using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Testing;
using osu.Game.Overlays.Dialog;
Expand All @@ -15,24 +12,25 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public partial class TestScenePopupDialog : OsuManualInputManagerTestScene
{
private TestPopupDialog dialog;
private TestPopupDialog dialog = null!;

[SetUpSteps]
public void SetUpSteps()
{
AddStep("new popup", () =>
{
Add(dialog = new TestPopupDialog
Child = dialog = new TestPopupDialog
{
RelativeSizeAxes = Axes.Both,
State = { Value = Framework.Graphics.Containers.Visibility.Visible },
});
};
});
}

[Test]
public void TestDangerousButton([Values(false, true)] bool atEdge)
{
AddStep("finish transforms", () => dialog.FinishTransforms(true));

if (atEdge)
{
AddStep("move mouse to button edge", () =>
Expand Down
14 changes: 7 additions & 7 deletions osu.Game/Graphics/UserInterface/DialogButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public partial class DialogButton : OsuClickableContainer, IStateful<SelectionSt
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<SelectionState>? StateChanged;
Expand Down Expand Up @@ -54,7 +54,7 @@ public SelectionState State
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)
Expand Down Expand Up @@ -279,15 +279,15 @@ private void selectionChanged(SelectionState newState)

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);
}
}

Expand Down
79 changes: 46 additions & 33 deletions osu.Game/Overlays/Dialog/PopupDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
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;
Expand All @@ -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!;
Expand Down Expand Up @@ -108,25 +108,34 @@ public IEnumerable<PopupDialogButton> Buttons

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[]
{
new Container
{
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[]
{
Expand All @@ -142,23 +151,29 @@ protected PopupDialog()
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[]
{
Expand All @@ -181,6 +196,7 @@ protected PopupDialog()
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Icon = FontAwesome.Solid.TimesCircle,
Y = -2,
Size = new Vector2(50),
},
},
Expand All @@ -194,6 +210,7 @@ protected PopupDialog()
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
TextAnchor = Anchor.TopCentre,
Padding = new MarginPadding { Horizontal = 5 },
},
body = new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 18))
{
Expand All @@ -202,25 +219,19 @@ protected PopupDialog()
TextAnchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding(5),
Padding = new MarginPadding { Horizontal = 5 },
},
buttonsContainer = new FillFlowContainer<PopupDialogButton>
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Top = 30 },
},
},
},
buttonsContainer = new FillFlowContainer<PopupDialogButton>
{
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"),
},
},
},
};
Expand All @@ -231,7 +242,7 @@ protected PopupDialog()
}

[BackgroundDependencyLoader]
private void load(AudioManager audio)
private void load(AudioManager audio, OsuColour colours)
{
flashSample = audio.Samples.Get(@"UI/default-select-disabled");
}
Expand Down Expand Up @@ -288,15 +299,15 @@ protected override void PopIn()
// 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()
Expand All @@ -306,7 +317,9 @@ protected override void PopOut()
// 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)
Expand Down
12 changes: 7 additions & 5 deletions osu.Game/Overlays/DialogOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@ public partial class DialogOverlay : OsuFocusedOverlayContainer, IDialogOverlay

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]
Expand Down
Loading