Files

211 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
namespace Robust.Client.UserInterface;
// ReSharper disable MemberCanBePrivate.Global
[PublicAPI]
public abstract class UIScreen : LayoutContainer
{
private IConfigurationManager _configManager = IoCManager.Resolve<IConfigurationManager>();
public Vector2i AutoscaleMaxResolution
{
get =>
new(_configManager.GetCVar<int>("interface.resolutionAutoScaleUpperCutoffX"),
_configManager.GetCVar<int>("interface.resolutionAutoScaleUpperCutoffY"));
protected set
{
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", value.X);
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffY", value.Y);
}
}
public Vector2i AutoscaleMinResolution
{
get
{
var configManager = IoCManager.Resolve<IConfigurationManager>();
return new Vector2i(configManager.GetCVar<int>("interface.resolutionAutoScaleLowerCutoffX"),
configManager.GetCVar<int>("interface.resolutionAutoScaleLowerCutoffY"));
}
protected set
{
_configManager.SetCVar("interface.resolutionAutoScaleLowerCutoffX", value.X);
_configManager.SetCVar("interface.resolutionAutoScaleLowerCutoffY", value.Y);
}
}
public float AutoscaleFloor
{
get
{
var configManager = IoCManager.Resolve<IConfigurationManager>();
return configManager.GetCVar<float>("interface.resolutionAutoScaleMinimum");
}
protected set { _configManager.SetCVar("interface.interface.resolutionAutoScaleMinimum", value); }
}
private readonly Dictionary<Type, UIWidget> _widgets = new();
protected UIScreen()
{
HorizontalAlignment = HAlignment.Stretch;
VerticalAlignment = VAlignment.Stretch;
}
public T RegisterWidget<T>() where T : UIWidget, new()
{
if (_widgets.ContainsKey(typeof(T))) throw new Exception("Hud Widget not found");
var newWidget = new T();
return newWidget;
}
public void RemoveWidget<T>() where T : UIWidget, new()
{
if (!_widgets.Remove(typeof(T), out var widget))
return;
widget.Parent?.RemoveChild(widget);
RemoveChildren(widget);
}
internal void OnRemoved()
{
OnUnloaded();
}
internal void OnAdded()
{
OnLoaded();
}
public UIWidget? this[Type type]
{
get
{
if ((type.IsAbstract) || !typeof(UIWidget).IsAssignableFrom(type))
throw new Exception("Tried to fetch a non UI widget from UI Screen");
_widgets.TryGetValue(type, out var widget);
return widget;
}
}
public void AddWidget(UIWidget widget)
{
AddChild(widget);
}
public void AddWidgetDirect(UIWidget widget)
{
if (!_widgets.TryAdd(widget.GetType(), widget))
throw new Exception("Tried to add duplicate widget to screen!");
RegisterChildren(widget);
}
public T? GetWidget<T>() where T : UIWidget, new()
{
return (T?) _widgets.GetValueOrDefault(typeof(T));
}
public T GetOrAddWidget<T>() where T : UIWidget, new()
{
if (!_widgets.TryGetValue(typeof(T), out var widget))
{
widget = new T();
AddWidget(widget);
}
return (T) widget;
}
public bool IsWidgetShown<T>() where T : UIWidget
{
return _widgets.TryGetValue(typeof(T), out var widget) && widget.Visible;
}
public bool TryGetWidget<T>([NotNullWhen(true)] out T? widget) where T : UIWidget, new()
{
if (!_widgets.TryGetValue(typeof(T), out var baseWidget))
{
widget = null;
return false;
}
widget = (T)baseWidget;
return true;
}
public void ShowWidget<T>(bool show) where T : UIWidget
{
_widgets[typeof(T)].Visible = show;
}
protected override void ChildAdded(Control newChild)
{
base.ChildAdded(newChild);
RegisterChildren(newChild);
if (newChild is not UIWidget widget) return;
if (!_widgets.TryAdd(widget.GetType(), widget))
throw new Exception("Tried to add duplicate widget to screen!");
}
private void RegisterChildren(Control control)
{
foreach (var child in control.Children)
{
RegisterChildren(child);
if (child is not UIWidget widget)
{
continue;
}
if (!_widgets.TryAdd(widget.GetType(), widget))
{
throw new Exception("Tried to add duplicate widget to screen!");
}
}
}
protected override void ChildRemoved(Control child)
{
base.ChildRemoved(child);
RemoveChildren(child);
if (child is not UIWidget widget) return;
_widgets.Remove(child.GetType());
}
private void RemoveChildren(Control control)
{
foreach (var child in control.Children)
{
RemoveChildren(child);
if (child is not UIWidget widget)
{
continue;
}
_widgets.Remove(widget.GetType());
}
}
protected virtual void OnLoaded()
{
}
protected virtual void OnUnloaded()
{
}
}