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