UnityExplorer/src/UI/UIManager.cs

349 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.CSharpConsole;
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
2021-04-23 21:50:58 +10:00
}
public static bool Initializing { get; private set; } = true;
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; }
// panels
2021-04-23 21:50:58 +10:00
internal static GameObject PanelHolder { get; private set; }
2021-04-28 23:58:13 +10:00
public static ObjectExplorerPanel Explorer { get; private set; }
public static InspectorPanel Inspector { get; private set; }
public static CSConsolePanel CSharpConsole { get; private set; }
2021-04-30 21:34:50 +10:00
public static AutoCompleter AutoCompleter { get; private set; }
// assets
internal static Font ConsoleFont { get; private set; }
internal static Shader BackupShader { get; private set; }
// Main Navbar UI
public static RectTransform NavBarRect;
public static GameObject NavbarButtonHolder;
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-04-30 21:34:50 +10:00
public static UIPanel GetPanel(Panels panel)
{
switch (panel)
{
case Panels.ObjectExplorer:
return Explorer;
case Panels.Inspector:
return Inspector;
case Panels.AutoCompleter:
return AutoCompleter;
case Panels.CSConsole:
return CSharpConsole;
2021-04-30 21:34:50 +10:00
default:
throw new NotImplementedException($"TODO GetPanel: {panel}");
}
}
// main menu toggle
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
public static void Update()
2021-03-11 17:57:58 +11:00
{
if (!CanvasRoot || Initializing)
2021-03-11 17:57:58 +11:00
return;
//if (InspectUnderMouse.Inspecting)
//{
// InspectUnderMouse.UpdateInspect();
// return;
//}
2021-03-11 17:57:58 +11:00
if (InputManager.GetKeyDown(ConfigManager.Main_Menu_Toggle.Value))
2021-03-11 17:57:58 +11:00
ShowMenu = !ShowMenu;
if (!ShowMenu)
2021-03-11 17:57:58 +11:00
return;
gcLabel.text = "GC : " + (GC.GetTotalMemory(false) / 1024 / 1024) + "MB";
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value))
CursorUnlocker.Unlock = !CursorUnlocker.Unlock;
if (EventSystem.current != EventSys)
CursorUnlocker.SetEventSystem();
2021-04-23 21:50:58 +10:00
UIPanel.UpdateFocus();
PanelDragger.UpdateInstances();
2021-04-23 21:50:58 +10:00
UIBehaviourModel.UpdateInstances();
}
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);
}
internal static void InitUI()
{
LoadBundle();
UIFactory.Init();
CreateRootCanvas();
PoolHolder = new GameObject("PoolHolder");
PoolHolder.transform.parent = CanvasRoot.transform;
PoolHolder.SetActive(false);
CreateTopNavBar();
2021-04-30 21:34:50 +10:00
//InspectUnderMouse.ConstructUI();
AutoCompleter = new AutoCompleter();
AutoCompleter.ConstructUI();
Explorer = new ObjectExplorerPanel();
Explorer.ConstructUI();
Inspector = new InspectorPanel();
Inspector.ConstructUI();
CSharpConsole = new CSConsolePanel();
CSharpConsole.ConstructUI();
CSConsole.Init();
2021-04-30 21:34:50 +10:00
ShowMenu = !ConfigManager.Hide_On_Startup.Value;
ExplorerCore.Log("UI initialized.");
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();
}
//// temp
//private static float lastTimeSpeed;
//private static bool pausing;
2021-04-28 23:58:13 +10:00
private static Text gcLabel;
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);
NavBarRect.anchorMin = new Vector2(0.5f, 1f);
NavBarRect.anchorMax = new Vector2(0.5f, 1f);
NavBarRect.sizeDelta = new Vector2(900f, 35f);
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: 240, flexibleWidth: 0);
// temp debug
gcLabel = UIFactory.CreateLabel(navbarPanel, "GCLabel", "GC: ", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(gcLabel.gameObject, minWidth: 150, minHeight: 25, flexibleWidth: 0);
// TODO something nicer for this, maybe a 'Tools' dropout below the main navbar with a few helpers like this.
//var btn = UIFactory.CreateButton(navbarPanel, "Button", "pause", new Color(0.2f, 0.2f, 0.2f));
//UIFactory.SetLayoutElement(btn.Button.gameObject, minWidth: 30, flexibleWidth: 0, minHeight: 25);
//btn.OnClick += () =>
//{
// if (!pausing)
// {
// lastTimeSpeed = Time.timeScale;
// Time.timeScale = 0;
// pausing = true;
// btn.ButtonText.text = "resume";
// }
// else
// {
// Time.timeScale = lastTimeSpeed;
// pausing = false;
// btn.ButtonText.text = "pause";
// }
//};
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, true, true, true, true, 4, 2, 2, 2, 2);
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
2021-04-28 23:58:13 +10:00
var closeBtn = UIFactory.CreateButton(navbarPanel, "CloseButton", ConfigManager.Main_Menu_Toggle.Value.ToString());
UIFactory.SetLayoutElement(closeBtn.Button.gameObject, minHeight: 25, minWidth: 80, flexibleWidth: 0);
RuntimeProvider.Instance.SetColorBlock(closeBtn.Button, 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));
2021-04-28 23:58:13 +10:00
ConfigManager.Main_Menu_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");
ExplorerCore.Log("Loaded UI AssetBundle");
}
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
}
}