1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 22:53:22 +08:00

Fix exit scenarios

This commit is contained in:
Dean Herbert 2019-09-19 20:17:58 +09:00
parent ead3ee3b41
commit 50d4206c45
5 changed files with 41 additions and 24 deletions

View File

@ -61,10 +61,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private class TestHoldToConfirmOverlay : ExitConfirmOverlay private class TestHoldToConfirmOverlay : ExitConfirmOverlay
{ {
protected override bool AllowMultipleFires => true;
public void Begin() => BeginConfirm(); public void Begin() => BeginConfirm();
public void Abort() => AbortConfirm();
} }
} }
} }

View File

@ -16,7 +16,11 @@ namespace osu.Game.Graphics.Containers
private const int fadeout_delay = 200; private const int fadeout_delay = 200;
private bool fired; /// <summary>
/// Whether currently in a fired state (and the confirm <see cref="Action"/> has been sent).
/// </summary>
public bool Fired { get; private set; }
private bool confirming; private bool confirming;
/// <summary> /// <summary>
@ -36,7 +40,7 @@ namespace osu.Game.Graphics.Containers
protected void BeginConfirm() protected void BeginConfirm()
{ {
if (confirming || (!AllowMultipleFires && fired)) return; if (confirming || (!AllowMultipleFires && Fired)) return;
confirming = true; confirming = true;
@ -46,14 +50,15 @@ namespace osu.Game.Graphics.Containers
protected virtual void Confirm() protected virtual void Confirm()
{ {
Action?.Invoke(); Action?.Invoke();
fired = true; Fired = true;
} }
protected void AbortConfirm() protected void AbortConfirm()
{ {
if (!AllowMultipleFires && fired) return; if (!AllowMultipleFires && Fired) return;
confirming = false; confirming = false;
Fired = false;
this.TransformBindableTo(Progress, 0, fadeout_delay, Easing.Out); this.TransformBindableTo(Progress, 0, fadeout_delay, Easing.Out);
} }

View File

@ -13,7 +13,8 @@ namespace osu.Game.Overlays
public class DialogOverlay : OsuFocusedOverlayContainer public class DialogOverlay : OsuFocusedOverlayContainer
{ {
private readonly Container dialogContainer; private readonly Container dialogContainer;
private PopupDialog currentDialog;
public PopupDialog CurrentDialog { get; private set; }
public DialogOverlay() public DialogOverlay()
{ {
@ -31,15 +32,15 @@ namespace osu.Game.Overlays
public void Push(PopupDialog dialog) public void Push(PopupDialog dialog)
{ {
if (dialog == currentDialog) return; if (dialog == CurrentDialog) return;
currentDialog?.Hide(); CurrentDialog?.Hide();
currentDialog = dialog; CurrentDialog = dialog;
dialogContainer.Add(currentDialog); dialogContainer.Add(CurrentDialog);
currentDialog.Show(); CurrentDialog.Show();
currentDialog.State.ValueChanged += state => onDialogOnStateChanged(dialog, state.NewValue); CurrentDialog.State.ValueChanged += state => onDialogOnStateChanged(dialog, state.NewValue);
Show(); Show();
} }
@ -52,8 +53,11 @@ namespace osu.Game.Overlays
//handle the dialog being dismissed. //handle the dialog being dismissed.
dialog.Delay(PopupDialog.EXIT_DURATION).Expire(); dialog.Delay(PopupDialog.EXIT_DURATION).Expire();
if (dialog == currentDialog) if (dialog == CurrentDialog)
{
Hide(); Hide();
CurrentDialog = null;
}
} }
protected override void PopIn() protected override void PopIn()
@ -66,9 +70,9 @@ namespace osu.Game.Overlays
{ {
base.PopOut(); base.PopOut();
if (currentDialog?.State.Value == Visibility.Visible) if (CurrentDialog?.State.Value == Visibility.Visible)
{ {
currentDialog.Hide(); CurrentDialog.Hide();
return; return;
} }
@ -80,7 +84,7 @@ namespace osu.Game.Overlays
switch (action) switch (action)
{ {
case GlobalAction.Select: case GlobalAction.Select:
currentDialog?.Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.Click(); CurrentDialog?.Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.Click();
return true; return true;
} }

View File

@ -9,6 +9,10 @@ namespace osu.Game.Screens.Menu
{ {
public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler<GlobalAction> public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler<GlobalAction>
{ {
protected override bool AllowMultipleFires => true;
public void Abort() => AbortConfirm();
public bool OnPressed(GlobalAction action) public bool OnPressed(GlobalAction action)
{ {
if (action == GlobalAction.Back) if (action == GlobalAction.Back)
@ -24,7 +28,8 @@ namespace osu.Game.Screens.Menu
{ {
if (action == GlobalAction.Back) if (action == GlobalAction.Back)
{ {
AbortConfirm(); if (!Fired)
AbortConfirm();
return true; return true;
} }

View File

@ -64,11 +64,13 @@ namespace osu.Game.Screens.Menu
private Bindable<int> holdDelay; private Bindable<int> holdDelay;
private ExitConfirmOverlay exitConfirmOverlay;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config) private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config)
{ {
if (host.CanExit) if (host.CanExit)
AddInternal(new ExitConfirmOverlay { Action = this.Exit }); AddInternal(exitConfirmOverlay = new ExitConfirmOverlay { Action = this.Exit });
holdDelay = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay); holdDelay = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay);
@ -237,12 +239,15 @@ namespace osu.Game.Screens.Menu
public override bool OnExiting(IScreen next) public override bool OnExiting(IScreen next)
{ {
if (holdDelay.Value == 0 && !exitConfirmed && dialogOverlay != null) if (holdDelay.Value == 0 && !exitConfirmed && dialogOverlay != null && !(dialogOverlay.CurrentDialog is ConfirmExitDialog))
{ {
dialogOverlay.Push(new ConfirmExitDialog(() => dialogOverlay.Push(new ConfirmExitDialog(() =>
{ {
exitConfirmed = true; exitConfirmed = true;
this.Exit(); this.Exit();
}, () =>
{
exitConfirmOverlay.Abort();
})); }));
return true; return true;
@ -253,9 +258,9 @@ namespace osu.Game.Screens.Menu
return base.OnExiting(next); return base.OnExiting(next);
} }
public class ConfirmExitDialog : PopupDialog private class ConfirmExitDialog : PopupDialog
{ {
public ConfirmExitDialog(Action confirm) public ConfirmExitDialog(Action confirm, Action cancel)
{ {
HeaderText = "Are you sure you want to exit?"; HeaderText = "Are you sure you want to exit?";
BodyText = "Last chance to back out."; BodyText = "Last chance to back out.";
@ -271,7 +276,8 @@ namespace osu.Game.Screens.Menu
}, },
new PopupDialogCancelButton new PopupDialogCancelButton
{ {
Text = @"Just a little more" Text = @"Just a little more",
Action = cancel
}, },
}; };
} }