1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:07:25 +08:00

Move confirmation bypass implementation to MainMenu to allow for more correct logic

This commit is contained in:
Dean Herbert 2023-06-21 19:06:47 +09:00
parent 59b1f08d53
commit 11a97e1bb8
5 changed files with 45 additions and 25 deletions

View File

@ -250,6 +250,8 @@ namespace osu.Game.Tests.Visual.Menus
}
public virtual IBindable<int> UnreadCount => null;
public bool HasOngoingOperations => false;
}
}
}

View File

@ -214,6 +214,8 @@ namespace osu.Game.Tests.Visual.UserInterface
}
public virtual IBindable<int> UnreadCount => null;
public bool HasOngoingOperations => false;
}
// interface mocks break hot reload, mocking this stub implementation instead works around it.

View File

@ -778,18 +778,8 @@ namespace osu.Game
public override void AttemptExit()
{
bool requiresConfirmationToExit = Notifications.HasOngoingOperations;
PerformFromScreen(menu =>
{
var mainMenu = ((MainMenu)menu);
// The main menu exit implementation gives the user a chance to interrupt the exit process if needed.
if (requiresConfirmationToExit)
mainMenu.Exit();
else
mainMenu.ExitWithoutConfirmation();
}, new[] { typeof(MainMenu) });
// The main menu exit implementation gives the user a chance to interrupt the exit process if needed.
PerformFromScreen(menu => menu.Exit(), new[] { typeof(MainMenu) });
}
/// <summary>

View File

@ -30,5 +30,10 @@ namespace osu.Game.Overlays
/// Current number of unread notifications.
/// </summary>
IBindable<int> UnreadCount { get; }
/// <summary>
/// Whether there are any ongoing operations, such as imports or downloads.
/// </summary>
bool HasOngoingOperations { get; }
}
}

View File

@ -53,6 +53,9 @@ namespace osu.Game.Screens.Menu
[Resolved]
private GameHost host { get; set; }
[Resolved]
private INotificationOverlay notifications { get; set; }
[Resolved]
private MusicController musicController { get; set; }
@ -74,6 +77,9 @@ namespace osu.Game.Screens.Menu
private ExitConfirmOverlay exitConfirmOverlay;
private bool exitConfirmedViaDialog;
private bool exitConfirmedViaHoldOrClick;
private ParallaxContainer buttonsContainer;
private SongTicker songTicker;
@ -89,10 +95,8 @@ namespace osu.Game.Screens.Menu
{
Action = () =>
{
if (holdDelay.Value > 0)
confirmAndExit();
else
this.Exit();
exitConfirmedViaHoldOrClick = holdDelay.Value > 0;
this.Exit();
}
});
}
@ -114,7 +118,11 @@ namespace osu.Game.Screens.Menu
OnSolo = loadSoloSongSelect,
OnMultiplayer = () => this.Push(new Multiplayer()),
OnPlaylists = () => this.Push(new Playlists()),
OnExit = confirmAndExit,
OnExit = () =>
{
exitConfirmedViaHoldOrClick = true;
this.Exit();
}
}
}
},
@ -154,13 +162,11 @@ namespace osu.Game.Screens.Menu
public void ReturnToOsuLogo() => Buttons.State = ButtonSystemState.Initial;
public void ExitWithoutConfirmation() => confirmAndExit();
private void confirmAndExit()
{
if (exitConfirmed) return;
if (exitConfirmedViaDialog) return;
exitConfirmed = true;
exitConfirmedViaDialog = true;
performer?.PerformFromScreen(menu => menu.Exit());
}
@ -203,8 +209,6 @@ namespace osu.Game.Screens.Menu
dialogOverlay?.Push(new StorageErrorDialog(osuStorage, osuStorage.Error));
}
private bool exitConfirmed;
protected override void LogoArriving(OsuLogo logo, bool resuming)
{
base.LogoArriving(logo, resuming);
@ -281,12 +285,29 @@ namespace osu.Game.Screens.Menu
public override bool OnExiting(ScreenExitEvent e)
{
if (!exitConfirmed && dialogOverlay != null)
bool requiresConfirmation =
// we need to have a dialog overlay to confirm in the first place.
dialogOverlay != null
// if the dialog has already displayed and been accepted by the user, we are good.
&& !exitConfirmedViaDialog
// Only require confirmation if there is either an ongoing operation or the user exited via a non-hold escape press.
&& (notifications.HasOngoingOperations || !exitConfirmedViaHoldOrClick);
if (requiresConfirmation)
{
if (dialogOverlay.CurrentDialog is ConfirmExitDialog exitDialog)
exitDialog.PerformOkAction();
else
dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort()));
{
dialogOverlay.Push(new ConfirmExitDialog(() =>
{
exitConfirmedViaDialog = true;
this.Exit();
}, () =>
{
exitConfirmOverlay.Abort();
}));
}
return true;
}