// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; using System.Linq; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transforms; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; namespace osu.Game.Overlays.Dialog { public class PopupDialog : FocusedOverlayContainer { public static readonly float ENTER_DURATION = 500; public static readonly float EXIT_DURATION = 200; private readonly Vector2 ringSize = new Vector2(100f); private readonly Vector2 ringMinifiedSize = new Vector2(20f); private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f); private Container content, ring; private FillFlowContainer buttonsContainer; private TextAwesome iconText; private SpriteText header, body; public FontAwesome Icon { get { return iconText.Icon; } set { iconText.Icon = value; } } public string HeaderText { get { return header.Text; } set { header.Text = value; } } public string BodyText { get { return body.Text; } set { body.Text = value; } } public PopupDialogButton[] Buttons { get { return buttonsContainer.Children.ToArray(); } set { buttonsContainer.Children = value; foreach (PopupDialogButton b in value) { var action = b.Action; b.Action = () => { Hide(); action?.Invoke(); }; } } } private void pressButtonAtIndex(int index) { if (index < Buttons.Length) Buttons[index].TriggerClick(); } private bool triggeredButton = false; // used to make it so the user can't press multiple buttons at once with the keyboard protected override bool OnKeyDown(Framework.Input.InputState state, Framework.Input.KeyDownEventArgs args) { if (args.Repeat) return false; if (!triggeredButton) { if (args.Key == Key.Enter) { Buttons.OfType()?.FirstOrDefault()?.TriggerClick(); triggeredButton = true; 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); triggeredButton = true; return true; } else if (k >= Key.Keypad1 && k <= Key.Keypad9) { pressButtonAtIndex(k - Key.Keypad1); triggeredButton = true; return true; } } return base.OnKeyDown(state, args); } protected override void PopIn() { base.PopIn(); triggeredButton = 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, EasingTypes.OutQuint); ring.ResizeTo(ringSize, ENTER_DURATION, EasingTypes.OutQuint); buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, EasingTypes.OutQuint); buttonsContainer.MoveToY(0, ENTER_DURATION, EasingTypes.OutQuint); } protected override void PopOut() { base.PopOut(); content.FadeOut(EXIT_DURATION, EasingTypes.InSine); } public PopupDialog() { RelativeSizeAxes = Axes.Both; Children = new Drawable[] { content = new Container { RelativeSizeAxes = Axes.Both, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Width = 0.4f, Alpha = 0f, Children = new Drawable[] { new Container { RelativeSizeAxes = Axes.Both, Masking = true, EdgeEffect = new EdgeEffect { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.5f), Radius = 8, }, Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"221a21"), }, new Triangles { RelativeSizeAxes = Axes.Both, ColourLight = OsuColour.FromHex(@"271e26"), ColourDark = OsuColour.FromHex(@"1e171e"), TriangleScale = 4, }, }, }, new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Position = new Vector2(0f, -50f), Direction = FillDirection.Down, Spacing = new Vector2(0f, 10f), Children = new Drawable[] { new Container { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Size = ringSize, Margin = new MarginPadding { Bottom = 30, }, Children = new Drawable[] { ring = new CircularContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, BorderColour = Color4.White, BorderThickness = 5f, Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = Color4.Black.Opacity(0), }, iconText = new TextAwesome { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = FontAwesome.fa_close, TextSize = 50, }, }, }, }, }, header = new SpriteText { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = @"Header", TextSize = 25, Shadow = true, }, body = new SpriteText { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = @"Body", TextSize = 18, Shadow = true, }, }, }, buttonsContainer = new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Down, }, }, }, }; } } }