using System.Collections.Generic; using Microsoft.VisualBasic.CompilerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MonoGameLibrary.Input; namespace FNAF_Clone.GUI; public class Screen { public 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[] screens) { foreach (var screen in screens){ 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 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(); } public void SetActive(bool active) { Active = active; if (Active == active) return; foreach (var keyValuePair in elements){ keyValuePair.Value.Active = Active; } } 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(); // TODO: differentiate between press, hold and release events } } } public void Update() { foreach (var element in elements.Values){ if (!element.Active) continue; element.Update(); } } public void Draw(SpriteBatch spriteBatch) { foreach (var val in elementsInDrawOrder){ val.Draw(spriteBatch); } } }