From 12fe19ba8e06d4fd886ca3de6810d5aa3a67d321 Mon Sep 17 00:00:00 2001 From: Sinai Date: Fri, 14 May 2021 02:45:59 +1000 Subject: [PATCH] Implemented the console log, some cleanups --- src/Core/Config/ConfigManager.cs | 3 - src/Core/Reflection/Il2CppReflection.cs | 7 +- src/Core/Reflection/ReflectionUtility.cs | 18 +- src/Core/Utility/IOUtility.cs | 18 +- src/ExplorerCore.cs | 17 +- src/UI/CSConsole/ConsoleController.cs | 61 ++---- src/UI/CSConsole/ScriptInteraction.cs | 58 +++--- src/UI/CacheObject/CacheConfigEntry.cs | 3 + src/UI/CacheObject/CacheMember.cs | 2 +- src/UI/IValues/InteractiveString.cs | 2 +- src/UI/Inspectors/ReflectionInspector.cs | 2 +- src/UI/Panels/CSConsolePanel.cs | 4 +- src/UI/Panels/ConsoleLogPanel.cs | 41 ---- src/UI/Panels/LogPanel.cs | 243 +++++++++++++++++++++++ src/UI/Panels/OptionsPanel.cs | 2 +- src/UI/UIManager.cs | 5 +- src/UnityExplorer.csproj | 2 +- 17 files changed, 341 insertions(+), 147 deletions(-) delete mode 100644 src/UI/Panels/ConsoleLogPanel.cs create mode 100644 src/UI/Panels/LogPanel.cs diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs index ae55b89..991f067 100644 --- a/src/Core/Config/ConfigManager.cs +++ b/src/Core/Config/ConfigManager.cs @@ -108,9 +108,6 @@ namespace UnityExplorer.Core.Config "\r\nSeperate signatures with a semicolon ';'.", "DEFAULT"); - Reflection_Signature_Blacklist.OnValueChanged += ReflectionUtility.LoadBlacklistString; - ReflectionUtility.LoadBlacklistString(Reflection_Signature_Blacklist.Value); - // Internal configs (panel save data) ObjectExplorerData = new ConfigElement("ObjectExplorer", "", "", true); diff --git a/src/Core/Reflection/Il2CppReflection.cs b/src/Core/Reflection/Il2CppReflection.cs index f8aeaf0..3d3e03f 100644 --- a/src/Core/Reflection/Il2CppReflection.cs +++ b/src/Core/Reflection/Il2CppReflection.cs @@ -14,13 +14,16 @@ using System.Diagnostics.CodeAnalysis; using UnityExplorer.Core; using CppType = Il2CppSystem.Type; using BF = System.Reflection.BindingFlags; +using UnityExplorer.Core.Config; namespace UnityExplorer { public class Il2CppReflection : ReflectionUtility { - public Il2CppReflection() + protected override void Initialize() { + base.Initialize(); + TryLoadGameModules(); BuildDeobfuscationCache(); @@ -70,7 +73,7 @@ namespace UnityExplorer } if (DeobfuscatedTypes.Count > 0) - ExplorerCore.Log($"Built deobfuscation cache, count: {DeobfuscatedTypes.Count}"); + ExplorerCore.Log($"Built IL2CPP deobfuscation cache, initial count: {DeobfuscatedTypes.Count}"); } private static void TryCacheDeobfuscatedType(Type type) diff --git a/src/Core/Reflection/ReflectionUtility.cs b/src/Core/Reflection/ReflectionUtility.cs index 0ce235a..3012d91 100644 --- a/src/Core/Reflection/ReflectionUtility.cs +++ b/src/Core/Reflection/ReflectionUtility.cs @@ -17,16 +17,25 @@ namespace UnityExplorer { public const BF FLAGS = BF.Public | BF.Instance | BF.NonPublic | BF.Static; - internal static readonly ReflectionUtility Instance = + internal static ReflectionUtility Instance; + + public static void Init() + { + Instance = #if CPP new Il2CppReflection(); #else new ReflectionUtility(); #endif + Instance.Initialize(); + } - static ReflectionUtility() + protected virtual void Initialize() { SetupTypeCache(); + + LoadBlacklistString(ConfigManager.Reflection_Signature_Blacklist.Value); + ConfigManager.Reflection_Signature_Blacklist.OnValueChanged += LoadBlacklistString; } #region Type cache @@ -409,7 +418,12 @@ namespace UnityExplorer public static void LoadBlacklistString(string blacklist) { if (string.Equals(blacklist, "DEFAULT", StringComparison.InvariantCultureIgnoreCase)) + { blacklist = Instance.DefaultReflectionBlacklist; + ConfigManager.Reflection_Signature_Blacklist.Value = blacklist; + ConfigManager.Handler.SaveConfig(); + return; + } if (string.IsNullOrEmpty(blacklist)) return; diff --git a/src/Core/Utility/IOUtility.cs b/src/Core/Utility/IOUtility.cs index 9282703..3e6fdda 100644 --- a/src/Core/Utility/IOUtility.cs +++ b/src/Core/Utility/IOUtility.cs @@ -8,21 +8,17 @@ namespace UnityExplorer { public static class IOUtility { - public static string EnsureValid(string path) + private static readonly char[] invalidDirectoryCharacters = Path.GetInvalidPathChars(); + private static readonly char[] invalidFilenameCharacters = Path.GetInvalidFileNameChars(); + + public static string EnsureValidDirectory(string path) { - path = RemoveInvalidChars(path); - - var dir = Path.GetDirectoryName(path); - - if (!Directory.Exists(dir)) - Directory.CreateDirectory(dir); - - return path; + return string.Concat(path.Split(invalidDirectoryCharacters)); } - public static string RemoveInvalidChars(string path) + public static string EnsureValidFilename(string filename) { - return string.Concat(path.Split(Path.GetInvalidPathChars())); + return string.Concat(filename.Split(invalidFilenameCharacters)); } } } diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index f8e329c..2e0a52f 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -38,6 +38,8 @@ namespace UnityExplorer } Loader = loader; + Log($"{NAME} {VERSION} initializing..."); + ExplorerBehaviour.Setup(); if (!Directory.Exists(Loader.ExplorerFolder)) @@ -45,13 +47,15 @@ namespace UnityExplorer ConfigManager.Init(Loader.ConfigHandler); + ReflectionUtility.Init(); + RuntimeProvider.Init(); SceneHandler.Init(); InputManager.Init(); - Log($"{NAME} {VERSION} initialized."); - RuntimeProvider.Instance.StartCoroutine(SetupCoroutine()); + + Log($"Finished core setup, waiting for UI setup..."); } // Do a delayed setup so that objects aren't destroyed instantly. @@ -71,11 +75,11 @@ namespace UnityExplorer yield return null; } - Log($"Creating UI, after delay of {ConfigManager.Startup_Delay_Time.Value} second(s)."); + Log($"Creating UI..."); UIManager.InitUI(); - // END + Log($"{NAME} {VERSION} initialized."); //InspectorManager.Inspect(typeof(TestClass)); } @@ -123,23 +127,22 @@ namespace UnityExplorer { string log = message?.ToString() ?? ""; + LogPanel.Log(log, logType); + switch (logType) { case LogType.Assert: case LogType.Log: Loader.OnLogMessage(log); - //DebugConsole.Log(log, Color.white); break; case LogType.Warning: Loader.OnLogWarning(log); - //DebugConsole.Log(log, Color.yellow); break; case LogType.Error: case LogType.Exception: Loader.OnLogError(log); - //DebugConsole.Log(log, Color.red); break; } } diff --git a/src/UI/CSConsole/ConsoleController.cs b/src/UI/CSConsole/ConsoleController.cs index 6e284a8..945dda3 100644 --- a/src/UI/CSConsole/ConsoleController.cs +++ b/src/UI/CSConsole/ConsoleController.cs @@ -16,47 +16,6 @@ namespace UnityExplorer.UI.CSConsole { public static class ConsoleController { - #region Strings / defaults - - internal const string STARTUP_TEXT = @"Welcome to the UnityExplorer C# Console. - -The following helper methods are available: - -* Log(""message"") logs a message to the debug console - -* StartCoroutine(IEnumerator routine) start the IEnumerator as a UnityEngine.Coroutine - -* CurrentTarget() returns the target of the active Inspector tab as System.Object - -* AllTargets() returns a System.Object[] array containing the targets of all active tabs - -* Inspect(someObject) to inspect an instance, eg. Inspect(Camera.main); - -* Inspect(typeof(SomeClass)) to inspect a Class with static reflection - -* AddUsing(""SomeNamespace"") adds a using directive to the C# console - -* GetUsing() logs the current using directives to the debug console - -* Reset() resets all using directives and variables -"; - - internal static readonly string[] DefaultUsing = new string[] - { - "System", - "System.Linq", - "System.Collections", - "System.Collections.Generic", - "System.Reflection", - "UnityEngine", -#if CPP - "UnhollowerBaseLib", - "UnhollowerRuntimeLib", -#endif - }; - - #endregion - public static ScriptEvaluator Evaluator; public static LexerBuilder Lexer; public static CSAutoCompleter Completer; @@ -75,16 +34,34 @@ The following helper methods are available: public static bool EnableAutoIndent { get; private set; } = true; public static bool EnableSuggestions { get; private set; } = true; + internal static readonly string[] DefaultUsing = new string[] + { + "System", + "System.Linq", + "System.Collections", + "System.Collections.Generic", + "System.Reflection", + "UnityEngine", +#if CPP + "UnhollowerBaseLib", + "UnhollowerRuntimeLib", +#endif + }; + public static void Init() { try { ResetConsole(false); + // ensure the compiler is supported (if this fails then SRE is probably stubbed) Evaluator.Compile("0 == 0"); } catch { - ExplorerCore.LogWarning("C# Console probably not supported, todo"); + ExplorerCore.LogWarning("C# Console is not supported, System.Reflection.Emit was probably stubbed! You can use UnityDoorstop to patch this."); + var navButton = Panel.NavButton; + navButton.Component.interactable = false; + navButton.ButtonText.text += "(disabled)"; return; } diff --git a/src/UI/CSConsole/ScriptInteraction.cs b/src/UI/CSConsole/ScriptInteraction.cs index 5abb977..cbeca00 100644 --- a/src/UI/CSConsole/ScriptInteraction.cs +++ b/src/UI/CSConsole/ScriptInteraction.cs @@ -10,40 +10,37 @@ namespace UnityExplorer.UI.CSConsole { public class ScriptInteraction : InteractiveBase { + internal const string STARTUP_TEXT = @"Welcome to the UnityExplorer C# Console. + +Use this console to declare temporary C# classes, or evaluate standalone expressions as though you were executing a method body. "+ +@"Use the Reset button to clear all classes and variables, and restore the default using directives. + +* using SomeNamespace; to add a namespace to the Console. This is not required if you use full namespaces to access classes. + +When evaluating standalone expressions, these helpers are available: + +* System.Object CurrentTarget - the target of the active Inspector tab + +* System.Object[] AllTargets - an array containing the targets of all Inspector tabs + +* void Log(""message"") - logs a message to the console log + +* void Inspect(someObject) - inspect an instance, eg. Inspect(Camera.main); + +* void Inspect(typeof(SomeClass)) - inspect a Class with static reflection + +* void StartCoroutine(ienumerator) - start the IEnumerator as a Coroutine + +"; + public static void Log(object message) { ExplorerCore.Log(message); } - public static void StartCoroutine(IEnumerator ienumerator) - { - RuntimeProvider.Instance.StartCoroutine(ienumerator); - } + public static object CurrentTarget => InspectorManager.ActiveInspector?.Target; - public static void AddUsing(string directive) - { - ConsoleController.AddUsing(directive); - } - - public static void GetUsing() - { - ExplorerCore.Log(ConsoleController.Evaluator.GetUsing()); - } - - public static void Reset() - { - ConsoleController.ResetConsole(); - } - - public static object CurrentTarget() - { - return InspectorManager.ActiveInspector?.Target; - } - - public static object[] AllTargets() - { - return InspectorManager.Inspectors.Select(it => it.Target).ToArray(); - } + public static object[] AllTargets() => InspectorManager.Inspectors.Select(it => it.Target).ToArray(); public static void Inspect(object obj) { @@ -54,5 +51,10 @@ namespace UnityExplorer.UI.CSConsole { InspectorManager.Inspect(type); } + + public static void StartCoroutine(IEnumerator ienumerator) + { + RuntimeProvider.Instance.StartCoroutine(ienumerator); + } } } \ No newline at end of file diff --git a/src/UI/CacheObject/CacheConfigEntry.cs b/src/UI/CacheObject/CacheConfigEntry.cs index 4060d4c..97e83cc 100644 --- a/src/UI/CacheObject/CacheConfigEntry.cs +++ b/src/UI/CacheObject/CacheConfigEntry.cs @@ -33,6 +33,9 @@ namespace UnityExplorer.UI.CacheObject return; SetValueFromSource(RefConfigElement.BoxedValue); + + if (this.CellView != null) + this.SetDataToCell(CellView); } public override void TrySetUserValue(object value) diff --git a/src/UI/CacheObject/CacheMember.cs b/src/UI/CacheObject/CacheMember.cs index 411c31f..237c878 100644 --- a/src/UI/CacheObject/CacheMember.cs +++ b/src/UI/CacheObject/CacheMember.cs @@ -256,7 +256,7 @@ namespace UnityExplorer.UI.CacheObject case MemberTypes.Method: { var mi = member as MethodInfo; - if (!ignorePropertyMethodInfos + if (ignorePropertyMethodInfos && (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_"))) return; diff --git a/src/UI/IValues/InteractiveString.cs b/src/UI/IValues/InteractiveString.cs index c00892a..1a0c8a7 100644 --- a/src/UI/IValues/InteractiveString.cs +++ b/src/UI/IValues/InteractiveString.cs @@ -79,7 +79,7 @@ namespace UnityExplorer.UI.IValues return; } - var path = IOUtility.EnsureValid(SaveFilePath.Text); + var path = IOUtility.EnsureValidDirectory(SaveFilePath.Text); if (File.Exists(path)) File.Delete(path); diff --git a/src/UI/Inspectors/ReflectionInspector.cs b/src/UI/Inspectors/ReflectionInspector.cs index b77a1b0..c8fb9d5 100644 --- a/src/UI/Inspectors/ReflectionInspector.cs +++ b/src/UI/Inspectors/ReflectionInspector.cs @@ -665,7 +665,7 @@ namespace UnityExplorer.UI.Inspectors return; } - path = IOUtility.EnsureValid(path); + path = IOUtility.EnsureValidDirectory(path); if (File.Exists(path)) File.Delete(path); diff --git a/src/UI/Panels/CSConsolePanel.cs b/src/UI/Panels/CSConsolePanel.cs index 787ecbb..d40538c 100644 --- a/src/UI/Panels/CSConsolePanel.cs +++ b/src/UI/Panels/CSConsolePanel.cs @@ -102,7 +102,7 @@ namespace UnityExplorer.UI.Panels var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, "IndentToggle", out var AutoIndentToggle, out Text autoIndentToggleText); UIFactory.SetLayoutElement(autoIndentToggleObj, minWidth: 180, flexibleWidth: 0, minHeight: 25); autoIndentToggleText.alignment = TextAnchor.UpperLeft; - autoIndentToggleText.text = "Auto-indent on Enter"; + autoIndentToggleText.text = "Auto-indent"; AutoIndentToggle.onValueChanged.AddListener((bool val) => { OnAutoIndentToggled?.Invoke(val); }); #endregion @@ -111,7 +111,7 @@ namespace UnityExplorer.UI.Panels int fontSize = 16; - var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", ConsoleController.STARTUP_TEXT, out var inputScroller, fontSize); + var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", ScriptInteraction.STARTUP_TEXT, out var inputScroller, fontSize); InputScroll = inputScroller; ConsoleController.defaultInputFieldAlpha = Input.Component.selectionColor.a; Input.OnValueChanged += InvokeOnValueChanged; diff --git a/src/UI/Panels/ConsoleLogPanel.cs b/src/UI/Panels/ConsoleLogPanel.cs deleted file mode 100644 index 7bc22e8..0000000 --- a/src/UI/Panels/ConsoleLogPanel.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; -using UnityExplorer.Core.Config; - -namespace UnityExplorer.UI.Panels -{ - public class ConsoleLogPanel : UIPanel - { - public override string Name => "Console Log"; - public override UIManager.Panels PanelType => UIManager.Panels.ConsoleLog; - - public override int MinWidth => 300; - public override int MinHeight => 75; - - public override string GetSaveDataFromConfigManager() - { - return ConfigManager.ConsoleLogData.Value; - } - - public override void DoSaveToConfigElement() - { - ConfigManager.ConsoleLogData.Value = this.ToSaveData(); - } - - protected internal override void DoSetDefaultPosAndAnchors() - { - mainPanelRect.localPosition = Vector2.zero; - mainPanelRect.pivot = new Vector2(0f, 1f); - mainPanelRect.anchorMin = new Vector2(0.5f, 0.1f); - mainPanelRect.anchorMax = new Vector2(0.9f, 0.25f); - } - - public override void ConstructPanelContent() - { - - } - } -} diff --git a/src/UI/Panels/LogPanel.cs b/src/UI/Panels/LogPanel.cs new file mode 100644 index 0000000..c9acb58 --- /dev/null +++ b/src/UI/Panels/LogPanel.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.UI; +using UnityExplorer.Core.Config; +using UnityExplorer.UI.Widgets; + +namespace UnityExplorer.UI.Panels +{ + public class LogPanel : UIPanel, ICellPoolDataSource + { + public struct LogInfo + { + public string message; + public LogType type; + + public LogInfo(string message, LogType type) { this.message = message; this.type = type; } + } + + private static readonly List Logs = new List(); + private static string CurrentStreamPath; + + public override string Name => "Log"; + public override UIManager.Panels PanelType => UIManager.Panels.ConsoleLog; + + public override int MinWidth => 300; + public override int MinHeight => 75; + + public int ItemCount => Logs.Count; + + private static ScrollPool logScrollPool; + + public LogPanel() + { + SetupIO(); + } + + private static bool DoneScrollPoolInit; + + public override void SetActive(bool active) + { + base.SetActive(active); + + if (active && !DoneScrollPoolInit) + { + LayoutRebuilder.ForceRebuildLayoutImmediate(this.mainPanelRect); + logScrollPool.Initialize(this); + DoneScrollPoolInit = true; + } + + logScrollPool.Refresh(true, false); + } + + private void SetupIO() + { + var path = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Logs"); + path = IOUtility.EnsureValidDirectory(path); + + // clean old log(s) + var files = Directory.GetFiles(path); + if (files.Length >= 10) + { + var sorted = files.ToList(); + // sort by 'datetime.ToString("u")' will put the oldest ones first + sorted.Sort(); + for (int i = 0; i < files.Length - 9; i++) + File.Delete(files[i]); + } + + var fileName = $"UnityExplorer {DateTime.Now:u}.txt"; + fileName = IOUtility.EnsureValidFilename(fileName); + + CurrentStreamPath = Path.Combine(path, fileName); + + File.WriteAllLines(CurrentStreamPath, Logs.Select(it => it.message)); + } + + // Logging + + public static void Log(string message, LogType type) + { + Logs.Add(new LogInfo(message, type)); + + if (CurrentStreamPath != null) + File.AppendAllText(CurrentStreamPath, '\n' + message); + + if (logScrollPool != null) + logScrollPool.Refresh(true, false); + } + + private static void ClearLogs() + { + Logs.Clear(); + logScrollPool.Refresh(true, true); + } + + private static void OpenLogFile() + { + if (File.Exists(CurrentStreamPath)) + Process.Start(CurrentStreamPath); + } + + // Cell pool + + private static readonly Dictionary logColors = new Dictionary + { + { LogType.Log, Color.white }, + { LogType.Warning, Color.yellow }, + { LogType.Assert, Color.yellow }, + { LogType.Error, Color.red }, + { LogType.Exception, Color.red }, + }; + + private readonly Color logEvenColor = new Color(0.34f, 0.34f, 0.34f); + private readonly Color logOddColor = new Color(0.28f, 0.28f, 0.28f); + + public void OnCellBorrowed(ConsoleLogCell cell) { } + + public void SetCell(ConsoleLogCell cell, int index) + { + if (index >= Logs.Count) + { + cell.Disable(); + return; + } + + // Logs are displayed in reverse order (newest at top) + index = Logs.Count - index - 1; + + var log = Logs[index]; + cell.IndexLabel.text = $"{index}:"; + cell.Input.Text = log.message; + cell.Input.Component.textComponent.color = logColors[log.type]; + + var color = index % 2 == 0 ? logEvenColor : logOddColor; + RuntimeProvider.Instance.SetColorBlock(cell.Input.Component, color); + } + + // Panel save data + + public override string GetSaveDataFromConfigManager() + { + return ConfigManager.ConsoleLogData.Value; + } + + public override void DoSaveToConfigElement() + { + ConfigManager.ConsoleLogData.Value = this.ToSaveData(); + } + + protected internal override void DoSetDefaultPosAndAnchors() + { + mainPanelRect.localPosition = Vector2.zero; + mainPanelRect.pivot = new Vector2(0f, 1f); + mainPanelRect.anchorMin = new Vector2(0.5f, 0.1f); + mainPanelRect.anchorMax = new Vector2(0.9f, 0.25f); + } + + // UI Construction + + public override void ConstructPanelContent() + { + // Log scroll pool + + logScrollPool = UIFactory.CreateScrollPool(this.content, "Logs", out GameObject scrollObj, + out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f)); + UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999); + + // Buttons and toggles + + var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.content); + UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999); + UIFactory.SetLayoutGroup(optionsRow, false, false, true, true, 5, 2, 2, 2, 2); + + var clearButton = UIFactory.CreateButton(optionsRow, "ClearButton", "Clear", new Color(0.2f, 0.2f, 0.2f)); + UIFactory.SetLayoutElement(clearButton.Component.gameObject, minHeight: 23, flexibleHeight: 0, minWidth: 60); + clearButton.OnClick += ClearLogs; + clearButton.Component.transform.SetSiblingIndex(1); + + var fileButton = UIFactory.CreateButton(optionsRow, "FileButton", "Open Log File", new Color(0.2f, 0.2f, 0.2f)); + UIFactory.SetLayoutElement(fileButton.Component.gameObject, minHeight: 23, flexibleHeight: 0, minWidth: 100); + fileButton.OnClick += OpenLogFile; + fileButton.Component.transform.SetSiblingIndex(2); + + var unityToggle = UIFactory.CreateToggle(optionsRow, "UnityLogToggle", out var toggle, out var toggleText); + UIFactory.SetLayoutElement(unityToggle, minHeight: 25, minWidth: 150); + toggleText.text = "Log Unity Debug?"; + toggle.isOn = ConfigManager.Log_Unity_Debug.Value; + ConfigManager.Log_Unity_Debug.OnValueChanged += (bool val) => toggle.isOn = val; + toggle.onValueChanged.AddListener((bool val) => ConfigManager.Log_Unity_Debug.Value = val); + } + } + + #region Log Cell View + + public class ConsoleLogCell : ICell + { + public Text IndexLabel; + public InputFieldRef Input; + + public RectTransform Rect { get; set; } + public GameObject UIRoot { get; set; } + + public float DefaultHeight => 25; + + public bool Enabled => UIRoot.activeInHierarchy; + public void Enable() => UIRoot.SetActive(true); + public void Disable() => UIRoot.SetActive(false); + + + public GameObject CreateContent(GameObject parent) + { + UIRoot = UIFactory.CreateUIObject("LogCell", parent, new Vector2(25, 25)); + Rect = UIRoot.GetComponent(); + UIFactory.SetLayoutGroup(UIRoot, false, false, true, true, 3); + UIFactory.SetLayoutElement(UIRoot, minHeight: 25, minWidth: 50, flexibleWidth: 9999); + + IndexLabel = UIFactory.CreateLabel(UIRoot, "IndexLabel", "i:", TextAnchor.MiddleCenter, Color.grey, false, 12); + UIFactory.SetLayoutElement(IndexLabel.gameObject, minHeight: 25, minWidth: 30, flexibleWidth: 40); + + Input = UIFactory.CreateInputField(UIRoot, "Input", ""); + //Input.Component.gameObject.AddComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize; + UIFactory.SetLayoutElement(Input.UIRoot, minHeight: 25, flexibleWidth: 9999); + RuntimeProvider.Instance.SetColorBlock(Input.Component, new Color(0.1f, 0.1f, 0.1f), new Color(0.13f, 0.13f, 0.13f), + new Color(0.07f, 0.07f, 0.07f)); + Input.Component.GetComponent().color = new Color(0.2f, 0.2f, 0.2f); + + Input.Component.readOnly = true; + Input.Component.textComponent.supportRichText = true; + Input.Component.lineType = InputField.LineType.MultiLineNewline; + Input.Component.textComponent.font = UIManager.ConsoleFont; + Input.PlaceholderText.font = UIManager.ConsoleFont; + + return UIRoot; + } + } + + #endregion +} diff --git a/src/UI/Panels/OptionsPanel.cs b/src/UI/Panels/OptionsPanel.cs index 3c32acf..2b9ab64 100644 --- a/src/UI/Panels/OptionsPanel.cs +++ b/src/UI/Panels/OptionsPanel.cs @@ -80,7 +80,7 @@ namespace UnityExplorer.UI.Panels { // Save button - var saveBtn = UIFactory.CreateButton(this.content, "Save", "Save Options", new Color(0.25f, 0.3f, 0.25f)); + var saveBtn = UIFactory.CreateButton(this.content, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f)); UIFactory.SetLayoutElement(saveBtn.Component.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0); saveBtn.OnClick += ConfigManager.Handler.SaveConfig; diff --git a/src/UI/UIManager.cs b/src/UI/UIManager.cs index 0a5510b..49ef712 100644 --- a/src/UI/UIManager.cs +++ b/src/UI/UIManager.cs @@ -165,7 +165,7 @@ namespace UnityExplorer.UI UIPanels.Add(Panels.Inspector, new InspectorPanel()); UIPanels.Add(Panels.CSConsole, new CSConsolePanel()); UIPanels.Add(Panels.Options, new OptionsPanel()); - UIPanels.Add(Panels.ConsoleLog, new ConsoleLogPanel()); + UIPanels.Add(Panels.ConsoleLog, new LogPanel()); foreach (var panel in UIPanels.Values) panel.ConstructUI(); @@ -174,7 +174,6 @@ namespace UnityExplorer.UI ShowMenu = !ConfigManager.Hide_On_Startup.Value; - ExplorerCore.Log("UI initialized."); Initializing = false; } @@ -279,8 +278,6 @@ namespace UnityExplorer.UI BackupShader = Graphic.defaultGraphicMaterial.shader; ConsoleFont = bundle.LoadAsset("CONSOLA"); - - ExplorerCore.Log("Loaded UI AssetBundle"); } private static AssetBundle LoadBundle(string id) diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj index a46d055..d4b9d96 100644 --- a/src/UnityExplorer.csproj +++ b/src/UnityExplorer.csproj @@ -264,7 +264,7 @@ - +