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(); public Vector2i AutoscaleMaxResolution { get => new(_configManager.GetCVar("interface.resolutionAutoScaleUpperCutoffX"), _configManager.GetCVar("interface.resolutionAutoScaleUpperCutoffY")); protected set { _configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", value.X); _configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffY", value.Y); } } public Vector2i AutoscaleMinResolution { get { var configManager = IoCManager.Resolve(); return new Vector2i(configManager.GetCVar("interface.resolutionAutoScaleLowerCutoffX"), configManager.GetCVar("interface.resolutionAutoScaleLowerCutoffY")); } protected set { _configManager.SetCVar("interface.resolutionAutoScaleLowerCutoffX", value.X); _configManager.SetCVar("interface.resolutionAutoScaleLowerCutoffY", value.Y); } } public float AutoscaleFloor { get { var configManager = IoCManager.Resolve(); return configManager.GetCVar("interface.resolutionAutoScaleMinimum"); } protected set { _configManager.SetCVar("interface.interface.resolutionAutoScaleMinimum", value); } } private readonly Dictionary _widgets = new(); protected UIScreen() { HorizontalAlignment = HAlignment.Stretch; VerticalAlignment = VAlignment.Stretch; } public T RegisterWidget() 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() 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() where T : UIWidget, new() { return (T?) _widgets.GetValueOrDefault(typeof(T)); } public T GetOrAddWidget() where T : UIWidget, new() { if (!_widgets.TryGetValue(typeof(T), out var widget)) { widget = new T(); AddWidget(widget); } return (T) widget; } public bool IsWidgetShown() where T : UIWidget { return _widgets.TryGetValue(typeof(T), out var widget) && widget.Visible; } public bool TryGetWidget([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(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() { } }