mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
213 lines
7.9 KiB
C#
213 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace Robust.Shared.Input
|
|
{
|
|
/// <summary>
|
|
/// Contains a set of created <see cref="InputCmdContext"/>s.
|
|
/// </summary>
|
|
public interface IInputContextContainer
|
|
{
|
|
/// <summary>
|
|
/// The current "active" context that should be used for filtering key binds.
|
|
/// </summary>
|
|
IInputCmdContext ActiveContext { get; }
|
|
|
|
/// <summary>
|
|
/// This event is raised when ever the Active Context is changed.
|
|
/// </summary>
|
|
event EventHandler<ContextChangedEventArgs> ContextChanged;
|
|
|
|
/// <summary>
|
|
/// Adds a new unique context to the set.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of the new context.</param>
|
|
/// <param name="parentName">Unique name of the parent context. Tee parent context must already exist in the set.</param>
|
|
/// <returns>Instance of the newly created context.</returns>
|
|
IInputCmdContext New(string uniqueName, string parentName);
|
|
|
|
/// <summary>
|
|
/// Adds a new unique context to the set.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of the new context.</param>
|
|
/// <param name="parent">Context to set, as the parent context, of the newly created context.</param>
|
|
/// <returns>Instance of the newly created context.</returns>
|
|
IInputCmdContext New(string uniqueName, IInputCmdContext parent);
|
|
|
|
/// <summary>
|
|
/// Checks if a context with a unique name exists in the set.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique Name to search for.</param>
|
|
/// <returns>If a context exists with the given unique name in the set.</returns>
|
|
bool Exists(string uniqueName);
|
|
|
|
/// <summary>
|
|
/// Returns the context with the given unique name from the set.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of the context to search for.</param>
|
|
/// <returns>Context with the given unique name in the set.</returns>
|
|
IInputCmdContext GetContext(string uniqueName);
|
|
|
|
/// <summary>
|
|
/// Tries to find a context with a given unique name.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of the context to search for.</param>
|
|
/// <param name="context">The context with the given unique name (if any).</param>
|
|
/// <returns>If a context with a given unique name exists in the set.</returns>
|
|
bool TryGetContext(string uniqueName, [NotNullWhen(true)] out IInputCmdContext? context);
|
|
|
|
/// <summary>
|
|
/// Removes the context with the given unique name.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of context to remove.</param>
|
|
void Remove(string uniqueName);
|
|
|
|
/// <summary>
|
|
/// Sets the context with the given unique name as the Active context.
|
|
/// </summary>
|
|
/// <param name="uniqueName">Unique name of the context to set as active.</param>
|
|
void SetActiveContext(string uniqueName);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
internal class InputContextContainer : IInputContextContainer
|
|
{
|
|
/// <summary>
|
|
/// Default 'root' context unique name that always exists in the set.
|
|
/// </summary>
|
|
public const string DefaultContextName = "common";
|
|
|
|
/// <inheritdoc />
|
|
public event EventHandler<ContextChangedEventArgs>? ContextChanged;
|
|
|
|
private readonly Dictionary<string, InputCmdContext> _contexts = new();
|
|
private InputCmdContext _activeContext = default!;
|
|
|
|
/// <inheritdoc />
|
|
public IInputCmdContext ActiveContext
|
|
{
|
|
get => _activeContext;
|
|
private set
|
|
{
|
|
var args = new ContextChangedEventArgs(_activeContext, value);
|
|
_activeContext = (InputCmdContext) value;
|
|
ContextChanged?.Invoke(this, args);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of <see cref="InputCmdContext"/>.
|
|
/// </summary>
|
|
public InputContextContainer()
|
|
{
|
|
_contexts.Add(DefaultContextName, new InputCmdContext());
|
|
SetActiveContext(DefaultContextName);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IInputCmdContext New(string uniqueName, string parentName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(uniqueName))
|
|
throw new ArgumentException("String is null or whitespace.", nameof(uniqueName));
|
|
|
|
if (string.IsNullOrWhiteSpace(parentName))
|
|
throw new ArgumentException("String is null or whitespace.", nameof(parentName));
|
|
|
|
if (!_contexts.TryGetValue(parentName, out var parentContext))
|
|
throw new ArgumentException("Parent does not exist.", nameof(parentName));
|
|
|
|
if (_contexts.ContainsKey(uniqueName))
|
|
throw new ArgumentException($"Context with name {uniqueName} already exists.", nameof(uniqueName));
|
|
|
|
var newContext = new InputCmdContext(parentContext);
|
|
_contexts.Add(uniqueName, newContext);
|
|
return newContext;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IInputCmdContext New(string uniqueName, IInputCmdContext parent)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(uniqueName))
|
|
throw new ArgumentException("String is null or whitespace.", nameof(uniqueName));
|
|
|
|
if (_contexts.ContainsKey(uniqueName))
|
|
throw new ArgumentException($"Context with name {uniqueName} already exists.", nameof(uniqueName));
|
|
|
|
if (parent == null)
|
|
throw new ArgumentNullException(nameof(parent));
|
|
|
|
var newContext = new InputCmdContext(parent);
|
|
_contexts.Add(uniqueName, newContext);
|
|
return newContext;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool Exists(string uniqueName)
|
|
{
|
|
return _contexts.ContainsKey(uniqueName);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IInputCmdContext GetContext(string uniqueName)
|
|
{
|
|
return _contexts[uniqueName];
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool TryGetContext(string uniqueName, [NotNullWhen(true)] out IInputCmdContext? context)
|
|
{
|
|
if (_contexts.TryGetValue(uniqueName, out var ctext))
|
|
{
|
|
context = ctext;
|
|
return true;
|
|
}
|
|
|
|
context = default;
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Remove(string uniqueName)
|
|
{
|
|
if (uniqueName == DefaultContextName)
|
|
throw new ArgumentException("The default context cannot be removed.", nameof(uniqueName));
|
|
|
|
_contexts.Remove(uniqueName);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void SetActiveContext(string uniqueName)
|
|
{
|
|
ActiveContext = _contexts[uniqueName];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event arguments for an input context change.
|
|
/// </summary>
|
|
public class ContextChangedEventArgs : EventArgs
|
|
{
|
|
/// <summary>
|
|
/// The new context that became active.
|
|
/// </summary>
|
|
public IInputCmdContext? NewContext { get; }
|
|
|
|
/// <summary>
|
|
/// The old context that used to be active.
|
|
/// </summary>
|
|
public IInputCmdContext? OldContext { get; }
|
|
|
|
/// <summary>
|
|
/// Constructs a new instance of <see cref="ContextChangedEventArgs"/>/
|
|
/// </summary>
|
|
/// <param name="oldContext">The old context that used to be active.</param>
|
|
/// <param name="newContext">The new context that became active.</param>
|
|
public ContextChangedEventArgs(IInputCmdContext? oldContext, IInputCmdContext? newContext)
|
|
{
|
|
OldContext = oldContext;
|
|
NewContext = newContext;
|
|
}
|
|
}
|
|
}
|