using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MonoGameLibrary.Input; namespace ONDClient.GUI; public class Screen { private static Dictionary screens = new(); public static Screen CurrentScreen{ get; private set; } = Empty; public static Screen OverlayScreen{ get; private set; } = Empty; public static void AddScreens(Screen[] screensToAdd) { foreach (var screen in screensToAdd){ Screen.screens.Add(screen.Label, screen); } } public static void AddScreen(string id, Screen screen, bool activate = false) { screens.Add(id, screen); if (activate) SetScreen(id); } public static void SetScreen(string id) { if (CurrentScreen.temporary){ screens.Remove(CurrentScreen.Label); } CurrentScreen.Active = false; CurrentScreen = screens[id]; CurrentScreen.Active = true; } public static void RemoveScreen(string id) { screens.Remove(id); } public static void UpdateAll() { foreach (var screen in screens.Values){ if (!screen.Active) continue; screen.Update(); } } public static Screen Empty => new(""){temporary = true}; public static void SetOverlayScreen(string id) { if (OverlayScreen.temporary){ screens.Remove(OverlayScreen.Label); } OverlayScreen.Active = false; OverlayScreen = screens[id]; OverlayScreen.Active = true; } public static void DisableOverlay() { OverlayScreen = Empty; } public static void DrawCurrentAndOverlay(SpriteBatch spriteBatch) { CurrentScreen.Draw(spriteBatch); OverlayScreen.Draw(spriteBatch); } public static Screen[] GetAllScreens() => screens.Values.ToArray(); public string Label{ get; } private Dictionary elements = new(); private List elementsInDrawOrder = new(); public bool Active { get; private set; } = false; private InputListenerHook mouseInputHook = new(true); private bool temporary = false; private List temporaryElements = new(); public Screen(string label) { Label = label; InputManager.AddListener(InputManager.MouseButton.LEFT, () => ProcessMouseInput(InputManager.MouseState), InputTiming.PRESS, mouseInputHook); } public Screen(string label, Dictionary elements) { this.elements = elements; Label = label; } public UIElement this[string id] => elements[id]; public UIElement TryGetElement(string id) => elements.TryGetValue(id, out var val) ? val : null; public UIElement AddElement(string id, UIElement element, bool temporary = false) { elements.Add(id, element); int insertIndex = elementsInDrawOrder.FindLastIndex(e => e.DrawPriority == element.DrawPriority); if (insertIndex == -1){ elementsInDrawOrder.Add(element); } else{ elementsInDrawOrder.Insert(insertIndex + 1, element); } if (temporary){ temporaryElements.Add(id); } return element; } public void RemoveElement(string id) { if (!elements.ContainsKey(id)) return; elements.Remove(id, out var element); elementsInDrawOrder.RemoveAll(e => e == element); } public void RemoveTemporary() { temporaryElements.ForEach(RemoveElement); temporaryElements.Clear(); } private void ProcessMouseInput(MouseState mouseState) { if (!Active){ return; } foreach (var element in elements.Values){ if (!element.Pressable) continue; if (element.IsWithinBounds(mouseState.Position)){ element.OnMousePress(); } } } private void Update() { foreach (var element in elements.Values){ if (!element.Active) continue; element.Update(); } } private void Draw(SpriteBatch spriteBatch) { foreach (var val in elementsInDrawOrder){ val.Draw(spriteBatch); } } }