using System; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem.UI; using UnityEngine.UIElements; namespace ProjectM.Client { /// /// Shared UI Toolkit helpers for the code-built menu / settings / pause screens — a small palette + styled /// element factories (so every screen reads in one visual language) plus runtime plumbing: loading the /// shared PanelSettings (from Resources) and ensuring an EventSystem with an /// InputSystemUIInputModule exists. Runtime UITK receives pointer/click events THROUGH the /// EventSystem, and this project uses the Input System (1.19.0), so the module must be the Input-System one, /// not the legacy StandaloneInputModule — without it the buttons are silently dead. /// public static class MenuUi { public static readonly Color Bg = new(0.04f, 0.05f, 0.07f, 0.96f); public static readonly Color PanelBg = new(0.09f, 0.11f, 0.15f, 0.98f); public static readonly Color Accent = new(0.30f, 0.85f, 1f, 1f); // Aether cyan public static readonly Color TextCol = new(0.86f, 0.92f, 0.97f, 1f); public static readonly Color SubCol = new(0.60f, 0.68f, 0.76f, 1f); public static PanelSettings LoadPanelSettings() => Resources.Load("RuntimePanelSettings"); public static void EnsureEventSystem() { if (UnityEngine.Object.FindFirstObjectByType() != null) return; var go = new GameObject("EventSystem"); go.AddComponent(); go.AddComponent(); } public static VisualElement FullScreenRoot(bool dim) { var root = new VisualElement(); root.style.position = Position.Absolute; root.style.left = 0; root.style.right = 0; root.style.top = 0; root.style.bottom = 0; root.style.alignItems = Align.Center; root.style.justifyContent = Justify.Center; if (dim) root.style.backgroundColor = Bg; return root; } public static VisualElement Card(string titleText) { var card = new VisualElement(); card.style.backgroundColor = PanelBg; card.style.paddingLeft = 28; card.style.paddingRight = 28; card.style.paddingTop = 22; card.style.paddingBottom = 22; card.style.minWidth = 380; card.style.alignItems = Align.Stretch; Round(card, 10); Border(card, new Color(Accent.r, Accent.g, Accent.b, 0.25f), 1); if (!string.IsNullOrEmpty(titleText)) card.Add(Title(titleText)); return card; } public static Label Title(string text) { var l = new Label(text); l.style.unityFontStyleAndWeight = FontStyle.Bold; l.style.fontSize = 26; l.style.color = Accent; l.style.unityTextAlign = TextAnchor.MiddleCenter; l.style.marginBottom = 16; var theme = HudTheme.Get(); if (theme != null) theme.ApplyDisplay(l.style); return l; } public static Label Caption(string text) { var l = new Label(text); l.style.fontSize = 13; l.style.color = SubCol; l.style.unityTextAlign = TextAnchor.MiddleCenter; l.style.marginTop = 8; l.style.marginBottom = 6; var theme = HudTheme.Get(); if (theme != null) theme.ApplyBodyLight(l.style); return l; } public static Button Button(string text, Action onClick) { var b = new Button(onClick) { text = text }; b.style.height = 40; b.style.fontSize = 16; b.style.marginTop = 5; b.style.marginBottom = 5; b.style.color = TextCol; b.style.backgroundColor = new Color(0.16f, 0.20f, 0.27f, 1f); b.style.unityFontStyleAndWeight = FontStyle.Bold; Round(b, 6); Border(b, new Color(0f, 0f, 0f, 0f), 0); var theme = HudTheme.Get(); if (theme != null) theme.ApplyBody(b.style); return b; } public static Button SmallButton(string text, Action onClick) { var b = Button(text, onClick); b.style.width = 36; b.style.height = 30; b.style.marginLeft = 4; b.style.marginRight = 4; return b; } public static void Round(VisualElement e, float r) { e.style.borderTopLeftRadius = r; e.style.borderTopRightRadius = r; e.style.borderBottomLeftRadius = r; e.style.borderBottomRightRadius = r; } public static void Border(VisualElement e, Color c, float w) { e.style.borderLeftWidth = w; e.style.borderRightWidth = w; e.style.borderTopWidth = w; e.style.borderBottomWidth = w; e.style.borderLeftColor = c; e.style.borderRightColor = c; e.style.borderTopColor = c; e.style.borderBottomColor = c; } } }