UnityExplorer/src/UI/UIManager.cs

350 lines
12 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.Core.Config;
using UnityExplorer.Core.Input;
using UnityExplorer.UI.CSConsole;
using UnityExplorer.UI.Inspectors;
using UnityExplorer.UI.Models;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Utility;
using UnityExplorer.UI.Widgets;
2021-04-23 21:50:58 +10:00
using UnityExplorer.UI.Widgets.AutoComplete;
namespace UnityExplorer.UI
{
public static class UIManager
{
2021-04-23 21:50:58 +10:00
public enum Panels
{
ObjectExplorer,
Inspector,
CSConsole,
Options,
ConsoleLog,
AutoCompleter,
MouseInspector
2021-04-23 21:50:58 +10:00
}
public enum VerticalAnchor
{
Top,
Bottom
}
public static bool Initializing { get; private set; } = true;
private static readonly Dictionary<Panels, UIPanel> UIPanels = new Dictionary<Panels, UIPanel>();
public static VerticalAnchor NavbarAnchor = VerticalAnchor.Top;
// References
public static GameObject CanvasRoot { get; private set; }
2021-04-23 21:50:58 +10:00
public static Canvas Canvas { get; private set; }
public static EventSystem EventSys { get; private set; }
internal static GameObject PoolHolder { get; private set; }
2021-04-23 21:50:58 +10:00
internal static GameObject PanelHolder { get; private set; }
internal static Font ConsoleFont { get; private set; }
internal static Shader BackupShader { get; private set; }
public static RectTransform NavBarRect;
public static GameObject NavbarButtonHolder;
public static Dropdown MouseInspectDropdown;
// defaults
2021-05-04 20:10:46 +10:00
internal static readonly Color enabledButtonColor = new Color(0.2f, 0.4f, 0.28f);
internal static readonly Color disabledButtonColor = new Color(0.25f, 0.25f, 0.25f);
2021-04-28 23:58:13 +10:00
public const int MAX_INPUTFIELD_CHARS = 16000;
public const int MAX_TEXT_VERTS = 65000;
2021-03-11 17:57:58 +11:00
public static bool ShowMenu
{
get => s_showMenu;
set
2021-03-11 17:57:58 +11:00
{
if (s_showMenu == value || !CanvasRoot)
return;
s_showMenu = value;
CanvasRoot.SetActive(value);
CursorUnlocker.UpdateCursorControl();
2021-03-11 17:57:58 +11:00
}
}
public static bool s_showMenu = true;
2021-03-11 17:57:58 +11:00
2021-05-13 23:03:30 +10:00
// Panels
2021-03-11 17:57:58 +11:00
2021-05-13 23:03:30 +10:00
public static UIPanel GetPanel(Panels panel)
{
return UIPanels[panel];
}
2021-05-13 23:03:30 +10:00
public static T GetPanel<T>(Panels panel) where T : UIPanel
{
return (T)UIPanels[panel];
}
public static void TogglePanel(Panels panel)
{
var uiPanel = GetPanel(panel);
SetPanelActive(panel, !uiPanel.Enabled);
}
public static void SetPanelActive(Panels panel, bool active)
{
var obj = GetPanel(panel);
2021-04-28 23:58:13 +10:00
SetPanelActive(obj, active);
}
public static void SetPanelActive(UIPanel panel, bool active)
{
panel.SetActive(active);
if (active)
{
2021-04-28 23:58:13 +10:00
panel.UIRoot.transform.SetAsLastSibling();
UIPanel.InvokeOnPanelsReordered();
}
2021-04-28 23:58:13 +10:00
}
2021-04-28 23:58:13 +10:00
internal static void SetPanelActive(Transform transform, bool value)
{
if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
SetPanelActive(panel, value);
}
2021-05-13 23:03:30 +10:00
// Main UI Update loop
public static void Update()
{
if (!CanvasRoot || Initializing)
return;
if (InspectUnderMouse.Inspecting)
{
InspectUnderMouse.Instance.UpdateInspect();
return;
}
2021-05-13 23:03:30 +10:00
if (InputManager.GetKeyDown(ConfigManager.Master_Toggle.Value))
2021-05-13 23:03:30 +10:00
ShowMenu = !ShowMenu;
if (!ShowMenu)
return;
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Toggle.Value))
CursorUnlocker.Unlock = !CursorUnlocker.Unlock;
if (EventSystem.current != EventSys)
CursorUnlocker.SetEventSystem();
UIPanel.UpdateFocus();
PanelDragger.UpdateInstances();
InputFieldRef.UpdateInstances();
2021-05-13 23:03:30 +10:00
UIBehaviourModel.UpdateInstances();
}
// Initialization and UI Construction
internal static void InitUI()
{
LoadBundle();
UIFactory.Init();
CreateRootCanvas();
2021-05-13 23:03:30 +10:00
// Global UI Pool Holder
PoolHolder = new GameObject("PoolHolder");
PoolHolder.transform.parent = CanvasRoot.transform;
PoolHolder.SetActive(false);
CreateTopNavBar();
2021-05-13 23:03:30 +10:00
UIPanels.Add(Panels.AutoCompleter, new AutoCompleteModal());
UIPanels.Add(Panels.ObjectExplorer, new ObjectExplorerPanel());
UIPanels.Add(Panels.Inspector, new InspectorPanel());
UIPanels.Add(Panels.CSConsole, new CSConsolePanel());
UIPanels.Add(Panels.ConsoleLog, new LogPanel());
UIPanels.Add(Panels.Options, new OptionsPanel());
UIPanels.Add(Panels.MouseInspector, new InspectUnderMouse());
2021-05-13 23:03:30 +10:00
foreach (var panel in UIPanels.Values)
panel.ConstructUI();
ConsoleController.Init();
2021-04-30 21:34:50 +10:00
ShowMenu = !ConfigManager.Hide_On_Startup.Value;
Initializing = false;
}
private static void CreateRootCanvas()
{
CanvasRoot = new GameObject("ExplorerCanvas");
UnityEngine.Object.DontDestroyOnLoad(CanvasRoot);
CanvasRoot.hideFlags |= HideFlags.HideAndDontSave;
CanvasRoot.layer = 5;
CanvasRoot.transform.position = new Vector3(0f, 0f, 1f);
EventSys = CanvasRoot.AddComponent<EventSystem>();
InputManager.AddUIModule();
2021-04-23 21:50:58 +10:00
Canvas = CanvasRoot.AddComponent<Canvas>();
Canvas.renderMode = RenderMode.ScreenSpaceCamera;
Canvas.referencePixelsPerUnit = 100;
Canvas.sortingOrder = 999;
CanvasScaler scaler = CanvasRoot.AddComponent<CanvasScaler>();
scaler.referenceResolution = new Vector2(1920, 1080);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
CanvasRoot.AddComponent<GraphicRaycaster>();
2021-04-23 21:50:58 +10:00
PanelHolder = new GameObject("PanelHolder");
PanelHolder.transform.SetParent(CanvasRoot.transform, false);
PanelHolder.layer = 5;
var rect = PanelHolder.AddComponent<RectTransform>();
rect.sizeDelta = Vector2.zero;
rect.anchoredPosition = Vector2.zero;
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
PanelHolder.transform.SetAsFirstSibling();
}
public static void SetNavBarAnchor()
{
switch (NavbarAnchor)
{
case VerticalAnchor.Top:
NavBarRect.anchorMin = new Vector2(0.5f, 1f);
NavBarRect.anchorMax = new Vector2(0.5f, 1f);
NavBarRect.anchoredPosition = new Vector2(NavBarRect.anchoredPosition.x, 0);
NavBarRect.sizeDelta = new Vector2(900f, 35f);
break;
case VerticalAnchor.Bottom:
NavBarRect.anchorMin = new Vector2(0.5f, 0f);
NavBarRect.anchorMax = new Vector2(0.5f, 0f);
NavBarRect.anchoredPosition = new Vector2(NavBarRect.anchoredPosition.x, 35);
NavBarRect.sizeDelta = new Vector2(900f, 35f);
break;
}
}
2021-04-28 23:58:13 +10:00
private static void CreateTopNavBar()
2021-04-23 21:50:58 +10:00
{
2021-04-28 23:58:13 +10:00
var navbarPanel = UIFactory.CreateUIObject("MainNavbar", CanvasRoot);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(navbarPanel, false, true, true, true, 5, 4, 4, 4, 4, TextAnchor.MiddleCenter);
navbarPanel.AddComponent<Image>().color = new Color(0.1f, 0.1f, 0.1f);
NavBarRect = navbarPanel.GetComponent<RectTransform>();
NavBarRect.pivot = new Vector2(0.5f, 1f);
NavbarAnchor = ConfigManager.Main_Navbar_Anchor.Value;
SetNavBarAnchor();
ConfigManager.Main_Navbar_Anchor.OnValueChanged += (VerticalAnchor val) =>
{
NavbarAnchor = val;
SetNavBarAnchor();
};
2021-04-23 21:50:58 +10:00
2021-04-28 23:58:13 +10:00
// UnityExplorer title
2021-04-23 21:50:58 +10:00
string titleTxt = $"{ExplorerCore.NAME} <i><color=grey>{ExplorerCore.VERSION}</color></i>";
2021-04-28 23:58:13 +10:00
var title = UIFactory.CreateLabel(navbarPanel, "Title", titleTxt, TextAnchor.MiddleLeft, default, true, 18);
UIFactory.SetLayoutElement(title.gameObject, minWidth: 180, flexibleWidth: 0);
2021-04-28 23:58:13 +10:00
// Navbar
2021-04-23 21:50:58 +10:00
NavbarButtonHolder = UIFactory.CreateUIObject("NavButtonHolder", navbarPanel);
UIFactory.SetLayoutElement(NavbarButtonHolder, flexibleHeight: 999, flexibleWidth: 999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(NavbarButtonHolder, false, true, true, true, 4, 2, 2, 2, 2);
// Inspect under mouse dropdown
var mouseDropdown = UIFactory.CreateDropdown(navbarPanel, out MouseInspectDropdown, "Mouse Inspect", 14,
InspectUnderMouse.OnDropdownSelect);
UIFactory.SetLayoutElement(mouseDropdown, minHeight: 25, minWidth: 140);
MouseInspectDropdown.options.Add(new Dropdown.OptionData("Mouse Inspect"));
MouseInspectDropdown.options.Add(new Dropdown.OptionData("World"));
MouseInspectDropdown.options.Add(new Dropdown.OptionData("UI"));
2021-04-23 21:50:58 +10:00
2021-04-28 23:58:13 +10:00
// Hide menu button
2021-04-23 21:50:58 +10:00
var closeBtn = UIFactory.CreateButton(navbarPanel, "CloseButton", ConfigManager.Master_Toggle.Value.ToString());
2021-05-11 19:18:27 +10:00
UIFactory.SetLayoutElement(closeBtn.Component.gameObject, minHeight: 25, minWidth: 80, flexibleWidth: 0);
RuntimeProvider.Instance.SetColorBlock(closeBtn.Component, new Color(0.63f, 0.32f, 0.31f),
2021-04-23 21:50:58 +10:00
new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f));
ConfigManager.Master_Toggle.OnValueChanged += (KeyCode val) => { closeBtn.ButtonText.text = val.ToString(); };
2021-04-23 21:50:58 +10:00
2021-04-28 23:58:13 +10:00
closeBtn.OnClick += () => { ShowMenu = false; };
}
2021-04-23 21:50:58 +10:00
#region UI AssetBundle
2021-01-02 19:38:01 +01:00
private static void LoadBundle()
{
AssetBundle bundle = null;
try
{
bundle = LoadBundle("modern");
if (bundle == null)
bundle = LoadBundle("legacy");
2021-01-02 19:38:01 +01:00
}
catch { }
2021-01-02 19:38:01 +01:00
if (bundle == null)
{
ExplorerCore.LogWarning("Could not load the ExplorerUI Bundle!");
ConsoleFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
2021-01-02 19:38:01 +01:00
return;
}
2021-01-02 19:38:01 +01:00
BackupShader = bundle.LoadAsset<Shader>("DefaultUI");
2021-01-02 19:38:01 +01:00
// Fix for games which don't ship with 'UI/Default' shader.
if (Graphic.defaultGraphicMaterial.shader?.name != "UI/Default")
{
2021-01-02 19:38:01 +01:00
ExplorerCore.Log("This game does not ship with the 'UI/Default' shader, using manual Default Shader...");
Graphic.defaultGraphicMaterial.shader = BackupShader;
}
2021-04-05 16:28:30 +10:00
else
BackupShader = Graphic.defaultGraphicMaterial.shader;
2021-01-02 19:38:01 +01:00
ConsoleFont = bundle.LoadAsset<Font>("CONSOLA");
}
private static AssetBundle LoadBundle(string id)
{
var stream = typeof(ExplorerCore).Assembly
2021-04-05 16:28:30 +10:00
.GetManifestResourceStream($"UnityExplorer.Resources.explorerui.{id}.bundle");
return AssetBundle.LoadFromMemory(ReadFully(stream));
}
private static byte[] ReadFully(Stream input)
{
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[81920];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) != 0)
ms.Write(buffer, 0, read);
return ms.ToArray();
}
}
2021-04-23 21:50:58 +10:00
#endregion
}
}