From 23723a4ffd0de5c05f117b61a62298ba58cb10c9 Mon Sep 17 00:00:00 2001 From: sinaioutlander <49360850+sinaioutlander@users.noreply.github.com> Date: Wed, 30 Sep 2020 01:52:49 +1000 Subject: [PATCH] Some more unstrip fixes, and a few cleanups --- src/CachedObjects/CacheObjectBase.cs | 72 +- src/CachedObjects/Struct/CacheColor.cs | 8 +- src/CachedObjects/Struct/CacheEnum.cs | 2 +- src/CachedObjects/Struct/CacheEnumFlags.cs | 11 +- src/CachedObjects/Struct/CachePrimitive.cs | 4 +- src/CachedObjects/Struct/CacheQuaternion.cs | 6 +- src/CachedObjects/Struct/CacheRect.cs | 8 +- src/CachedObjects/Struct/CacheVector.cs | 8 +- src/Explorer.csproj | 12 +- src/ExplorerCore.cs | 2 +- src/Helpers/PageHelper.cs | 2 +- src/Menu/MainMenu/Pages/ConsolePage.cs | 2 +- src/Menu/MainMenu/Pages/ScenePage.cs | 9 +- src/Menu/MainMenu/Pages/SearchPage.cs | 4 +- src/Menu/ResizeDrag.cs | 45 +- src/Menu/Windows/GameObjectWindow.cs | 8 +- src/Menu/Windows/ReflectionWindow.cs | 2 +- src/Properties/AssemblyInfo.cs | 2 +- src/UnstripFixes/GUIUnstrip.cs | 523 +------------- src/UnstripFixes/Internal.cs | 674 ++++++++++++++++++ ...tyUnstrip.cs => Internal_LayoutUtility.cs} | 48 +- ...Unstrip.cs => Internal_ScrollViewState.cs} | 9 +- ...erUnstrip.cs => Internal_SliderHandler.cs} | 86 ++- src/UnstripFixes/Internal_SliderState.cs | 26 + src/UnstripFixes/UnstripExtensions.cs | 24 - 25 files changed, 924 insertions(+), 673 deletions(-) create mode 100644 src/UnstripFixes/Internal.cs rename src/UnstripFixes/{LayoutUtilityUnstrip.cs => Internal_LayoutUtility.cs} (59%) rename src/UnstripFixes/{ScrollViewStateUnstrip.cs => Internal_ScrollViewState.cs} (56%) rename src/UnstripFixes/{SliderHandlerUnstrip.cs => Internal_SliderHandler.cs} (78%) create mode 100644 src/UnstripFixes/Internal_SliderState.cs delete mode 100644 src/UnstripFixes/UnstripExtensions.cs diff --git a/src/CachedObjects/CacheObjectBase.cs b/src/CachedObjects/CacheObjectBase.cs index f257905..9b8e3d7 100644 --- a/src/CachedObjects/CacheObjectBase.cs +++ b/src/CachedObjects/CacheObjectBase.cs @@ -27,7 +27,7 @@ namespace Explorer public string RichTextName => m_richTextName ?? GetRichTextName(); private string m_richTextName; - public bool CanWrite => m_canWrite ?? (bool)(m_canWrite = GetCanWrite()); + public bool CanWrite => m_canWrite ?? GetCanWrite(); private bool? m_canWrite; public virtual void Init() { } @@ -114,51 +114,45 @@ namespace Explorer type = type.GetElementType(); } - if (string.IsNullOrEmpty(input)) + if (!string.IsNullOrEmpty(input)) { - // No input, see if there is a default value. - if (HasDefaultValue(m_arguments[i])) + if (type == typeof(string)) { - parsedArgs.Add(m_arguments[i].DefaultValue); + parsedArgs.Add(input); continue; } + else + { + try + { + var arg = type.GetMethod("Parse", new Type[] { typeof(string) }) + .Invoke(null, new object[] { input }); - // Try add a null arg I guess - parsedArgs.Add(null); + parsedArgs.Add(arg); + continue; + } + catch + { + ExplorerCore.Log($"Argument #{i} '{m_arguments[i].Name}' ({type.Name}), could not parse input '{input}'."); + } + } + } + + // No input, see if there is a default value. + if (HasDefaultValue(m_arguments[i])) + { + parsedArgs.Add(m_arguments[i].DefaultValue); continue; } - // strings can obviously just be used directly - if (type == typeof(string)) - { - parsedArgs.Add(input); - continue; - } - else - { - try - { - var arg = type.GetMethod("Parse", new Type[] { typeof(string) }) - .Invoke(null, new object[] { input }); - parsedArgs.Add(arg); - continue; - } - catch - { - ExplorerCore.Log($"Argument #{i} '{m_arguments[i].Name}' ({type.Name}), could not parse input '{input}'."); - } - } + // Try add a null arg I guess + parsedArgs.Add(null); } return parsedArgs.ToArray(); } - public static bool HasDefaultValue(ParameterInfo arg) => -#if NET35 - arg.DefaultValue != null; -#else - arg.HasDefaultValue; -#endif + public static bool HasDefaultValue(ParameterInfo arg) => arg.DefaultValue != DBNull.Value; // ========= Gui Draw ========== @@ -246,7 +240,7 @@ namespace Explorer $"{cm.GenericArgs[i].Name}", new GUILayoutOption[] { GUILayout.Width(15) } ); - cm.GenericArgInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); + cm.GenericArgInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUILayout.Label(types, new GUILayoutOption[0]); @@ -274,7 +268,7 @@ namespace Explorer GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) }); - m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); + m_argumentInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUILayout.Label(label, new GUILayoutOption[0]); @@ -350,11 +344,13 @@ namespace Explorer private bool GetCanWrite() { if (MemInfo is FieldInfo fi) - return !(fi.IsLiteral && !fi.IsInitOnly); + m_canWrite = !(fi.IsLiteral && !fi.IsInitOnly); else if (MemInfo is PropertyInfo pi) - return pi.CanWrite; + m_canWrite = pi.CanWrite; else - return false; + m_canWrite = false; + + return (bool)m_canWrite; } private string GetRichTextName() diff --git a/src/CachedObjects/Struct/CacheColor.cs b/src/CachedObjects/Struct/CacheColor.cs index b8726ef..2ce1191 100644 --- a/src/CachedObjects/Struct/CacheColor.cs +++ b/src/CachedObjects/Struct/CacheColor.cs @@ -64,25 +64,25 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) }); - r = GUILayout.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) }); + r = GUIUnstrip.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) }); - g = GUILayout.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) }); + g = GUIUnstrip.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) }); - b = GUILayout.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) }); + b = GUIUnstrip.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) }); - a = GUILayout.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) }); + a = GUIUnstrip.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); // draw set value button diff --git a/src/CachedObjects/Struct/CacheEnum.cs b/src/CachedObjects/Struct/CacheEnum.cs index f59f826..5de045c 100644 --- a/src/CachedObjects/Struct/CacheEnum.cs +++ b/src/CachedObjects/Struct/CacheEnum.cs @@ -10,7 +10,7 @@ namespace Explorer public class CacheEnum : CacheObjectBase { // public Type EnumType; - public string[] EnumNames; + public string[] EnumNames = new string[0]; public override void Init() { diff --git a/src/CachedObjects/Struct/CacheEnumFlags.cs b/src/CachedObjects/Struct/CacheEnumFlags.cs index 74b1ae3..de1316d 100644 --- a/src/CachedObjects/Struct/CacheEnumFlags.cs +++ b/src/CachedObjects/Struct/CacheEnumFlags.cs @@ -17,22 +17,21 @@ namespace Explorer { base.Init(); - if (ValueType != null) - { - m_enabledFlags = new bool[EnumNames.Length]; - - UpdateValue(); - } + UpdateValue(); } public override void UpdateValue() { base.UpdateValue(); + if (Value == null) return; + try { var enabledNames = Value.ToString().Split(',').Select(it => it.Trim()); + m_enabledFlags = new bool[EnumNames.Length]; + for (int i = 0; i < EnumNames.Length; i++) { m_enabledFlags[i] = enabledNames.Contains(EnumNames[i]); diff --git a/src/CachedObjects/Struct/CachePrimitive.cs b/src/CachedObjects/Struct/CachePrimitive.cs index bd66fef..07ec5f9 100644 --- a/src/CachedObjects/Struct/CachePrimitive.cs +++ b/src/CachedObjects/Struct/CachePrimitive.cs @@ -186,14 +186,14 @@ namespace Explorer } } - m_bitwiseOperatorInput = GUILayout.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) }); + m_bitwiseOperatorInput = GUIUnstrip.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) }); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.Label($"Binary:", new GUILayoutOption[] { GUILayout.Width(60) }); - m_binaryInput = GUILayout.TextField(m_binaryInput, new GUILayoutOption[0]); + m_binaryInput = GUIUnstrip.TextField(m_binaryInput, new GUILayoutOption[0]); if (CanWrite) { if (GUILayout.Button("Apply", new GUILayoutOption[0])) diff --git a/src/CachedObjects/Struct/CacheQuaternion.cs b/src/CachedObjects/Struct/CacheQuaternion.cs index 0a132bd..6b02684 100644 --- a/src/CachedObjects/Struct/CacheQuaternion.cs +++ b/src/CachedObjects/Struct/CacheQuaternion.cs @@ -59,19 +59,19 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); - x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); + x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); - y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); + y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) }); - z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); + z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); // draw set value button diff --git a/src/CachedObjects/Struct/CacheRect.cs b/src/CachedObjects/Struct/CacheRect.cs index 0df036e..4a69089 100644 --- a/src/CachedObjects/Struct/CacheRect.cs +++ b/src/CachedObjects/Struct/CacheRect.cs @@ -61,25 +61,25 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); - x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); + x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); - y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); + y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) }); - w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); + w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) }); - h = GUILayout.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) }); + h = GUIUnstrip.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); // draw set value button diff --git a/src/CachedObjects/Struct/CacheVector.cs b/src/CachedObjects/Struct/CacheVector.cs index 8056ec8..3f857b7 100644 --- a/src/CachedObjects/Struct/CacheVector.cs +++ b/src/CachedObjects/Struct/CacheVector.cs @@ -101,13 +101,13 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); - x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); + x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); - y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); + y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); if (VectorSize > 2) @@ -116,7 +116,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) }); - z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); + z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); } if (VectorSize > 3) @@ -125,7 +125,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.Space(whitespace); GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) }); - w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); + w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.EndHorizontal(); } diff --git a/src/Explorer.csproj b/src/Explorer.csproj index 53b12e8..7a8ffc6 100644 --- a/src/Explorer.csproj +++ b/src/Explorer.csproj @@ -11,6 +11,8 @@ 512 true + ..\Release\Explorer.MelonLoader.Il2Cpp\ + CPP,ML true true false @@ -25,6 +27,7 @@ Explorer D:\Steam\steamapps\common\Hellpoint + D:\Steam\steamapps\common\Outward @@ -241,8 +244,7 @@ - - + @@ -250,8 +252,8 @@ - - + + @@ -267,6 +269,8 @@ + + \ No newline at end of file diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index 0ab5217..496db89 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -5,7 +5,7 @@ namespace Explorer public class ExplorerCore { public const string NAME = "Explorer (" + PLATFORM + ", " + MODLOADER + ")"; - public const string VERSION = "1.8.0"; + public const string VERSION = "1.8.1"; public const string AUTHOR = "Sinai"; public const string GUID = "com.sinai.explorer"; diff --git a/src/Helpers/PageHelper.cs b/src/Helpers/PageHelper.cs index 2972e3d..efd6b4a 100644 --- a/src/Helpers/PageHelper.cs +++ b/src/Helpers/PageHelper.cs @@ -94,7 +94,7 @@ namespace Explorer { GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) }); var limit = this.ItemsPerPage.ToString(); - limit = GUILayout.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) }); + limit = GUIUnstrip.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) }); if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i)) { ItemsPerPage = i; diff --git a/src/Menu/MainMenu/Pages/ConsolePage.cs b/src/Menu/MainMenu/Pages/ConsolePage.cs index 3c74c3f..f5cd03f 100644 --- a/src/Menu/MainMenu/Pages/ConsolePage.cs +++ b/src/Menu/MainMenu/Pages/ConsolePage.cs @@ -165,7 +165,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) }); - UsingInput = GUILayout.TextField(UsingInput, new GUILayoutOption[] { GUILayout.Width(150) }); + UsingInput = GUIUnstrip.TextField(UsingInput, new GUILayoutOption[] { GUILayout.Width(150) }); if (GUILayout.Button("Add", new GUILayoutOption[] { GUILayout.Width(120) })) { AddUsing(UsingInput); diff --git a/src/Menu/MainMenu/Pages/ScenePage.cs b/src/Menu/MainMenu/Pages/ScenePage.cs index 4fdeeea..6328827 100644 --- a/src/Menu/MainMenu/Pages/ScenePage.cs +++ b/src/Menu/MainMenu/Pages/ScenePage.cs @@ -229,9 +229,12 @@ namespace Explorer GUILayout.EndVertical(); } - catch + catch (Exception e) { - // supress + if (!e.Message.Contains("in a group with only")) + { + ExplorerCore.Log(e.ToString()); + } } } @@ -250,7 +253,7 @@ namespace Explorer GUILayout.BeginHorizontal(GUIContent.none, GUI.skin.box, null); GUILayout.Label("Search Scene:", new GUILayoutOption[] { GUILayout.Width(100) }); - m_searchInput = GUILayout.TextField(m_searchInput, new GUILayoutOption[0]); + m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[0]); if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) })) { diff --git a/src/Menu/MainMenu/Pages/SearchPage.cs b/src/Menu/MainMenu/Pages/SearchPage.cs index a4ad4dd..0bc3818 100644 --- a/src/Menu/MainMenu/Pages/SearchPage.cs +++ b/src/Menu/MainMenu/Pages/SearchPage.cs @@ -175,7 +175,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) }); - m_searchInput = GUILayout.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) }); + m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) }); GUILayout.EndHorizontal(); @@ -193,7 +193,7 @@ namespace Explorer GUI.skin.label.alignment = TextAnchor.MiddleRight; GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) }); GUI.skin.label.alignment = TextAnchor.UpperLeft; - m_typeInput = GUILayout.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) }); + m_typeInput = GUIUnstrip.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) }); GUILayout.EndHorizontal(); } diff --git a/src/Menu/ResizeDrag.cs b/src/Menu/ResizeDrag.cs index 9c824da..bb8f6d2 100644 --- a/src/Menu/ResizeDrag.cs +++ b/src/Menu/ResizeDrag.cs @@ -8,7 +8,9 @@ namespace Explorer { public class ResizeDrag { +#if CPP private static bool RESIZE_FAILED = false; +#endif private static readonly GUIContent gcDrag = new GUIContent("<-- Drag to resize -->"); private static bool isResizing = false; @@ -17,6 +19,7 @@ namespace Explorer public static Rect ResizeWindow(Rect _rect, int ID) { +#if CPP if (!RESIZE_FAILED) { var origRect = _rect; @@ -26,18 +29,14 @@ namespace Explorer GUILayout.BeginHorizontal(GUIContent.none, GUI.skin.box, null); GUI.skin.label.alignment = TextAnchor.MiddleCenter; -#if CPP #if ML GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) }); #else GUILayout.Button(gcDrag.ToString(), new GUILayoutOption[] { GUILayout.Height(15) }); #endif -#else - GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) }); -#endif //var r = GUILayoutUtility.GetLastRect(); - var r = LayoutUtilityUnstrip.GetLastRect(); + var r = Internal_LayoutUtility.GetLastRect(); var mousePos = InputHelper.mousePosition; @@ -116,6 +115,42 @@ namespace Explorer GUI.skin.label.alignment = TextAnchor.UpperLeft; } +#else // mono + + GUILayout.BeginHorizontal(GUIContent.none, GUI.skin.box, null); + + GUI.skin.label.alignment = TextAnchor.MiddleCenter; + GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) }); + + //var r = GUILayoutUtility.GetLastRect(); + var r = GUILayoutUtility.GetLastRect(); + + var mousePos = InputHelper.mousePosition; + + var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y)); + if (r.Contains(mouse) && InputHelper.GetMouseButtonDown(0)) + { + isResizing = true; + m_currentWindow = ID; + m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height); + } + else if (!InputHelper.GetMouseButton(0)) + { + isResizing = false; + } + + if (isResizing && ID == m_currentWindow) + { + _rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x)); + _rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y)); + _rect.xMax = Mathf.Min(Screen.width, _rect.xMax); // modifying xMax affects width, not x + _rect.yMax = Mathf.Min(Screen.height, _rect.yMax); // modifying yMax affects height, not y + } + + GUILayout.EndHorizontal(); + +#endif + return _rect; } } diff --git a/src/Menu/Windows/GameObjectWindow.cs b/src/Menu/Windows/GameObjectWindow.cs index 74f9461..e853702 100644 --- a/src/Menu/Windows/GameObjectWindow.cs +++ b/src/Menu/Windows/GameObjectWindow.cs @@ -370,7 +370,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); var width = m_rect.width / 2 - 135f; - m_addComponentInput = GUILayout.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) }); + m_addComponentInput = GUIUnstrip.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) }); if (GUILayout.Button("Add Comp", new GUILayoutOption[0])) { if (ReflectionHelpers.GetTypeByName(m_addComponentInput) is Type compType) @@ -532,7 +532,7 @@ namespace Explorer GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); - m_setParentInput = GUILayout.TextField(m_setParentInput, new GUILayoutOption[0]); + m_setParentInput = GUIUnstrip.TextField(m_setParentInput, new GUILayoutOption[0]); if (GUILayout.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) })) { if (GameObject.Find(m_setParentInput) is GameObject newparent) @@ -682,7 +682,7 @@ namespace Explorer GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) }); var amountInput = amount.ToString("F3"); - amountInput = GUILayout.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) }); + amountInput = GUIUnstrip.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) }); if (float.TryParse(amountInput, out float f)) { amount = f; @@ -697,7 +697,7 @@ namespace Explorer private void PlusMinusFloat(ref float f, float amount, bool multByTime) { string s = f.ToString("F3"); - s = GUILayout.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) }); + s = GUIUnstrip.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) }); if (float.TryParse(s, out float f2)) { f = f2; diff --git a/src/Menu/Windows/ReflectionWindow.cs b/src/Menu/Windows/ReflectionWindow.cs index 84f43d7..b0a3909 100644 --- a/src/Menu/Windows/ReflectionWindow.cs +++ b/src/Menu/Windows/ReflectionWindow.cs @@ -272,7 +272,7 @@ namespace Explorer GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.Label("Search:", new GUILayoutOption[] { GUILayout.Width(75) }); - m_search = GUILayout.TextField(m_search, new GUILayoutOption[0]); + m_search = GUIUnstrip.TextField(m_search, new GUILayoutOption[0]); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(new GUILayoutOption[0]); diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index 89c2874..d607c6f 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -6,7 +6,7 @@ using Explorer; #if ML using MelonLoader; -[assembly: MelonInfo(typeof(ExplorerMelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)] +[assembly: MelonInfo(typeof(ExplorerMelonMod), "Explorer", ExplorerCore.VERSION, ExplorerCore.AUTHOR)] [assembly: MelonGame(null, null)] #endif diff --git a/src/UnstripFixes/GUIUnstrip.cs b/src/UnstripFixes/GUIUnstrip.cs index 673bfbf..ae0abed 100644 --- a/src/UnstripFixes/GUIUnstrip.cs +++ b/src/UnstripFixes/GUIUnstrip.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Reflection; using UnityEngine; #if CPP +using Explorer.UnstripInternals; using UnityEngineInternal; using UnhollowerRuntimeLib; #endif @@ -10,50 +12,14 @@ namespace Explorer { public class GUIUnstrip { -#if CPP - public static int s_ScrollControlId; - - public static bool ScrollFailed = false; - public static bool ManualUnstripFailed = false; - - private static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack(); - private static PropertyInfo m_scrollViewStatesInfo; - private static GenericStack m_scrollStack; - - public static DateTime nextScrollStepTime; - - private static MethodInfo ScreenToGuiPointMethod; - private static bool m_screenToGuiAttemped; - - private static MethodInfo m_bringWindowToFrontMethod; - private static bool m_bringWindowFrontAttempted; - - private static GenericStack GetScrollStack() + public static string TextField(string text, GUILayoutOption[] options) { - if (m_scrollViewStatesInfo == null) - { - if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo) - { - m_scrollViewStatesInfo = scrollStatesInfo; - } - else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo) - { - m_scrollViewStatesInfo = s_scrollStatesInfo; - } - } - - if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack) - { - m_scrollStack = stack; - } - else - { - m_scrollStack = new GenericStack(); - } - - return m_scrollStack; - } +#if CPP + return Internal.TextField(text, options); +#else + return GUIUnstrip.TextField(text, options); #endif + } public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title) { @@ -85,17 +51,7 @@ namespace Explorer public static void BringWindowToFront(int id) { #if CPP - - if (!m_bringWindowFrontAttempted) - { - m_bringWindowFrontAttempted = true; - m_bringWindowToFrontMethod = typeof(GUI).GetMethod("BringWindowToFront"); - } - if (m_bringWindowToFrontMethod == null) - { - throw new Exception("Couldn't get method 'GUIUtility.BringWindowToFront'!"); - } - m_bringWindowToFrontMethod.Invoke(null, new object[] { id }); + Internal.BringWindowToFront(id); #else GUI.BringWindowToFront(id); #endif @@ -104,16 +60,7 @@ namespace Explorer public static Vector2 ScreenToGUIPoint(Vector2 screenPoint) { #if CPP - if (!m_screenToGuiAttemped) - { - m_screenToGuiAttemped = true; - ScreenToGuiPointMethod = typeof(GUIUtility).GetMethod("ScreenToGUIPoint"); - } - if (ScreenToGuiPointMethod == null) - { - throw new Exception("Couldn't get method 'GUIUtility.ScreenToGUIPoint'!"); - } - return (Vector2)ScreenToGuiPointMethod.Invoke(null, new object[] { screenPoint }); + return Internal.ScreenToGUIPoint(screenPoint); #else return GUIUtility.ScreenToGUIPoint(screenPoint); #endif @@ -122,68 +69,28 @@ namespace Explorer public static void Space(float pixels) { #if CPP - if (GUILayoutUtility.current.topLevel.isVertical) - LayoutUtilityUnstrip.GetRect(0, pixels, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) }); - else - LayoutUtilityUnstrip.GetRect(pixels, 0, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) }); - - if (Event.current.type == EventType.Layout) - { - GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false; - } + Internal.Space(pixels); #else GUILayout.Space(pixels); #endif } - // fix for repeatbutton - #if CPP -#if ML - static public bool RepeatButton(Texture image, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), GUI.skin.button, options); } - static public bool RepeatButton(GUIContent content, params GUILayoutOption[] options) { return DoRepeatButton(content, GUI.skin.button, options); } - static public bool RepeatButton(Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), style, options); } - // Make a repeating button. The button returns true as long as the user holds down the mouse -#endif - static public bool RepeatButton(string text, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); } - static public bool RepeatButton(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(content, style, options); } - static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options) - { - return GUI.DoRepeatButton(LayoutUtilityUnstrip.GetRect(content, style, options), content, style, FocusType.Passive); + public static bool RepeatButton(string text, params GUILayoutOption[] options) + { + return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); } -#else // mono +#else public static bool RepeatButton(string text, params GUILayoutOption[] args) { return GUILayout.RepeatButton(text, args); } #endif - // Fix for BeginArea - #if CPP -#if ML - static public void BeginArea(Rect screenRect) { BeginArea(screenRect, GUIContent.none, GUIStyle.none); } - static public void BeginArea(Rect screenRect, string text) { BeginArea(screenRect, GUIContent.Temp(text), GUIStyle.none); } - static public void BeginArea(Rect screenRect, Texture image) { BeginArea(screenRect, GUIContent.Temp(image), GUIStyle.none); } - static public void BeginArea(Rect screenRect, GUIContent content) { BeginArea(screenRect, content, GUIStyle.none); } - static public void BeginArea(Rect screenRect, string text, GUIStyle style) { BeginArea(screenRect, GUIContent.Temp(text), style); } - static public void BeginArea(Rect screenRect, Texture image, GUIStyle style) { BeginArea(screenRect, GUIContent.Temp(image), style); } -#endif - - static public void BeginArea(Rect screenRect, GUIStyle style) { BeginArea(screenRect, GUIContent.none, style); } - - static public void BeginArea(Rect screenRect, GUIContent content, GUIStyle style) + public static void BeginArea(Rect screenRect, GUIStyle style) { - GUILayoutGroup g = GUILayoutUtility.BeginLayoutArea(style, Il2CppType.Of()); - if (Event.current.type == EventType.Layout) - { - g.resetCoords = true; - g.minWidth = g.maxWidth = screenRect.width; - g.minHeight = g.maxHeight = screenRect.height; - g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax); - } - - GUI.BeginGroup(g.rect, content, style); + Internal.BeginArea(screenRect, GUIContent.none, style); } #else public static void BeginArea(Rect rect, GUIStyle skin) @@ -192,15 +99,10 @@ namespace Explorer } #endif - // Close a GUILayout block started with BeginArea #if CPP static public void EndArea() { - if (Event.current.type == EventType.Used) - return; - GUILayoutUtility.current.layoutGroups.Pop(); - GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast(); - GUI.EndGroup(); + Internal.EndArea(); } #else public static void EndArea() @@ -209,401 +111,16 @@ namespace Explorer } #endif - // Fix for BeginGroup - -#if CPP -#if ML - public static void BeginGroup(Rect position) { BeginGroup(position, GUIContent.none, GUIStyle.none); } - public static void BeginGroup(Rect position, string text) { BeginGroup(position, GUIContent.Temp(text), GUIStyle.none); } - public static void BeginGroup(Rect position, Texture image) { BeginGroup(position, GUIContent.Temp(image), GUIStyle.none); } - public static void BeginGroup(Rect position, GUIContent content) { BeginGroup(position, content, GUIStyle.none); } - public static void BeginGroup(Rect position, GUIStyle style) { BeginGroup(position, GUIContent.none, style); } - public static void BeginGroup(Rect position, string text, GUIStyle style) { BeginGroup(position, GUIContent.Temp(text), style); } - public static void BeginGroup(Rect position, Texture image, GUIStyle style) { BeginGroup(position, GUIContent.Temp(image), style); } - -#endif - public static void BeginGroup(Rect position, GUIContent content, GUIStyle style) { BeginGroup(position, content, style, Vector2.zero); } - - internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset) - { - int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive); - - if (content != GUIContent.none || style != GUIStyle.none) - { - switch (Event.current.type) - { - case EventType.Repaint: - style.Draw(position, content, id); - break; - default: - if (position.Contains(Event.current.mousePosition)) - GUIUtility.mouseUsed = true; - break; - } - } - GUIClip.Push(position, scrollOffset, Vector2.zero, false); - } -#else - public static void BeginGroup(Rect rect, GUIStyle style) - { - GUI.BeginGroup(rect, style); - } -#endif - -#if CPP - public static void EndGroup() - { - GUIClip.Internal_Pop(); - } -#else - public static void EndGroup() - { - GUI.EndGroup(); - } -#endif - - // Fix for BeginScrollView. #if CPP public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) { - // First, just try normal way, may not have been stripped or was unstripped successfully. - if (!ScrollFailed) - { - try - { - return GUILayout.BeginScrollView(scroll, options); - } - catch - { - ScrollFailed = true; - } - } - - // Try manual implementation. - if (!ManualUnstripFailed) - { - try - { - return BeginScrollView_ImplLayout(scroll, false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.scrollView, options); - } - catch (Exception e) - { - ExplorerCore.Log("Exception on manual BeginScrollView: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); - ManualUnstripFailed = true; - } - } - - // Sorry! No scrolling for you. - return scroll; + return Internal.BeginScrollView(scroll, options); } public static void EndScrollView(bool handleScrollWheel = true) { - // Only end the scroll view for the relevant BeginScrollView option, if any. - - if (!ScrollFailed) - { - GUILayout.EndScrollView(); - } - else if (!ManualUnstripFailed) - { - GUILayoutUtility.EndLayoutGroup(); - - EndScrollView_Impl(handleScrollWheel); - } - } - - private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, - GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options) - { - var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of()) - .TryCast(); - - EventType type = Event.current.type; - if (type == EventType.Layout) - { - guiscrollGroup.resetCoords = true; - guiscrollGroup.isVertical = true; - guiscrollGroup.stretchWidth = 1; - guiscrollGroup.stretchHeight = 1; - guiscrollGroup.verticalScrollbar = verticalScrollbar; - guiscrollGroup.horizontalScrollbar = horizontalScrollbar; - guiscrollGroup.needsVerticalScrollbar = alwaysShowVertical; - guiscrollGroup.needsHorizontalScrollbar = alwaysShowHorizontal; - guiscrollGroup.ApplyOptions(options); - } - - return BeginScrollView_Impl(guiscrollGroup.rect, - scrollPosition, - new Rect(0f, 0f, guiscrollGroup.clientWidth, guiscrollGroup.clientHeight), - alwaysShowHorizontal, - alwaysShowVertical, - horizontalScrollbar, - verticalScrollbar, - background - ); - } - - private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, - bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background) - { - // GUIUtility.CheckOnGUI(); - - int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive); - - var scrollViewState = GUIUtility.GetStateObject(Il2CppType.Of(), controlID).TryCast(); - - var scrollExt = ScrollViewStateUnstrip.FromPointer(scrollViewState.Pointer); - - if (scrollExt == null) throw new Exception($"Could not get scrollExt for pointer '{scrollViewState.Pointer}'!"); - - bool apply = scrollExt.apply; - if (apply) - { - scrollPosition = scrollExt.scrollPosition; - scrollExt.apply = false; - } - - scrollExt.position = position; - - scrollExt.scrollPosition = scrollPosition; - scrollExt.visibleRect = scrollExt.viewRect = viewRect; - - var rect = scrollExt.visibleRect; - rect.width = position.width; - rect.height = position.height; - - ScrollStack.Push(scrollViewState); - - Rect screenRect = new Rect(position.x, position.y, position.width, position.height); - EventType type = Event.current.type; - if (type != EventType.Layout) - { - if (type != EventType.Used) - { - bool flag = alwaysShowVertical; - bool flag2 = alwaysShowHorizontal; - if (flag2 || viewRect.width > screenRect.width) - { - rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; - - screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; - flag2 = true; - } - if (flag || viewRect.height > screenRect.height) - { - rect.width = position.width - verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left; - - screenRect.width -= verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left; - flag = true; - if (!flag2 && viewRect.width > screenRect.width) - { - rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; - screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; - flag2 = true; - } - } - if (Event.current.type == EventType.Repaint && background != GUIStyle.none) - { - background.Draw(position, position.Contains(Event.current.mousePosition), false, flag2 && flag, false); - } - if (flag2 && horizontalScrollbar != GUIStyle.none) - { - scrollPosition.x = HorizBar_Impl( - new Rect( - position.x, - position.yMax - horizontalScrollbar.fixedHeight, - screenRect.width, - horizontalScrollbar.fixedHeight), - scrollPosition.x, - Mathf.Min(screenRect.width, viewRect.width), - 0f, - viewRect.width, - horizontalScrollbar - ); - } - else - { - GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - scrollPosition.x = ((horizontalScrollbar == GUIStyle.none) ? Mathf.Clamp(scrollPosition.x, 0f, Mathf.Max(viewRect.width - position.width, 0f)) : 0f); - } - if (flag && verticalScrollbar != GUIStyle.none) - { - scrollPosition.y = VertBar_Impl( - new Rect( - screenRect.xMax + (float)verticalScrollbar.margin.left, - screenRect.y, - verticalScrollbar.fixedWidth, - screenRect.height), - scrollPosition.y, - Mathf.Min(screenRect.height, viewRect.height), - 0f, - viewRect.height, - verticalScrollbar - ); - } - else - { - GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - scrollPosition.y = ((verticalScrollbar == GUIStyle.none) ? Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(viewRect.height - position.height, 0f)) : 0f); - } - } - } - else - { - GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); - } - GUIClip.Push(screenRect, new Vector2(Mathf.Round(-scrollPosition.x - viewRect.x), Mathf.Round(-scrollPosition.y - viewRect.y)), Vector2.zero, false); - - return scrollPosition; - } - - public static float HorizBar_Impl(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style) - { - return Scroller_Impl(position, value, size, leftValue, rightValue, style, - GUI.skin.GetStyle(style.name + "thumb"), - GUI.skin.GetStyle(style.name + "leftbutton"), - GUI.skin.GetStyle(style.name + "rightbutton"), - true); - } - - public static float VertBar_Impl(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style) - { - return Scroller_Impl(position, value, size, topValue, bottomValue, style, - GUI.skin.GetStyle(style.name + "thumb"), - GUI.skin.GetStyle(style.name + "upbutton"), - GUI.skin.GetStyle(style.name + "downbutton"), - false); - } - - private static void EndScrollView_Impl(bool handleScrollWheel) - { - GUIUtility.CheckOnGUI(); - - if (ScrollStack.Count <= 0) return; - - var state = ScrollStack.Peek().TryCast(); - var scrollExt = ScrollViewStateUnstrip.FromPointer(state.Pointer); - - if (scrollExt == null) throw new Exception("Could not get scrollExt!"); - - GUIClip.Pop(); - - ScrollStack.Pop(); - - var position = scrollExt.position; - - if (handleScrollWheel && Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition)) - { - var pos = scrollExt.scrollPosition; - pos.x = Mathf.Clamp(scrollExt.scrollPosition.x + Event.current.delta.x * 20f, 0f, scrollExt.viewRect.width - scrollExt.visibleRect.width); - pos.y = Mathf.Clamp(scrollExt.scrollPosition.y + Event.current.delta.y * 20f, 0f, scrollExt.viewRect.height - scrollExt.visibleRect.height); - - if (scrollExt.scrollPosition.x < 0f) - { - pos.x = 0f; - } - if (pos.y < 0f) - { - pos.y = 0f; - } - - scrollExt.apply = true; - - Event.current.Use(); - } - } - - private static float Scroller_Impl(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz) - { - GUIUtility.CheckOnGUI(); - int controlID = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position); - Rect position2; - Rect rect; - Rect rect2; - if (horiz) - { - position2 = new Rect(position.x + leftButton.fixedWidth, position.y, position.width - leftButton.fixedWidth - rightButton.fixedWidth, position.height); - rect = new Rect(position.x, position.y, leftButton.fixedWidth, position.height); - rect2 = new Rect(position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height); - } - else - { - position2 = new Rect(position.x, position.y + leftButton.fixedHeight, position.width, position.height - leftButton.fixedHeight - rightButton.fixedHeight); - rect = new Rect(position.x, position.y, position.width, leftButton.fixedHeight); - rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight); - } - - value = Slider_Impl(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID); - - bool flag = Event.current.type == EventType.MouseUp; - if (ScrollerRepeatButton_Impl(controlID, rect, leftButton)) - { - value -= 10f * ((leftValue >= rightValue) ? -1f : 1f); - } - if (ScrollerRepeatButton_Impl(controlID, rect2, rightButton)) - { - value += 10f * ((leftValue >= rightValue) ? -1f : 1f); - } - if (flag && Event.current.type == EventType.Used) - { - s_ScrollControlId = 0; - } - if (leftValue < rightValue) - { - value = Mathf.Clamp(value, leftValue, rightValue - size); - } - else - { - value = Mathf.Clamp(value, rightValue, leftValue - size); - } - return value; - } - - public static float Slider_Impl(Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id) - { - if (id == 0) - { - id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position); - } - var sliderHandler = new SliderHandlerUnstrip(position, value, size, start, end, slider, thumb, horiz, id); - return sliderHandler.Handle(); - } - - private static bool ScrollerRepeatButton_Impl(int scrollerID, Rect rect, GUIStyle style) - { - bool result = false; - if (GUI.DoRepeatButton(rect, GUIContent.none, style, FocusType.Passive)) - { - bool flag = s_ScrollControlId != scrollerID; - s_ScrollControlId = scrollerID; - - if (flag) - { - result = true; - nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0); - } - else if (DateTime.Now >= nextScrollStepTime) - { - result = true; - nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0); - } - if (Event.current.type == EventType.Repaint) - { - GUI.InternalRepaintEditorWindow(); - } - } - return result; + Internal.EndScrollView(handleScrollWheel); } #else public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) diff --git a/src/UnstripFixes/Internal.cs b/src/UnstripFixes/Internal.cs new file mode 100644 index 0000000..ba33e34 --- /dev/null +++ b/src/UnstripFixes/Internal.cs @@ -0,0 +1,674 @@ +#if CPP +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngineInternal; +using UnhollowerRuntimeLib; + +namespace Explorer.UnstripInternals +{ + public class Internal + { + #region Properties + public static int s_ScrollControlId; + + public static bool ScrollFailed = false; + public static bool ManualUnstripFailed = false; + + public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack(); + public static PropertyInfo m_scrollViewStatesInfo; + public static GenericStack m_scrollStack; + + public static Dictionary StateCache => m_stateCacheDict ?? GetStateCacheDict(); + public static Dictionary m_stateCacheDict; + + public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle(); + public static GUIStyle m_spaceStyle; + + public static DateTime nextScrollStepTime; + + public static MethodInfo ScreenToGuiPointMethod; + public static bool m_screenToGuiAttemped; + + public static MethodInfo m_bringWindowToFrontMethod; + public static bool m_bringWindowFrontAttempted; + + private static GenericStack GetScrollStack() + { + if (m_scrollViewStatesInfo == null) + { + if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo) + { + m_scrollViewStatesInfo = scrollStatesInfo; + } + else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo) + { + m_scrollViewStatesInfo = s_scrollStatesInfo; + } + } + + if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack) + { + m_scrollStack = stack; + } + else + { + m_scrollStack = new GenericStack(); + } + + return m_scrollStack; + } + + private static Dictionary GetStateCacheDict() + { + if (m_stateCacheDict == null) + { + try + { + var type = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects"); + m_stateCacheDict = type.GetProperty("s_StateCache") + .GetValue(null, null) + as Dictionary; + + if (m_stateCacheDict == null) throw new Exception(); + } + catch + { + m_stateCacheDict = new Dictionary(); + } + } + return m_stateCacheDict; + } + + private static GUIStyle GetSpaceStyle() + { + try + { + m_spaceStyle = typeof(GUILayoutUtility) + .GetProperty("s_SpaceStyle") + .GetValue(null, null) + .Il2CppCast(typeof(GUIStyle)) + as GUIStyle; + + if (m_spaceStyle == null) throw new Exception(); + } + catch { } + + if (m_spaceStyle == null) + { + m_spaceStyle = new GUIStyle(); + } + m_spaceStyle.stretchWidth = false; + return m_spaceStyle; + } + + #endregion + + #region GUILayout Methods + + public static string TextField(string text, GUILayoutOption[] options) + { + int controlID = GUIUtility.GetControlID(FocusType.Keyboard); + GUIContent guicontent = GUIContent.Temp(text); + bool flag = GUIUtility.keyboardControl != controlID; + if (flag) + { + guicontent = GUIContent.Temp(text); + } + else + { + guicontent = GUIContent.Temp(text); + // guicontent = GUIContent.Temp(text + GUIUtility.compositionString); + } + Rect rect = Internal_LayoutUtility.GetRect(guicontent, GUI.skin.textField, options); + bool flag2 = GUIUtility.keyboardControl == controlID; + if (flag2) + { + guicontent = GUIContent.Temp(text); + } + DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField); + return guicontent.text; + } + + internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style) + { + if (GetStateObject(Il2CppType.Of(), id).TryCast() is TextEditor textEditor) + { + if (maxLength >= 0 && content.text.Length > maxLength) + { + content.text = content.text.Substring(0, maxLength); + } + textEditor.m_Content.text = content.text; + textEditor.SaveBackup(); + textEditor.position = position; + textEditor.style = style; + textEditor.multiline = multiline; + textEditor.controlID = id; + textEditor.DetectFocusChange(); + GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor); + textEditor.UpdateScrollOffsetIfNeeded(Event.current); + } + } + + public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options) + { + return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive); + } + + public static void Space(float pixels) + { + if (GUILayoutUtility.current.topLevel.isVertical) + Internal_LayoutUtility.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) }); + else + Internal_LayoutUtility.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) }); + + if (Event.current.type == EventType.Layout) + { + GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false; + } + } + + public static Vector2 ScreenToGUIPoint(Vector2 screenPoint) + { + if (!m_screenToGuiAttemped) + { + m_screenToGuiAttemped = true; + ScreenToGuiPointMethod = typeof(GUIUtility).GetMethod("ScreenToGUIPoint"); + } + if (ScreenToGuiPointMethod == null) + { + throw new Exception("Couldn't get method 'GUIUtility.ScreenToGUIPoint'!"); + } + return (Vector2)ScreenToGuiPointMethod.Invoke(null, new object[] { screenPoint }); + } + + public static void BringWindowToFront(int id) + { + if (!m_bringWindowFrontAttempted) + { + m_bringWindowFrontAttempted = true; + m_bringWindowToFrontMethod = typeof(GUI).GetMethod("BringWindowToFront"); + } + if (m_bringWindowToFrontMethod == null) + { + throw new Exception("Couldn't get method 'GUIUtility.BringWindowToFront'!"); + } + m_bringWindowToFrontMethod.Invoke(null, new object[] { id }); + } + + public static void BeginArea(Rect screenRect, GUIContent content, GUIStyle style) + { + var g = BeginLayoutArea(style, typeof(GUILayoutGroup)); + if (Event.current.type == EventType.Layout) + { + g.resetCoords = true; + g.minWidth = g.maxWidth = screenRect.width; + g.minHeight = g.maxHeight = screenRect.height; + g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax); + } + + BeginGroup(g.rect, content, style); + } + + internal static GUILayoutGroup BeginLayoutArea(GUIStyle style, Type layoutType) + { + EventType type = Event.current.type; + GUILayoutGroup guilayoutGroup; + if (type != EventType.Used && type != EventType.Layout) + { + guilayoutGroup = GUILayoutUtility.current.windows.GetNext().TryCast(); + guilayoutGroup.ResetCursor(); + } + else + { + guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType); + guilayoutGroup.style = style; + GUILayoutUtility.current.windows.Add(guilayoutGroup); + } + GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup); + GUILayoutUtility.current.topLevel = guilayoutGroup; + return guilayoutGroup; + } + + public static void BeginGroup(Rect position, GUIContent content, GUIStyle style) + { + BeginGroup(position, content, style, Vector2.zero); + } + + internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset) + { + int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive); + + if (content != GUIContent.none || style != GUIStyle.none) + { + switch (Event.current.type) + { + case EventType.Repaint: + style.Draw(position, content, id); + break; + default: + if (position.Contains(Event.current.mousePosition)) + GUIUtility.mouseUsed = true; + break; + } + } + GUIClip.Push(position, scrollOffset, Vector2.zero, false); + } + + public static void EndArea() + { + if (Event.current.type == EventType.Used) + return; + GUILayoutUtility.current.layoutGroups.Pop(); + GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast(); + GUI.EndGroup(); + } + +#endregion + +#region Scrolling + + private static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID) + { + Il2CppSystem.Object obj; + if (StateCache.ContainsKey(controlID)) + { + obj = StateCache[controlID]; + } + else + { + obj = Il2CppSystem.Activator.CreateInstance(type); + StateCache.Add(controlID, obj); + } + + return obj; + } + + public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) + { + // First, just try normal way, may not have been stripped or was unstripped successfully. + if (!ScrollFailed) + { + try + { + return GUILayout.BeginScrollView(scroll, options); + } + catch + { + ScrollFailed = true; + } + } + + // Try manual implementation. + if (!ManualUnstripFailed) + { + try + { + return BeginScrollView_ImplLayout(scroll, + false, + false, + GUI.skin.horizontalScrollbar, + GUI.skin.verticalScrollbar, + GUI.skin.scrollView, + options); + } + catch (Exception e) + { + ExplorerCore.Log("Exception on manual BeginScrollView: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); + ManualUnstripFailed = true; + } + } + + // Sorry! No scrolling for you. + return scroll; + } + + internal static void EndScrollView(bool handleScrollWheel) + { + // Only end the scroll view for the relevant BeginScrollView option, if any. + + if (!ScrollFailed) + { + GUILayout.EndScrollView(); + } + else if (!ManualUnstripFailed) + { + GUILayoutUtility.EndLayoutGroup(); + + if (ScrollStack.Count <= 0) return; + + var state = ScrollStack.Peek().TryCast(); + var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer); + + if (scrollExt == null) throw new Exception("Could not get scrollExt!"); + + GUIClip.Pop(); + + ScrollStack.Pop(); + + var position = scrollExt.position; + + if (handleScrollWheel && Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition)) + { + var pos = scrollExt.scrollPosition; + pos.x = Mathf.Clamp(scrollExt.scrollPosition.x + Event.current.delta.x * 20f, 0f, scrollExt.viewRect.width - scrollExt.visibleRect.width); + pos.y = Mathf.Clamp(scrollExt.scrollPosition.y + Event.current.delta.y * 20f, 0f, scrollExt.viewRect.height - scrollExt.visibleRect.height); + + if (scrollExt.scrollPosition.x < 0f) + { + pos.x = 0f; + } + if (pos.y < 0f) + { + pos.y = 0f; + } + + scrollExt.apply = true; + + Event.current.Use(); + } + } + } + + private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, + GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options) + { + var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of()) + .TryCast(); + + EventType type = Event.current.type; + if (type == EventType.Layout) + { + guiscrollGroup.resetCoords = true; + guiscrollGroup.isVertical = true; + guiscrollGroup.stretchWidth = 1; + guiscrollGroup.stretchHeight = 1; + guiscrollGroup.verticalScrollbar = verticalScrollbar; + guiscrollGroup.horizontalScrollbar = horizontalScrollbar; + guiscrollGroup.needsVerticalScrollbar = alwaysShowVertical; + guiscrollGroup.needsHorizontalScrollbar = alwaysShowHorizontal; + guiscrollGroup.ApplyOptions(options); + } + + return BeginScrollView_Impl(guiscrollGroup.rect, + scrollPosition, + new Rect(0f, 0f, guiscrollGroup.clientWidth, guiscrollGroup.clientHeight), + alwaysShowHorizontal, + alwaysShowVertical, + horizontalScrollbar, + verticalScrollbar, + background + ); + } + + private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, + bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background) + { + // GUIUtility.CheckOnGUI(); + + int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive); + + var scrollViewState = GetStateObject(Il2CppType.Of(), controlID) + .TryCast(); + + if (scrollViewState == null) + return scrollPosition; + + var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer); + + if (scrollExt == null) + return scrollPosition; + + bool apply = scrollExt.apply; + if (apply) + { + scrollPosition = scrollExt.scrollPosition; + scrollExt.apply = false; + } + + scrollExt.position = position; + + scrollExt.scrollPosition = scrollPosition; + scrollExt.visibleRect = scrollExt.viewRect = viewRect; + + var rect = scrollExt.visibleRect; + rect.width = position.width; + rect.height = position.height; + + ScrollStack.Push(scrollViewState); + + Rect screenRect = new Rect(position.x, position.y, position.width, position.height); + EventType type = Event.current.type; + if (type != EventType.Layout) + { + if (type != EventType.Used) + { + bool flag = alwaysShowVertical; + bool flag2 = alwaysShowHorizontal; + if (flag2 || viewRect.width > screenRect.width) + { + rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; + + screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; + flag2 = true; + } + if (flag || viewRect.height > screenRect.height) + { + rect.width = position.width - verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left; + + screenRect.width -= verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left; + flag = true; + if (!flag2 && viewRect.width > screenRect.width) + { + rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; + screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top; + flag2 = true; + } + } + if (Event.current.type == EventType.Repaint && background != GUIStyle.none) + { + background.Draw(position, position.Contains(Event.current.mousePosition), false, flag2 && flag, false); + } + if (flag2 && horizontalScrollbar != GUIStyle.none) + { + scrollPosition.x = HorizontalScroll( + new Rect( + position.x, + position.yMax - horizontalScrollbar.fixedHeight, + screenRect.width, + horizontalScrollbar.fixedHeight), + scrollPosition.x, + Mathf.Min(screenRect.width, viewRect.width), + 0f, + viewRect.width, + horizontalScrollbar + ); + } + else + { + GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + scrollPosition.x = ((horizontalScrollbar == GUIStyle.none) + ? Mathf.Clamp(scrollPosition.x, 0f, Mathf.Max(viewRect.width - position.width, 0f)) + : 0f); + } + if (flag && verticalScrollbar != GUIStyle.none) + { + scrollPosition.y = VerticalScroll( + new Rect( + screenRect.xMax + (float)verticalScrollbar.margin.left, + screenRect.y, + verticalScrollbar.fixedWidth, + screenRect.height), + scrollPosition.y, + Mathf.Min(screenRect.height, viewRect.height), + 0f, + viewRect.height, + verticalScrollbar + ); + } + else + { + GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + scrollPosition.y = ((verticalScrollbar == GUIStyle.none) + ? Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(viewRect.height - position.height, 0f)) + : 0f); + } + } + } + else + { + GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive); + } + GUIClip.Push(screenRect, + new Vector2( + Mathf.Round(-scrollPosition.x - viewRect.x), + Mathf.Round(-scrollPosition.y - viewRect.y)), + Vector2.zero, + false + ); + + return scrollPosition; + } + + public static float HorizontalScroll(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style) + { + return Scroller(position, value, size, leftValue, rightValue, style, + GUI.skin.GetStyle(style.name + "thumb"), + GUI.skin.GetStyle(style.name + "leftbutton"), + GUI.skin.GetStyle(style.name + "rightbutton"), + true); + } + + public static float VerticalScroll(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style) + { + return Scroller(position, value, size, topValue, bottomValue, style, + GUI.skin.GetStyle(style.name + "thumb"), + GUI.skin.GetStyle(style.name + "upbutton"), + GUI.skin.GetStyle(style.name + "downbutton"), + false); + } + + private static float Scroller(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider, + GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz) + { + GUIUtility.CheckOnGUI(); + int controlID = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position); + Rect position2; + Rect rect; + Rect rect2; + if (horiz) + { + position2 = new Rect(position.x + leftButton.fixedWidth, + position.y, + position.width - leftButton.fixedWidth - rightButton.fixedWidth, + position.height); + + rect = new Rect(position.x, position.y, leftButton.fixedWidth, position.height); + rect2 = new Rect(position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height); + } + else + { + position2 = new Rect(position.x, + position.y + leftButton.fixedHeight, + position.width, + position.height - leftButton.fixedHeight - rightButton.fixedHeight); + + rect = new Rect(position.x, position.y, position.width, leftButton.fixedHeight); + rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight); + } + + value = Slider(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID); + + bool flag = Event.current.type == EventType.MouseUp; + if (ScrollerRepeatButton(controlID, rect, leftButton)) + { + value -= 10f * ((leftValue >= rightValue) ? -1f : 1f); + } + if (ScrollerRepeatButton(controlID, rect2, rightButton)) + { + value += 10f * ((leftValue >= rightValue) ? -1f : 1f); + } + if (flag && Event.current.type == EventType.Used) + { + s_ScrollControlId = 0; + } + if (leftValue < rightValue) + { + value = Mathf.Clamp(value, leftValue, rightValue - size); + } + else + { + value = Mathf.Clamp(value, rightValue, leftValue - size); + } + return value; + } + + public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider, + GUIStyle thumb, bool horiz, int id) + { + if (id == 0) + { + id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position); + } + var sliderHandler = new Internal_SliderHandler(position, value, size, start, end, slider, thumb, horiz, id); + return sliderHandler.Handle(); + } + + private static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle style) + { + bool result = false; + if (GUI.DoRepeatButton(rect, GUIContent.none, style, FocusType.Passive)) + { + bool flag = s_ScrollControlId != scrollerID; + s_ScrollControlId = scrollerID; + + if (flag) + { + result = true; + nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0); + } + else if (DateTime.Now >= nextScrollStepTime) + { + result = true; + nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0); + } + if (Event.current.type == EventType.Repaint) + { + GUI.InternalRepaintEditorWindow(); + } + } + return result; + } + +#endregion + } + + public static class UnstripExtensions + { + public static Rect Unstripped_GetLast(this GUILayoutGroup group) + { + Rect result; + if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count) + { + GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1]; + result = guilayoutEntry.rect; + } + else + { + result = GUILayoutEntry.kDummyRect; + } + return result; + } + } +} +#endif diff --git a/src/UnstripFixes/LayoutUtilityUnstrip.cs b/src/UnstripFixes/Internal_LayoutUtility.cs similarity index 59% rename from src/UnstripFixes/LayoutUtilityUnstrip.cs rename to src/UnstripFixes/Internal_LayoutUtility.cs index 466c8f1..f7d4583 100644 --- a/src/UnstripFixes/LayoutUtilityUnstrip.cs +++ b/src/UnstripFixes/Internal_LayoutUtility.cs @@ -1,34 +1,17 @@ -using UnityEngine; +#if CPP +using UnityEngine; +using Explorer.UnstripInternals; namespace Explorer { - public class LayoutUtilityUnstrip + public class Internal_LayoutUtility { -#if CPP - public static Rect GetRect(float width, float height) { return DoGetRect(width, width, height, height, GUIStyle.none, null); } - public static Rect GetRect(float width, float height, GUIStyle style) { return DoGetRect(width, width, height, height, style, null); } - public static Rect GetRect(float width, float height, params GUILayoutOption[] options) { return DoGetRect(width, width, height, height, GUIStyle.none, options); } - // Reserve layout space for a rectangle with a fixed content area. public static Rect GetRect(float width, float height, GUIStyle style, params GUILayoutOption[] options) - { return DoGetRect(width, width, height, height, style, options); } - - public static Rect GetRect(float minWidth, float maxWidth, float minHeight, float maxHeight) - { return DoGetRect(minWidth, maxWidth, minHeight, maxHeight, GUIStyle.none, null); } - - public static Rect GetRect(float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style) - { return DoGetRect(minWidth, maxWidth, minHeight, maxHeight, style, null); } - - public static Rect GetRect(float minWidth, float maxWidth, float minHeight, float maxHeight, params GUILayoutOption[] options) - { return DoGetRect(minWidth, maxWidth, minHeight, maxHeight, GUIStyle.none, options); } - // Reserve layout space for a flexible rect. - public static Rect GetRect(float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style, params GUILayoutOption[] options) - { return DoGetRect(minWidth, maxWidth, minHeight, maxHeight, style, options); } - static Rect DoGetRect(float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style, GUILayoutOption[] options) { switch (Event.current.type) { case EventType.Layout: - GUILayoutUtility.current.topLevel.Add(new GUILayoutEntry(minWidth, maxWidth, minHeight, maxHeight, style, options)); + GUILayoutUtility.current.topLevel.Add(new GUILayoutEntry(width, width, height, height, style, options)); return GUILayoutUtility.kDummyRect; case EventType.Used: return GUILayoutUtility.kDummyRect; @@ -36,14 +19,14 @@ namespace Explorer return GUILayoutUtility.current.topLevel.GetNext().rect; } } - public static Rect GetRect(GUIContent content, GUIStyle style) { return DoGetRect(content, style, null); } - // Reserve layout space for a rectangle for displaying some contents with a specific style. - public static Rect GetRect(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoGetRect(content, style, options); } + + public static Rect GetRect(GUIContent content, GUIStyle style, params GUILayoutOption[] options) + { + return DoGetRect(content, style, options); + } static Rect DoGetRect(GUIContent content, GUIStyle style, GUILayoutOption[] options) { - GUIUtility.CheckOnGUI(); - switch (Event.current.type) { case EventType.Layout: @@ -96,7 +79,7 @@ namespace Explorer Rect last; if (type != EventType.Layout && type != EventType.Used) { - last = GUILayoutUtility.current.topLevel.GetLastUnstripped(); + last = GUILayoutUtility.current.topLevel.Unstripped_GetLast(); } else { @@ -104,11 +87,6 @@ namespace Explorer } return last; } -#else - public static Rect GetLastRect() - { - return GUILayoutUtility.GetLastRect(); - } -#endif } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/UnstripFixes/ScrollViewStateUnstrip.cs b/src/UnstripFixes/Internal_ScrollViewState.cs similarity index 56% rename from src/UnstripFixes/ScrollViewStateUnstrip.cs rename to src/UnstripFixes/Internal_ScrollViewState.cs index 2e735b3..c1b84b9 100644 --- a/src/UnstripFixes/ScrollViewStateUnstrip.cs +++ b/src/UnstripFixes/Internal_ScrollViewState.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace Explorer { - public class ScrollViewStateUnstrip + public class Internal_ScrollViewState { public Rect position; public Rect visibleRect; @@ -13,18 +13,17 @@ namespace Explorer public Vector2 scrollPosition; public bool apply; - public static Dictionary Dict = new Dictionary(); + public static Dictionary Dict = new Dictionary(); - public static ScrollViewStateUnstrip FromPointer(IntPtr ptr) + public static Internal_ScrollViewState FromPointer(IntPtr ptr) { if (!Dict.ContainsKey(ptr)) { - Dict.Add(ptr, new ScrollViewStateUnstrip()); + Dict.Add(ptr, new Internal_ScrollViewState()); } return Dict[ptr]; } } } - #endif \ No newline at end of file diff --git a/src/UnstripFixes/SliderHandlerUnstrip.cs b/src/UnstripFixes/Internal_SliderHandler.cs similarity index 78% rename from src/UnstripFixes/SliderHandlerUnstrip.cs rename to src/UnstripFixes/Internal_SliderHandler.cs index c00087d..9b57f31 100644 --- a/src/UnstripFixes/SliderHandlerUnstrip.cs +++ b/src/UnstripFixes/Internal_SliderHandler.cs @@ -2,11 +2,53 @@ using System; using UnhollowerRuntimeLib; using UnityEngine; +using Explorer.UnstripInternals; +using Il2CppSystem.Reflection; namespace Explorer { - public struct SliderHandlerUnstrip + public struct Internal_SliderHandler { + public static int ScrollTroughSide + { + get + { + if (!m_getScrollTroughSideFailed) + { + try + { + return GUI.scrollTroughSide; + } + catch + { + m_getScrollTroughSideFailed = true; + } + } + + return m_manualScrollTrough; + } + set + { + if (!m_setScrollTroughSideFailed) + { + try + { + GUI.scrollTroughSide = value; + return; + } + catch + { + m_setScrollTroughSideFailed = true; + } + } + m_manualScrollTrough = value; + } + } + private static bool m_getScrollTroughSideFailed; + private static bool m_setScrollTroughSideFailed; + private static int m_manualScrollTrough; + + private readonly Rect position; private readonly float currentValue; private readonly float size; @@ -17,7 +59,8 @@ namespace Explorer private readonly bool horiz; private readonly int id; - public SliderHandlerUnstrip(Rect position, float currentValue, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id) + public Internal_SliderHandler(Rect position, float currentValue, float size, float start, + float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id) { this.position = position; this.currentValue = currentValue; @@ -64,7 +107,7 @@ namespace Explorer } else { - GUI.scrollTroughSide = 0; + ScrollTroughSide = 0; GUIUtility.hotControl = this.id; this.CurrentEvent().Use(); if (this.ThumbSelectionRect().Contains(this.CurrentEvent().mousePosition)) @@ -77,9 +120,10 @@ namespace Explorer GUI.changed = true; if (this.SupportsPageMovements()) { - this.SliderState().isDragging = false; - GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0); - GUI.scrollTroughSide = this.CurrentScrollTroughSide(); + var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); + ext.isDragging = false; + Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0); + ScrollTroughSide = this.CurrentScrollTroughSide(); result = this.PageMovementValue(); } else @@ -102,8 +146,8 @@ namespace Explorer } else { - SliderState sliderState = this.SliderState(); - if (!sliderState.isDragging) + var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); + if (!ext.isDragging) { result = this.currentValue; } @@ -111,8 +155,8 @@ namespace Explorer { GUI.changed = true; this.CurrentEvent().Use(); - float num = this.MousePosition() - sliderState.dragStartPos; - float value = sliderState.dragStartValue + num / this.ValuesPerPixel(); + float num = this.MousePosition() - ext.dragStartPos; + float value = ext.dragStartValue + num / this.ValuesPerPixel(); result = this.Clamp(value); } } @@ -143,7 +187,7 @@ namespace Explorer } else if (this.ThumbRect().Contains(this.CurrentEvent().mousePosition)) { - if (GUI.scrollTroughSide != 0) + if (ScrollTroughSide != 0) { GUIUtility.hotControl = 0; } @@ -152,20 +196,20 @@ namespace Explorer else { GUI.InternalRepaintEditorWindow(); - if (DateTime.Now < GUIUnstrip.nextScrollStepTime) + if (DateTime.Now < Internal.nextScrollStepTime) { result = this.currentValue; } - else if (this.CurrentScrollTroughSide() != GUI.scrollTroughSide) + else if (this.CurrentScrollTroughSide() != ScrollTroughSide) { result = this.currentValue; } else { - GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0); + Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0); if (this.SupportsPageMovements()) { - this.SliderState().isDragging = false; + Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false; GUI.changed = true; result = this.PageMovementValue(); } @@ -261,15 +305,15 @@ namespace Explorer private void StartDraggingWithValue(float dragStartValue) { - SliderState sliderState = this.SliderState(); - sliderState.dragStartPos = this.MousePosition(); - sliderState.dragStartValue = dragStartValue; - sliderState.isDragging = true; + var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); + ext.dragStartPos = this.MousePosition(); + ext.dragStartValue = dragStartValue; + ext.isDragging = true; } - private SliderState SliderState() + private SliderState GetSliderState() { - return (SliderState)GUIUtility.GetStateObject(Il2CppType.Of(), this.id).TryCast(); + return GUIUtility.GetStateObject(Il2CppType.Of(), this.id).TryCast(); } private Rect ThumbRect() diff --git a/src/UnstripFixes/Internal_SliderState.cs b/src/UnstripFixes/Internal_SliderState.cs new file mode 100644 index 0000000..83326a3 --- /dev/null +++ b/src/UnstripFixes/Internal_SliderState.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Explorer +{ + public class Internal_SliderState + { + public float dragStartPos; + public float dragStartValue; + public bool isDragging; + + public static Dictionary Dict = new Dictionary(); + + public static Internal_SliderState FromPointer(IntPtr ptr) + { + if (!Dict.ContainsKey(ptr)) + { + Dict.Add(ptr, new Internal_SliderState()); + } + + return Dict[ptr]; + } + } +} diff --git a/src/UnstripFixes/UnstripExtensions.cs b/src/UnstripFixes/UnstripExtensions.cs deleted file mode 100644 index c94e597..0000000 --- a/src/UnstripFixes/UnstripExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -#if CPP -using UnityEngine; - -namespace Explorer -{ - public static class UnstripExtensions - { - public static Rect GetLastUnstripped(this GUILayoutGroup group) - { - Rect result; - if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count) - { - GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1]; - result = guilayoutEntry.rect; - } - else - { - result = GUILayoutEntry.kDummyRect; - } - return result; - } - } -} -#endif \ No newline at end of file