Standardise input handling of popup dialogs

This commit is contained in:
Dean Herbert
2018-07-02 14:22:37 +09:00
parent 6fe768366f
commit 596787c941
2 changed files with 100 additions and 96 deletions

View File

@ -6,16 +6,16 @@ using System.Linq;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Input; using OpenTK.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Dialog namespace osu.Game.Overlays.Dialog
{ {
@ -23,6 +23,9 @@ namespace osu.Game.Overlays.Dialog
{ {
public static readonly float ENTER_DURATION = 500; public static readonly float ENTER_DURATION = 500;
public static readonly float EXIT_DURATION = 200; public static readonly float EXIT_DURATION = 200;
protected override bool BlockPassThroughMouse => false;
private readonly Vector2 ringSize = new Vector2(100f); private readonly Vector2 ringSize = new Vector2(100f);
private readonly Vector2 ringMinifiedSize = new Vector2(20f); private readonly Vector2 ringMinifiedSize = new Vector2(20f);
private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f); private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f);
@ -34,26 +37,28 @@ namespace osu.Game.Overlays.Dialog
private readonly SpriteText header; private readonly SpriteText header;
private readonly TextFlowContainer body; private readonly TextFlowContainer body;
private bool actionInvoked;
public FontAwesome Icon public FontAwesome Icon
{ {
get { return icon.Icon; } get => icon.Icon;
set { icon.Icon = value; } set => icon.Icon = value;
} }
public string HeaderText public string HeaderText
{ {
get { return header.Text; } get => header.Text;
set { header.Text = value; } set => header.Text = value;
} }
public string BodyText public string BodyText
{ {
set { body.Text = value; } set => body.Text = value;
} }
public IEnumerable<PopupDialogButton> Buttons public IEnumerable<PopupDialogButton> Buttons
{ {
get { return buttonsContainer.Children; } get => buttonsContainer.Children;
set set
{ {
buttonsContainer.ChildrenEnumerable = value; buttonsContainer.ChildrenEnumerable = value;
@ -62,71 +67,17 @@ namespace osu.Game.Overlays.Dialog
var action = b.Action; var action = b.Action;
b.Action = () => b.Action = () =>
{ {
if (actionInvoked) return;
Hide(); Hide();
actionInvoked = true;
action?.Invoke(); action?.Invoke();
}; };
} }
} }
} }
private void pressButtonAtIndex(int index)
{
if (index < Buttons.Count())
Buttons.Skip(index).First().TriggerOnClick();
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Repeat) return false;
if (args.Key == Key.Enter || args.Key == Key.KeypadEnter)
{
Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.TriggerOnClick();
return true;
}
// press button at number if 1-9 on number row or keypad are pressed
var k = args.Key;
if (k >= Key.Number1 && k <= Key.Number9)
{
pressButtonAtIndex(k - Key.Number1);
return true;
}
if (k >= Key.Keypad1 && k <= Key.Keypad9)
{
pressButtonAtIndex(k - Key.Keypad1);
return true;
}
return base.OnKeyDown(state, args);
}
protected override void PopIn()
{
base.PopIn();
// Reset various animations but only if the dialog animation fully completed
if (content.Alpha == 0)
{
buttonsContainer.TransformSpacingTo(buttonsEnterSpacing);
buttonsContainer.MoveToY(buttonsEnterSpacing.Y);
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);
}
protected override void PopOut()
{
base.PopOut();
content.FadeOut(EXIT_DURATION, Easing.InSine);
}
public PopupDialog() public PopupDialog()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
@ -136,9 +87,6 @@ namespace osu.Game.Overlays.Dialog
content = new Container content = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Width = 0.4f,
Alpha = 0f, Alpha = 0f,
Children = new Drawable[] Children = new Drawable[]
{ {
@ -243,5 +191,66 @@ namespace osu.Game.Overlays.Dialog
}, },
}; };
} }
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Repeat) return false;
if (args.Key == Key.Enter || args.Key == Key.KeypadEnter)
{
Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.TriggerOnClick();
return true;
}
// press button at number if 1-9 on number row or keypad are pressed
var k = args.Key;
if (k >= Key.Number1 && k <= Key.Number9)
{
pressButtonAtIndex(k - Key.Number1);
return true;
}
if (k >= Key.Keypad1 && k <= Key.Keypad9)
{
pressButtonAtIndex(k - Key.Keypad1);
return true;
}
return base.OnKeyDown(state, args);
}
protected override void PopIn()
{
base.PopIn();
actionInvoked = false;
// Reset various animations but only if the dialog animation fully completed
if (content.Alpha == 0)
{
buttonsContainer.TransformSpacingTo(buttonsEnterSpacing);
buttonsContainer.MoveToY(buttonsEnterSpacing.Y);
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);
}
protected override void PopOut()
{
if (!actionInvoked) buttonsContainer.Last().TriggerOnClick();
base.PopOut();
content.FadeOut(EXIT_DURATION, Easing.InSine);
}
private void pressButtonAtIndex(int index)
{
if (index < Buttons.Count())
Buttons.Skip(index).First().TriggerOnClick();
}
} }
} }

View File

@ -1,12 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Dialog; using osu.Game.Overlays.Dialog;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays namespace osu.Game.Overlays
@ -16,6 +13,20 @@ namespace osu.Game.Overlays
private readonly Container dialogContainer; private readonly Container dialogContainer;
private PopupDialog currentDialog; private PopupDialog currentDialog;
public DialogOverlay()
{
RelativeSizeAxes = Axes.Both;
Child = dialogContainer = new Container
{
RelativeSizeAxes = Axes.Both,
};
Width = 0.4f;
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
}
public void Push(PopupDialog dialog) public void Push(PopupDialog dialog)
{ {
if (dialog == currentDialog) return; if (dialog == currentDialog) return;
@ -32,6 +43,8 @@ namespace osu.Game.Overlays
protected override bool PlaySamplesOnStateChange => false; protected override bool PlaySamplesOnStateChange => false;
protected override bool BlockPassThroughKeyboard => true;
private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v) private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v)
{ {
if (v != Visibility.Hidden) return; if (v != Visibility.Hidden) return;
@ -52,32 +65,14 @@ namespace osu.Game.Overlays
protected override void PopOut() protected override void PopOut()
{ {
base.PopOut(); base.PopOut();
this.FadeOut(PopupDialog.EXIT_DURATION, Easing.InSine);
}
public DialogOverlay() if (currentDialog?.State == Visibility.Visible)
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{ {
new Container currentDialog.Hide();
{ return;
RelativeSizeAxes = Axes.Both, }
Children = new Drawable[]
{ this.FadeOut(PopupDialog.EXIT_DURATION, Easing.InSine);
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
},
},
dialogContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
};
} }
} }
} }