UI: Close window hotkeys (#15227)
This commit is contained in:
@@ -145,6 +145,8 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
AddButton(ContentKeyFunctions.OpenTileSpawnWindow);
|
AddButton(ContentKeyFunctions.OpenTileSpawnWindow);
|
||||||
AddButton(ContentKeyFunctions.OpenDecalSpawnWindow);
|
AddButton(ContentKeyFunctions.OpenDecalSpawnWindow);
|
||||||
AddButton(ContentKeyFunctions.OpenAdminMenu);
|
AddButton(ContentKeyFunctions.OpenAdminMenu);
|
||||||
|
AddButton(EngineKeyFunctions.WindowCloseAll);
|
||||||
|
AddButton(EngineKeyFunctions.WindowCloseRecent);
|
||||||
|
|
||||||
AddHeader("ui-options-header-misc");
|
AddHeader("ui-options-header-misc");
|
||||||
AddButton(ContentKeyFunctions.TakeScreenshot);
|
AddButton(ContentKeyFunctions.TakeScreenshot);
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Content.Client.Gameplay;
|
||||||
|
using Content.Client.Info;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controllers;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface.Systems.Info;
|
||||||
|
|
||||||
|
public sealed class CloseAllWindowsUIController : UIController
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
|
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
_inputManager.SetInputCommand(EngineKeyFunctions.WindowCloseAll,
|
||||||
|
InputCmdHandler.FromDelegate(session => CloseAllWindows()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseAllWindows()
|
||||||
|
{
|
||||||
|
foreach (var childControl in new List<Control>(_uiManager.WindowRoot.Children)) // Copy children list as it will be modified on Close()
|
||||||
|
{
|
||||||
|
if (childControl is BaseWindow)
|
||||||
|
{
|
||||||
|
((BaseWindow) childControl).Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
using Content.Client.Gameplay;
|
||||||
|
using Content.Client.Info;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controllers;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface.Systems.Info;
|
||||||
|
|
||||||
|
public sealed class CloseRecentWindowUIController : UIController
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
|
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of windows that have been interacted with recently. Windows should only
|
||||||
|
/// be in this list once, with the most recent window at the end, and the oldest
|
||||||
|
/// window at the start.
|
||||||
|
/// </summary>
|
||||||
|
List<BaseWindow> recentlyInteractedWindows = new List<BaseWindow>();
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
// Add listeners to be able to know when windows are opened.
|
||||||
|
// (Does not need to be unlistened since UIControllers live forever)
|
||||||
|
_uiManager.OnKeyBindDown += OnKeyBindDown;
|
||||||
|
_uiManager.WindowRoot.OnChildAdded += OnRootChildAdded;
|
||||||
|
|
||||||
|
_inputManager.SetInputCommand(EngineKeyFunctions.WindowCloseRecent,
|
||||||
|
InputCmdHandler.FromDelegate(session => CloseMostRecentWindow()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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--)
|
||||||
|
{
|
||||||
|
var window = recentlyInteractedWindows[i];
|
||||||
|
recentlyInteractedWindows.RemoveAt(i); // Should always be removed as either the reference is stale or we're closing it
|
||||||
|
if (window.IsOpen)
|
||||||
|
{
|
||||||
|
window.Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// continue going down the list, hoping to find a still-open window
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnKeyBindDown(Control control)
|
||||||
|
{
|
||||||
|
// On click, we should set the window that owns this control (if any) to the most recently
|
||||||
|
// clicked window. By doing this, we can create an ordering of what windows have been
|
||||||
|
// interacted with.
|
||||||
|
|
||||||
|
// Something was clicked, so find the window corresponding to what was clicked
|
||||||
|
var window = GetWindowForControl(control);
|
||||||
|
|
||||||
|
// Find the window owning the control
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
// And move to top of recent stack
|
||||||
|
//Logger.Debug("Most recent window is " + window.Name);
|
||||||
|
SetMostRecentlyInteractedWindow(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the window as the one most recently interacted with. This function will update the
|
||||||
|
/// internal recentlyInteractedWindows tracking.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="window"></param>
|
||||||
|
private void SetMostRecentlyInteractedWindow(BaseWindow window)
|
||||||
|
{
|
||||||
|
// Search through the list and see if already added.
|
||||||
|
// (This search is backwards since it's fairly common that the user is clicking the same
|
||||||
|
// window multiple times in a row, and so that saves a tiny bit of perf doing it this way)
|
||||||
|
for (int i=recentlyInteractedWindows.Count-1; i>=0; i--)
|
||||||
|
{
|
||||||
|
if (recentlyInteractedWindows[i] == window)
|
||||||
|
{
|
||||||
|
// Window already in the list
|
||||||
|
|
||||||
|
// Is window the top most recent entry?
|
||||||
|
if (i == recentlyInteractedWindows.Count-1)
|
||||||
|
return; // Then there's nothing to do, it's already in the right spot
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Need to remove the old entry so it can be readded (no duplicates in list allowed)
|
||||||
|
recentlyInteractedWindows.RemoveAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that the list has been checked for duplicates, okay to add new window at end of tracking
|
||||||
|
recentlyInteractedWindows.Add(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseWindow? GetWindowForControl(Control? control)
|
||||||
|
{
|
||||||
|
if (control == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (control is BaseWindow)
|
||||||
|
return (BaseWindow) control;
|
||||||
|
|
||||||
|
// Go up the hierarchy until we find a window (or don't)
|
||||||
|
return GetWindowForControl(control.Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRootChildAdded(Control control)
|
||||||
|
{
|
||||||
|
if (control is BaseWindow)
|
||||||
|
{
|
||||||
|
// On new window open, add to tracking
|
||||||
|
SetMostRecentlyInteractedWindow((BaseWindow) control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -135,6 +135,8 @@ ui-options-function-open-tile-spawn-window = Open tile spawn menu
|
|||||||
ui-options-function-open-decal-spawn-window = Open decal spawn menu
|
ui-options-function-open-decal-spawn-window = Open decal spawn menu
|
||||||
ui-options-function-open-admin-menu = Open admin menu
|
ui-options-function-open-admin-menu = Open admin menu
|
||||||
ui-options-function-open-guidebook = Open guidebook
|
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-take-screenshot = Take screenshot
|
ui-options-function-take-screenshot = Take screenshot
|
||||||
ui-options-function-take-screenshot-no-ui = Take screenshot (without UI)
|
ui-options-function-take-screenshot-no-ui = Take screenshot (without UI)
|
||||||
@@ -214,4 +216,4 @@ ui-options-net-pvs-leave-tooltip = This limits the rate at which the client will
|
|||||||
|
|
||||||
## Toggle window console command
|
## Toggle window console command
|
||||||
cmd-options-desc = Opens options menu, optionally with a specific tab selected.
|
cmd-options-desc = Opens options menu, optionally with a specific tab selected.
|
||||||
cmd-options-help = Usage: options [tab]
|
cmd-options-help = Usage: options [tab]
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ binds:
|
|||||||
# Misc
|
# Misc
|
||||||
- function: ShowEscapeMenu
|
- function: ShowEscapeMenu
|
||||||
type: State
|
type: State
|
||||||
key: Escape
|
key: F12
|
||||||
- function: CycleChatChannelForward
|
- function: CycleChatChannelForward
|
||||||
type: State
|
type: State
|
||||||
key: Tab
|
key: Tab
|
||||||
@@ -404,6 +404,13 @@ binds:
|
|||||||
type: State
|
type: State
|
||||||
key: Tab
|
key: Tab
|
||||||
mod1: Shift
|
mod1: Shift
|
||||||
|
- function: WindowCloseRecent
|
||||||
|
type: State
|
||||||
|
key: Escape
|
||||||
|
- function: WindowCloseAll
|
||||||
|
type: State
|
||||||
|
key: Escape
|
||||||
|
mod1: Shift
|
||||||
- function: Point
|
- function: Point
|
||||||
type: State
|
type: State
|
||||||
key: MouseMiddle
|
key: MouseMiddle
|
||||||
|
|||||||
Reference in New Issue
Block a user