From 3d66493f9ca9fad7babed9a60ac183185d39125b Mon Sep 17 00:00:00 2001 From: Sinai <49360850+sinai-dev@users.noreply.github.com> Date: Thu, 14 Apr 2022 01:25:59 +1000 Subject: [PATCH] Use UniverseLib PanelBase/PanelDragger --- src/CSConsole/CSAutoCompleter.cs | 1 + src/CacheObject/CacheObjectBase.cs | 6 +- src/CacheObject/IValues/InteractiveEnum.cs | 1 + src/ExplorerCore.cs | 6 +- src/Inspectors/MouseInspector.cs | 25 +- src/Tests/TestClass.cs | 2 +- src/UI/DisplayManager.cs | 2 +- src/UI/ExplorerUIBase.cs | 19 + src/UI/Panels/AutoCompleteModal.cs | 54 +- src/UI/Panels/CSConsolePanel.cs | 25 +- src/UI/Panels/ClipboardPanel.cs | 24 +- src/UI/Panels/HookManagerPanel.cs | 36 +- src/UI/Panels/InspectorPanel.cs | 36 +- src/UI/Panels/LogPanel.cs | 21 +- src/UI/Panels/MouseInspectorResultsPanel.cs | 29 +- src/UI/Panels/ObjectExplorerPanel.cs | 27 +- src/UI/Panels/OptionsPanel.cs | 29 +- src/UI/Panels/PanelDragger.cs | 487 ------------------ src/UI/Panels/UEPanel.cs | 260 ++++++++++ src/UI/Panels/UEPanelDragger.cs | 23 + src/UI/Panels/UIPanel.cs | 420 --------------- src/UI/UEPanelManager.cs | 39 ++ src/UI/UIManager.cs | 72 +-- src/UI/Widgets/AutoComplete/EnumCompleter.cs | 1 + src/UI/Widgets/AutoComplete/TypeCompleter.cs | 1 + .../Widgets/UnityObjects/Texture2DWidget.cs | 2 +- src/UnityExplorer.csproj | 4 +- 27 files changed, 539 insertions(+), 1113 deletions(-) create mode 100644 src/UI/ExplorerUIBase.cs delete mode 100644 src/UI/Panels/PanelDragger.cs create mode 100644 src/UI/Panels/UEPanel.cs create mode 100644 src/UI/Panels/UEPanelDragger.cs delete mode 100644 src/UI/Panels/UIPanel.cs create mode 100644 src/UI/UEPanelManager.cs diff --git a/src/CSConsole/CSAutoCompleter.cs b/src/CSConsole/CSAutoCompleter.cs index 5b37799..1b809fb 100644 --- a/src/CSConsole/CSAutoCompleter.cs +++ b/src/CSConsole/CSAutoCompleter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using UnityExplorer.CSConsole.Lexers; +using UnityExplorer.UI.Panels; using UnityExplorer.UI.Widgets.AutoComplete; using UniverseLib; using UniverseLib.UI.Models; diff --git a/src/CacheObject/CacheObjectBase.cs b/src/CacheObject/CacheObjectBase.cs index 1dfd24b..ebc6546 100644 --- a/src/CacheObject/CacheObjectBase.cs +++ b/src/CacheObject/CacheObjectBase.cs @@ -268,9 +268,9 @@ namespace UnityExplorer.CacheObject if (cell.CopyButton != null) { - bool hasEvaluated = State != ValueState.NotEvaluated && State != ValueState.Exception; - cell.CopyButton.Component.gameObject.SetActive(hasEvaluated); - cell.PasteButton.Component.gameObject.SetActive(hasEvaluated && this.CanWrite); + bool canCopy = State != ValueState.NotEvaluated && State != ValueState.Exception; + cell.CopyButton.Component.gameObject.SetActive(canCopy); + cell.PasteButton.Component.gameObject.SetActive(canCopy && this.CanWrite); } if (!evaluated) diff --git a/src/CacheObject/IValues/InteractiveEnum.cs b/src/CacheObject/IValues/InteractiveEnum.cs index f54e30e..ccf4138 100644 --- a/src/CacheObject/IValues/InteractiveEnum.cs +++ b/src/CacheObject/IValues/InteractiveEnum.cs @@ -4,6 +4,7 @@ using System.Collections.Specialized; using System.Linq; using UnityEngine; using UnityEngine.UI; +using UnityExplorer.UI.Panels; using UnityExplorer.UI.Widgets.AutoComplete; using UniverseLib.UI; using UniverseLib.UI.Models; diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index 42b107a..f174821 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -14,7 +14,7 @@ namespace UnityExplorer public static class ExplorerCore { public const string NAME = "UnityExplorer"; - public const string VERSION = "4.7.1"; + public const string VERSION = "4.7.2"; public const string AUTHOR = "Sinai"; public const string GUID = "com.sinai.unityexplorer"; @@ -57,8 +57,6 @@ namespace UnityExplorer // Default delay is 1 second which is usually enough. static void LateInit() { - Log($"Setting up late core features..."); - SceneHandler.Init(); Log($"Creating UI..."); @@ -66,6 +64,8 @@ namespace UnityExplorer UIManager.InitUI(); Log($"{NAME} {VERSION} ({Universe.Context}) initialized."); + + // InspectorManager.Inspect(typeof(Tests.TestClass)); } internal static void Update() diff --git a/src/Inspectors/MouseInspector.cs b/src/Inspectors/MouseInspector.cs index 4d9721e..bf50fd8 100644 --- a/src/Inspectors/MouseInspector.cs +++ b/src/Inspectors/MouseInspector.cs @@ -6,6 +6,7 @@ using UnityExplorer.UI; using UnityExplorer.UI.Panels; using UniverseLib.Input; using UniverseLib.UI; +using UniverseLib.UI.Panels; using UniverseLib.Utility; namespace UnityExplorer.Inspectors @@ -16,7 +17,7 @@ namespace UnityExplorer.Inspectors UI } - public class MouseInspector : UIPanel + public class MouseInspector : UEPanel { public static MouseInspector Instance { get; private set; } @@ -43,6 +44,9 @@ namespace UnityExplorer.Inspectors public override UIManager.Panels PanelType => UIManager.Panels.MouseInspector; public override int MinWidth => -1; public override int MinHeight => -1; + public override Vector2 DefaultAnchorMin => Vector2.zero; + public override Vector2 DefaultAnchorMax => Vector2.zero; + public override bool CanDragAndResize => false; public override bool NavButtonWanted => false; public override bool ShouldSaveActiveState => false; @@ -52,7 +56,7 @@ namespace UnityExplorer.Inspectors internal Text objPathLabel; internal Text mousePosLabel; - public MouseInspector() + public MouseInspector(UIBase owner) : base(owner) { Instance = this; worldInspector = new WorldInspector(); @@ -77,11 +81,12 @@ namespace UnityExplorer.Inspectors CurrentInspector.OnBeginMouseInspect(); - PanelDragger.ForceEnd(); + PanelManager.ForceEndResize(); UIManager.NavBarRect.gameObject.SetActive(false); - UIManager.PanelHolder.SetActive(false); + UIManager.UiBase.Panels.PanelHolder.SetActive(false); + UIManager.UiBase.SetOnTop(); - UIRoot.SetActive(true); + SetActive(true); } internal void ClearHitData() @@ -99,7 +104,7 @@ namespace UnityExplorer.Inspectors Inspecting = false; UIManager.NavBarRect.gameObject.SetActive(true); - UIManager.PanelHolder.SetActive(true); + UIManager.UiBase.Panels.PanelHolder.SetActive(true); Dropdown drop = InspectorPanel.Instance.MouseInspectDropdown; if (drop.transform.Find("Dropdown List") is Transform list) @@ -180,21 +185,23 @@ namespace UnityExplorer.Inspectors // UI Construction - protected internal override void DoSetDefaultPosAndAnchors() + public override void SetDefaultSizeAndPosition() { + base.SetDefaultSizeAndPosition(); + Rect.anchorMin = Vector2.zero; Rect.anchorMax = Vector2.zero; Rect.pivot = new Vector2(0.5f, 1); Rect.sizeDelta = new Vector2(700, 150); } - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { // hide title bar this.TitleBar.SetActive(false); this.UIRoot.transform.SetParent(UIManager.UIRoot.transform, false); - GameObject inspectContent = UIFactory.CreateVerticalGroup(this.uiContent, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2)); + GameObject inspectContent = UIFactory.CreateVerticalGroup(this.ContentRoot, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2)); UIFactory.SetLayoutElement(inspectContent, flexibleWidth: 9999, flexibleHeight: 9999); // Title text diff --git a/src/Tests/TestClass.cs b/src/Tests/TestClass.cs index df839d5..faaa333 100644 --- a/src/Tests/TestClass.cs +++ b/src/Tests/TestClass.cs @@ -237,7 +237,7 @@ namespace UnityExplorer.Tests try { Il2CppSystem.Type cppType = Il2CppType.Of(); - if (cppType != null) + if (cppType is not null) { Il2CppSystem.Object boxedEnum = Il2CppSystem.Enum.Parse(cppType, "Color"); IL2CPP_listOfBoxedObjects.Add(boxedEnum); diff --git a/src/UI/DisplayManager.cs b/src/UI/DisplayManager.cs index 1c9e22c..cd33fea 100644 --- a/src/UI/DisplayManager.cs +++ b/src/UI/DisplayManager.cs @@ -68,7 +68,7 @@ namespace UnityExplorer.UI yield return null; yield return null; - foreach (Panels.UIPanel panel in UIManager.UIPanels.Values) + foreach (Panels.UEPanel panel in UIManager.UIPanels.Values) { panel.EnsureValidSize(); panel.EnsureValidPosition(); diff --git a/src/UI/ExplorerUIBase.cs b/src/UI/ExplorerUIBase.cs new file mode 100644 index 0000000..c1d6e61 --- /dev/null +++ b/src/UI/ExplorerUIBase.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UniverseLib.UI; +using UniverseLib.UI.Panels; + +namespace UnityExplorer.UI +{ + internal class ExplorerUIBase : UIBase + { + public ExplorerUIBase(string id, Action updateMethod) : base(id, updateMethod) { } + + protected override PanelManager CreatePanelManager() + { + return new UEPanelManager(this); + } + } +} diff --git a/src/UI/Panels/AutoCompleteModal.cs b/src/UI/Panels/AutoCompleteModal.cs index 3acfa82..4e73329 100644 --- a/src/UI/Panels/AutoCompleteModal.cs +++ b/src/UI/Panels/AutoCompleteModal.cs @@ -4,6 +4,7 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; using UnityExplorer.UI.Panels; +using UnityExplorer.UI.Widgets.AutoComplete; using UniverseLib; using UniverseLib.Input; using UniverseLib.UI; @@ -12,20 +13,25 @@ using UniverseLib.UI.Widgets.ButtonList; using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.Utility; -namespace UnityExplorer.UI.Widgets.AutoComplete +namespace UnityExplorer.UI.Panels { // Shared modal panel for "AutoComplete" suggestions. // A data source implements ISuggestionProvider and uses TakeOwnership and ReleaseOwnership // for control, and SetSuggestions to set the actual suggestion data. - public class AutoCompleteModal : UIPanel + public class AutoCompleteModal : UEPanel { public static AutoCompleteModal Instance => UIManager.GetPanel(UIManager.Panels.AutoCompleter); public override string Name => "AutoCompleter"; public override UIManager.Panels PanelType => UIManager.Panels.AutoCompleter; - public override int MinWidth => -1; - public override int MinHeight => -1; + + public override int MinWidth => 100; + public override int MinHeight => 25; + public override Vector2 DefaultAnchorMin => new(MIN_X, 0.4f); + public override Vector2 DefaultAnchorMax => new(0.68f, MAX_Y); + const float MIN_X = 0.42f; + const float MAX_Y = 0.6f; public override bool CanDragAndResize => true; public override bool ShouldSaveActiveState => false; @@ -44,10 +50,10 @@ namespace UnityExplorer.UI.Widgets.AutoComplete public static bool Suggesting(ISuggestionProvider handler) => CurrentHandler == handler && Instance.UIRoot.activeSelf; - public AutoCompleteModal() + public AutoCompleteModal(UIBase owner) : base(owner) { - OnPanelsReordered += UIPanel_OnPanelsReordered; - OnClickedOutsidePanels += AutoCompleter_OnClickedOutsidePanels; + UIManager.UiBase.Panels.OnPanelsReordered += UIPanel_OnPanelsReordered; + UIManager.UiBase.Panels.OnClickedOutsidePanels += AutoCompleter_OnClickedOutsidePanels; } public static void TakeOwnership(ISuggestionProvider provider) @@ -263,7 +269,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete if (!this.UIRoot || !this.UIRoot.activeInHierarchy) return; - if (this.UIRoot.transform.GetSiblingIndex() != UIManager.PanelHolder.transform.childCount - 1) + if (this.UIRoot.transform.GetSiblingIndex() != UIManager.UiBase.Panels.PanelHolder.transform.childCount - 1) { if (CurrentHandler != null) ReleaseOwnership(CurrentHandler); @@ -272,46 +278,36 @@ namespace UnityExplorer.UI.Widgets.AutoComplete } } - // UI Construction - - const float MIN_X = 0.42f; - const float MAX_Y = 0.6f; - - protected internal override void DoSetDefaultPosAndAnchors() + public override void OnFinishResize() { - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(MIN_X, 0.4f); - Rect.anchorMax = new Vector2(0.68f, MAX_Y); - } - - public override void OnFinishResize(RectTransform panel) - { - float xDiff = panel.anchorMin.x - MIN_X; - float yDiff = panel.anchorMax.y - MAX_Y; + float xDiff = Rect.anchorMin.x - MIN_X; + float yDiff = Rect.anchorMax.y - MAX_Y; if (xDiff != 0 || yDiff != 0) { - panel.anchorMin = new(MIN_X, panel.anchorMin.y - yDiff); - panel.anchorMax = new(panel.anchorMax.x - xDiff, MAX_Y); + Rect.anchorMin = new(MIN_X, Rect.anchorMin.y - yDiff); + Rect.anchorMax = new(Rect.anchorMax.x - xDiff, MAX_Y); } - base.OnFinishResize(panel); + base.OnFinishResize(); } - public override void ConstructPanelContent() + // UI Construction + + protected override void ConstructPanelContent() { // hide the titlebar this.TitleBar.gameObject.SetActive(false); buttonListDataHandler = new ButtonListHandler(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked); - scrollPool = UIFactory.CreateScrollPool(this.uiContent, "AutoCompleter", out GameObject scrollObj, + scrollPool = UIFactory.CreateScrollPool(this.ContentRoot, "AutoCompleter", out GameObject scrollObj, out GameObject scrollContent); scrollPool.Initialize(buttonListDataHandler); UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999); UIFactory.SetLayoutGroup(scrollContent, true, false, true, false); - navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiContent, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2)); + navigationTipRow = UIFactory.CreateHorizontalGroup(this.ContentRoot, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2)); UIFactory.SetLayoutElement(navigationTipRow, minHeight: 20, flexibleWidth: 9999); UIFactory.CreateLabel(navigationTipRow, "HelpText", "Up/Down to select, Enter to use, Esc to close", TextAnchor.MiddleLeft, Color.grey, false, 13); diff --git a/src/UI/Panels/CSConsolePanel.cs b/src/UI/Panels/CSConsolePanel.cs index 1eed941..3b9cbce 100644 --- a/src/UI/Panels/CSConsolePanel.cs +++ b/src/UI/Panels/CSConsolePanel.cs @@ -10,12 +10,15 @@ using UniverseLib.UI.Widgets; namespace UnityExplorer.UI.Panels { - public class CSConsolePanel : UIPanel + public class CSConsolePanel : UEPanel { public override string Name => "C# Console"; public override UIManager.Panels PanelType => UIManager.Panels.CSConsole; + public override int MinWidth => 750; public override int MinHeight => 300; + public override Vector2 DefaultAnchorMin => new(0.4f, 0.175f); + public override Vector2 DefaultAnchorMax => new(0.85f, 0.925f); public InputFieldScroller InputScroller { get; private set; } public InputFieldRef Input => InputScroller.InputField; @@ -35,6 +38,10 @@ namespace UnityExplorer.UI.Panels public Action OnAutoIndentToggled; public Action OnPanelResized; + public CSConsolePanel(UIBase owner) : base(owner) + { + } + private void InvokeOnValueChanged(string value) { if (value.Length == UniversalUI.MAX_INPUTFIELD_CHARS) @@ -52,24 +59,16 @@ namespace UnityExplorer.UI.Panels // UI Construction - public override void OnFinishResize(RectTransform panel) + public override void OnFinishResize() { OnPanelResized?.Invoke(); } - protected internal override void DoSetDefaultPosAndAnchors() - { - Rect.localPosition = Vector2.zero; - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(0.4f, 0.175f); - Rect.anchorMax = new Vector2(0.85f, 0.925f); - } - - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { // Tools Row - GameObject toolsRow = UIFactory.CreateHorizontalGroup(this.uiContent, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5), + GameObject toolsRow = UIFactory.CreateHorizontalGroup(this.ContentRoot, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5), default, TextAnchor.MiddleLeft); UIFactory.SetLayoutElement(toolsRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); @@ -118,7 +117,7 @@ namespace UnityExplorer.UI.Panels // Console Input - GameObject inputArea = UIFactory.CreateUIObject("InputGroup", uiContent); + GameObject inputArea = UIFactory.CreateUIObject("InputGroup", ContentRoot); UIFactory.SetLayoutElement(inputArea, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutGroup(inputArea, false, true, true, true); inputArea.AddComponent().color = Color.white; diff --git a/src/UI/Panels/ClipboardPanel.cs b/src/UI/Panels/ClipboardPanel.cs index f5ee7a1..dc4254a 100644 --- a/src/UI/Panels/ClipboardPanel.cs +++ b/src/UI/Panels/ClipboardPanel.cs @@ -7,14 +7,18 @@ using UniverseLib.Utility; namespace UnityExplorer.UI.Panels { - public class ClipboardPanel : UIPanel + public class ClipboardPanel : UEPanel { public static object Current { get; private set; } - public override UIManager.Panels PanelType => UIManager.Panels.Clipboard; public override string Name => "Clipboard"; + public override UIManager.Panels PanelType => UIManager.Panels.Clipboard; + public override int MinWidth => 500; public override int MinHeight => 95; + public override Vector2 DefaultAnchorMin => new(0.1f, 0.05f); + public override Vector2 DefaultAnchorMax => new(0.4f, 0.15f); + public override bool CanDragAndResize => true; public override bool NavButtonWanted => true; public override bool ShouldSaveActiveState => true; @@ -22,6 +26,10 @@ namespace UnityExplorer.UI.Panels private static Text CurrentPasteLabel; + public ClipboardPanel(UIBase owner) : base(owner) + { + } + public static void Copy(object obj) { Current = obj; @@ -66,21 +74,21 @@ namespace UnityExplorer.UI.Panels InspectorManager.Inspect(Current); } - protected internal override void DoSetDefaultPosAndAnchors() + public override void SetDefaultSizeAndPosition() { + base.SetDefaultSizeAndPosition(); + this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth); this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight); - this.Rect.anchorMin = new Vector2(0.1f, 0.05f); - this.Rect.anchorMax = new Vector2(0.4f, 0.15f); } - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { this.UIRoot.GetComponent().color = new(0.1f, 0.1f, 0.1f); // Actual panel content - GameObject firstRow = UIFactory.CreateHorizontalGroup(uiContent, "FirstRow", false, false, true, true, 5, new(2, 2, 2, 2), new(1, 1, 1, 0)); + GameObject firstRow = UIFactory.CreateHorizontalGroup(ContentRoot, "FirstRow", false, false, true, true, 5, new(2, 2, 2, 2), new(1, 1, 1, 0)); UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 999); // Title for "Current Paste:" @@ -93,7 +101,7 @@ namespace UnityExplorer.UI.Panels clearButton.OnClick += () => Copy(null); // Current Paste info row - GameObject currentPasteHolder = UIFactory.CreateHorizontalGroup(uiContent, "SecondRow", false, false, true, true, 0, + GameObject currentPasteHolder = UIFactory.CreateHorizontalGroup(ContentRoot, "SecondRow", false, false, true, true, 0, new(2, 2, 2, 2), childAlignment: TextAnchor.UpperCenter); // Actual current paste info label diff --git a/src/UI/Panels/HookManagerPanel.cs b/src/UI/Panels/HookManagerPanel.cs index ecc28c4..5716ead 100644 --- a/src/UI/Panels/HookManagerPanel.cs +++ b/src/UI/Panels/HookManagerPanel.cs @@ -9,7 +9,7 @@ using UniverseLib.UI.Widgets.ScrollView; namespace UnityExplorer.UI.Panels { - public class HookManagerPanel : UIPanel + public class HookManagerPanel : UEPanel { public enum Pages { @@ -21,9 +21,12 @@ namespace UnityExplorer.UI.Panels public override UIManager.Panels PanelType => UIManager.Panels.HookManager; public override string Name => "Hooks"; + public override bool ShowByDefault => false; + public override int MinWidth => 500; public override int MinHeight => 600; - public override bool ShowByDefault => false; + public override Vector2 DefaultAnchorMin => new(0.5f, 0.5f); + public override Vector2 DefaultAnchorMax => new(0.5f, 0.5f); public Pages CurrentPage { get; private set; } = Pages.CurrentHooks; @@ -37,11 +40,16 @@ namespace UnityExplorer.UI.Panels private InputFieldRef AddHooksMethodFilterInput; private GameObject editorPanel; + public InputFieldScroller EditorInputScroller { get; private set; } public InputFieldRef EditorInput => EditorInputScroller.InputField; public Text EditorInputText { get; private set; } public Text EditorHighlightText { get; private set; } + public HookManagerPanel(UIBase owner) : base(owner) + { + } + private void OnClassInputAddClicked() { HookManager.Instance.OnClassSelectedForHooks(this.classSelectorInputField.Text); @@ -73,11 +81,19 @@ namespace UnityExplorer.UI.Panels public void ResetMethodFilter() => AddHooksMethodFilterInput.Text = string.Empty; - public override void ConstructPanelContent() + public override void SetDefaultSizeAndPosition() + { + base.SetDefaultSizeAndPosition(); + + this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth); + this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight); + } + + protected override void ConstructPanelContent() { // ~~~~~~~~~ Active hooks scroll pool - currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiContent); + currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.ContentRoot); UIFactory.SetLayoutElement(currentHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutGroup(currentHooksPanel, true, true, true, true); @@ -103,7 +119,7 @@ namespace UnityExplorer.UI.Panels // ~~~~~~~~~ Add hooks panel - addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiContent); + addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.ContentRoot); UIFactory.SetLayoutElement(addHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutGroup(addHooksPanel, true, true, true, true); @@ -130,7 +146,7 @@ namespace UnityExplorer.UI.Panels // ~~~~~~~~~ Hook source editor panel - editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiContent); + editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.ContentRoot); UIFactory.SetLayoutElement(editorPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutGroup(editorPanel, true, true, true, true); @@ -185,13 +201,5 @@ namespace UnityExplorer.UI.Panels editorPanel.SetActive(false); } - - protected internal override void DoSetDefaultPosAndAnchors() - { - this.Rect.anchorMin = new Vector2(0.5f, 0.5f); - this.Rect.anchorMax = new Vector2(0.5f, 0.5f); - this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth); - this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight); - } } } diff --git a/src/UI/Panels/InspectorPanel.cs b/src/UI/Panels/InspectorPanel.cs index 30ab264..edaae5a 100644 --- a/src/UI/Panels/InspectorPanel.cs +++ b/src/UI/Panels/InspectorPanel.cs @@ -5,17 +5,18 @@ using UniverseLib.UI; namespace UnityExplorer.UI.Panels { - public class InspectorPanel : UIPanel + public class InspectorPanel : UEPanel { public static InspectorPanel Instance { get; private set; } - public InspectorPanel() { Instance = this; } - public override string Name => "Inspector"; public override UIManager.Panels PanelType => UIManager.Panels.Inspector; public override bool ShouldSaveActiveState => false; + public override int MinWidth => 810; public override int MinHeight => 350; + public override Vector2 DefaultAnchorMin => new(0.35f, 0.175f); + public override Vector2 DefaultAnchorMax => new(0.8f, 0.925f); public GameObject NavbarHolder; public Dropdown MouseInspectDropdown; @@ -25,28 +26,25 @@ namespace UnityExplorer.UI.Panels public static float CurrentPanelWidth => Instance.Rect.rect.width; public static float CurrentPanelHeight => Instance.Rect.rect.height; + public InspectorPanel(UIBase owner) : base(owner) + { + Instance = this; + } + public override void Update() { InspectorManager.Update(); } - public override void OnFinishResize(RectTransform panel) + public override void OnFinishResize() { - base.OnFinishResize(panel); + base.OnFinishResize(); InspectorManager.PanelWidth = this.Rect.rect.width; - InspectorManager.OnPanelResized(panel.rect.width); + InspectorManager.OnPanelResized(Rect.rect.width); } - protected internal override void DoSetDefaultPosAndAnchors() - { - Rect.localPosition = Vector2.zero; - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(0.35f, 0.175f); - Rect.anchorMax = new Vector2(0.8f, 0.925f); - } - - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { GameObject closeHolder = this.TitleBar.transform.Find("CloseHolder").gameObject; @@ -70,19 +68,19 @@ namespace UnityExplorer.UI.Panels // this.UIRoot.GetComponent().enabled = false; - UIFactory.SetLayoutGroup(this.uiContent, true, true, true, true, 4, padLeft: 5, padRight: 5); + UIFactory.SetLayoutGroup(this.ContentRoot, true, true, true, true, 4, padLeft: 5, padRight: 5); - this.NavbarHolder = UIFactory.CreateGridGroup(this.uiContent, "Navbar", new Vector2(200, 22), new Vector2(4, 4), + this.NavbarHolder = UIFactory.CreateGridGroup(this.ContentRoot, "Navbar", new Vector2(200, 22), new Vector2(4, 4), new Color(0.05f, 0.05f, 0.05f)); //UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999); NavbarHolder.AddComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize; - this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiContent, "ContentHolder", true, true, true, true, 0, default, + this.ContentHolder = UIFactory.CreateVerticalGroup(this.ContentRoot, "ContentHolder", true, true, true, true, 0, default, new Color(0.1f, 0.1f, 0.1f)); UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999); ContentRect = ContentHolder.GetComponent(); - UIManager.SetPanelActive(PanelType, false); + this.SetActive(false); } } } \ No newline at end of file diff --git a/src/UI/Panels/LogPanel.cs b/src/UI/Panels/LogPanel.cs index 7ede88c..e988b2b 100644 --- a/src/UI/Panels/LogPanel.cs +++ b/src/UI/Panels/LogPanel.cs @@ -16,7 +16,7 @@ namespace UnityExplorer.UI.Panels { // TODO move the logic out of this class into a LogUtil class (also move ExplorerCore.Log into that) - public class LogPanel : UIPanel, ICellPoolDataSource + public class LogPanel : UEPanel, ICellPoolDataSource { public struct LogInfo { @@ -34,6 +34,9 @@ namespace UnityExplorer.UI.Panels public override int MinWidth => 350; public override int MinHeight => 75; + public override Vector2 DefaultAnchorMin => new(0.5f, 0.03f); + public override Vector2 DefaultAnchorMax => new(0.9f, 0.2f); + public override bool ShouldSaveActiveState => true; public override bool ShowByDefault => true; @@ -41,7 +44,7 @@ namespace UnityExplorer.UI.Panels private static ScrollPool logScrollPool; - public LogPanel() + public LogPanel(UIBase owner) : base(owner) { SetupIO(); } @@ -144,27 +147,19 @@ namespace UnityExplorer.UI.Panels RuntimeHelper.SetColorBlock(cell.Input.Component, color); } - protected internal override void DoSetDefaultPosAndAnchors() - { - Rect.localPosition = Vector2.zero; - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(0.5f, 0.03f); - Rect.anchorMax = new Vector2(0.9f, 0.2f); - } - // UI Construction - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { // Log scroll pool - logScrollPool = UIFactory.CreateScrollPool(this.uiContent, "Logs", out GameObject scrollObj, + logScrollPool = UIFactory.CreateScrollPool(this.ContentRoot, "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 - GameObject optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiContent); + GameObject optionsRow = UIFactory.CreateUIObject("OptionsRow", this.ContentRoot); UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999); UIFactory.SetLayoutGroup(optionsRow, false, false, true, true, 5, 2, 2, 2, 2); diff --git a/src/UI/Panels/MouseInspectorResultsPanel.cs b/src/UI/Panels/MouseInspectorResultsPanel.cs index c4aceed..29fedfd 100644 --- a/src/UI/Panels/MouseInspectorResultsPanel.cs +++ b/src/UI/Panels/MouseInspectorResultsPanel.cs @@ -8,7 +8,7 @@ using UniverseLib.Utility; namespace UnityExplorer.UI.Panels { - public class MouseInspectorResultsPanel : UIPanel + public class MouseInspectorResultsPanel : UEPanel { public override UIManager.Panels PanelType => UIManager.Panels.UIInspectorResults; @@ -16,6 +16,9 @@ namespace UnityExplorer.UI.Panels public override int MinWidth => 500; public override int MinHeight => 500; + public override Vector2 DefaultAnchorMin => new(0.5f, 0.5f); + public override Vector2 DefaultAnchorMax => new(0.5f, 0.5f); + public override bool CanDragAndResize => true; public override bool NavButtonWanted => false; public override bool ShouldSaveActiveState => false; @@ -24,6 +27,10 @@ namespace UnityExplorer.UI.Panels private ButtonListHandler dataHandler; private ScrollPool buttonScrollPool; + public MouseInspectorResultsPanel(UIBase owner) : base(owner) + { + } + public void ShowResults() { dataHandler.RefreshData(); @@ -51,23 +58,23 @@ namespace UnityExplorer.UI.Panels cell.Button.ButtonText.text = $"{obj.name} ({obj.transform.GetTransformPath(true)})"; } - public override void ConstructPanelContent() + public override void SetDefaultSizeAndPosition() + { + base.SetDefaultSizeAndPosition(); + + this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f); + this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f); + } + + protected override void ConstructPanelContent() { dataHandler = new ButtonListHandler(buttonScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked); - buttonScrollPool = UIFactory.CreateScrollPool(this.uiContent, "ResultsList", out GameObject scrollObj, + buttonScrollPool = UIFactory.CreateScrollPool(this.ContentRoot, "ResultsList", out GameObject scrollObj, out GameObject scrollContent); buttonScrollPool.Initialize(dataHandler); UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999); } - - protected internal override void DoSetDefaultPosAndAnchors() - { - this.Rect.anchorMin = new Vector2(0.5f, 0.5f); - this.Rect.anchorMax = new Vector2(0.5f, 0.5f); - this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f); - this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f); - } } } diff --git a/src/UI/Panels/ObjectExplorerPanel.cs b/src/UI/Panels/ObjectExplorerPanel.cs index 08995e9..f5253b2 100644 --- a/src/UI/Panels/ObjectExplorerPanel.cs +++ b/src/UI/Panels/ObjectExplorerPanel.cs @@ -9,12 +9,15 @@ using UniverseLib.UI.Models; namespace UnityExplorer.UI.Panels { - public class ObjectExplorerPanel : UIPanel + public class ObjectExplorerPanel : UEPanel { public override string Name => "Object Explorer"; public override UIManager.Panels PanelType => UIManager.Panels.ObjectExplorer; + public override int MinWidth => 350; public override int MinHeight => 200; + public override Vector2 DefaultAnchorMin => new(0.125f, 0.175f); + public override Vector2 DefaultAnchorMax => new(0.325f, 0.925f); public SceneExplorer SceneExplorer; public ObjectSearch ObjectSearch; @@ -26,6 +29,10 @@ namespace UnityExplorer.UI.Panels private readonly List tabPages = new(); private readonly List tabButtons = new(); + public ObjectExplorerPanel(UIBase owner) : base(owner) + { + } + public void SetTab(int tabIndex) { if (SelectedTab != -1) @@ -80,28 +87,20 @@ namespace UnityExplorer.UI.Panels SetTab(SelectedTab); } - protected internal override void DoSetDefaultPosAndAnchors() - { - Rect.localPosition = Vector2.zero; - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(0.125f, 0.175f); - Rect.anchorMax = new Vector2(0.325f, 0.925f); - } - - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { // Tab bar - GameObject tabGroup = UIFactory.CreateHorizontalGroup(uiContent, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2)); + GameObject tabGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2)); UIFactory.SetLayoutElement(tabGroup, minHeight: 25, flexibleHeight: 0); // Scene Explorer SceneExplorer = new SceneExplorer(this); - SceneExplorer.ConstructUI(uiContent); + SceneExplorer.ConstructUI(ContentRoot); tabPages.Add(SceneExplorer); // Object search ObjectSearch = new ObjectSearch(this); - ObjectSearch.ConstructUI(uiContent); + ObjectSearch.ConstructUI(ContentRoot); tabPages.Add(ObjectSearch); // set up tabs @@ -109,7 +108,7 @@ namespace UnityExplorer.UI.Panels AddTabButton(tabGroup, "Object Search"); // default active state: Active - UIManager.SetPanelActive(PanelType, true); + this.SetActive(true); } private void AddTabButton(GameObject tabGroup, string label) diff --git a/src/UI/Panels/OptionsPanel.cs b/src/UI/Panels/OptionsPanel.cs index 20de9a9..f236543 100644 --- a/src/UI/Panels/OptionsPanel.cs +++ b/src/UI/Panels/OptionsPanel.cs @@ -9,13 +9,15 @@ using UniverseLib.UI.Widgets.ScrollView; namespace UnityExplorer.UI.Panels { - public class OptionsPanel : UIPanel, ICacheObjectController, ICellPoolDataSource + public class OptionsPanel : UEPanel, ICacheObjectController, ICellPoolDataSource { public override string Name => "Options"; public override UIManager.Panels PanelType => UIManager.Panels.Options; public override int MinWidth => 600; public override int MinHeight => 200; + public override Vector2 DefaultAnchorMin => new(0.5f, 0.1f); + public override Vector2 DefaultAnchorMax => new(0.5f, 0.85f); public override bool ShouldSaveActiveState => false; public override bool ShowByDefault => false; @@ -32,7 +34,7 @@ namespace UnityExplorer.UI.Panels // ICellPoolDataSource public int ItemCount => configEntries.Count; - public OptionsPanel() + public OptionsPanel(UIBase owner) : base(owner) { foreach (KeyValuePair entry in ConfigManager.ConfigElements) { @@ -42,6 +44,9 @@ namespace UnityExplorer.UI.Panels }; configEntries.Add(cache); } + + foreach (CacheConfigEntry config in configEntries) + config.UpdateValueFromSource(); } public void OnCellBorrowed(ConfigEntryCell cell) @@ -55,32 +60,30 @@ namespace UnityExplorer.UI.Panels // UI Construction - protected internal override void DoSetDefaultPosAndAnchors() + public override void SetDefaultSizeAndPosition() { - Rect.localPosition = Vector2.zero; - Rect.pivot = new Vector2(0f, 1f); - Rect.anchorMin = new Vector2(0.5f, 0.1f); - Rect.anchorMax = new Vector2(0.5f, 0.85f); + base.SetDefaultSizeAndPosition(); + Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 600f); } - public override void ConstructPanelContent() + protected override void ConstructPanelContent() { // Save button - UniverseLib.UI.Models.ButtonRef saveBtn = UIFactory.CreateButton(this.uiContent, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f)); + UniverseLib.UI.Models.ButtonRef saveBtn = UIFactory.CreateButton(this.ContentRoot, "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; // Config entries - ScrollPool scrollPool = UIFactory.CreateScrollPool(this.uiContent, "ConfigEntries", out GameObject scrollObj, + ScrollPool scrollPool = UIFactory.CreateScrollPool( + this.ContentRoot, + "ConfigEntries", + out GameObject scrollObj, out GameObject scrollContent); scrollPool.Initialize(this); - - foreach (CacheConfigEntry config in configEntries) - config.UpdateValueFromSource(); } } } diff --git a/src/UI/Panels/PanelDragger.cs b/src/UI/Panels/PanelDragger.cs deleted file mode 100644 index 2b65845..0000000 --- a/src/UI/Panels/PanelDragger.cs +++ /dev/null @@ -1,487 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using UnityExplorer.UI.Widgets.AutoComplete; -using UniverseLib.Input; -using UniverseLib.UI; -using UniverseLib.Utility; - -namespace UnityExplorer.UI.Panels -{ - public class PanelDragger - { - private enum MouseState - { - Down, - Held, - NotPressed - } - - #region Static - - public static bool Resizing { get; private set; } - public static bool ResizePrompting => resizeCursorObj && resizeCursorObj.activeSelf; - - public static GameObject resizeCursorObj; - internal static bool wasAnyDragging; - - internal static List Instances = new(); - - private static bool handledInstanceThisFrame; - - static PanelDragger() - { - UIPanel.OnPanelsReordered += OnPanelsReordered; - } - - internal static void ForceEnd() - { - resizeCursorObj.SetActive(false); - wasAnyDragging = false; - Resizing = false; - - foreach (PanelDragger instance in Instances) - { - instance.WasDragging = false; - instance.WasResizing = false; - } - } - - public static void OnPanelsReordered() - { - Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex())); - - // move AutoCompleter to bottom - if (AutoCompleteModal.Instance != null) - { - int idx = Instances.IndexOf(AutoCompleteModal.Instance.Dragger); - Instances.RemoveAt(idx); - Instances.Insert(0, AutoCompleteModal.Instance.Dragger); - } - } - - public static void UpdateInstances() - { - if (!DisplayManager.MouseInTargetDisplay) - return; - - if (!resizeCursorObj) - CreateCursorUI(); - - MouseState state; - if (InputManager.GetMouseButtonDown(0)) - state = MouseState.Down; - else if (InputManager.GetMouseButton(0)) - state = MouseState.Held; - else - state = MouseState.NotPressed; - - Vector3 mousePos = DisplayManager.MousePosition; - - handledInstanceThisFrame = false; - foreach (PanelDragger instance in Instances) - { - if (!instance.Panel.gameObject.activeSelf) - continue; - - instance.Update(state, mousePos); - if (handledInstanceThisFrame) - break; - } - - if (wasAnyDragging && state == MouseState.NotPressed) - { - foreach (PanelDragger instance in Instances) - instance.WasDragging = false; - wasAnyDragging = false; - } - } - - #endregion - - // Instance - - public UIPanel UIPanel { get; private set; } - public bool AllowDragAndResize => UIPanel.CanDragAndResize; - - public RectTransform Panel { get; set; } - public event Action OnFinishResize; - public event Action OnFinishDrag; - - // Dragging - public RectTransform DragableArea { get; set; } - public bool WasDragging { get; set; } - private Vector2 lastDragPosition; - - // Resizing - private const int RESIZE_THICKNESS = 10; - - private bool WasResizing { get; set; } - private ResizeTypes currentResizeType = ResizeTypes.NONE; - private Vector2 lastResizePos; - - private bool WasHoveringResize => resizeCursorObj.activeInHierarchy; - - private ResizeTypes lastResizeHoverType; - - private Rect totalResizeRect; - - public PanelDragger(RectTransform dragArea, RectTransform panelToDrag, UIPanel panel) - { - this.UIPanel = panel; - Instances.Add(this); - DragableArea = dragArea; - Panel = panelToDrag; - - UpdateResizeCache(); - } - - public void Destroy() - { - if (resizeCursorObj) - GameObject.Destroy(resizeCursorObj); - - if (Instances.Contains(this)) - Instances.Remove(this); - } - - private void Update(MouseState state, Vector3 rawMousePos) - { - ResizeTypes type; - Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos); - bool inResizePos = !UIManager.NavBarRect.rect.Contains(UIManager.NavBarRect.InverseTransformPoint(rawMousePos)) - && MouseInResizeArea(resizePos); - - Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); - bool inDragPos = DragableArea.rect.Contains(dragPos); - - if (WasHoveringResize && resizeCursorObj) - UpdateHoverImagePos(); - - switch (state) - { - case MouseState.Down: - if (inDragPos || inResizePos) - UIManager.SetPanelActive(Panel, true); - - if (inDragPos) - { - if (AllowDragAndResize) - OnBeginDrag(); - handledInstanceThisFrame = true; - return; - } - else if (inResizePos) - { - type = GetResizeType(resizePos); - if (type != ResizeTypes.NONE) - OnBeginResize(type); - - handledInstanceThisFrame = true; - } - break; - - case MouseState.Held: - if (WasDragging) - { - OnDrag(); - handledInstanceThisFrame = true; - } - else if (WasResizing) - { - OnResize(); - handledInstanceThisFrame = true; - } - break; - - case MouseState.NotPressed: - if (AllowDragAndResize && inDragPos) - { - if (WasDragging) - OnEndDrag(); - - if (WasHoveringResize) - OnHoverResizeEnd(); - - handledInstanceThisFrame = true; - } - else if (inResizePos || WasResizing) - { - if (WasResizing) - OnEndResize(); - - type = GetResizeType(resizePos); - if (type != ResizeTypes.NONE) - OnHoverResize(type); - else if (WasHoveringResize) - OnHoverResizeEnd(); - - handledInstanceThisFrame = true; - } - else if (WasHoveringResize) - OnHoverResizeEnd(); - break; - } - - return; - } - - #region DRAGGING - - public void OnBeginDrag() - { - wasAnyDragging = true; - WasDragging = true; - lastDragPosition = DisplayManager.MousePosition; - } - - public void OnDrag() - { - Vector3 mousePos = DisplayManager.MousePosition; - - Vector2 diff = (Vector2)mousePos - lastDragPosition; - lastDragPosition = mousePos; - - Panel.localPosition = Panel.localPosition + (Vector3)diff; - - UIPanel.EnsureValidPosition(Panel); - } - - public void OnEndDrag() - { - WasDragging = false; - - OnFinishDrag?.Invoke(Panel); - } - - #endregion - - #region RESIZE - - private readonly Dictionary m_resizeMask = new() - { - { ResizeTypes.Top, default }, - { ResizeTypes.Left, default }, - { ResizeTypes.Right, default }, - { ResizeTypes.Bottom, default }, - }; - - [Flags] - public enum ResizeTypes : ulong - { - NONE = 0, - Top = 1, - Left = 2, - Right = 4, - Bottom = 8, - TopLeft = Top | Left, - TopRight = Top | Right, - BottomLeft = Bottom | Left, - BottomRight = Bottom | Right, - } - - // private const int HALF_THICKESS = RESIZE_THICKNESS / 2; - private const int DBL_THICKESS = RESIZE_THICKNESS * 2; - - private void UpdateResizeCache() - { - totalResizeRect = new Rect(Panel.rect.x - RESIZE_THICKNESS + 1, - Panel.rect.y - RESIZE_THICKNESS + 1, - Panel.rect.width + DBL_THICKESS - 2, - Panel.rect.height + DBL_THICKESS - 2); - - // calculate the four cross sections to use as flags - if (AllowDragAndResize) - { - m_resizeMask[ResizeTypes.Bottom] = new Rect( - totalResizeRect.x, - totalResizeRect.y, - totalResizeRect.width, - RESIZE_THICKNESS); - - m_resizeMask[ResizeTypes.Left] = new Rect( - totalResizeRect.x, - totalResizeRect.y, - RESIZE_THICKNESS, - totalResizeRect.height); - - m_resizeMask[ResizeTypes.Top] = new Rect( - totalResizeRect.x, - Panel.rect.y + Panel.rect.height - 2, - totalResizeRect.width, - RESIZE_THICKNESS); - - m_resizeMask[ResizeTypes.Right] = new Rect( - totalResizeRect.x + Panel.rect.width + RESIZE_THICKNESS - 2, - totalResizeRect.y, - RESIZE_THICKNESS, - totalResizeRect.height); - } - } - - private bool MouseInResizeArea(Vector2 mousePos) - { - return totalResizeRect.Contains(mousePos); - } - - private ResizeTypes GetResizeType(Vector2 mousePos) - { - // Calculate which part of the resize area we're in, if any. - // More readable method commented out below. - - int mask = 0; - mask |= (int)ResizeTypes.Top * (m_resizeMask[ResizeTypes.Top].Contains(mousePos) ? 1 : 0); - mask |= (int)ResizeTypes.Bottom * (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos) ? 1 : 0); - mask |= (int)ResizeTypes.Left * (m_resizeMask[ResizeTypes.Left].Contains(mousePos) ? 1 : 0); - mask |= (int)ResizeTypes.Right * (m_resizeMask[ResizeTypes.Right].Contains(mousePos) ? 1 : 0); - - //if (m_resizeMask[ResizeTypes.Top].Contains(mousePos)) - // mask |= ResizeTypes.Top; - //else if (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos)) - // mask |= ResizeTypes.Bottom; - - //if (m_resizeMask[ResizeTypes.Left].Contains(mousePos)) - // mask |= ResizeTypes.Left; - //else if (m_resizeMask[ResizeTypes.Right].Contains(mousePos)) - // mask |= ResizeTypes.Right; - - return (ResizeTypes)mask; - } - - public void OnHoverResize(ResizeTypes resizeType) - { - if (WasHoveringResize && lastResizeHoverType == resizeType) - return; - - // we are entering resize, or the resize type has changed. - - //WasHoveringResize = true; - lastResizeHoverType = resizeType; - - resizeCursorObj.SetActive(true); - resizeCursorObj.transform.SetAsLastSibling(); - - // set the rotation for the resize icon - float iconRotation = 0f; - switch (resizeType) - { - case ResizeTypes.TopRight: - case ResizeTypes.BottomLeft: - iconRotation = 45f; break; - case ResizeTypes.Top: - case ResizeTypes.Bottom: - iconRotation = 90f; break; - case ResizeTypes.TopLeft: - case ResizeTypes.BottomRight: - iconRotation = 135f; break; - } - - Quaternion rot = resizeCursorObj.transform.rotation; - rot.eulerAngles = new Vector3(0, 0, iconRotation); - resizeCursorObj.transform.rotation = rot; - - UpdateHoverImagePos(); - } - - // update the resize icon position to be above the mouse - private void UpdateHoverImagePos() - { - resizeCursorObj.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(DisplayManager.MousePosition); - } - - public void OnHoverResizeEnd() - { - //WasHoveringResize = false; - resizeCursorObj.SetActive(false); - } - - public void OnBeginResize(ResizeTypes resizeType) - { - currentResizeType = resizeType; - lastResizePos = DisplayManager.MousePosition; - WasResizing = true; - Resizing = true; - } - - public void OnResize() - { - Vector3 mousePos = DisplayManager.MousePosition; - Vector2 diff = lastResizePos - (Vector2)mousePos; - - if ((Vector2)mousePos == lastResizePos) - return; - - if (mousePos.x < 0 || mousePos.y < 0 || mousePos.x > DisplayManager.Width || mousePos.y > DisplayManager.Height) - return; - - lastResizePos = mousePos; - - float diffX = (float)((decimal)diff.x / DisplayManager.Width); - float diffY = (float)((decimal)diff.y / DisplayManager.Height); - - Vector2 anchorMin = Panel.anchorMin; - Vector2 anchorMax = Panel.anchorMax; - - if (currentResizeType.HasFlag(ResizeTypes.Left)) - anchorMin.x -= diffX; - else if (currentResizeType.HasFlag(ResizeTypes.Right)) - anchorMax.x -= diffX; - - if (currentResizeType.HasFlag(ResizeTypes.Top)) - anchorMax.y -= diffY; - else if (currentResizeType.HasFlag(ResizeTypes.Bottom)) - anchorMin.y -= diffY; - - Vector2 prevMin = Panel.anchorMin; - Vector2 prevMax = Panel.anchorMax; - - Panel.anchorMin = new Vector2(anchorMin.x, anchorMin.y); - Panel.anchorMax = new Vector2(anchorMax.x, anchorMax.y); - - if (Panel.rect.width < UIPanel.MinWidth) - { - Panel.anchorMin = new Vector2(prevMin.x, Panel.anchorMin.y); - Panel.anchorMax = new Vector2(prevMax.x, Panel.anchorMax.y); - } - if (Panel.rect.height < UIPanel.MinHeight) - { - Panel.anchorMin = new Vector2(Panel.anchorMin.x, prevMin.y); - Panel.anchorMax = new Vector2(Panel.anchorMax.x, prevMax.y); - } - } - - public void OnEndResize() - { - WasResizing = false; - Resizing = false; - try { OnHoverResizeEnd(); } catch { } - UpdateResizeCache(); - OnFinishResize?.Invoke(Panel); - } - - internal static void CreateCursorUI() - { - try - { - Text text = UIFactory.CreateLabel(UIManager.UIRoot, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35); - resizeCursorObj = text.gameObject; - Outline outline = text.gameObject.AddComponent(); - outline.effectColor = Color.black; - outline.effectDistance = new(1, 1); - - RectTransform rect = resizeCursorObj.GetComponent(); - rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64); - rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64); - - resizeCursorObj.SetActive(false); - } - catch (Exception e) - { - ExplorerCore.LogWarning("Exception creating Resize Cursor UI!\r\n" + e.ToString()); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/src/UI/Panels/UEPanel.cs b/src/UI/Panels/UEPanel.cs new file mode 100644 index 0000000..fd25dab --- /dev/null +++ b/src/UI/Panels/UEPanel.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using UnityEngine; +using UnityEngine.UI; +using UnityExplorer.Config; +using UniverseLib; +using UniverseLib.Input; +using UniverseLib.UI; +using UniverseLib.UI.Models; +using UniverseLib.UI.Panels; + +namespace UnityExplorer.UI.Panels +{ + public abstract class UEPanel : PanelBase + { + protected UEPanel(UIBase owner) : base(owner) { } + + public abstract UIManager.Panels PanelType { get; } + public virtual bool ShowByDefault => false; + public virtual bool ShouldSaveActiveState => true; + + public virtual bool NavButtonWanted => true; + public ButtonRef NavButton { get; internal set; } + + protected override PanelDragger CreatePanelDragger() + { + return new UEPanelDragger(this); + } + + public override void OnFinishDrag() + { + base.OnFinishDrag(); + SaveInternalData(); + } + + public override void OnFinishResize() + { + base.OnFinishResize(); + SaveInternalData(); + } + + public override void SetActive(bool active) + { + if (this.Enabled != active) + { + base.SetActive(active); + + if (!ApplyingSaveData) + SaveInternalData(); + + if (NavButtonWanted && NavButton != null) + { + Color color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor; + RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f); + } + } + + if (!active) + { + if (Dragger != null) + this.Dragger.WasDragging = false; + } + else + { + this.UIRoot.transform.SetAsLastSibling(); + (this.Owner.Panels as UEPanelManager).DoInvokeOnPanelsReordered(); + } + } + + // Save Data + + public bool ApplyingSaveData { get; set; } + + public void SaveInternalData() + { + if (UIManager.Initializing) + return; + + SetSaveDataToConfigValue(); + } + + private void SetSaveDataToConfigValue() => ConfigManager.GetPanelSaveData(this.PanelType).Value = this.ToSaveData(); + + public virtual string ToSaveData() + { + try + { + return string.Join("|", new string[] + { + $"{ShouldSaveActiveState && Enabled}", + Rect.RectAnchorsToString(), + Rect.RectPositionToString() + }); + } + catch (Exception ex) + { + ExplorerCore.LogWarning($"Exception generating Panel save data: {ex}"); + return ""; + } + } + + public virtual void ApplySaveData() + { + string data = ConfigManager.GetPanelSaveData(this.PanelType).Value; + ApplySaveData(data); + } + + protected virtual void ApplySaveData(string data) + { + if (string.IsNullOrEmpty(data)) + return; + + string[] split = data.Split('|'); + + try + { + Rect.SetAnchorsFromString(split[1]); + Rect.SetPositionFromString(split[2]); + this.SetActive(bool.Parse(split[0])); + } + catch + { + ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default."); + SetDefaultSizeAndPosition(); + SetSaveDataToConfigValue(); + } + } + + public override void ConstructUI() + { + base.ConstructUI(); + + if (NavButtonWanted) + { + // create navbar button + + NavButton = UIFactory.CreateButton(UIManager.NavbarTabButtonHolder, $"Button_{PanelType}", Name); + GameObject navBtn = NavButton.Component.gameObject; + navBtn.AddComponent().horizontalFit = ContentSizeFitter.FitMode.PreferredSize; + UIFactory.SetLayoutGroup(navBtn, false, true, true, true, 0, 0, 0, 5, 5, TextAnchor.MiddleCenter); + UIFactory.SetLayoutElement(navBtn, minWidth: 80); + + RuntimeHelper.SetColorBlock(NavButton.Component, UniversalUI.DisabledButtonColor, UniversalUI.DisabledButtonColor * 1.2f); + NavButton.OnClick += () => { UIManager.TogglePanel(PanelType); }; + + GameObject txtObj = navBtn.transform.Find("Text").gameObject; + txtObj.AddComponent().horizontalFit = ContentSizeFitter.FitMode.PreferredSize; + } + + this.SetActive(true); + this.SetActive(false); + this.SetActive(ShowByDefault); + } + + protected override void LateConstructUI() + { + base.LateConstructUI(); + + ApplyingSaveData = true; + // apply panel save data or revert to default + try + { + ApplySaveData(); + } + catch (Exception ex) + { + ExplorerCore.Log($"Exception loading panel save data: {ex}"); + SetDefaultSizeAndPosition(); + } + + // simple listener for saving enabled state + this.OnToggleEnabled += (bool val) => + { + SaveInternalData(); + }; + + ApplyingSaveData = false; + } + } + + #region WINDOW ANCHORS / POSITION SAVE DATA HELPERS + + public static class RectSaveExtensions + { + // Window Anchors helpers + + internal static string RectAnchorsToString(this RectTransform rect) + { + if (!rect) + throw new ArgumentNullException("rect"); + + return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", new object[] + { + rect.anchorMin.x, + rect.anchorMin.y, + rect.anchorMax.x, + rect.anchorMax.y + }); + } + + internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors) + { + if (string.IsNullOrEmpty(stringAnchors)) + throw new ArgumentNullException("stringAnchors"); + + if (stringAnchors.Contains(" ")) + // outdated save data, not worth recovering just reset it. + throw new Exception("invalid save data, resetting."); + + string[] split = stringAnchors.Split(','); + + if (split.Length != 4) + throw new Exception($"stringAnchors split is unexpected length: {split.Length}"); + + Vector4 anchors; + anchors.x = float.Parse(split[0], CultureInfo.InvariantCulture); + anchors.y = float.Parse(split[1], CultureInfo.InvariantCulture); + anchors.z = float.Parse(split[2], CultureInfo.InvariantCulture); + anchors.w = float.Parse(split[3], CultureInfo.InvariantCulture); + + panel.anchorMin = new Vector2(anchors.x, anchors.y); + panel.anchorMax = new Vector2(anchors.z, anchors.w); + } + + internal static string RectPositionToString(this RectTransform rect) + { + if (!rect) + throw new ArgumentNullException("rect"); + + return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[] + { + rect.anchoredPosition.x, rect.anchoredPosition.y + }); + } + + internal static void SetPositionFromString(this RectTransform rect, string stringPosition) + { + if (string.IsNullOrEmpty(stringPosition)) + throw new ArgumentNullException(stringPosition); + + if (stringPosition.Contains(" ")) + // outdated save data, not worth recovering just reset it. + throw new Exception("invalid save data, resetting."); + + string[] split = stringPosition.Split(','); + + if (split.Length != 2) + throw new Exception($"stringPosition split is unexpected length: {split.Length}"); + + Vector3 vector = rect.anchoredPosition; + vector.x = float.Parse(split[0], CultureInfo.InvariantCulture); + vector.y = float.Parse(split[1], CultureInfo.InvariantCulture); + rect.anchoredPosition = vector; + } + } + + #endregion +} diff --git a/src/UI/Panels/UEPanelDragger.cs b/src/UI/Panels/UEPanelDragger.cs new file mode 100644 index 0000000..725ee7a --- /dev/null +++ b/src/UI/Panels/UEPanelDragger.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using UnityExplorer.UI.Widgets.AutoComplete; +using UniverseLib.Input; +using UniverseLib.UI; +using UniverseLib.UI.Panels; +using UniverseLib.Utility; + +namespace UnityExplorer.UI.Panels +{ + public class UEPanelDragger : PanelDragger + { + public UEPanelDragger(PanelBase uiPanel) : base(uiPanel) { } + + protected override bool MouseInResizeArea(Vector2 mousePos) + { + return !UIManager.NavBarRect.rect.Contains(UIManager.NavBarRect.InverseTransformPoint(mousePos)) + && base.MouseInResizeArea(mousePos); + } + } +} diff --git a/src/UI/Panels/UIPanel.cs b/src/UI/Panels/UIPanel.cs deleted file mode 100644 index 7892002..0000000 --- a/src/UI/Panels/UIPanel.cs +++ /dev/null @@ -1,420 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using UnityEngine; -using UnityEngine.UI; -using UnityExplorer.Config; -using UniverseLib; -using UniverseLib.Input; -using UniverseLib.UI; -using UniverseLib.UI.Models; - -namespace UnityExplorer.UI.Panels -{ - public abstract class UIPanel : UIBehaviourModel - { - #region STATIC - - internal static void InvokeOnPanelsReordered() => OnPanelsReordered?.Invoke(); - - public static event Action OnPanelsReordered; - public static event Action OnClickedOutsidePanels; - - internal static readonly List instances = new(); - internal static readonly Dictionary transformToPanelDict = new(); - - public static void UpdateFocus() - { - if (PanelDragger.ResizePrompting) - return; - - // if the user is clicking - if (DisplayManager.MouseInTargetDisplay - && (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1))) - { - int count = UIManager.PanelHolder.transform.childCount; - Vector3 mousePos = DisplayManager.MousePosition; - bool clickedInAny = false; - - for (int i = count - 1; i >= 0; i--) - { - // make sure this is a real recognized panel - Transform transform = UIManager.PanelHolder.transform.GetChild(i); - if (!transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel)) - continue; - - // check if our mouse is clicking inside the panel - Vector3 pos = panel.Rect.InverseTransformPoint(mousePos); - if (!panel.Enabled || !panel.Rect.rect.Contains(pos)) - continue; - - // if this is not the top panel, reorder and invoke the onchanged event - if (transform.GetSiblingIndex() != count - 1) - { - transform.SetAsLastSibling(); - OnPanelsReordered?.Invoke(); - } - // panel was found, break - clickedInAny = true; - break; - } - - if (!clickedInAny) - OnClickedOutsidePanels?.Invoke(); - } - } - - #endregion - - // INSTANCE - - public UIPanel() - { - instances.Add(this); - } - - public abstract UIManager.Panels PanelType { get; } - public abstract string Name { get; } - public abstract int MinWidth { get; } - public abstract int MinHeight { get; } - - public virtual bool ShowByDefault => false; - public virtual bool ShouldSaveActiveState => true; - public virtual bool CanDragAndResize => true; - public virtual bool NavButtonWanted => true; - - public ButtonRef NavButton { get; internal set; } - public PanelDragger Dragger { get; internal set; } - - public override GameObject UIRoot => uiRoot; - protected GameObject uiRoot; - protected GameObject uiContent; - public RectTransform Rect { get; private set; } - public GameObject TitleBar { get; private set; } - - public virtual void OnFinishResize(RectTransform panel) - { - SaveInternalData(); - } - - public virtual void OnFinishDrag(RectTransform panel) - { - SaveInternalData(); - } - - public override void SetActive(bool active) - { - if (this.Enabled != active) - { - base.SetActive(active); - - if (!ApplyingSaveData) - SaveInternalData(); - - if (NavButtonWanted) - { - Color color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor; - RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f); - } - } - - if (!active) - this.Dragger.WasDragging = false; - else - { - this.UIRoot.transform.SetAsLastSibling(); - InvokeOnPanelsReordered(); - } - } - - public override void Destroy() - { - instances.Remove(this); - base.Destroy(); - } - - protected internal abstract void DoSetDefaultPosAndAnchors(); - - public void SetTransformDefaults() - { - DoSetDefaultPosAndAnchors(); - } - - public void EnsureValidSize() - { - if (Rect.rect.width < MinWidth) - Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth); - if (Rect.rect.height < MinHeight) - Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight); - } - - public void EnsureValidPosition() => EnsureValidPosition(this.Rect); - - public static void EnsureValidPosition(RectTransform panel) - { - Vector3 pos = panel.localPosition; - - // Prevent panel going oustide screen bounds - float halfW = DisplayManager.Width * 0.5f; - float halfH = DisplayManager.Height * 0.5f; - - pos.x = Math.Max(-halfW - panel.rect.width + 50, Math.Min(pos.x, halfW - 50)); - pos.y = Math.Max(-halfH + 50, Math.Min(pos.y, halfH)); - - panel.localPosition = pos; - } - - // Save Data - - public bool ApplyingSaveData { get; set; } - - public void SaveInternalData() - { - if (UIManager.Initializing) - return; - - SetSaveDataToConfigValue(); - } - - private void SetSaveDataToConfigValue() => ConfigManager.GetPanelSaveData(this.PanelType).Value = this.ToSaveData(); - - public virtual string ToSaveData() - { - try - { - return string.Join("|", new string[] - { - $"{ShouldSaveActiveState && Enabled}", - Rect.RectAnchorsToString(), - Rect.RectPositionToString() - }); - } - catch (Exception ex) - { - ExplorerCore.LogWarning($"Exception generating Panel save data: {ex}"); - return ""; - } - } - - public virtual void ApplySaveData() - { - string data = ConfigManager.GetPanelSaveData(this.PanelType).Value; - ApplySaveData(data); - } - - protected virtual void ApplySaveData(string data) - { - if (string.IsNullOrEmpty(data)) - return; - - string[] split = data.Split('|'); - - try - { - Rect.SetAnchorsFromString(split[1]); - Rect.SetPositionFromString(split[2]); - UIManager.SetPanelActive(this.PanelType, bool.Parse(split[0])); - } - catch - { - ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default."); - SetTransformDefaults(); - SetSaveDataToConfigValue(); - } - } - - // UI Construction - - public abstract void ConstructPanelContent(); - - public void ConstructUI() - { - //this.Enabled = true; - - if (NavButtonWanted) - { - // create navbar button - - NavButton = UIFactory.CreateButton(UIManager.NavbarTabButtonHolder, $"Button_{PanelType}", Name); - GameObject navBtn = NavButton.Component.gameObject; - navBtn.AddComponent().horizontalFit = ContentSizeFitter.FitMode.PreferredSize; - UIFactory.SetLayoutGroup(navBtn, false, true, true, true, 0, 0, 0, 5, 5, TextAnchor.MiddleCenter); - UIFactory.SetLayoutElement(navBtn, minWidth: 80); - - RuntimeHelper.SetColorBlock(NavButton.Component, UniversalUI.DisabledButtonColor, UniversalUI.DisabledButtonColor * 1.2f); - NavButton.OnClick += () => { UIManager.TogglePanel(PanelType); }; - - GameObject txtObj = navBtn.transform.Find("Text").gameObject; - txtObj.AddComponent().horizontalFit = ContentSizeFitter.FitMode.PreferredSize; - } - - // create core canvas - uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder, out uiContent); - Rect = this.uiRoot.GetComponent(); - //UIFactory.SetLayoutGroup(this.uiRoot, false, false, true, true, 0, 2, 2, 2, 2, TextAnchor.UpperLeft); - - int id = this.uiRoot.transform.GetInstanceID(); - transformToPanelDict.Add(id, this); - - UIFactory.SetLayoutGroup(this.uiContent, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft); - - // Title bar - TitleBar = UIFactory.CreateHorizontalGroup(uiContent, "TitleBar", false, true, true, true, 2, - new Vector4(2, 2, 2, 2), new Color(0.06f, 0.06f, 0.06f)); - UIFactory.SetLayoutElement(TitleBar, minHeight: 25, flexibleHeight: 0); - - // Title text - - Text titleTxt = UIFactory.CreateLabel(TitleBar, "TitleBar", Name, TextAnchor.MiddleLeft); - UIFactory.SetLayoutElement(titleTxt.gameObject, minWidth: 250, minHeight: 25, flexibleHeight: 0); - - // close button - - GameObject closeHolder = UIFactory.CreateUIObject("CloseHolder", TitleBar); - UIFactory.SetLayoutElement(closeHolder, minHeight: 25, flexibleHeight: 0, minWidth: 30, flexibleWidth: 9999); - UIFactory.SetLayoutGroup(closeHolder, false, false, true, true, 3, childAlignment: TextAnchor.MiddleRight); - ButtonRef closeBtn = UIFactory.CreateButton(closeHolder, "CloseButton", "—"); - UIFactory.SetLayoutElement(closeBtn.Component.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0); - RuntimeHelper.SetColorBlock(closeBtn.Component, new Color(0.33f, 0.32f, 0.31f)); - - closeBtn.OnClick += () => - { - UIManager.SetPanelActive(this.PanelType, false); - SaveInternalData(); - }; - - if (!CanDragAndResize) - TitleBar.SetActive(false); - - // Panel dragger - - Dragger = new PanelDragger(TitleBar.GetComponent(), Rect, this); - Dragger.OnFinishResize += OnFinishResize; - Dragger.OnFinishDrag += OnFinishDrag; - - // content (abstract) - - ConstructPanelContent(); - - UIManager.SetPanelActive(this.PanelType, true); - UIManager.SetPanelActive(this.PanelType, false); - UIManager.SetPanelActive(this.PanelType, ShowByDefault); - - ApplyingSaveData = true; - SetTransformDefaults(); - // apply panel save data or revert to default - try - { - ApplySaveData(); - } - catch (Exception ex) - { - ExplorerCore.Log($"Exception loading panel save data: {ex}"); - SetTransformDefaults(); - } - - RuntimeHelper.StartCoroutine(LateSetupCoroutine()); - - // simple listener for saving enabled state - this.OnToggleEnabled += (bool val) => - { - SaveInternalData(); - }; - - ApplyingSaveData = false; - } - - private IEnumerator LateSetupCoroutine() - { - yield return null; - - // ensure initialized position is valid - EnsureValidSize(); - EnsureValidPosition(this.Rect); - - // update dragger and save data - Dragger.OnEndResize(); - } - - public override void ConstructUI(GameObject parent) => ConstructUI(); - } - - #region WINDOW ANCHORS / POSITION HELPERS - - public static class RectSaveExtensions - { - // Window Anchors helpers - - internal static string RectAnchorsToString(this RectTransform rect) - { - if (!rect) - throw new ArgumentNullException("rect"); - - return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", new object[] - { - rect.anchorMin.x, - rect.anchorMin.y, - rect.anchorMax.x, - rect.anchorMax.y - }); - } - - internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors) - { - if (string.IsNullOrEmpty(stringAnchors)) - throw new ArgumentNullException("stringAnchors"); - - if (stringAnchors.Contains(" ")) - // outdated save data, not worth recovering just reset it. - throw new Exception("invalid save data, resetting."); - - string[] split = stringAnchors.Split(','); - - if (split.Length != 4) - throw new Exception($"stringAnchors split is unexpected length: {split.Length}"); - - Vector4 anchors; - anchors.x = float.Parse(split[0], CultureInfo.InvariantCulture); - anchors.y = float.Parse(split[1], CultureInfo.InvariantCulture); - anchors.z = float.Parse(split[2], CultureInfo.InvariantCulture); - anchors.w = float.Parse(split[3], CultureInfo.InvariantCulture); - - panel.anchorMin = new Vector2(anchors.x, anchors.y); - panel.anchorMax = new Vector2(anchors.z, anchors.w); - } - - internal static string RectPositionToString(this RectTransform rect) - { - if (!rect) - throw new ArgumentNullException("rect"); - - return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[] - { - rect.anchoredPosition.x, rect.anchoredPosition.y - }); - } - - internal static void SetPositionFromString(this RectTransform rect, string stringPosition) - { - if (string.IsNullOrEmpty(stringPosition)) - throw new ArgumentNullException(stringPosition); - - if (stringPosition.Contains(" ")) - // outdated save data, not worth recovering just reset it. - throw new Exception("invalid save data, resetting."); - - string[] split = stringPosition.Split(','); - - if (split.Length != 2) - throw new Exception($"stringPosition split is unexpected length: {split.Length}"); - - Vector3 vector = rect.anchoredPosition; - vector.x = float.Parse(split[0], CultureInfo.InvariantCulture); - vector.y = float.Parse(split[1], CultureInfo.InvariantCulture); - rect.anchoredPosition = vector; - } - } - - #endregion -} diff --git a/src/UI/UEPanelManager.cs b/src/UI/UEPanelManager.cs new file mode 100644 index 0000000..071444f --- /dev/null +++ b/src/UI/UEPanelManager.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityExplorer.UI.Panels; +using UniverseLib.UI; +using UniverseLib.UI.Panels; + +namespace UnityExplorer.UI +{ + public class UEPanelManager : PanelManager + { + public UEPanelManager(UIBase owner) : base(owner) { } + + protected override Vector3 MousePosition => DisplayManager.MousePosition; + + protected override Vector2 ScreenDimensions => new(DisplayManager.Width, DisplayManager.Height); + + protected override bool MouseInTargetDisplay => DisplayManager.MouseInTargetDisplay; + + internal void DoInvokeOnPanelsReordered() + { + InvokeOnPanelsReordered(); + } + + protected override void SortDraggerHeirarchy() + { + base.SortDraggerHeirarchy(); + + // move AutoCompleter to first update + if (!UIManager.Initializing && AutoCompleteModal.Instance != null) + { + this.draggerInstances.Remove(AutoCompleteModal.Instance.Dragger); + this.draggerInstances.Insert(0, AutoCompleteModal.Instance.Dragger); + } + } + } +} diff --git a/src/UI/UIManager.cs b/src/UI/UIManager.cs index 6c82ba4..190cab3 100644 --- a/src/UI/UIManager.cs +++ b/src/UI/UIManager.cs @@ -10,6 +10,7 @@ using UniverseLib; using UniverseLib.Input; using UniverseLib.UI; using UniverseLib.UI.Models; +using UniverseLib.UI.Panels; using UniverseLib.UI.Widgets.ScrollView; using UniverseLib.Utility; @@ -46,8 +47,7 @@ namespace UnityExplorer.UI public static RectTransform UIRootRect { get; private set; } public static Canvas UICanvas { get; private set; } - internal static GameObject PanelHolder { get; private set; } - internal static readonly Dictionary UIPanels = new(); + internal static readonly Dictionary UIPanels = new(); public static RectTransform NavBarRect; public static GameObject NavbarTabButtonHolder; @@ -79,7 +79,7 @@ namespace UnityExplorer.UI internal static void InitUI() { - UiBase = UniversalUI.RegisterUI(ExplorerCore.GUID, Update); + UiBase = UniversalUI.RegisterUI(ExplorerCore.GUID, Update); UIRootRect = UIRoot.GetComponent(); UICanvas = UIRoot.GetComponent(); @@ -91,31 +91,24 @@ namespace UnityExplorer.UI lastScreenHeight = display.renderingHeight; // Create UI. - CreatePanelHolder(); CreateTopNavBar(); // This could be automated with Assembly.GetTypes(), // but the order is important and I'd have to write something to handle the order. - 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.HookManager, new HookManagerPanel()); - UIPanels.Add(Panels.Clipboard, new ClipboardPanel()); - UIPanels.Add(Panels.ConsoleLog, new LogPanel()); - UIPanels.Add(Panels.Options, new OptionsPanel()); - UIPanels.Add(Panels.UIInspectorResults, new MouseInspectorResultsPanel()); - UIPanels.Add(Panels.MouseInspector, new MouseInspector()); - - foreach (UIPanel panel in UIPanels.Values) - panel.ConstructUI(); + UIPanels.Add(Panels.AutoCompleter, new AutoCompleteModal(UiBase)); + UIPanels.Add(Panels.ObjectExplorer, new ObjectExplorerPanel(UiBase)); + UIPanels.Add(Panels.Inspector, new InspectorPanel(UiBase)); + UIPanels.Add(Panels.CSConsole, new CSConsolePanel(UiBase)); + UIPanels.Add(Panels.HookManager, new HookManagerPanel(UiBase)); + UIPanels.Add(Panels.Clipboard, new ClipboardPanel(UiBase)); + UIPanels.Add(Panels.ConsoleLog, new LogPanel(UiBase)); + UIPanels.Add(Panels.Options, new OptionsPanel(UiBase)); + UIPanels.Add(Panels.UIInspectorResults, new MouseInspectorResultsPanel(UiBase)); + UIPanels.Add(Panels.MouseInspector, new MouseInspector(UiBase)); // Call some initialize methods Notification.Init(); ConsoleController.Init(); - // Add this listener to prevent ScrollPool doing anything while we are resizing panels - ScrollPool.writingLockedListeners.Add(() => !PanelDragger.Resizing); - // Set default menu visibility ShowMenu = !ConfigManager.Hide_On_Startup.Value; @@ -144,10 +137,6 @@ namespace UnityExplorer.UI if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Toggle.Value)) UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = !UniverseLib.Config.ConfigManager.Force_Unlock_Mouse; - // update focused panel - UIPanel.UpdateFocus(); - PanelDragger.UpdateInstances(); - // update the timescale value if (!timeInput.Component.isFocused && lastTimeScale != Time.timeScale) { @@ -172,33 +161,26 @@ namespace UnityExplorer.UI // Panels - public static UIPanel GetPanel(Panels panel) => UIPanels[panel]; + public static UEPanel GetPanel(Panels panel) => UIPanels[panel]; - public static T GetPanel(Panels panel) where T : UIPanel => (T)UIPanels[panel]; + public static T GetPanel(Panels panel) where T : UEPanel => (T)UIPanels[panel]; public static void TogglePanel(Panels panel) { - UIPanel uiPanel = GetPanel(panel); + UEPanel uiPanel = GetPanel(panel); SetPanelActive(panel, !uiPanel.Enabled); } public static void SetPanelActive(Panels panelType, bool active) { - GetPanel(panelType) - .SetActive(active); + GetPanel(panelType).SetActive(active); } - public static void SetPanelActive(UIPanel panel, bool active) + public static void SetPanelActive(UEPanel panel, bool active) { panel.SetActive(active); } - internal static void SetPanelActive(Transform transform, bool value) - { - if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel)) - panel.SetActive(value); - } - // navbar public static void SetNavBarAnchor() @@ -229,10 +211,10 @@ namespace UnityExplorer.UI lastScreenWidth = display.renderingWidth; lastScreenHeight = display.renderingHeight; - foreach (KeyValuePair panel in UIPanels) + foreach (KeyValuePair panel in UIPanels) { panel.Value.EnsureValidSize(); - UIPanel.EnsureValidPosition(panel.Value.Rect); + panel.Value.EnsureValidPosition(); panel.Value.Dragger.OnEndResize(); } } @@ -285,20 +267,6 @@ namespace UnityExplorer.UI // UI Construction - private static void CreatePanelHolder() - { - PanelHolder = new GameObject("PanelHolder"); - PanelHolder.transform.SetParent(UIRoot.transform, false); - PanelHolder.layer = 5; - RectTransform rect = PanelHolder.AddComponent(); - 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(); - } - private static void CreateTopNavBar() { GameObject navbarPanel = UIFactory.CreateUIObject("MainNavbar", UIRoot); diff --git a/src/UI/Widgets/AutoComplete/EnumCompleter.cs b/src/UI/Widgets/AutoComplete/EnumCompleter.cs index 9ef51ca..4460ede 100644 --- a/src/UI/Widgets/AutoComplete/EnumCompleter.cs +++ b/src/UI/Widgets/AutoComplete/EnumCompleter.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using UnityExplorer.CacheObject.IValues; +using UnityExplorer.UI.Panels; using UniverseLib.UI.Models; using UniverseLib.Utility; diff --git a/src/UI/Widgets/AutoComplete/TypeCompleter.cs b/src/UI/Widgets/AutoComplete/TypeCompleter.cs index e005ae2..3b36faa 100644 --- a/src/UI/Widgets/AutoComplete/TypeCompleter.cs +++ b/src/UI/Widgets/AutoComplete/TypeCompleter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using UnityExplorer.UI.Panels; using UniverseLib; using UniverseLib.UI.Models; using UniverseLib.Utility; diff --git a/src/UI/Widgets/UnityObjects/Texture2DWidget.cs b/src/UI/Widgets/UnityObjects/Texture2DWidget.cs index 6aac71b..f617d4a 100644 --- a/src/UI/Widgets/UnityObjects/Texture2DWidget.cs +++ b/src/UI/Widgets/UnityObjects/Texture2DWidget.cs @@ -103,7 +103,7 @@ namespace UnityExplorer.UI.Widgets image.sprite = sprite; } - private void OnInspectorFinishResize(RectTransform _) + private void OnInspectorFinishResize() { SetImageSize(); } diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj index 6d0fcbe..2a3bcfc 100644 --- a/src/UnityExplorer.csproj +++ b/src/UnityExplorer.csproj @@ -79,11 +79,11 @@ - + - +