OneNightDuel/ONDClient/GUI/Screen.cs

148 lines
4.3 KiB
C#
Raw Normal View History

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<string, Screen> 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<string, UIElement> elements = new();
private List<UIElement> elementsInDrawOrder = new();
public bool Active { get; private set; } = false;
private InputListenerHook mouseInputHook = new(true);
private bool temporary = false;
private List<string> temporaryElements = new();
public Screen(string label) {
Label = label;
InputManager.AddListener(InputManager.MouseButton.LEFT, () => ProcessMouseInput(InputManager.MouseState), InputTiming.PRESS, mouseInputHook);
}
public Screen(string label, Dictionary<string, UIElement> 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);
}
}
}