* Unstrip fixes and cleanups
This commit is contained in:
sinaioutlander 2020-10-14 20:47:19 +11:00
parent 680556d74e
commit 968546d43c
18 changed files with 1972 additions and 297 deletions

View File

@ -262,6 +262,8 @@
<Compile Include="UI\WindowBase.cs" /> <Compile Include="UI\WindowBase.cs" />
<Compile Include="UI\WindowManager.cs" /> <Compile Include="UI\WindowManager.cs" />
<Compile Include="Unstrip\ImageConversion\ImageConversionUnstrip.cs" /> <Compile Include="Unstrip\ImageConversion\ImageConversionUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\Internal_GUIUtility.cs" />
<Compile Include="Unstrip\IMGUI\Internal_TextEditor.cs" />
<Compile Include="Unstrip\LayerMask\LayerMaskUnstrip.cs" /> <Compile Include="Unstrip\LayerMask\LayerMaskUnstrip.cs" />
<Compile Include="Unstrip\Scene\SceneUnstrip.cs" /> <Compile Include="Unstrip\Scene\SceneUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" /> <Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" />

View File

@ -1,4 +1,6 @@
using Explorer.Config; using System.Collections;
using System.Linq;
using Explorer.Config;
using Explorer.UI; using Explorer.UI;
using Explorer.UI.Inspectors; using Explorer.UI.Inspectors;
using Explorer.UI.Main; using Explorer.UI.Main;
@ -10,7 +12,7 @@ namespace Explorer
public class ExplorerCore public class ExplorerCore
{ {
public const string NAME = "Explorer " + VERSION + " (" + PLATFORM + ", " + MODLOADER + ")"; public const string NAME = "Explorer " + VERSION + " (" + PLATFORM + ", " + MODLOADER + ")";
public const string VERSION = "2.0.5"; public const string VERSION = "2.0.6";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.explorer"; public const string GUID = "com.sinai.explorer";

View File

@ -13,7 +13,7 @@ namespace Explorer.Helpers
{ {
public static class Texture2DHelpers public static class Texture2DHelpers
{ {
#if CPP #if CPP // If Mono
#else #else
private static bool isNewEncodeMethod = false; private static bool isNewEncodeMethod = false;
private static MethodInfo EncodeToPNGMethod => m_encodeToPNGMethod ?? GetEncodeToPNGMethod(); private static MethodInfo EncodeToPNGMethod => m_encodeToPNGMethod ?? GetEncodeToPNGMethod();
@ -56,16 +56,16 @@ namespace Explorer.Helpers
} }
} }
public static Texture2D Copy(Texture2D other, Rect rect, bool isDTXnmNormal = false) public static Texture2D Copy(Texture2D orig, Rect rect, bool isDTXnmNormal = false)
{ {
Color[] pixels; Color[] pixels;
if (!other.IsReadable()) if (!orig.IsReadable())
{ {
other = ForceReadTexture(other, isDTXnmNormal); orig = ForceReadTexture(orig);
} }
pixels = other.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height); pixels = orig.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
var _newTex = new Texture2D((int)rect.width, (int)rect.height); var _newTex = new Texture2D((int)rect.width, (int)rect.height);
_newTex.SetPixels(pixels); _newTex.SetPixels(pixels);
@ -73,26 +73,21 @@ namespace Explorer.Helpers
return _newTex; return _newTex;
} }
public static Texture2D ForceReadTexture(Texture2D tex, bool isDTXnmNormal = false) public static Texture2D ForceReadTexture(Texture2D tex)
{ {
try try
{ {
var origFilter = tex.filterMode; var origFilter = tex.filterMode;
tex.filterMode = FilterMode.Point; tex.filterMode = FilterMode.Point;
RenderTexture rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32); var rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32);
rt.filterMode = FilterMode.Point; rt.filterMode = FilterMode.Point;
RenderTexture.active = rt; RenderTexture.active = rt;
Graphics.Blit(tex, rt); Graphics.Blit(tex, rt);
Texture2D _newTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false); var _newTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
_newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0); _newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
if (isDTXnmNormal)
{
_newTex = DTXnmToRGBA(_newTex);
}
_newTex.Apply(false, false); _newTex.Apply(false, false);
RenderTexture.active = null; RenderTexture.active = null;
@ -117,8 +112,11 @@ namespace Explorer.Helpers
byte[] data; byte[] data;
var savepath = dir + @"\" + name + ".png"; var savepath = dir + @"\" + name + ".png";
// Fix for non-Readable or Compressed textures. // Make sure we can EncodeToPNG it.
tex = ForceReadTexture(tex, isDTXnmNormal); if (tex.format != TextureFormat.ARGB32 || !tex.IsReadable())
{
tex = ForceReadTexture(tex);
}
if (isDTXnmNormal) if (isDTXnmNormal)
{ {
@ -129,15 +127,13 @@ namespace Explorer.Helpers
#if CPP #if CPP
data = tex.EncodeToPNG(); data = tex.EncodeToPNG();
#else #else
var method = EncodeToPNGMethod;
if (isNewEncodeMethod) if (isNewEncodeMethod)
{ {
data = (byte[])method.Invoke(null, new object[] { tex }); data = (byte[])EncodeToPNGMethod.Invoke(null, new object[] { tex });
} }
else else
{ {
data = (byte[])method.Invoke(tex, new object[0]); data = (byte[])EncodeToPNGMethod.Invoke(tex, new object[0]);
} }
#endif #endif
@ -148,8 +144,10 @@ namespace Explorer.Helpers
else else
{ {
#if CPP #if CPP
// The IL2CPP method will return invalid byte data. // The Il2Cpp EncodeToPNG() method does return System.Byte[],
// However, we can just iterate into safe C# byte[] array. // but for some reason it is not recognized or valid.
// Simple fix is iterating into a new array manually.
byte[] safeData = new byte[data.Length]; byte[] safeData = new byte[data.Length];
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
{ {
@ -185,7 +183,7 @@ namespace Explorer.Helpers
); );
} }
var newtex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false); var newtex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
newtex.SetPixels(colors); newtex.SetPixels(colors);
return newtex; return newtex;

View File

@ -50,33 +50,37 @@ namespace Explorer
public static void ResetInputAxes() => UnityEngine.Input.ResetInputAxes(); public static void ResetInputAxes() => UnityEngine.Input.ResetInputAxes();
#endif #endif
//#if CPP #if CPP
//#pragma warning disable IDE1006 #pragma warning disable IDE1006
// // public extern static string compositionString { get; } // public extern static string compositionString { get; }
// internal delegate string get_compositionString_delegate(); internal delegate IntPtr d_get_compositionString();
// internal static get_compositionString_delegate get_compositionString_iCall = internal static d_get_compositionString get_compositionString_iCall =
// IL2CPP.ResolveICall<get_compositionString_delegate>("UnityEngine.Input::get_compositionString"); IL2CPP.ResolveICall<d_get_compositionString>("UnityEngine.Input::get_compositionString");
// public static string compositionString => get_compositionString_iCall(); public static string compositionString => IL2CPP.Il2CppStringToManaged(get_compositionString_iCall());
// // public extern static Vector2 compositionCursorPos { get; set; } // public extern static Vector2 compositionCursorPos { get; set; }
// internal delegate Vector2 get_compositionCursorPos_delegate(); internal delegate void d_get_compositionCursorPos(out Vector2 ret);
// internal static get_compositionCursorPos_delegate get_compositionCursorPos_iCall = internal static d_get_compositionCursorPos get_compositionCursorPos_iCall =
// IL2CPP.ResolveICall<get_compositionCursorPos_delegate>("UnityEngine.Input::get_compositionCursorPos"); IL2CPP.ResolveICall<d_get_compositionCursorPos>("UnityEngine.Input::get_compositionCursorPos_Injected");
// internal delegate void set_compositionCursorPos_delegate(Vector2 value); internal delegate void set_compositionCursorPos_delegate(ref Vector2 value);
// internal static set_compositionCursorPos_delegate set_compositionCursorPos_iCall = internal static set_compositionCursorPos_delegate set_compositionCursorPos_iCall =
// IL2CPP.ResolveICall<set_compositionCursorPos_delegate>("UnityEngine.Input::set_compositionCursorPos"); IL2CPP.ResolveICall<set_compositionCursorPos_delegate>("UnityEngine.Input::set_compositionCursorPos_Injected");
// public static Vector2 compositionCursorPos public static Vector2 compositionCursorPos
// { {
// get => get_compositionCursorPos_iCall(); get
// set => set_compositionCursorPos_iCall(value); {
// } get_compositionCursorPos_iCall(out Vector2 ret);
return ret;
}
set => set_compositionCursorPos_iCall(ref value);
}
//#pragma warning restore IDE1006 #pragma warning restore IDE1006
//#endif #endif
} }
} }

View File

@ -72,11 +72,11 @@ namespace Explorer.UI.Inspectors
public void DrawInstanceControls(Rect rect) public void DrawInstanceControls(Rect rect)
{ {
if (m_uObj) //if (m_uObj)
{ //{
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]); // GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
} //}
GUILayout.EndHorizontal(); //GUILayout.EndHorizontal();
if (m_uObj) if (m_uObj)
{ {
@ -89,13 +89,17 @@ namespace Explorer.UI.Inspectors
GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) }); GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) });
var charWidth = obj.name.Length * 15; var charWidth = obj.name.Length * 15;
var maxWidth = rect.width - 350; var maxWidth = rect.width - 350;
var labelWidth = charWidth < maxWidth ? charWidth : maxWidth; var btnWidth = charWidth < maxWidth ? charWidth : maxWidth;
if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) })) if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(btnWidth) }))
{ {
WindowManager.InspectObject(obj, out bool _); WindowManager.InspectObject(obj, out bool _);
} }
GUI.skin.label.alignment = TextAnchor.UpperLeft; GUI.skin.label.alignment = TextAnchor.UpperLeft;
} }
else
{
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
}
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
} }

View File

@ -263,15 +263,12 @@ namespace Explorer.UI.Inspectors
? new GUILayoutOption[] { GUILayout.Width(245f) } ? new GUILayoutOption[] { GUILayout.Width(245f) }
: new GUILayoutOption[0]; : new GUILayoutOption[0];
GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth); GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth);
GUILayout.EndHorizontal();
if (asInstance != null) if (asInstance != null)
{ {
asInstance.DrawInstanceControls(rect); asInstance.DrawInstanceControls(rect);
} }
else
{
GUILayout.EndHorizontal();
}
UIStyles.HorizontalLine(Color.grey); UIStyles.HorizontalLine(Color.grey);

View File

@ -6,6 +6,10 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using System.Linq;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.UI namespace Explorer.UI
{ {

View File

@ -33,7 +33,7 @@ namespace Explorer.UI.Main
public static TextEditor textEditor; public static TextEditor textEditor;
private bool shouldRefocus; private bool shouldRefocus;
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetCompletionStyle(); public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetAutocompleteStyle();
private static GUIStyle autocompleteStyle; private static GUIStyle autocompleteStyle;
public static readonly string[] DefaultUsing = new string[] public static readonly string[] DefaultUsing = new string[]
@ -342,9 +342,9 @@ Help();";
} }
// Credit ManlyMarco // Credit ManlyMarco
private static GUIStyle GetCompletionStyle() private static GUIStyle GetAutocompleteStyle()
{ {
return autocompleteStyle = new GUIStyle(GUI.skin.button) var style = new GUIStyle
{ {
border = new RectOffset(0, 0, 0, 0), border = new RectOffset(0, 0, 0, 0),
margin = new RectOffset(0, 0, 0, 0), margin = new RectOffset(0, 0, 0, 0),
@ -353,8 +353,10 @@ Help();";
normal = { background = null }, normal = { background = null },
focused = { background = Texture2D.whiteTexture, textColor = Color.black }, focused = { background = Texture2D.whiteTexture, textColor = Color.black },
active = { background = Texture2D.whiteTexture, textColor = Color.black }, active = { background = Texture2D.whiteTexture, textColor = Color.black },
alignment = TextAnchor.MiddleLeft, alignment = TextAnchor.MiddleLeft
}; };
return autocompleteStyle = style;
} }
private class VoidType private class VoidType

View File

@ -19,8 +19,6 @@ namespace Explorer.UI.Main
private float m_timeOfLastUpdate = -1f; private float m_timeOfLastUpdate = -1f;
private const int PASSIVE_UPDATE_INTERVAL = 1; private const int PASSIVE_UPDATE_INTERVAL = 1;
private static bool m_getRootObjectsFailed;
private static string m_currentScene = ""; private static string m_currentScene = "";
// gameobject list // gameobject list
@ -50,7 +48,7 @@ namespace Explorer.UI.Main
if (m_searching) if (m_searching)
CancelSearch(); CancelSearch();
Update_Impl(true); Update_Impl();
} }
public void TraverseUp() public void TraverseUp()
@ -75,11 +73,6 @@ namespace Explorer.UI.Main
public void CancelSearch() public void CancelSearch()
{ {
m_searching = false; m_searching = false;
if (m_getRootObjectsFailed && !m_currentTransform)
{
GetRootObjectsManual_Impl();
}
} }
public List<CacheObjectBase> SearchSceneObjects(string _search) public List<CacheObjectBase> SearchSceneObjects(string _search)
@ -112,7 +105,7 @@ namespace Explorer.UI.Main
Update_Impl(); Update_Impl();
} }
private void Update_Impl(bool manual = false) private void Update_Impl()
{ {
List<Transform> allTransforms = new List<Transform>(); List<Transform> allTransforms = new List<Transform>();
@ -125,10 +118,6 @@ namespace Explorer.UI.Main
} }
} }
else else
{
if (!m_getRootObjectsFailed)
{
try
{ {
for (int i = 0; i < SceneManager.sceneCount; i++) for (int i = 0; i < SceneManager.sceneCount; i++)
{ {
@ -136,31 +125,19 @@ namespace Explorer.UI.Main
if (scene.name == m_currentScene) if (scene.name == m_currentScene)
{ {
allTransforms.AddRange(scene.GetRootGameObjects() var rootObjects =
.Select(it => it.transform)); #if CPP
Unstrip.Scenes.SceneUnstrip.GetRootGameObjects(scene)
.Select(it => it.transform);
#else
scene.GetRootGameObjects().Select(it => it.transform);
#endif
allTransforms.AddRange(rootObjects);
break; break;
} }
} }
} }
catch
{
ExplorerCore.Log("Exception getting root scene objects, falling back to backup method...");
m_getRootObjectsFailed = true;
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
else
{
if (!manual)
{
return;
}
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
Pages.ItemCount = allTransforms.Count; Pages.ItemCount = allTransforms.Count;
@ -178,36 +155,6 @@ namespace Explorer.UI.Main
} }
} }
private IEnumerable<Transform> GetRootObjectsManual_Impl()
{
try
{
var array = Resources.FindObjectsOfTypeAll(ReflectionHelpers.TransformType);
var list = new List<Transform>();
foreach (var obj in array)
{
#if CPP
var transform = obj.TryCast<Transform>();
#else
var transform = obj as Transform;
#endif
if (transform.parent == null && transform.gameObject.scene.name == m_currentScene)
{
list.Add(transform);
}
}
return list;
}
catch (Exception e)
{
ExplorerCore.Log("Exception getting root scene objects (manual): "
+ e.GetType() + ", " + e.Message + "\r\n"
+ e.StackTrace);
return new Transform[0];
}
}
// --------- GUI Draw Function --------- // // --------- GUI Draw Function --------- //
public override void DrawWindow() public override void DrawWindow()
@ -292,15 +239,12 @@ namespace Explorer.UI.Main
{ {
int index = names.IndexOf(m_currentScene); int index = names.IndexOf(m_currentScene);
index += changeWanted; index += changeWanted;
if (index > scenes.Count - 1)
if (index >= 0 && index < SceneManager.sceneCount)
{ {
index = 0;
}
else if (index < 0)
{
index = scenes.Count - 1;
}
m_currentScene = scenes[index].name; m_currentScene = scenes[index].name;
Update_Impl();
}
} }
} }
} }
@ -317,7 +261,7 @@ namespace Explorer.UI.Main
{ {
Pages.TurnPage(Turn.Left, ref this.scroll); Pages.TurnPage(Turn.Left, ref this.scroll);
Update_Impl(true); Update_Impl();
} }
Pages.CurrentPageLabel(); Pages.CurrentPageLabel();
@ -326,7 +270,7 @@ namespace Explorer.UI.Main
{ {
Pages.TurnPage(Turn.Right, ref this.scroll); Pages.TurnPage(Turn.Right, ref this.scroll);
Update_Impl(true); Update_Impl();
} }
} }
@ -356,14 +300,6 @@ namespace Explorer.UI.Main
else else
{ {
GUILayout.Label("Scene Root GameObjects:", new GUILayoutOption[0]); GUILayout.Label("Scene Root GameObjects:", new GUILayoutOption[0]);
if (m_getRootObjectsFailed)
{
if (GUILayout.Button("Update Root Object List (auto-update failed!)", new GUILayoutOption[0]))
{
Update_Impl(true);
}
}
} }
if (m_objectList.Count > 0) if (m_objectList.Count > 0)

View File

@ -117,13 +117,6 @@ namespace Explorer.UI.Main
Pages.PageOffset = 0; Pages.PageOffset = 0;
// Would use Task, but Explorer is .NET 3.5-compatible.
var objectsOfType = FindAllObjectsOfType(m_searchInput, m_typeInput);
CacheResults(objectsOfType);
}
private List<object> FindAllObjectsOfType(string searchQuery, string typeName)
{
#if CPP #if CPP
Il2CppSystem.Type searchType = null; Il2CppSystem.Type searchType = null;
@ -132,9 +125,7 @@ namespace Explorer.UI.Main
#endif #endif
if (TypeMode == TypeFilter.Custom) if (TypeMode == TypeFilter.Custom)
{ {
try if (ReflectionHelpers.GetTypeByName(m_typeInput) is Type t)
{
if (ReflectionHelpers.GetTypeByName(typeName) is Type t)
{ {
#if CPP #if CPP
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName); searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
@ -144,12 +135,8 @@ namespace Explorer.UI.Main
} }
else else
{ {
throw new Exception($"Could not find a Type by the name of '{typeName}'!"); ExplorerCore.Log($"Could not find a Type by the name of '{m_typeInput}'!");
} return;
}
catch (Exception e)
{
ExplorerCore.Log("Exception getting Search Type: " + e.GetType() + ", " + e.Message);
} }
} }
else if (TypeMode == TypeFilter.Object) else if (TypeMode == TypeFilter.Object)
@ -171,7 +158,7 @@ namespace Explorer.UI.Main
{ {
ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!"); ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!");
} }
return new List<object>(); return;
} }
var matches = new List<object>(); var matches = new List<object>();
@ -185,7 +172,7 @@ namespace Explorer.UI.Main
{ {
if (i >= MaxSearchResults) break; if (i >= MaxSearchResults) break;
if (searchQuery != "" && !obj.name.ToLower().Contains(searchQuery.ToLower())) if (m_searchInput != "" && !obj.name.ToLower().Contains(m_searchInput.ToLower()))
{ {
continue; continue;
} }
@ -215,11 +202,7 @@ namespace Explorer.UI.Main
i++; i++;
} }
allObjectsOfType = null; CacheResults(matches);
searchType = null;
searchQuery = null;
return matches;
} }
public static bool FilterScene(object obj, SceneFilter filter) public static bool FilterScene(object obj, SceneFilter filter)

View File

@ -66,7 +66,7 @@ namespace Explorer.UI
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.button.alignment = TextAnchor.MiddleLeft; GUI.skin.button.alignment = TextAnchor.MiddleLeft;
int tabPerRow = Mathf.FloorToInt((float)((decimal)m_rect.width / 238)); int tabPerRow = (int)Math.Floor((float)((decimal)m_rect.width / 238));
int rowCount = 0; int rowCount = 0;
for (int i = 0; i < WindowManager.Windows.Count; i++) for (int i = 0; i < WindowManager.Windows.Count; i++)
{ {

View File

@ -53,12 +53,21 @@ namespace Explorer
public static string TextField(string text, GUILayoutOption[] options) public static string TextField(string text, GUILayoutOption[] options)
{ {
#if CPP #if CPP
return Internal.TextField(text, options); return Internal.TextField(text, options, false);
#else #else
return GUILayout.TextField(text, options); return GUILayout.TextField(text, options);
#endif #endif
} }
public static string TextArea(string text, params GUILayoutOption[] options)
{
#if CPP
return Internal.TextField(text, options, true);
#else
return GUILayout.TextArea(text, options);
#endif
}
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title) public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
{ {
#if CPP #if CPP
@ -77,15 +86,6 @@ namespace Explorer
#endif #endif
} }
public static string TextArea(string text, params GUILayoutOption[] options)
{
#if CPP
return GUILayout.DoTextField(text, -1, true, GUI.skin.textArea, options);
#else
return GUILayout.TextArea(text, options);
#endif
}
public static void BringWindowToFront(int id) public static void BringWindowToFront(int id)
{ {
#if CPP #if CPP

View File

@ -16,12 +16,9 @@ namespace Explorer.Unstrip.IMGUI
public static bool ScrollFailed = false; public static bool ScrollFailed = false;
public static bool ManualUnstripFailed = false; public static bool ManualUnstripFailed = false;
public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack(); public static Stack<object> ScrollStack => m_scrollStack ?? GetScrollStack();
public static PropertyInfo m_scrollViewStatesInfo; public static Stack<object> m_scrollStack;
public static GenericStack m_scrollStack; //public static PropertyInfo m_scrollViewStatesInfo;
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle(); public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle();
public static GUIStyle m_spaceStyle; public static GUIStyle m_spaceStyle;
@ -34,53 +31,13 @@ namespace Explorer.Unstrip.IMGUI
public static MethodInfo m_bringWindowToFrontMethod; public static MethodInfo m_bringWindowToFrontMethod;
public static bool m_bringWindowFrontAttempted; public static bool m_bringWindowFrontAttempted;
private static GenericStack GetScrollStack() private static Stack<object> GetScrollStack()
{ {
if (m_scrollViewStatesInfo == null) m_scrollStack = new Stack<object>();
{
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; return m_scrollStack;
} }
private static Dictionary<int, Il2CppSystem.Object> GetStateCacheDict()
{
if (m_stateCacheDict == null)
{
try
{
var type = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects");
m_stateCacheDict = type.GetProperty("s_StateCache")
.GetValue(null, null)
as Dictionary<int, Il2CppSystem.Object>;
if (m_stateCacheDict == null) throw new Exception();
}
catch
{
m_stateCacheDict = new Dictionary<int, Il2CppSystem.Object>();
}
}
return m_stateCacheDict;
}
private static GUIStyle GetSpaceStyle() private static GUIStyle GetSpaceStyle()
{ {
try try
@ -115,7 +72,7 @@ namespace Explorer.Unstrip.IMGUI
GUI.Box(g.rect, content, style); GUI.Box(g.rect, content, style);
} }
public static string TextField(string text, GUILayoutOption[] options) public static string TextField(string text, GUILayoutOption[] options, bool multiLine)
{ {
text = text ?? string.Empty; text = text ?? string.Empty;
@ -137,13 +94,13 @@ namespace Explorer.Unstrip.IMGUI
{ {
guicontent = GUIContent.Temp(text); guicontent = GUIContent.Temp(text);
} }
DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField); DoTextField(rect, controlID, guicontent, multiLine, -1, GUI.skin.textField);
return guicontent.text; return guicontent.text;
} }
internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style) internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style)
{ {
if (GetStateObject(Il2CppType.Of<TextEditor>(), id).TryCast<TextEditor>() is TextEditor textEditor) if (Internal_GUIUtility.GetMonoStateObject(typeof(Internal_TextEditor), id) is Internal_TextEditor textEditor)
{ {
if (maxLength >= 0 && content.text.Length > maxLength) if (maxLength >= 0 && content.text.Length > maxLength)
{ {
@ -156,11 +113,138 @@ namespace Explorer.Unstrip.IMGUI
textEditor.multiline = multiline; textEditor.multiline = multiline;
textEditor.controlID = id; textEditor.controlID = id;
textEditor.DetectFocusChange(); textEditor.DetectFocusChange();
GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor); HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
textEditor.UpdateScrollOffsetIfNeeded(Event.current); textEditor.UpdateScrollOffsetIfNeeded(Event.current);
} }
} }
private static void HandleTextFieldEventForDesktop(Rect position, int id, GUIContent content, bool multiline, int maxLength,
GUIStyle style, Internal_TextEditor editor)
{
var evt = Event.current;
bool change = false;
switch (evt.type)
{
case EventType.MouseDown:
if (position.Contains(evt.mousePosition))
{
GUIUtility.hotControl = id;
GUIUtility.keyboardControl = id;
editor.m_HasFocus = true;
editor.MoveCursorToPosition(Event.current.mousePosition);
if (Event.current.clickCount == 2 && GUI.skin.settings.doubleClickSelectsWord)
{
editor.SelectCurrentWord();
editor.DblClickSnap(Internal_TextEditor.DblClickSnapping.WORDS);
editor.MouseDragSelectsWholeWords(true);
}
if (Event.current.clickCount == 3 && GUI.skin.settings.tripleClickSelectsLine)
{
editor.SelectCurrentParagraph();
editor.MouseDragSelectsWholeWords(true);
editor.DblClickSnap(Internal_TextEditor.DblClickSnapping.PARAGRAPHS);
}
evt.Use();
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl == id)
{
if (evt.shift)
editor.MoveCursorToPosition(Event.current.mousePosition);
else
editor.SelectToPosition(Event.current.mousePosition);
evt.Use();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == id)
{
editor.MouseDragSelectsWholeWords(false);
GUIUtility.hotControl = 0;
evt.Use();
}
break;
case EventType.KeyDown:
if (GUIUtility.keyboardControl != id)
return;
if (editor.HandleKeyEvent(evt))
{
evt.Use();
change = true;
content.text = editor.text;
break;
}
// Ignore tab & shift-tab in textfields
if (evt.keyCode == KeyCode.Tab || evt.character == '\t')
return;
char c = evt.character;
if (c == '\n' && !multiline && !evt.alt)
return;
// Simplest test: only allow the character if the display font supports it.
Font font = style.font;
if (!font)
font = GUI.skin.font;
if (font.HasCharacter(c) || c == '\n')
{
editor.Insert(c);
change = true;
break;
}
// On windows, keypresses also send events with keycode but no character. Eat them up here.
if (c == 0)
{
// if we have a composition string, make sure we clear the previous selection.
if (InputManager.compositionString.Length > 0)
{
editor.ReplaceSelection("");
change = true;
}
evt.Use();
}
// else {
// REALLY USEFUL:
// Debug.Log ("unhandled " +evt);
// evt.Use ();
// }
break;
case EventType.Repaint:
// If we have keyboard focus, draw the cursor
// TODO: check if this OpenGL view has keyboard focus
if (GUIUtility.keyboardControl != id)
{
style.Draw(position, content, id, false);
}
else
{
editor.DrawCursor(content.text);
}
break;
}
if (GUIUtility.keyboardControl == id)
GUIUtility.textFieldInput = true;
if (change)
{
GUI.changed = true;
content.text = editor.text;
if (maxLength >= 0 && content.text.Length > maxLength)
content.text = content.text.Substring(0, maxLength);
evt.Use();
}
}
public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options) public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ {
return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive); return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive);
@ -279,22 +363,6 @@ namespace Explorer.Unstrip.IMGUI
#region Scrolling #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) public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
{ {
// First, just try normal way, may not have been stripped or was unstripped successfully. // First, just try normal way, may not have been stripped or was unstripped successfully.
@ -348,10 +416,12 @@ namespace Explorer.Unstrip.IMGUI
if (ScrollStack.Count <= 0) return; if (ScrollStack.Count <= 0) return;
var state = ScrollStack.Peek().TryCast<ScrollViewState>(); var scrollExt = ScrollStack.Peek() as Internal_ScrollViewState;
var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
if (scrollExt == null) throw new Exception("Could not get scrollExt!"); //var state = ScrollStack.Peek().TryCast<ScrollViewState>();
//var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
//if (scrollExt == null) throw new Exception("Could not get scrollExt!");
GUIClip.Pop(); GUIClip.Pop();
@ -419,16 +489,18 @@ namespace Explorer.Unstrip.IMGUI
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive); int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
var scrollViewState = GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID) var scrollExt = (Internal_ScrollViewState)Internal_GUIUtility.GetMonoStateObject(typeof(Internal_ScrollViewState), controlID);
.TryCast<ScrollViewState>();
if (scrollViewState == null) //var scrollViewState = Internal_GUIUtility.GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID)
return scrollPosition; // .TryCast<ScrollViewState>();
var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer); //if (scrollViewState == null)
// return scrollPosition;
if (scrollExt == null) //var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer);
return scrollPosition;
//if (scrollExt == null)
// return scrollPosition;
bool apply = scrollExt.apply; bool apply = scrollExt.apply;
if (apply) if (apply)
@ -446,7 +518,7 @@ namespace Explorer.Unstrip.IMGUI
rect.width = position.width; rect.width = position.width;
rect.height = position.height; rect.height = position.height;
ScrollStack.Push(scrollViewState); ScrollStack.Push(scrollExt);
Rect screenRect = new Rect(position.x, position.y, position.width, position.height); Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
EventType type = Event.current.type; EventType type = Event.current.type;

View File

@ -0,0 +1,66 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Explorer.Unstrip.IMGUI
{
public class Internal_GUIUtility
{
public static Dictionary<int, object> MonoStateCache = new Dictionary<int, object>();
public static object GetMonoStateObject(Type type, int controlID)
{
if (!MonoStateCache.ContainsKey(controlID))
{
MonoStateCache.Add(controlID, Activator.CreateInstance(type));
}
return MonoStateCache[controlID];
}
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
public 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;
}
private static Dictionary<int, Il2CppSystem.Object> GetStateCacheDict()
{
if (m_stateCacheDict == null)
{
try
{
m_stateCacheDict = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects")
.GetProperty("s_StateCache")
.GetValue(null, null)
as Dictionary<int, Il2CppSystem.Object>;
if (m_stateCacheDict == null) throw new Exception();
}
catch
{
m_stateCacheDict = new Dictionary<int, Il2CppSystem.Object>();
}
}
return m_stateCacheDict;
}
}
}
#endif

View File

@ -13,16 +13,76 @@ namespace Explorer.Unstrip.IMGUI
public Vector2 scrollPosition; public Vector2 scrollPosition;
public bool apply; public bool apply;
public static Dictionary<IntPtr, Internal_ScrollViewState> Dict = new Dictionary<IntPtr, Internal_ScrollViewState>(); public void ScrollTo(Rect pos)
public static Internal_ScrollViewState FromPointer(IntPtr ptr)
{ {
if (!Dict.ContainsKey(ptr)) this.ScrollTowards(pos, float.PositiveInfinity);
{
Dict.Add(ptr, new Internal_ScrollViewState());
} }
return Dict[ptr]; public bool ScrollTowards(Rect pos, float maxDelta)
{
Vector2 b = this.ScrollNeeded(pos);
bool result;
if (b.sqrMagnitude < 0.0001f)
{
result = false;
}
else if (maxDelta == 0f)
{
result = true;
}
else
{
if (b.magnitude > maxDelta)
{
b = b.normalized * maxDelta;
}
this.scrollPosition += b;
this.apply = true;
result = true;
}
return result;
}
private Vector2 ScrollNeeded(Rect pos)
{
Rect rect = this.visibleRect;
rect.x += this.scrollPosition.x;
rect.y += this.scrollPosition.y;
float num = pos.width - this.visibleRect.width;
if (num > 0f)
{
pos.width -= num;
pos.x += num * 0.5f;
}
num = pos.height - this.visibleRect.height;
if (num > 0f)
{
pos.height -= num;
pos.y += num * 0.5f;
}
Vector2 zero = Vector2.zero;
if (pos.xMax > rect.xMax)
{
zero.x += pos.xMax - rect.xMax;
}
else if (pos.xMin < rect.xMin)
{
zero.x -= rect.xMin - pos.xMin;
}
if (pos.yMax > rect.yMax)
{
zero.y += pos.yMax - rect.yMax;
}
else if (pos.yMin < rect.yMin)
{
zero.y -= rect.yMin - pos.yMin;
}
Rect rect2 = this.viewRect;
rect2.width = Mathf.Max(rect2.width, this.visibleRect.width);
rect2.height = Mathf.Max(rect2.height, this.visibleRect.height);
zero.x = Mathf.Clamp(zero.x, rect2.xMin - this.scrollPosition.x, rect2.xMax - this.visibleRect.width - this.scrollPosition.x);
zero.y = Mathf.Clamp(zero.y, rect2.yMin - this.scrollPosition.y, rect2.yMax - this.visibleRect.height - this.scrollPosition.y);
return zero;
} }
} }
} }

View File

@ -118,8 +118,8 @@ namespace Explorer.Unstrip.IMGUI
GUI.changed = true; GUI.changed = true;
if (this.SupportsPageMovements()) if (this.SupportsPageMovements())
{ {
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); var state = GetSliderState();
ext.isDragging = false; state.isDragging = false;
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0); Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
ScrollTroughSide = this.CurrentScrollTroughSide(); ScrollTroughSide = this.CurrentScrollTroughSide();
result = this.PageMovementValue(); result = this.PageMovementValue();
@ -144,8 +144,8 @@ namespace Explorer.Unstrip.IMGUI
} }
else else
{ {
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); var state = GetSliderState();
if (!ext.isDragging) if (!state.isDragging)
{ {
result = this.currentValue; result = this.currentValue;
} }
@ -153,8 +153,8 @@ namespace Explorer.Unstrip.IMGUI
{ {
GUI.changed = true; GUI.changed = true;
this.CurrentEvent().Use(); this.CurrentEvent().Use();
float num = this.MousePosition() - ext.dragStartPos; float num = this.MousePosition() - state.dragStartPos;
float value = ext.dragStartValue + num / this.ValuesPerPixel(); float value = state.dragStartValue + num / this.ValuesPerPixel();
result = this.Clamp(value); result = this.Clamp(value);
} }
} }
@ -207,7 +207,7 @@ namespace Explorer.Unstrip.IMGUI
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0); Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
if (this.SupportsPageMovements()) if (this.SupportsPageMovements())
{ {
Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false; GetSliderState().isDragging = false;
GUI.changed = true; GUI.changed = true;
result = this.PageMovementValue(); result = this.PageMovementValue();
} }
@ -303,15 +303,15 @@ namespace Explorer.Unstrip.IMGUI
private void StartDraggingWithValue(float dragStartValue) private void StartDraggingWithValue(float dragStartValue)
{ {
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer); var state = GetSliderState();
ext.dragStartPos = this.MousePosition(); state.dragStartPos = this.MousePosition();
ext.dragStartValue = dragStartValue; state.dragStartValue = dragStartValue;
ext.isDragging = true; state.isDragging = true;
} }
private SliderState GetSliderState() private Internal_SliderState GetSliderState()
{ {
return GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>(); return (Internal_SliderState)Internal_GUIUtility.GetMonoStateObject(typeof(Internal_SliderState), this.id);
} }
private Rect ThumbRect() private Rect ThumbRect()

View File

@ -10,17 +10,5 @@ namespace Explorer.Unstrip.IMGUI
public float dragStartPos; public float dragStartPos;
public float dragStartValue; public float dragStartValue;
public bool isDragging; public bool isDragging;
public static Dictionary<IntPtr, Internal_SliderState> Dict = new Dictionary<IntPtr, Internal_SliderState>();
public static Internal_SliderState FromPointer(IntPtr ptr)
{
if (!Dict.ContainsKey(ptr))
{
Dict.Add(ptr, new Internal_SliderState());
}
return Dict[ptr];
}
} }
} }

File diff suppressed because it is too large Load Diff