From 61ddf1e6cf90a9fb9041afdc9335ac57205b6b83 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Mar 2022 15:28:31 +0900 Subject: [PATCH] Disallow exiting the editor without saving (unless explicitly confirming) --- .../Visual/Editing/TestSceneEditorSaving.cs | 7 +++++++ osu.Game/Screens/Edit/Editor.cs | 13 +++++-------- osu.Game/Tests/Visual/EditorTestScene.cs | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index d1c1558003..e75c7f25a3 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -17,6 +17,13 @@ namespace osu.Game.Tests.Visual.Editing { public class TestSceneEditorSaving : EditorSavingTestScene { + [Test] + public void TestCantExitWithoutSaving() + { + AddRepeatStep("Exit", () => InputManager.Key(Key.Escape), 10); + AddAssert("Editor is still active screen", () => Game.ScreenStack.CurrentScreen is Editor); + } + [Test] public void TestMetadata() { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 444b2fe6f9..7254a9140f 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -98,7 +98,7 @@ namespace osu.Game.Screens.Edit private bool canSave; - private bool exitConfirmed; + protected bool ExitConfirmed { get; private set; } private string lastSavedHash; @@ -587,7 +587,7 @@ namespace osu.Game.Screens.Edit public override bool OnExiting(IScreen next) { - if (!exitConfirmed) + if (!ExitConfirmed) { // dialog overlay may not be available in visual tests. if (dialogOverlay == null) @@ -596,12 +596,9 @@ namespace osu.Game.Screens.Edit return true; } - // if the dialog is already displayed, confirm exit with no save. + // if the dialog is already displayed, block exiting until the user explicitly makes a decision. if (dialogOverlay.CurrentDialog is PromptForSaveDialog saveDialog) - { - saveDialog.PerformAction(); return true; - } if (isNewBeatmap || HasUnsavedChanges) { @@ -646,7 +643,7 @@ namespace osu.Game.Screens.Edit { Save(); - exitConfirmed = true; + ExitConfirmed = true; this.Exit(); } @@ -669,7 +666,7 @@ namespace osu.Game.Screens.Edit Beatmap.SetDefault(); } - exitConfirmed = true; + ExitConfirmed = true; this.Exit(); } diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 24015590e2..efaf6f2253 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -7,10 +7,13 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.IO.Stores; using osu.Framework.Platform; +using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Online.API; +using osu.Game.Overlays; +using osu.Game.Overlays.Dialog; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; @@ -93,6 +96,9 @@ namespace osu.Game.Tests.Visual protected class TestEditor : Editor { + [Resolved(canBeNull: true)] + private DialogOverlay dialogOverlay { get; set; } + public new void Undo() => base.Undo(); public new void Redo() => base.Redo(); @@ -111,6 +117,18 @@ namespace osu.Game.Tests.Visual public new bool HasUnsavedChanges => base.HasUnsavedChanges; + public override bool OnExiting(IScreen next) + { + // For testing purposes allow the screen to exit without saving on second attempt. + if (!ExitConfirmed && dialogOverlay.CurrentDialog is PromptForSaveDialog saveDialog) + { + saveDialog.PerformAction(); + return true; + } + + return base.OnExiting(next); + } + public TestEditor(EditorLoader loader = null) : base(loader) {