From 3b21421ef18c1e747b7ab4eba60d57846224c108 Mon Sep 17 00:00:00 2001
From: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
Date: Thu, 13 Apr 2023 18:10:44 -0700
Subject: [PATCH] Add EscapeContext keybind (#15301)
* Add EscapeContext
Escape context input closes windows if there are any open. If there are not any windows it opens the game menu.
* Add fluent for Escape Context
* Move EngineContext keybind to content
* Readd WindowCloseAll
* Fix EscapeContext not opening the game menu after using WindowCloseAll
WindowCloseAll does not clear the CloseRecentWindowUIController.recentlyInteractedWindows, which caused HasClosableWindow to return true because the list still had items.
Changed HasClosableWindow to check if windows in the list are still open and clear them if they aren't.
* Clean up EscapeContextUIController
---
Content.Client/Input/ContentContexts.cs | 1 +
.../Options/UI/Tabs/KeyRebindTab.xaml.cs | 1 +
.../CloseRecentWindowUIController.cs | 25 ++++++++++++-
.../EscapeMenu/EscapeContextUIController.cs | 37 +++++++++++++++++++
.../Systems/EscapeMenu/EscapeUIController.cs | 5 ++-
Content.Shared/Input/ContentKeyFunctions.cs | 1 +
.../en-US/escape-menu/ui/options-menu.ftl | 1 +
Resources/keybinds.yml | 2 +-
8 files changed, 69 insertions(+), 4 deletions(-)
create mode 100644 Content.Client/UserInterface/Systems/EscapeMenu/EscapeContextUIController.cs
diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs
index c3beda136d..d9c103b7eb 100644
--- a/Content.Client/Input/ContentContexts.cs
+++ b/Content.Client/Input/ContentContexts.cs
@@ -22,6 +22,7 @@ namespace Content.Client.Input
common.AddFunction(ContentKeyFunctions.FocusDeadChat);
common.AddFunction(ContentKeyFunctions.CycleChatChannelForward);
common.AddFunction(ContentKeyFunctions.CycleChatChannelBackward);
+ common.AddFunction(ContentKeyFunctions.EscapeContext);
common.AddFunction(ContentKeyFunctions.ExamineEntity);
common.AddFunction(ContentKeyFunctions.OpenAHelp);
common.AddFunction(ContentKeyFunctions.TakeScreenshot);
diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
index 74aaf466aa..9d2614c096 100644
--- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
+++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
@@ -148,6 +148,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(EngineKeyFunctions.WindowCloseAll);
AddButton(EngineKeyFunctions.WindowCloseRecent);
AddButton(EngineKeyFunctions.EscapeMenu);
+ AddButton(ContentKeyFunctions.EscapeContext);
AddHeader("ui-options-header-misc");
AddButton(ContentKeyFunctions.TakeScreenshot);
diff --git a/Content.Client/UserInterface/Systems/CloseWindow/CloseRecentWindowUIController.cs b/Content.Client/UserInterface/Systems/CloseWindow/CloseRecentWindowUIController.cs
index 18f20727e1..3517a001c2 100644
--- a/Content.Client/UserInterface/Systems/CloseWindow/CloseRecentWindowUIController.cs
+++ b/Content.Client/UserInterface/Systems/CloseWindow/CloseRecentWindowUIController.cs
@@ -32,7 +32,10 @@ public sealed class CloseRecentWindowUIController : UIController
InputCmdHandler.FromDelegate(session => CloseMostRecentWindow()));
}
- private void CloseMostRecentWindow()
+ ///
+ /// Closes the most recently focused window.
+ ///
+ public void CloseMostRecentWindow()
{
// Search backwards through the recency list to find a still open window and close it
for (int i=recentlyInteractedWindows.Count-1; i>=0; i--)
@@ -118,5 +121,23 @@ public sealed class CloseRecentWindowUIController : UIController
SetMostRecentlyInteractedWindow((BaseWindow) control);
}
}
-}
+ ///
+ /// Checks whether there are any windows that can be closed.
+ ///
+ ///
+ public bool HasClosableWindow()
+ {
+ for (var i = recentlyInteractedWindows.Count - 1; i >= 0; i--)
+ {
+ var window = recentlyInteractedWindows[i];
+ if (window.IsOpen)
+ return true;
+
+ recentlyInteractedWindows.RemoveAt(i);
+ // continue going down the list, hoping to find a still-open window
+ }
+
+ return false;
+ }
+}
diff --git a/Content.Client/UserInterface/Systems/EscapeMenu/EscapeContextUIController.cs b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeContextUIController.cs
new file mode 100644
index 0000000000..3a7c2caa0a
--- /dev/null
+++ b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeContextUIController.cs
@@ -0,0 +1,37 @@
+using Content.Client.UserInterface.Systems.Info;
+using Content.Shared.Input;
+using JetBrains.Annotations;
+using Robust.Client.Input;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controllers;
+using Robust.Shared.Input;
+using Robust.Shared.Input.Binding;
+
+namespace Content.Client.UserInterface.Systems.EscapeMenu;
+
+[UsedImplicitly]
+public sealed class EscapeContextUIController : UIController
+{
+ [Dependency] private readonly IInputManager _inputManager = default!;
+
+ [Dependency] private readonly CloseRecentWindowUIController _closeRecentWindowUIController = default!;
+ [Dependency] private readonly EscapeUIController _escapeUIController = default!;
+
+ public override void Initialize()
+ {
+ _inputManager.SetInputCommand(ContentKeyFunctions.EscapeContext,
+ InputCmdHandler.FromDelegate(_ => CloseWindowOrOpenGameMenu()));
+ }
+
+ private void CloseWindowOrOpenGameMenu()
+ {
+ if (_closeRecentWindowUIController.HasClosableWindow())
+ {
+ _closeRecentWindowUIController.CloseMostRecentWindow();
+ }
+ else
+ {
+ _escapeUIController.ToggleWindow();
+ }
+ }
+}
diff --git a/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs
index 56792c2992..a6a8b01022 100644
--- a/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs
+++ b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs
@@ -133,7 +133,10 @@ public sealed class EscapeUIController : UIController, IOnStateEntered
+ /// Toggles the game menu.
+ ///
+ public void ToggleWindow()
{
if (_escapeWindow == null)
return;
diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs
index ddcbca8967..f9742eb6d5 100644
--- a/Content.Shared/Input/ContentKeyFunctions.cs
+++ b/Content.Shared/Input/ContentKeyFunctions.cs
@@ -21,6 +21,7 @@ namespace Content.Shared.Input
public static readonly BoundKeyFunction FocusConsoleChat = "FocusConsoleChatWindow";
public static readonly BoundKeyFunction CycleChatChannelForward = "CycleChatChannelForward";
public static readonly BoundKeyFunction CycleChatChannelBackward = "CycleChatChannelBackward";
+ public static readonly BoundKeyFunction EscapeContext = "EscapeContext";
public static readonly BoundKeyFunction OpenCharacterMenu = "OpenCharacterMenu";
public static readonly BoundKeyFunction OpenCraftingMenu = "OpenCraftingMenu";
public static readonly BoundKeyFunction OpenGuidebook = "OpenGuidebook";
diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
index 9808110ea2..af825fff46 100644
--- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
+++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
@@ -138,6 +138,7 @@ ui-options-function-open-guidebook = Open guidebook
ui-options-function-window-close-all = Close all windows
ui-options-function-window-close-recent = Close recent window
ui-options-function-show-escape-menu = Toggle game menu
+ui-options-function-escape-context = Close recent window or toggle game menu
ui-options-function-take-screenshot = Take screenshot
ui-options-function-take-screenshot-no-ui = Take screenshot (without UI)
diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml
index 493dc9bb73..e69bf62575 100644
--- a/Resources/keybinds.yml
+++ b/Resources/keybinds.yml
@@ -404,7 +404,7 @@ binds:
type: State
key: Tab
mod1: Shift
-- function: WindowCloseRecent
+- function: EscapeContext
type: State
key: Escape
- function: WindowCloseAll
--
2.51.2