diff --git a/Intersect.Client.Core/Interface/Game/SimplifiedEscapeMenu.cs b/Intersect.Client.Core/Interface/Game/SimplifiedEscapeMenu.cs index 0007d7c403..2812fe208c 100644 --- a/Intersect.Client.Core/Interface/Game/SimplifiedEscapeMenu.cs +++ b/Intersect.Client.Core/Interface/Game/SimplifiedEscapeMenu.cs @@ -6,8 +6,8 @@ using Intersect.Client.General; using Intersect.Client.Interface.Shared; using Intersect.Client.Localization; +using Intersect.Client.MonoGame; using Intersect.Framework.Core; -using Intersect.Utilities; namespace Intersect.Client.Interface.Game; @@ -114,6 +114,11 @@ private void LogoutToMainToMainMenuClicked(Base sender, MouseButtonState argumen private void ExitToDesktopClicked(Base sender, MouseButtonState arguments) { + if (IntersectGame._isShowingExitConfirmation) + { + return; + } + if (Globals.Me?.CombatTimer > Timing.Global?.Milliseconds) { AlertWindow.Open( @@ -123,8 +128,13 @@ private void ExitToDesktopClicked(Base sender, MouseButtonState arguments) inputType: InputType.YesNo, handleSubmit: (_, _) => { + IntersectGame._isShowingExitConfirmation = false; Globals.Me.CombatTimer = 0; Globals.IsRunning = false; + }, + handleCancel: (_, _) => + { + IntersectGame._isShowingExitConfirmation = false; } ); } @@ -137,10 +147,17 @@ private void ExitToDesktopClicked(Base sender, MouseButtonState arguments) inputType: InputType.YesNo, handleSubmit: (_, _) => { + IntersectGame._isShowingExitConfirmation = false; Globals.IsRunning = false; + }, + handleCancel: (_, _) => + { + IntersectGame._isShowingExitConfirmation = false; } ); } + + IntersectGame._isShowingExitConfirmation = true; } private void OpenSettingsWindow(object? sender, EventArgs? e) diff --git a/Intersect.Client.Core/Interface/Menu/EscapeMenuWindow.cs b/Intersect.Client.Core/Interface/Menu/EscapeMenuWindow.cs index 22d483c3a6..9c96c46102 100644 --- a/Intersect.Client.Core/Interface/Menu/EscapeMenuWindow.cs +++ b/Intersect.Client.Core/Interface/Menu/EscapeMenuWindow.cs @@ -5,8 +5,8 @@ using Intersect.Client.General; using Intersect.Client.Interface.Shared; using Intersect.Client.Localization; +using Intersect.Client.MonoGame; using Intersect.Framework.Core; -using Intersect.Utilities; namespace Intersect.Client.Interface.Menu; @@ -217,6 +217,11 @@ private void ShowCombatWarning() private void ExitToDesktop(object? sender, EventArgs? e) { + if (IntersectGame._isShowingExitConfirmation) + { + return; + } + AlertWindow.Open( Strings.General.QuitPrompt, Strings.General.QuitTitle, @@ -229,8 +234,15 @@ private void ExitToDesktop(object? sender, EventArgs? e) Globals.Me.CombatTimer = 0; } + IntersectGame._isShowingExitConfirmation = false; Globals.IsRunning = false; + }, + handleCancel: (_, _) => + { + IntersectGame._isShowingExitConfirmation = false; } ); + + IntersectGame._isShowingExitConfirmation = true; } } \ No newline at end of file diff --git a/Intersect.Client.Core/Interface/Shared/AlertWindow.cs b/Intersect.Client.Core/Interface/Shared/AlertWindow.cs index 74e91a9d58..6c492019d9 100644 --- a/Intersect.Client.Core/Interface/Shared/AlertWindow.cs +++ b/Intersect.Client.Core/Interface/Shared/AlertWindow.cs @@ -20,6 +20,7 @@ public record struct Alert(string Message, string? Title = default, AlertType Ty public class AlertWindow : InputBox { private static readonly HashSet _instances = []; + private readonly GwenEventHandler? _handleCancel; private AlertWindow( string title, @@ -39,6 +40,8 @@ private AlertWindow( userData: userData ) { + _handleCancel = handleCancel; + Icon = GameContentManager.Current.GetTexture( TextureType.Gui, $"icon.alert.{alertType.ToString().ToLowerInvariant()}.png" @@ -49,6 +52,15 @@ private AlertWindow( var titleLabelMargin = TitleLabel.Margin; TitleLabel.Margin = titleLabelMargin with { Left = titleLabelMargin.Left + 4 }; + + // Subscribe to the Closed event to handle X button clicks + Closed += OnWindowClosed; + } + + private void OnWindowClosed(Base sender, EventArgs args) + { + // Trigger the cancel handler when window is closed via X button + _handleCancel?.Invoke(this, args); } protected override void OnCanceled(Base sender, EventArgs args) diff --git a/Intersect.Client.Core/MonoGame/IntersectGame.cs b/Intersect.Client.Core/MonoGame/IntersectGame.cs index dbb9e0fb4d..9248855e37 100644 --- a/Intersect.Client.Core/MonoGame/IntersectGame.cs +++ b/Intersect.Client.Core/MonoGame/IntersectGame.cs @@ -11,8 +11,6 @@ using Intersect.Configuration; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using System.Diagnostics; -using System.Reflection; using Intersect.Client.Framework.Database; using Intersect.Client.Framework.Graphics; using Intersect.Client.ThirdParty; @@ -58,6 +56,8 @@ internal partial class IntersectGame : Game private SpriteBatch? updateBatch; private bool updaterGraphicsReset; + + public static bool _isShowingExitConfirmation; #endregion @@ -355,6 +355,11 @@ protected override void OnExiting(object sender, ExitingEventArgs args) Globals.Me.CombatTimer > Timing.Global?.Milliseconds && Globals.GameState == GameStates.InGame; + if (_isShowingExitConfirmation) + { + return; + } + if (inCombat) { AlertWindow.Open( @@ -369,7 +374,12 @@ protected override void OnExiting(object sender, ExitingEventArgs args) Globals.Me.CombatTimer = 0; } + _isShowingExitConfirmation = false; Globals.IsRunning = false; + }, + handleCancel: (_, _) => + { + _isShowingExitConfirmation = false; } ); } @@ -382,10 +392,16 @@ protected override void OnExiting(object sender, ExitingEventArgs args) inputType: InputType.YesNo, handleSubmit: (_, _) => { + _isShowingExitConfirmation = false; Globals.IsRunning = false; + }, + handleCancel: (_, _) => + { + _isShowingExitConfirmation = false; } ); } + _isShowingExitConfirmation = true; } private void TryExit(object sender, ExitingEventArgs args)