mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-23 17:02:36 +08:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
d20461fa0e | |||
72ec34090d | |||
883a8705c3 | |||
6adaaf5500 | |||
5de771389e | |||
51cfbe524e |
@ -15,9 +15,9 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
### Known issue
|
### Known issue
|
||||||
Some games are experiencing `MissingMethodException`s or exceptions about failed unstripping, which prevent the CppExplorer menu from showing properly or at all. This is a bug with [Il2CppAssemblyUnhollower](https://github.com/knah/Il2CppAssemblyUnhollower) and there isn't much I can do about it myself.
|
Due to limitations with [Il2CppAssemblyUnhollower](https://github.com/knah/Il2CppAssemblyUnhollower)'s Unstripping, CppExplorer may encounter a `MissingMethodException` when trying to use certain UnityEngine methods.
|
||||||
|
|
||||||
If you're familiar with C# and Unity, one possibility for now is making a fork of this repo and manually fixing all the broken methods to ones which aren't broken (if possible). There may be another overload of the same method which wasn't stripped or was unstripped successfully, which you can use instead.
|
Since version [1.5.4](https://github.com/sinai-dev/CppExplorer/releases/tag/1.5.4), CppExplorer manually unstrips most of these methods itself. If you encounter more methods which failed unstripping, please let me know by opening an issue and I will do my best to fix it.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Scene hierarchy explorer
|
* Scene hierarchy explorer
|
||||||
@ -51,7 +51,9 @@ Requires [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) to be ins
|
|||||||
|
|
||||||
CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Reflection Inspector</b>.
|
CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Reflection Inspector</b>.
|
||||||
|
|
||||||
<b>Tip:</b> when in Tab View, GameObjects are denoted by a [G] prefix, and Reflection objects are denoted by a [R] prefix.
|
<b>Tips:</b>
|
||||||
|
* When in Tab View, GameObjects are denoted by a [G] prefix, and Reflection objects are denoted by a [R] prefix.
|
||||||
|
* Hold <b>Left Shift</b> when you click the Inspect button to force Reflection mode for GameObjects and Transforms.
|
||||||
|
|
||||||
### GameObject Inspector
|
### GameObject Inspector
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
{
|
{
|
||||||
UIHelpers.GameobjButton(Value, null, false, width);
|
UIHelpers.GOButton(Value, null, false, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
|
@ -279,19 +279,15 @@ namespace Explorer
|
|||||||
ClampLabelWidth(window, ref whitespace);
|
ClampLabelWidth(window, ref whitespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages.Count = count;
|
Pages.ItemCount = count;
|
||||||
|
|
||||||
if (count > Pages.PageLimit)
|
if (count > Pages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
GUILayout.Space(whitespace);
|
GUILayout.Space(whitespace);
|
||||||
|
|
||||||
//int maxOffset = (int)Mathf.Ceil((float)(count / (decimal)ArrayLimit)) - 1;
|
|
||||||
Pages.CalculateMaxOffset();
|
|
||||||
|
|
||||||
//GUILayout.Label($"Page {PH.ArrayOffset + 1}/{maxOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
|
|
||||||
Pages.CurrentPageLabel();
|
Pages.CurrentPageLabel();
|
||||||
|
|
||||||
// prev/next page buttons
|
// prev/next page buttons
|
||||||
@ -317,7 +313,7 @@ namespace Explorer
|
|||||||
//}
|
//}
|
||||||
int offset = Pages.CalculateOffsetIndex();
|
int offset = Pages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int i = offset; i < offset + Pages.PageLimit && i < count; i++)
|
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
|
||||||
{
|
{
|
||||||
var entry = m_cachedEntries[i];
|
var entry = m_cachedEntries[i];
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
public const string VERSION = "1.5.2";
|
public const string VERSION = "1.5.5";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
|
|
||||||
public const string NAME = "CppExplorer"
|
public const string NAME = "CppExplorer"
|
||||||
@ -99,6 +99,8 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void OnGUI()
|
public override void OnGUI()
|
||||||
{
|
{
|
||||||
|
if (!ShowMenu) return;
|
||||||
|
|
||||||
MainMenu.Instance.OnGUI();
|
MainMenu.Instance.OnGUI();
|
||||||
WindowManager.Instance.OnGUI();
|
WindowManager.Instance.OnGUI();
|
||||||
InspectUnderMouse.OnGUI();
|
InspectUnderMouse.OnGUI();
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
<DebugSymbols>false</DebugSymbols>
|
<DebugSymbols>false</DebugSymbols>
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>..\Release\</OutputPath>
|
<OutputPath>..\Release\2019\</OutputPath>
|
||||||
<DefineConstants>DEBUG</DefineConstants>
|
<DefineConstants>Release_2019</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<DebugSymbols>false</DebugSymbols>
|
<DebugSymbols>false</DebugSymbols>
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>..\Release\</OutputPath>
|
<OutputPath>..\Release\2018\</OutputPath>
|
||||||
<DefineConstants>Release_Unity2018</DefineConstants>
|
<DefineConstants>Release_Unity2018</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="mcs">
|
<Reference Include="mcs">
|
||||||
<HintPath>..\lib\mcs.dll</HintPath>
|
<HintPath>..\lib\mcs.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MelonLoader.ModHandler">
|
<Reference Include="MelonLoader.ModHandler">
|
||||||
<HintPath>..\..\..\..\..\Steam\steamapps\common\Hellpoint\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
|
<HintPath>..\..\..\..\..\Steam\steamapps\common\Hellpoint\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
|
||||||
@ -129,6 +129,8 @@
|
|||||||
<Compile Include="CachedObjects\CacheMethod.cs" />
|
<Compile Include="CachedObjects\CacheMethod.cs" />
|
||||||
<Compile Include="CppExplorer.cs" />
|
<Compile Include="CppExplorer.cs" />
|
||||||
<Compile Include="Extensions\ReflectionExtensions.cs" />
|
<Compile Include="Extensions\ReflectionExtensions.cs" />
|
||||||
|
<Compile Include="Unstripping\GUIUnstrip.cs" />
|
||||||
|
<Compile Include="Unstripping\ScrollViewStateUnstrip.cs" />
|
||||||
<Compile Include="Extensions\UnityExtensions.cs" />
|
<Compile Include="Extensions\UnityExtensions.cs" />
|
||||||
<Compile Include="Helpers\PageHelper.cs" />
|
<Compile Include="Helpers\PageHelper.cs" />
|
||||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||||
@ -136,6 +138,8 @@
|
|||||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||||
<Compile Include="MainMenu\InspectUnderMouse.cs" />
|
<Compile Include="MainMenu\InspectUnderMouse.cs" />
|
||||||
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
||||||
|
<Compile Include="Unstripping\SliderHandlerUnstrip.cs" />
|
||||||
|
<Compile Include="Unstripping\UnstripExtensions.cs" />
|
||||||
<Compile Include="Windows\ResizeDrag.cs" />
|
<Compile Include="Windows\ResizeDrag.cs" />
|
||||||
<Compile Include="Windows\TabViewWindow.cs" />
|
<Compile Include="Windows\TabViewWindow.cs" />
|
||||||
<Compile Include="Windows\UIWindow.cs" />
|
<Compile Include="Windows\UIWindow.cs" />
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using UnhollowerBaseLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
|
@ -16,13 +16,23 @@ namespace Explorer
|
|||||||
public class PageHelper
|
public class PageHelper
|
||||||
{
|
{
|
||||||
public int PageOffset { get; set; }
|
public int PageOffset { get; set; }
|
||||||
public int PageLimit { get; set; } = 20;
|
public int ItemsPerPage { get; set; } = 20;
|
||||||
public int Count { get; set; }
|
public int ItemCount
|
||||||
public int MaxOffset { get; set; } = -1;
|
|
||||||
|
|
||||||
public int CalculateMaxOffset()
|
|
||||||
{
|
{
|
||||||
return MaxOffset = (int)Mathf.Ceil((float)(Count / (decimal)PageLimit)) - 1;
|
get => m_count;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_count = value;
|
||||||
|
CalculateMaxOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int m_count;
|
||||||
|
|
||||||
|
public int MaxPageOffset { get; private set; } = -1;
|
||||||
|
|
||||||
|
private int CalculateMaxOffset()
|
||||||
|
{
|
||||||
|
return MaxPageOffset = (int)Mathf.Ceil((float)(ItemCount / (decimal)ItemsPerPage)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CurrentPageLabel()
|
public void CurrentPageLabel()
|
||||||
@ -30,7 +40,7 @@ namespace Explorer
|
|||||||
var orig = GUI.skin.label.alignment;
|
var orig = GUI.skin.label.alignment;
|
||||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||||
|
|
||||||
GUILayout.Label($"Page {PageOffset + 1}/{MaxOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
|
GUILayout.Label($"Page {PageOffset + 1}/{MaxPageOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
|
||||||
|
|
||||||
GUI.skin.label.alignment = orig;
|
GUI.skin.label.alignment = orig;
|
||||||
}
|
}
|
||||||
@ -53,7 +63,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (PageOffset < MaxOffset)
|
if (PageOffset < MaxPageOffset)
|
||||||
{
|
{
|
||||||
PageOffset++;
|
PageOffset++;
|
||||||
scroll = Vector2.zero;
|
scroll = Vector2.zero;
|
||||||
@ -63,9 +73,9 @@ namespace Explorer
|
|||||||
|
|
||||||
public int CalculateOffsetIndex()
|
public int CalculateOffsetIndex()
|
||||||
{
|
{
|
||||||
int offset = PageOffset * PageLimit;
|
int offset = PageOffset * ItemsPerPage;
|
||||||
|
|
||||||
if (offset >= Count)
|
if (offset >= ItemCount)
|
||||||
{
|
{
|
||||||
offset = 0;
|
offset = 0;
|
||||||
PageOffset = 0;
|
PageOffset = 0;
|
||||||
@ -77,11 +87,11 @@ namespace Explorer
|
|||||||
public void DrawLimitInputArea()
|
public void DrawLimitInputArea()
|
||||||
{
|
{
|
||||||
GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
|
GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||||
var limit = this.PageLimit.ToString();
|
var limit = this.ItemsPerPage.ToString();
|
||||||
limit = GUILayout.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
|
limit = GUILayout.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
|
||||||
if (limit != PageLimit.ToString() && int.TryParse(limit, out int i))
|
if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i))
|
||||||
{
|
{
|
||||||
PageLimit = i;
|
ItemsPerPage = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
@ -22,13 +24,13 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper for drawing a styled button for a GameObject or Transform
|
// helper for drawing a styled button for a GameObject or Transform
|
||||||
public static void GameobjButton(object _obj, Action<Transform> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
|
public static void GOButton(object _obj, Action<Transform> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
|
||||||
{
|
{
|
||||||
var obj = (_obj as GameObject) ?? (_obj as Transform).gameObject;
|
var obj = (_obj as GameObject) ?? (_obj as Transform).gameObject;
|
||||||
|
|
||||||
bool children = obj.transform.childCount > 0;
|
bool hasChild = obj.transform.childCount > 0;
|
||||||
|
|
||||||
string label = children ? "[" + obj.transform.childCount + " children] " : "";
|
string label = hasChild ? $"[{obj.transform.childCount} children] " : "";
|
||||||
label += obj.name;
|
label += obj.name;
|
||||||
|
|
||||||
bool enabled = obj.activeSelf;
|
bool enabled = obj.activeSelf;
|
||||||
@ -51,10 +53,10 @@ namespace Explorer
|
|||||||
color = Color.red;
|
color = Color.red;
|
||||||
}
|
}
|
||||||
|
|
||||||
FastGameobjButton(_obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width);
|
GOButton_Impl(_obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FastGameobjButton(object _obj, Color activeColor, string label, bool enabled, Action<Transform> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
|
public static void GOButton_Impl(object _obj, Color activeColor, string label, bool enabled, Action<Transform> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
|
||||||
{
|
{
|
||||||
var obj = _obj as GameObject ?? (_obj as Transform).gameObject;
|
var obj = _obj as GameObject ?? (_obj as Transform).gameObject;
|
||||||
|
|
||||||
|
@ -51,15 +51,12 @@ namespace Explorer
|
|||||||
|
|
||||||
public void OnGUI()
|
public void OnGUI()
|
||||||
{
|
{
|
||||||
if (CppExplorer.ShowMenu)
|
var origSkin = GUI.skin;
|
||||||
{
|
GUI.skin = UIStyles.WindowSkin;
|
||||||
var origSkin = GUI.skin;
|
|
||||||
GUI.skin = UIStyles.WindowSkin;
|
|
||||||
|
|
||||||
MainRect = GUI.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, CppExplorer.NAME);
|
MainRect = GUI.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, CppExplorer.NAME);
|
||||||
|
|
||||||
GUI.skin = origSkin;
|
GUI.skin = origSkin;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainWindow(int id)
|
private void MainWindow(int id)
|
||||||
@ -77,9 +74,12 @@ namespace Explorer
|
|||||||
MainHeader();
|
MainHeader();
|
||||||
|
|
||||||
var page = Pages[m_currentPage];
|
var page = Pages[m_currentPage];
|
||||||
page.scroll = GUILayout.BeginScrollView(page.scroll, GUI.skin.scrollView);
|
|
||||||
|
page.scroll = GUIUnstrip.BeginScrollView(page.scroll);
|
||||||
|
|
||||||
page.DrawWindow();
|
page.DrawWindow();
|
||||||
GUILayout.EndScrollView();
|
|
||||||
|
GUIUnstrip.EndScrollView();
|
||||||
|
|
||||||
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
|
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
|
||||||
|
|
||||||
|
@ -75,22 +75,27 @@ namespace Explorer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var scene = SceneManager.GetSceneByName(m_currentScene);
|
var scene = SceneManager.GetSceneByName(m_currentScene);
|
||||||
var rootObjects = scene.GetRootGameObjects();
|
|
||||||
|
|
||||||
foreach (var obj in rootObjects)
|
var list = new Il2CppSystem.Collections.Generic.List<GameObject>
|
||||||
|
{
|
||||||
|
Capacity = scene.rootCount
|
||||||
|
};
|
||||||
|
Scene.GetRootGameObjectsInternal(scene.handle, list);
|
||||||
|
|
||||||
|
foreach (var obj in list)
|
||||||
{
|
{
|
||||||
allTransforms.Add(obj.transform);
|
allTransforms.Add(obj.transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages.Count = allTransforms.Count;
|
Pages.ItemCount = allTransforms.Count;
|
||||||
|
|
||||||
int offset = Pages.CalculateOffsetIndex();
|
int offset = Pages.CalculateOffsetIndex();
|
||||||
|
|
||||||
// sort by childcount
|
// sort by childcount
|
||||||
allTransforms.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
allTransforms.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
||||||
|
|
||||||
for (int i = offset; i < offset + Pages.PageLimit && i < Pages.Count; i++)
|
for (int i = offset; i < offset + Pages.ItemsPerPage && i < Pages.ItemCount; i++)
|
||||||
{
|
{
|
||||||
var child = allTransforms[i];
|
var child = allTransforms[i];
|
||||||
m_objectList.Add(new GameObjectCache(child.gameObject));
|
m_objectList.Add(new GameObjectCache(child.gameObject));
|
||||||
@ -124,7 +129,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
m_searchResults = SearchSceneObjects(m_searchInput);
|
m_searchResults = SearchSceneObjects(m_searchInput);
|
||||||
m_searching = true;
|
m_searching = true;
|
||||||
Pages.Count = m_searchResults.Count;
|
Pages.ItemCount = m_searchResults.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CancelSearch()
|
public void CancelSearch()
|
||||||
@ -240,11 +245,13 @@ namespace Explorer
|
|||||||
|
|
||||||
Pages.DrawLimitInputArea();
|
Pages.DrawLimitInputArea();
|
||||||
|
|
||||||
if (Pages.Count > Pages.PageLimit)
|
if (Pages.ItemCount > Pages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Left, ref this.scroll);
|
Pages.TurnPage(Turn.Left, ref this.scroll);
|
||||||
|
|
||||||
|
m_timeOfLastUpdate = -1f;
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,6 +260,8 @@ namespace Explorer
|
|||||||
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
|
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Right, ref this.scroll);
|
Pages.TurnPage(Turn.Right, ref this.scroll);
|
||||||
|
|
||||||
|
m_timeOfLastUpdate = -1f;
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,7 +312,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UIHelpers.FastGameobjButton(obj.RefGameObject,
|
UIHelpers.GOButton_Impl(obj.RefGameObject,
|
||||||
obj.EnabledColor,
|
obj.EnabledColor,
|
||||||
obj.Label,
|
obj.Label,
|
||||||
obj.RefGameObject.activeSelf,
|
obj.RefGameObject.activeSelf,
|
||||||
@ -328,13 +337,13 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
int offset = Pages.CalculateOffsetIndex();
|
int offset = Pages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int i = offset; i < offset + Pages.PageLimit && i < m_searchResults.Count; i++)
|
for (int i = offset; i < offset + Pages.ItemsPerPage && i < m_searchResults.Count; i++)
|
||||||
{
|
{
|
||||||
var obj = m_searchResults[i];
|
var obj = m_searchResults[i];
|
||||||
|
|
||||||
if (obj.RefGameObject)
|
if (obj.RefGameObject)
|
||||||
{
|
{
|
||||||
UIHelpers.FastGameobjButton(obj.RefGameObject,
|
UIHelpers.GOButton_Impl(obj.RefGameObject,
|
||||||
obj.EnabledColor,
|
obj.EnabledColor,
|
||||||
obj.Label,
|
obj.Label,
|
||||||
obj.RefGameObject.activeSelf,
|
obj.RefGameObject.activeSelf,
|
||||||
|
@ -75,7 +75,7 @@ namespace Explorer
|
|||||||
m_searchResults.Add(cache);
|
m_searchResults.Add(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages.Count = m_searchResults.Count;
|
Pages.ItemCount = m_searchResults.Count;
|
||||||
Pages.PageOffset = 0;
|
Pages.PageOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,17 +104,16 @@ namespace Explorer
|
|||||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||||
|
|
||||||
int count = m_searchResults.Count;
|
int count = m_searchResults.Count;
|
||||||
Pages.CalculateMaxOffset();
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
Pages.DrawLimitInputArea();
|
Pages.DrawLimitInputArea();
|
||||||
|
|
||||||
if (count > Pages.PageLimit)
|
if (count > Pages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
// prev/next page buttons
|
// prev/next page buttons
|
||||||
|
|
||||||
if (Pages.Count > Pages.PageLimit)
|
if (Pages.ItemCount > Pages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||||
{
|
{
|
||||||
@ -132,7 +131,7 @@ namespace Explorer
|
|||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
resultsScroll = GUILayout.BeginScrollView(resultsScroll, GUI.skin.scrollView);
|
resultsScroll = GUIUnstrip.BeginScrollView(resultsScroll);
|
||||||
|
|
||||||
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
|
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ namespace Explorer
|
|||||||
//if (offset >= count) m_pageOffset = 0;
|
//if (offset >= count) m_pageOffset = 0;
|
||||||
int offset = Pages.CalculateOffsetIndex();
|
int offset = Pages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int i = offset; i < offset + Pages.PageLimit && i < count; i++)
|
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
|
||||||
{
|
{
|
||||||
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
|
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
|
||||||
//m_searchResults[i].DrawValue(MainMenu.MainRect);
|
//m_searchResults[i].DrawValue(MainMenu.MainRect);
|
||||||
@ -153,7 +152,7 @@ namespace Explorer
|
|||||||
GUILayout.Label("<color=red><i>No results found!</i></color>", null);
|
GUILayout.Label("<color=red><i>No results found!</i></color>", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.EndScrollView();
|
GUIUnstrip.EndScrollView();
|
||||||
GUILayout.EndVertical();
|
GUILayout.EndVertical();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
427
src/Unstripping/GUIUnstrip.cs
Normal file
427
src/Unstripping/GUIUnstrip.cs
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnhollowerBaseLib;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngineInternal;
|
||||||
|
using Harmony;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
||||||
|
// Taken from dnSpy output using Unity 2018.4.20.
|
||||||
|
|
||||||
|
// Subject to Unity's License and ToS.
|
||||||
|
// https://unity3d.com/legal/terms-of-service
|
||||||
|
// https://unity3d.com/legal/terms-of-service/software
|
||||||
|
|
||||||
|
public class GUIUnstrip
|
||||||
|
{
|
||||||
|
public static int s_ScrollControlId;
|
||||||
|
|
||||||
|
public static bool ScrollFailed = false;
|
||||||
|
public static bool ManualUnstripFailed = false;
|
||||||
|
|
||||||
|
private static GenericStack ScrollStack
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
#if Release_2019
|
||||||
|
return GUI.scrollViewStates;
|
||||||
|
#else
|
||||||
|
return GUI.s_ScrollViewStates;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======= public methods ======= //
|
||||||
|
|
||||||
|
// Fix for GUILayoutUtility.GetLastRect().
|
||||||
|
// Calls UnstripExtensions.GetLastUnstripped().
|
||||||
|
|
||||||
|
public static Rect GetLastRect()
|
||||||
|
{
|
||||||
|
EventType type = Event.current.type;
|
||||||
|
Rect last;
|
||||||
|
if (type != EventType.Layout && type != EventType.Used)
|
||||||
|
{
|
||||||
|
last = GUILayoutUtility.current.topLevel.GetLastUnstripped();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last = GUILayoutUtility.kDummyRect;
|
||||||
|
}
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple unstrips for HorizontalScrollbar and VerticalScrollbar, they just call the Scroller unstrip.
|
||||||
|
|
||||||
|
public static float HorizontalScrollbar(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 VerticalScrollbar(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix for BeginScrollView.
|
||||||
|
// Uses several manually unstripped methods.
|
||||||
|
|
||||||
|
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;
|
||||||
|
return scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try manual unstripping implementation.
|
||||||
|
if (!ManualUnstripFailed)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return BeginScrollView_ImplLayout(scroll, false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.scrollView, options);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MelonLogger.Log("Exception on GUIUnstrip.BeginScrollView_Impl: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
||||||
|
|
||||||
|
ManualUnstripFailed = true;
|
||||||
|
return scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorry! No scrolling for you.
|
||||||
|
return scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 methods ======= //
|
||||||
|
|
||||||
|
// Actual unstrip of GUILayout.BeginScrollView()
|
||||||
|
|
||||||
|
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||||
|
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||||
|
{
|
||||||
|
GUIUtility.CheckOnGUI();
|
||||||
|
|
||||||
|
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<GUIScrollGroup>())
|
||||||
|
.TryCast<GUIScrollGroup>();
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual unstrip of GUI.BeginScrollView()
|
||||||
|
|
||||||
|
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<ScrollViewState>(), controlID).TryCast<ScrollViewState>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 = HorizontalScrollbar(
|
||||||
|
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 = VerticalScrollbar(
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual unstrip of GUI.EndScrollView()
|
||||||
|
|
||||||
|
private static void EndScrollView_Impl(bool handleScrollWheel)
|
||||||
|
{
|
||||||
|
GUIUtility.CheckOnGUI();
|
||||||
|
|
||||||
|
if (ScrollStack.Count <= 0) return;
|
||||||
|
|
||||||
|
var state = ScrollStack.Peek().TryCast<ScrollViewState>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual unstrip of GUI.Scroller
|
||||||
|
|
||||||
|
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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual unstrip of GUI.Slider
|
||||||
|
|
||||||
|
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 SliderHandlerUnstrip(position, value, size, start, end, slider, thumb, horiz, id);
|
||||||
|
return sliderHandler.Handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual unstrip of GUI.ScrollerRepeatButton
|
||||||
|
|
||||||
|
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;
|
||||||
|
GUI.nextScrollStepTime = Il2CppSystem.DateTime.Now.AddMilliseconds(250.0);
|
||||||
|
}
|
||||||
|
else if (Il2CppSystem.DateTime.Now >= GUI.nextScrollStepTime)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
GUI.nextScrollStepTime = Il2CppSystem.DateTime.Now.AddMilliseconds(30.0);
|
||||||
|
}
|
||||||
|
if (Event.current.type == EventType.Repaint)
|
||||||
|
{
|
||||||
|
GUI.InternalRepaintEditorWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/Unstripping/ScrollViewStateUnstrip.cs
Normal file
42
src/Unstripping/ScrollViewStateUnstrip.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Harmony;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
||||||
|
// Taken from dnSpy output using Unity 2018.4.20.
|
||||||
|
|
||||||
|
// Subject to Unity's License and ToS.
|
||||||
|
// https://unity3d.com/legal/terms-of-service
|
||||||
|
// https://unity3d.com/legal/terms-of-service/software
|
||||||
|
|
||||||
|
public class ScrollViewStateUnstrip
|
||||||
|
{
|
||||||
|
public Rect position;
|
||||||
|
public Rect visibleRect;
|
||||||
|
public Rect viewRect;
|
||||||
|
public Vector2 scrollPosition;
|
||||||
|
public bool apply;
|
||||||
|
|
||||||
|
// The code below is not unstripped.
|
||||||
|
// This is a custom dictionary to allow for the manual implementation.
|
||||||
|
|
||||||
|
public static Dictionary<IntPtr, ScrollViewStateUnstrip> Dict = new Dictionary<IntPtr, ScrollViewStateUnstrip>();
|
||||||
|
|
||||||
|
public static ScrollViewStateUnstrip FromPointer(IntPtr ptr)
|
||||||
|
{
|
||||||
|
if (!Dict.ContainsKey(ptr))
|
||||||
|
{
|
||||||
|
Dict.Add(ptr, new ScrollViewStateUnstrip());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Dict[ptr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
378
src/Unstripping/SliderHandlerUnstrip.cs
Normal file
378
src/Unstripping/SliderHandlerUnstrip.cs
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
||||||
|
// Taken from dnSpy output using Unity 2018.4.20.
|
||||||
|
|
||||||
|
// Subject to Unity's License and ToS.
|
||||||
|
// https://unity3d.com/legal/terms-of-service
|
||||||
|
// https://unity3d.com/legal/terms-of-service/software
|
||||||
|
|
||||||
|
public struct SliderHandlerUnstrip
|
||||||
|
{
|
||||||
|
private readonly Rect position;
|
||||||
|
private readonly float currentValue;
|
||||||
|
private readonly float size;
|
||||||
|
private readonly float start;
|
||||||
|
private readonly float end;
|
||||||
|
private readonly GUIStyle slider;
|
||||||
|
private readonly GUIStyle thumb;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
this.position = position;
|
||||||
|
this.currentValue = currentValue;
|
||||||
|
this.size = size;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.slider = slider;
|
||||||
|
this.thumb = thumb;
|
||||||
|
this.horiz = horiz;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Handle()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.slider == null || this.thumb == null)
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (this.CurrentEventType())
|
||||||
|
{
|
||||||
|
case EventType.MouseDown:
|
||||||
|
return this.OnMouseDown();
|
||||||
|
case EventType.MouseUp:
|
||||||
|
return this.OnMouseUp();
|
||||||
|
case EventType.MouseDrag:
|
||||||
|
return this.OnMouseDrag();
|
||||||
|
case EventType.Repaint:
|
||||||
|
return this.OnRepaint();
|
||||||
|
}
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float OnMouseDown()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (!this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.scrollTroughSide = 0;
|
||||||
|
GUIUtility.hotControl = this.id;
|
||||||
|
this.CurrentEvent().Use();
|
||||||
|
if (this.ThumbSelectionRect().Contains(this.CurrentEvent().mousePosition))
|
||||||
|
{
|
||||||
|
this.StartDraggingWithValue(this.ClampedCurrentValue());
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.changed = true;
|
||||||
|
if (this.SupportsPageMovements())
|
||||||
|
{
|
||||||
|
this.SliderState().isDragging = false;
|
||||||
|
GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(250.0);
|
||||||
|
GUI.scrollTroughSide = this.CurrentScrollTroughSide();
|
||||||
|
result = this.PageMovementValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float num = this.ValueForCurrentMousePosition();
|
||||||
|
this.StartDraggingWithValue(num);
|
||||||
|
result = this.Clamp(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float OnMouseDrag()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (GUIUtility.hotControl != this.id)
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SliderState sliderState = this.SliderState();
|
||||||
|
if (!sliderState.isDragging)
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.changed = true;
|
||||||
|
this.CurrentEvent().Use();
|
||||||
|
float num = this.MousePosition() - sliderState.dragStartPos;
|
||||||
|
float value = sliderState.dragStartValue + num / this.ValuesPerPixel();
|
||||||
|
result = this.Clamp(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float OnMouseUp()
|
||||||
|
{
|
||||||
|
if (GUIUtility.hotControl == this.id)
|
||||||
|
{
|
||||||
|
this.CurrentEvent().Use();
|
||||||
|
GUIUtility.hotControl = 0;
|
||||||
|
}
|
||||||
|
return this.currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float OnRepaint()
|
||||||
|
{
|
||||||
|
this.slider.Draw(this.position, GUIContent.none, this.id);
|
||||||
|
if (!this.IsEmptySlider() && this.currentValue >= this.MinValue() && this.currentValue <= this.MaxValue())
|
||||||
|
{
|
||||||
|
this.thumb.Draw(this.ThumbRect(), GUIContent.none, this.id);
|
||||||
|
}
|
||||||
|
float result;
|
||||||
|
if (GUIUtility.hotControl != this.id || !this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else if (this.ThumbRect().Contains(this.CurrentEvent().mousePosition))
|
||||||
|
{
|
||||||
|
if (GUI.scrollTroughSide != 0)
|
||||||
|
{
|
||||||
|
GUIUtility.hotControl = 0;
|
||||||
|
}
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.InternalRepaintEditorWindow();
|
||||||
|
if (SystemClock.now < GUI.nextScrollStepTime)
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else if (this.CurrentScrollTroughSide() != GUI.scrollTroughSide)
|
||||||
|
{
|
||||||
|
result = this.currentValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(30.0);
|
||||||
|
if (this.SupportsPageMovements())
|
||||||
|
{
|
||||||
|
this.SliderState().isDragging = false;
|
||||||
|
GUI.changed = true;
|
||||||
|
result = this.PageMovementValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.ClampedCurrentValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventType CurrentEventType()
|
||||||
|
{
|
||||||
|
return this.CurrentEvent().GetTypeForControl(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int CurrentScrollTroughSide()
|
||||||
|
{
|
||||||
|
float num = (!this.horiz) ? this.CurrentEvent().mousePosition.y : this.CurrentEvent().mousePosition.x;
|
||||||
|
float num2 = (!this.horiz) ? this.ThumbRect().y : this.ThumbRect().x;
|
||||||
|
return (num <= num2) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsEmptySlider()
|
||||||
|
{
|
||||||
|
return this.start == this.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SupportsPageMovements()
|
||||||
|
{
|
||||||
|
return this.size != 0f && GUI.usePageScrollbars;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float PageMovementValue()
|
||||||
|
{
|
||||||
|
float num = this.currentValue;
|
||||||
|
int num2 = (this.start <= this.end) ? 1 : -1;
|
||||||
|
if (this.MousePosition() > this.PageUpMovementBound())
|
||||||
|
{
|
||||||
|
num += this.size * (float)num2 * 0.9f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num -= this.size * (float)num2 * 0.9f;
|
||||||
|
}
|
||||||
|
return this.Clamp(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float PageUpMovementBound()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.horiz)
|
||||||
|
{
|
||||||
|
result = this.ThumbRect().xMax - this.position.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.ThumbRect().yMax - this.position.y;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Event CurrentEvent()
|
||||||
|
{
|
||||||
|
return Event.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float ValueForCurrentMousePosition()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.horiz)
|
||||||
|
{
|
||||||
|
result = (this.MousePosition() - this.ThumbRect().width * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (this.MousePosition() - this.ThumbRect().height * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float Clamp(float value)
|
||||||
|
{
|
||||||
|
return Mathf.Clamp(value, this.MinValue(), this.MaxValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect ThumbSelectionRect()
|
||||||
|
{
|
||||||
|
return this.ThumbRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartDraggingWithValue(float dragStartValue)
|
||||||
|
{
|
||||||
|
SliderState sliderState = this.SliderState();
|
||||||
|
sliderState.dragStartPos = this.MousePosition();
|
||||||
|
sliderState.dragStartValue = dragStartValue;
|
||||||
|
sliderState.isDragging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SliderState SliderState()
|
||||||
|
{
|
||||||
|
return (SliderState)GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect ThumbRect()
|
||||||
|
{
|
||||||
|
return (!this.horiz) ? this.VerticalThumbRect() : this.HorizontalThumbRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect VerticalThumbRect()
|
||||||
|
{
|
||||||
|
float num = this.ValuesPerPixel();
|
||||||
|
Rect result;
|
||||||
|
if (this.start < this.end)
|
||||||
|
{
|
||||||
|
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * num + this.ThumbSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() + this.size - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * -num + this.ThumbSize());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect HorizontalThumbRect()
|
||||||
|
{
|
||||||
|
float num = this.ValuesPerPixel();
|
||||||
|
Rect result;
|
||||||
|
if (this.start < this.end)
|
||||||
|
{
|
||||||
|
result = new Rect((this.ClampedCurrentValue() - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y + (float)this.slider.padding.top, this.size * num + this.ThumbSize(), this.position.height - (float)this.slider.padding.vertical);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = new Rect((this.ClampedCurrentValue() + this.size - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y, this.size * -num + this.ThumbSize(), this.position.height);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float ClampedCurrentValue()
|
||||||
|
{
|
||||||
|
return this.Clamp(this.currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float MousePosition()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.horiz)
|
||||||
|
{
|
||||||
|
result = this.CurrentEvent().mousePosition.x - this.position.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = this.CurrentEvent().mousePosition.y - this.position.y;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float ValuesPerPixel()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.horiz)
|
||||||
|
{
|
||||||
|
result = (this.position.width - (float)this.slider.padding.horizontal - this.ThumbSize()) / (this.end - this.start);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (this.position.height - (float)this.slider.padding.vertical - this.ThumbSize()) / (this.end - this.start);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float ThumbSize()
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
if (this.horiz)
|
||||||
|
{
|
||||||
|
result = ((this.thumb.fixedWidth == 0f) ? ((float)this.thumb.padding.horizontal) : this.thumb.fixedWidth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = ((this.thumb.fixedHeight == 0f) ? ((float)this.thumb.padding.vertical) : this.thumb.fixedHeight);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float MaxValue()
|
||||||
|
{
|
||||||
|
return Mathf.Max(this.start, this.end) - this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float MinValue()
|
||||||
|
{
|
||||||
|
return Mathf.Min(this.start, this.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
51
src/Unstripping/UnstripExtensions.cs
Normal file
51
src/Unstripping/UnstripExtensions.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
||||||
|
// Taken from dnSpy output using Unity 2018.4.20.
|
||||||
|
|
||||||
|
// Subject to Unity's License and ToS.
|
||||||
|
// https://unity3d.com/legal/terms-of-service
|
||||||
|
// https://unity3d.com/legal/terms-of-service/software
|
||||||
|
|
||||||
|
public static class UnstripExtensions
|
||||||
|
{
|
||||||
|
// This is a manual unstrip of GUILayoutGroup.GetLast().
|
||||||
|
// I'm using it as an Extension because it's easier this way.
|
||||||
|
|
||||||
|
public static Rect GetLastUnstripped(this GUILayoutGroup group)
|
||||||
|
{
|
||||||
|
Rect result;
|
||||||
|
if (group.m_Cursor == 0)
|
||||||
|
{
|
||||||
|
Debug.LogError("You cannot call GetLast immediately after beginning a group.");
|
||||||
|
result = GUILayoutEntry.kDummyRect;
|
||||||
|
}
|
||||||
|
else if (group.m_Cursor <= group.entries.Count)
|
||||||
|
{
|
||||||
|
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
|
||||||
|
result = guilayoutEntry.rect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError(string.Concat(new object[]
|
||||||
|
{
|
||||||
|
"Getting control ",
|
||||||
|
group.m_Cursor,
|
||||||
|
"'s position in a group with only ",
|
||||||
|
group.entries.Count,
|
||||||
|
" controls when doing ",
|
||||||
|
Event.current.type
|
||||||
|
}));
|
||||||
|
result = GUILayoutEntry.kDummyRect;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -73,8 +73,8 @@ namespace Explorer
|
|||||||
|
|
||||||
m_name = m_object.name;
|
m_name = m_object.name;
|
||||||
m_scene = string.IsNullOrEmpty(m_object.scene.name)
|
m_scene = string.IsNullOrEmpty(m_object.scene.name)
|
||||||
? "None"
|
? "None"
|
||||||
: m_object.scene.name;
|
: m_object.scene.name;
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ namespace Explorer
|
|||||||
list.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
list.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
||||||
m_children = list.ToArray();
|
m_children = list.ToArray();
|
||||||
|
|
||||||
ChildPages.Count = m_children.Length;
|
ChildPages.ItemCount = m_children.Length;
|
||||||
|
|
||||||
var list2 = new List<Component>();
|
var list2 = new List<Component>();
|
||||||
foreach (var comp in m_object.GetComponents(ReflectionHelpers.ComponentType))
|
foreach (var comp in m_object.GetComponents(ReflectionHelpers.ComponentType))
|
||||||
@ -111,7 +111,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
m_components = list2.ToArray();
|
m_components = list2.ToArray();
|
||||||
|
|
||||||
CompPages.Count = m_components.Length;
|
CompPages.ItemCount = m_components.Length;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ namespace Explorer
|
|||||||
|
|
||||||
private void DestroyOnException(Exception e)
|
private void DestroyOnException(Exception e)
|
||||||
{
|
{
|
||||||
MelonLogger.Log($"{e.GetType()}, {e.Message}");
|
MelonLogger.Log($"Exception drawing GameObject Window: {e.GetType()}, {e.Message}");
|
||||||
DestroyWindow();
|
DestroyWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ namespace Explorer
|
|||||||
GUILayout.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
GUILayout.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||||
}
|
}
|
||||||
|
|
||||||
scroll = GUILayout.BeginScrollView(scroll, GUI.skin.scrollView);
|
scroll = GUIUnstrip.BeginScrollView(scroll);
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", null);
|
GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", null);
|
||||||
@ -220,7 +220,7 @@ namespace Explorer
|
|||||||
|
|
||||||
GameObjectControls();
|
GameObjectControls();
|
||||||
|
|
||||||
GUILayout.EndScrollView();
|
GUIUnstrip.EndScrollView();
|
||||||
|
|
||||||
if (!WindowManager.TabView)
|
if (!WindowManager.TabView)
|
||||||
{
|
{
|
||||||
@ -237,18 +237,16 @@ namespace Explorer
|
|||||||
|
|
||||||
private void TransformList(Rect m_rect)
|
private void TransformList(Rect m_rect)
|
||||||
{
|
{
|
||||||
GUILayout.BeginVertical(GUI.skin.box, null); // new GUILayoutOption[] { GUILayout.Height(250) });
|
GUILayout.BeginVertical(GUI.skin.box, null);
|
||||||
m_transformScroll = GUILayout.BeginScrollView(m_transformScroll, GUI.skin.scrollView);
|
m_transformScroll = GUIUnstrip.BeginScrollView(m_transformScroll);
|
||||||
|
|
||||||
GUILayout.Label("<b><size=15>Children</size></b>", null);
|
GUILayout.Label("<b><size=15>Children</size></b>", null);
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
ChildPages.DrawLimitInputArea();
|
ChildPages.DrawLimitInputArea();
|
||||||
|
|
||||||
if (ChildPages.Count > ChildPages.PageLimit)
|
if (ChildPages.ItemCount > ChildPages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
ChildPages.CalculateMaxOffset();
|
|
||||||
|
|
||||||
ChildPages.CurrentPageLabel();
|
ChildPages.CurrentPageLabel();
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
@ -269,7 +267,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
int start = ChildPages.CalculateOffsetIndex();
|
int start = ChildPages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int j = start; (j < start + ChildPages.PageLimit && j < ChildPages.Count); j++)
|
for (int j = start; (j < start + ChildPages.ItemsPerPage && j < ChildPages.ItemCount); j++)
|
||||||
{
|
{
|
||||||
var obj = m_children[j];
|
var obj = m_children[j];
|
||||||
|
|
||||||
@ -279,7 +277,7 @@ namespace Explorer
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHelpers.GameobjButton(obj.gameObject, InspectGameObject, false, m_rect.width / 2 - 80);
|
UIHelpers.GOButton(obj.gameObject, InspectGameObject, false, m_rect.width / 2 - 80);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -287,23 +285,21 @@ namespace Explorer
|
|||||||
GUILayout.Label("<i>None</i>", null);
|
GUILayout.Label("<i>None</i>", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.EndScrollView();
|
GUIUnstrip.EndScrollView();
|
||||||
GUILayout.EndVertical();
|
GUILayout.EndVertical();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComponentList(Rect m_rect)
|
private void ComponentList(Rect m_rect)
|
||||||
{
|
{
|
||||||
GUILayout.BeginVertical(GUI.skin.box, null); // new GUILayoutOption[] { GUILayout.Height(250) });
|
GUILayout.BeginVertical(GUI.skin.box, null);
|
||||||
m_compScroll = GUILayout.BeginScrollView(m_compScroll, GUI.skin.scrollView);
|
m_compScroll = GUIUnstrip.BeginScrollView(m_compScroll);
|
||||||
GUILayout.Label("<b><size=15>Components</size></b>", null);
|
GUILayout.Label("<b><size=15>Components</size></b>", null);
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
CompPages.DrawLimitInputArea();
|
CompPages.DrawLimitInputArea();
|
||||||
|
|
||||||
if (CompPages.Count > CompPages.PageLimit)
|
if (CompPages.ItemCount > CompPages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
CompPages.CalculateMaxOffset();
|
|
||||||
|
|
||||||
CompPages.CurrentPageLabel();
|
CompPages.CurrentPageLabel();
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
@ -330,7 +326,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
int start = CompPages.CalculateOffsetIndex();
|
int start = CompPages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int j = start; (j < start + CompPages.PageLimit && j < CompPages.Count); j++)
|
for (int j = start; (j < start + CompPages.ItemsPerPage && j < CompPages.ItemCount); j++)
|
||||||
{
|
{
|
||||||
var component = m_components[j];
|
var component = m_components[j];
|
||||||
|
|
||||||
@ -369,7 +365,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.EndScrollView();
|
GUIUnstrip.EndScrollView();
|
||||||
|
|
||||||
GUILayout.EndVertical();
|
GUILayout.EndVertical();
|
||||||
}
|
}
|
||||||
|
@ -256,17 +256,15 @@ namespace Explorer
|
|||||||
|
|
||||||
GUILayout.Space(10);
|
GUILayout.Space(10);
|
||||||
|
|
||||||
Pages.Count = m_cachedMembersFiltered.Length;
|
Pages.ItemCount = m_cachedMembersFiltered.Length;
|
||||||
|
|
||||||
// prev/next page buttons
|
// prev/next page buttons
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
Pages.DrawLimitInputArea();
|
Pages.DrawLimitInputArea();
|
||||||
|
|
||||||
if (Pages.Count > Pages.PageLimit)
|
if (Pages.ItemCount > Pages.ItemsPerPage)
|
||||||
{
|
{
|
||||||
Pages.CalculateMaxOffset();
|
|
||||||
|
|
||||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Left, ref this.scroll);
|
Pages.TurnPage(Turn.Left, ref this.scroll);
|
||||||
@ -283,7 +281,7 @@ namespace Explorer
|
|||||||
|
|
||||||
// ====== BODY ======
|
// ====== BODY ======
|
||||||
|
|
||||||
scroll = GUILayout.BeginScrollView(scroll, GUI.skin.scrollView);
|
scroll = GUIUnstrip.BeginScrollView(scroll);
|
||||||
|
|
||||||
GUILayout.Space(10);
|
GUILayout.Space(10);
|
||||||
|
|
||||||
@ -294,7 +292,7 @@ namespace Explorer
|
|||||||
var members = this.m_cachedMembersFiltered;
|
var members = this.m_cachedMembersFiltered;
|
||||||
int start = Pages.CalculateOffsetIndex();
|
int start = Pages.CalculateOffsetIndex();
|
||||||
|
|
||||||
for (int j = start; (j < start + Pages.PageLimit && j < members.Length); j++)
|
for (int j = start; (j < start + Pages.ItemsPerPage && j < members.Length); j++)
|
||||||
{
|
{
|
||||||
var holder = members[j];
|
var holder = members[j];
|
||||||
|
|
||||||
@ -311,12 +309,12 @@ namespace Explorer
|
|||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
// if not last element
|
// if not last element
|
||||||
if (!(j == (start + Pages.PageLimit - 1) || j == (members.Length - 1)))
|
if (!(j == (start + Pages.ItemsPerPage - 1) || j == (members.Length - 1)))
|
||||||
UIStyles.HorizontalLine(new Color(0.07f, 0.07f, 0.07f), true);
|
UIStyles.HorizontalLine(new Color(0.07f, 0.07f, 0.07f), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.EndVertical();
|
GUILayout.EndVertical();
|
||||||
GUILayout.EndScrollView();
|
GUIUnstrip.EndScrollView();
|
||||||
|
|
||||||
if (!WindowManager.TabView)
|
if (!WindowManager.TabView)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,8 @@ namespace Explorer
|
|||||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||||
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
||||||
|
|
||||||
var r = GUILayoutUtility.GetLastRect();
|
//var r = GUILayoutUtility.GetLastRect();
|
||||||
|
var r = GUIUnstrip.GetLastRect();
|
||||||
|
|
||||||
Vector2 mouse = GUIUtility.ScreenToGUIPoint(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y));
|
Vector2 mouse = GUIUtility.ScreenToGUIPoint(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y));
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
RESIZE_FAILED = true;
|
RESIZE_FAILED = true;
|
||||||
MelonLogger.Log("Exception on GuiResize: " + e.GetType() + ", " + e.Message);
|
MelonLogger.Log("Exception on GuiResize: " + e.GetType() + ", " + e.Message);
|
||||||
|
MelonLogger.Log(e.StackTrace);
|
||||||
return origRect;
|
return origRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user