mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-23 00:52:31 +08:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
3c964cfef9 | |||
184b037523 | |||
a49a918790 | |||
e3a58bf675 | |||
cc29dbda30 | |||
bc0ad5eab6 | |||
bdf86a7448 | |||
968546d43c | |||
680556d74e | |||
f490203b10 | |||
39d9585f1d | |||
2d414e544b | |||
513fcaa534 | |||
b41f7211e5 |
14
README.md
14
README.md
@ -78,11 +78,16 @@ There is a simple Mod Config for the Explorer. You can access the settings via t
|
||||
* Whether or not to show the Bitwise Editing helper when inspecting integers
|
||||
|
||||
`Enable Tab View` (bool) | Default: `true`
|
||||
* Whether or not all inspector windows a grouped into a single window with tabs.
|
||||
* Whether or not all inspector windows a grouped into a single window with tabs.
|
||||
|
||||
`Default Output Path` (string) | Default: `Mods\Explorer`
|
||||
* Where output is generated to, by default (for Texture PNG saving, etc).
|
||||
|
||||
## Mouse Control
|
||||
|
||||
Explorer can force the mouse to be visible and unlocked when the menu is open, if you have enabled "Force Unlock Mouse" (Left-Alt toggle). However, you may also want to prevent the mouse clicking-through onto the game behind Explorer, this is possible but it requires specific patches for that game.
|
||||
Explorer can force the mouse to be visible and unlocked when the menu is open, if you have enabled "Force Unlock Mouse" (Left-Alt toggle). Explorer also attempts to prevent clicking-through onto the game behind the Explorer menu.
|
||||
|
||||
If you need more mouse control:
|
||||
|
||||
* For VRChat, use [VRCExplorerMouseControl](https://github.com/sinai-dev/VRCExplorerMouseControl)
|
||||
* For Hellpoint, use [HPExplorerMouseControl](https://github.com/sinai-dev/Hellpoint-Mods/tree/master/HPExplorerMouseControl/HPExplorerMouseControl)
|
||||
@ -93,8 +98,9 @@ For example:
|
||||
using Explorer;
|
||||
using Harmony; // or 'using HarmonyLib;' for BepInEx
|
||||
// ...
|
||||
[HarmonyPatch(typeof(MyGame.MenuClass), nameof(MyGame.MenuClass.CursorUpdate)]
|
||||
public class MenuClass_CursorUpdate
|
||||
// You will need to figure out the relevant Class and Method for your game using dnSpy.
|
||||
[HarmonyPatch(typeof(MyGame.InputManager), nameof(MyGame.InputManager.Update))]
|
||||
public class InputManager_Update
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
public static bool Prefix()
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Reflection;
|
||||
using Explorer.CacheObject;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using Explorer.UI;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.CacheObject
|
||||
{
|
||||
@ -21,6 +23,15 @@ namespace Explorer.CacheObject
|
||||
|
||||
public override void UpdateValue()
|
||||
{
|
||||
if (IValue is InteractiveDictionary iDict)
|
||||
{
|
||||
if (!iDict.EnsureDictionaryIsSupported())
|
||||
{
|
||||
ReflectionException = "Not supported due to TypeInitializationException";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var fi = MemInfo as FieldInfo;
|
||||
|
@ -53,7 +53,7 @@ namespace Explorer.CacheObject
|
||||
{
|
||||
if (m_arguments.Length < 1)
|
||||
{
|
||||
return null;
|
||||
return new object[0];
|
||||
}
|
||||
|
||||
var parsedArgs = new List<object>();
|
||||
@ -123,13 +123,13 @@ namespace Explorer.CacheObject
|
||||
label = $"<i>[{label} = {this.m_arguments[i].DefaultValue ?? "null"}]</i>";
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) });
|
||||
GUILayout.Label(label, new GUILayoutOption[] { GUILayout.ExpandWidth(false) });
|
||||
this.m_argumentInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
|
||||
this.m_argumentInput[i] = GUIHelper.TextField(input, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.CacheObject
|
||||
{
|
||||
@ -181,14 +182,14 @@ namespace Explorer.CacheObject
|
||||
}
|
||||
var input = this.GenericArgInput[i];
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label(
|
||||
$"<color={Syntax.StructGreen}>{this.GenericArgs[i].Name}</color>",
|
||||
new GUILayoutOption[] { GUILayout.Width(15) }
|
||||
);
|
||||
this.GenericArgInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
||||
this.GenericArgInput[i] = GUIHelper.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
|
||||
GUILayout.Label(types, new GUILayoutOption[0]);
|
||||
|
||||
|
@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.UI;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.CacheObject
|
||||
{
|
||||
@ -37,6 +38,10 @@ namespace Explorer.CacheObject
|
||||
{
|
||||
interactive = new InteractiveTexture2D();
|
||||
}
|
||||
else if (valueType == typeof(Texture))
|
||||
{
|
||||
interactive = new InteractiveTexture();
|
||||
}
|
||||
else if (valueType == typeof(Sprite))
|
||||
{
|
||||
interactive = new InteractiveSprite();
|
||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using Explorer.UI;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.CacheObject
|
||||
{
|
||||
@ -32,14 +34,38 @@ namespace Explorer.CacheObject
|
||||
return;
|
||||
}
|
||||
|
||||
if (IValue is InteractiveDictionary iDict)
|
||||
{
|
||||
if (!iDict.EnsureDictionaryIsSupported())
|
||||
{
|
||||
ReflectionException = "Not supported due to TypeInitializationException";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var pi = MemInfo as PropertyInfo;
|
||||
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
||||
|
||||
IValue.Value = pi.GetValue(target, ParseArguments());
|
||||
if (pi.CanRead)
|
||||
{
|
||||
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
||||
|
||||
base.UpdateValue();
|
||||
IValue.Value = pi.GetValue(target, ParseArguments());
|
||||
|
||||
base.UpdateValue();
|
||||
}
|
||||
else // create a dummy value for Write-Only properties.
|
||||
{
|
||||
if (IValue.ValueType == typeof(string))
|
||||
{
|
||||
IValue.Value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
IValue.Value = Activator.CreateInstance(IValue.ValueType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -208,11 +208,13 @@
|
||||
<Compile Include="CacheObject\CacheMethod.cs" />
|
||||
<Compile Include="CacheObject\CacheProperty.cs" />
|
||||
<Compile Include="CacheObject\CacheObjectBase.cs" />
|
||||
<Compile Include="Helpers\Texture2DHelpers.cs" />
|
||||
<Compile Include="UI\InteractiveValue\InteractiveValue.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveDictionary.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveEnumerable.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveGameObject.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveSprite.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveTexture.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Object\InteractiveTexture2D.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Struct\InteractiveQuaternion.cs" />
|
||||
<Compile Include="UI\InteractiveValue\Struct\InteractiveRect.cs" />
|
||||
@ -229,7 +231,7 @@
|
||||
<Compile Include="Extensions\UnityExtensions.cs" />
|
||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||
<Compile Include="Input\AbstractInput.cs" />
|
||||
<Compile Include="Input\IAbstractInput.cs" />
|
||||
<Compile Include="Tests\TestClass.cs" />
|
||||
<Compile Include="UI\ForceUnlockCursor.cs" />
|
||||
<Compile Include="Input\InputManager.cs" />
|
||||
@ -260,14 +262,19 @@
|
||||
<Compile Include="UI\WindowBase.cs" />
|
||||
<Compile Include="UI\WindowManager.cs" />
|
||||
<Compile Include="Unstrip\ImageConversion\ImageConversionUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\GUIUtilityUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\TextEditorUnstrip.cs" />
|
||||
<Compile Include="Helpers\ICallHelper.cs" />
|
||||
<Compile Include="Unstrip\LayerMask\LayerMaskUnstrip.cs" />
|
||||
<Compile Include="Unstrip\Resources\ResourcesUnstrip.cs" />
|
||||
<Compile Include="Unstrip\Scene\SceneUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\Internal_LayoutUtility.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\Internal_ScrollViewState.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\Internal_SliderHandler.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\GUIHelper.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\LayoutUtilityUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\ScrollViewStateUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\SliderHandlerUnstrip.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\Internal.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\Internal_SliderState.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" />
|
||||
<Compile Include="Unstrip\IMGUI\SliderStateUnstrip.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ILRepack.targets" />
|
||||
|
@ -1,4 +1,6 @@
|
||||
using Explorer.Config;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using Explorer.Config;
|
||||
using Explorer.UI;
|
||||
using Explorer.UI.Inspectors;
|
||||
using Explorer.UI.Main;
|
||||
@ -10,7 +12,7 @@ namespace Explorer
|
||||
public class ExplorerCore
|
||||
{
|
||||
public const string NAME = "Explorer " + VERSION + " (" + PLATFORM + ", " + MODLOADER + ")";
|
||||
public const string VERSION = "2.0.2";
|
||||
public const string VERSION = "2.0.7";
|
||||
public const string AUTHOR = "Sinai";
|
||||
public const string GUID = "com.sinai.explorer";
|
||||
|
||||
@ -31,6 +33,12 @@ namespace Explorer
|
||||
|
||||
public ExplorerCore()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
Log("An instance of Explorer is already active!");
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
|
||||
ModConfig.OnLoad();
|
||||
@ -87,6 +95,11 @@ namespace Explorer
|
||||
WindowManager.Instance.OnGUI();
|
||||
InspectUnderMouse.OnGUI();
|
||||
|
||||
if (!ResizeDrag.IsMouseInResizeArea && WindowManager.IsMouseInWindow)
|
||||
{
|
||||
InputManager.ResetInputAxes();
|
||||
}
|
||||
|
||||
GUI.skin = origSkin;
|
||||
}
|
||||
|
||||
@ -99,27 +112,27 @@ namespace Explorer
|
||||
public static void Log(object message)
|
||||
{
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.Log(message.ToString());
|
||||
MelonLoader.MelonLogger.Log(message?.ToString());
|
||||
#else
|
||||
ExplorerBepInPlugin.Logging?.LogMessage(message.ToString());
|
||||
ExplorerBepInPlugin.Logging?.LogMessage(message?.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogWarning(object message)
|
||||
{
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.LogWarning(message.ToString());
|
||||
MelonLoader.MelonLogger.LogWarning(message?.ToString());
|
||||
#else
|
||||
ExplorerBepInPlugin.Logging?.LogWarning(message.ToString());
|
||||
ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogError(object message)
|
||||
{
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.LogError(message.ToString());
|
||||
MelonLoader.MelonLogger.LogError(message?.ToString());
|
||||
#else
|
||||
ExplorerBepInPlugin.Logging?.LogError(message.ToString());
|
||||
ExplorerBepInPlugin.Logging?.LogError(message?.ToString());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
|
41
src/Helpers/ICallHelper.cs
Normal file
41
src/Helpers/ICallHelper.cs
Normal file
@ -0,0 +1,41 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Explorer.Helpers
|
||||
{
|
||||
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
|
||||
public static class ICallHelper
|
||||
{
|
||||
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
|
||||
|
||||
public static T GetICall<T>(string iCallName) where T : Delegate
|
||||
{
|
||||
if (iCallCache.ContainsKey(iCallName))
|
||||
{
|
||||
return (T)iCallCache[iCallName];
|
||||
}
|
||||
|
||||
var ptr = il2cpp_resolve_icall(iCallName);
|
||||
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new MissingMethodException($"Could not resolve internal call by name '{iCallName}'!");
|
||||
}
|
||||
|
||||
var iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
||||
iCallCache.Add(iCallName, iCall);
|
||||
|
||||
return (T)iCall;
|
||||
}
|
||||
|
||||
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -5,94 +5,83 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using BF = System.Reflection.BindingFlags;
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
#if CPP
|
||||
using ILType = Il2CppSystem.Type;
|
||||
using UnhollowerBaseLib;
|
||||
using UnhollowerRuntimeLib;
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
namespace Explorer
|
||||
namespace Explorer.Helpers
|
||||
{
|
||||
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
|
||||
public class ReflectionHelpers
|
||||
{
|
||||
public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
|
||||
|
||||
#if CPP
|
||||
public static ILType GameObjectType => Il2CppType.Of<GameObject>();
|
||||
public static ILType TransformType => Il2CppType.Of<Transform>();
|
||||
public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>();
|
||||
public static ILType ComponentType => Il2CppType.Of<Component>();
|
||||
public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
|
||||
public static ILType TransformType => Il2CppType.Of<Transform>();
|
||||
public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>();
|
||||
public static ILType ComponentType => Il2CppType.Of<Component>();
|
||||
public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
|
||||
#else
|
||||
public static Type GameObjectType => typeof(GameObject);
|
||||
public static Type TransformType => typeof(Transform);
|
||||
public static Type ObjectType => typeof(UnityEngine.Object);
|
||||
public static Type ComponentType => typeof(Component);
|
||||
public static Type BehaviourType => typeof(Behaviour);
|
||||
#endif
|
||||
|
||||
private static readonly MethodInfo tryCastMethodInfo = typeof(Il2CppObjectBase).GetMethod("TryCast");
|
||||
private static readonly Dictionary<Type, MethodInfo> cachedTryCastMethods = new Dictionary<Type, MethodInfo>();
|
||||
#if CPP
|
||||
private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>();
|
||||
|
||||
public static object Il2CppCast(object obj, Type castTo)
|
||||
{
|
||||
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo)) return obj;
|
||||
if (!(obj is Il2CppSystem.Object ilObj))
|
||||
return obj;
|
||||
|
||||
if (!cachedTryCastMethods.ContainsKey(castTo))
|
||||
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo))
|
||||
return obj;
|
||||
|
||||
IntPtr castToPtr;
|
||||
if (!ClassPointers.ContainsKey(castTo))
|
||||
{
|
||||
cachedTryCastMethods.Add(castTo, tryCastMethodInfo.MakeGenericMethod(castTo));
|
||||
}
|
||||
castToPtr = (IntPtr)typeof(Il2CppClassPointerStore<>)
|
||||
.MakeGenericType(new Type[] { castTo })
|
||||
.GetField("NativeClassPtr", BF.Public | BF.Static)
|
||||
.GetValue(null);
|
||||
|
||||
return cachedTryCastMethods[castTo].Invoke(obj, null);
|
||||
}
|
||||
#else
|
||||
public static Type GameObjectType => typeof(GameObject);
|
||||
public static Type TransformType => typeof(Transform);
|
||||
public static Type ObjectType => typeof(UnityEngine.Object);
|
||||
public static Type ComponentType => typeof(Component);
|
||||
public static Type BehaviourType => typeof(Behaviour);
|
||||
#endif
|
||||
|
||||
public static bool IsEnumerable(Type t)
|
||||
{
|
||||
if (typeof(IEnumerable).IsAssignableFrom(t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if CPP
|
||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.Generic.List<>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.IList<>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.HashSet<>).IsAssignableFrom(g);
|
||||
ClassPointers.Add(castTo, castToPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.IList).IsAssignableFrom(t);
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsDictionary(Type t)
|
||||
{
|
||||
if (typeof(IDictionary).IsAssignableFrom(t))
|
||||
{
|
||||
return true;
|
||||
castToPtr = ClassPointers[castTo];
|
||||
}
|
||||
|
||||
#if CPP
|
||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.IDictionary<,>).IsAssignableFrom(g);
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|
||||
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
if (castToPtr == IntPtr.Zero)
|
||||
return obj;
|
||||
|
||||
var classPtr = il2cpp_object_get_class(ilObj.Pointer);
|
||||
|
||||
if (!il2cpp_class_is_assignable_from(castToPtr, classPtr))
|
||||
return obj;
|
||||
|
||||
if (RuntimeSpecificsStore.IsInjected(castToPtr))
|
||||
return UnhollowerBaseLib.Runtime.ClassInjectorBase.GetMonoObjectFromIl2CppPointer(ilObj.Pointer);
|
||||
|
||||
return Activator.CreateInstance(castTo, ilObj.Pointer);
|
||||
}
|
||||
|
||||
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern bool il2cpp_class_is_assignable_from(IntPtr klass, IntPtr oklass);
|
||||
|
||||
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr il2cpp_object_get_class(IntPtr obj);
|
||||
|
||||
#endif
|
||||
|
||||
public static Type GetTypeByName(string fullName)
|
||||
{
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
@ -169,48 +158,55 @@ namespace Explorer
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsEnumerable(Type t)
|
||||
{
|
||||
if (typeof(IEnumerable).IsAssignableFrom(t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if CPP
|
||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.Generic.List<>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.IList<>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.HashSet<>).IsAssignableFrom(g);
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.IList).IsAssignableFrom(t);
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsDictionary(Type t)
|
||||
{
|
||||
if (typeof(IDictionary).IsAssignableFrom(t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if CPP
|
||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).IsAssignableFrom(g)
|
||||
|| typeof(Il2CppSystem.Collections.Generic.IDictionary<,>).IsAssignableFrom(g);
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|
||||
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string ExceptionToString(Exception e)
|
||||
{
|
||||
#if CPP
|
||||
if (IsFailedGeneric(e))
|
||||
{
|
||||
return "Unable to initialize this type.";
|
||||
}
|
||||
else if (IsObjectCollected(e))
|
||||
{
|
||||
return "Garbage collected in Il2Cpp.";
|
||||
}
|
||||
#endif
|
||||
return e.GetType() + ", " + e.Message;
|
||||
}
|
||||
|
||||
#if CPP
|
||||
public static bool IsFailedGeneric(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(TargetInvocationException)) && IsExceptionOfType(e, typeof(TypeLoadException));
|
||||
}
|
||||
|
||||
public static bool IsObjectCollected(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(ObjectCollectedException));
|
||||
}
|
||||
|
||||
public static bool IsExceptionOfType(Exception e, Type t, bool strict = true, bool checkInner = true)
|
||||
{
|
||||
bool isType;
|
||||
|
||||
if (strict)
|
||||
isType = e.GetType() == t;
|
||||
else
|
||||
isType = t.IsAssignableFrom(e.GetType());
|
||||
|
||||
if (isType) return true;
|
||||
|
||||
if (e.InnerException != null && checkInner)
|
||||
return IsExceptionOfType(e.InnerException, t, strict);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
178
src/Helpers/Texture2DHelpers.cs
Normal file
178
src/Helpers/Texture2DHelpers.cs
Normal file
@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
#if CPP
|
||||
using Explorer.Unstrip.ImageConversion;
|
||||
#endif
|
||||
|
||||
namespace Explorer.Helpers
|
||||
{
|
||||
public static class Texture2DHelpers
|
||||
{
|
||||
#if CPP // If Mono
|
||||
#else
|
||||
private static bool isNewEncodeMethod = false;
|
||||
private static MethodInfo EncodeToPNGMethod => m_encodeToPNGMethod ?? GetEncodeToPNGMethod();
|
||||
private static MethodInfo m_encodeToPNGMethod;
|
||||
|
||||
private static MethodInfo GetEncodeToPNGMethod()
|
||||
{
|
||||
if (ReflectionHelpers.GetTypeByName("UnityEngine.ImageConversion") is Type imageConversion)
|
||||
{
|
||||
isNewEncodeMethod = true;
|
||||
return m_encodeToPNGMethod = imageConversion.GetMethod("EncodeToPNG", ReflectionHelpers.CommonFlags);
|
||||
}
|
||||
|
||||
var method = typeof(Texture2D).GetMethod("EncodeToPNG", ReflectionHelpers.CommonFlags);
|
||||
if (method != null)
|
||||
{
|
||||
return m_encodeToPNGMethod = method;
|
||||
}
|
||||
|
||||
ExplorerCore.Log("ERROR: Cannot get any EncodeToPNG method!");
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public static bool IsReadable(this Texture2D tex)
|
||||
{
|
||||
try
|
||||
{
|
||||
// This will cause an exception if it's not readable.
|
||||
// Reason for doing it this way is not all Unity versions
|
||||
// ship with the 'Texture.isReadable' property.
|
||||
|
||||
tex.GetPixel(0, 0);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture2D Copy(Texture2D orig, Rect rect, bool isDTXnmNormal = false)
|
||||
{
|
||||
Color[] pixels;
|
||||
|
||||
if (!orig.IsReadable())
|
||||
{
|
||||
orig = ForceReadTexture(orig);
|
||||
}
|
||||
|
||||
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);
|
||||
_newTex.SetPixels(pixels);
|
||||
|
||||
return _newTex;
|
||||
}
|
||||
|
||||
public static Texture2D ForceReadTexture(Texture2D tex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var origFilter = tex.filterMode;
|
||||
tex.filterMode = FilterMode.Point;
|
||||
|
||||
var rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32);
|
||||
rt.filterMode = FilterMode.Point;
|
||||
RenderTexture.active = rt;
|
||||
Graphics.Blit(tex, rt);
|
||||
|
||||
var _newTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
|
||||
|
||||
_newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
|
||||
_newTex.Apply(false, false);
|
||||
|
||||
RenderTexture.active = null;
|
||||
tex.filterMode = origFilter;
|
||||
|
||||
return _newTex;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log("Exception on ForceReadTexture: " + e.ToString());
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveTextureAsPNG(Texture2D tex, string dir, string name, bool isDTXnmNormal = false)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
byte[] data;
|
||||
var savepath = dir + @"\" + name + ".png";
|
||||
|
||||
// Make sure we can EncodeToPNG it.
|
||||
if (tex.format != TextureFormat.ARGB32 || !tex.IsReadable())
|
||||
{
|
||||
tex = ForceReadTexture(tex);
|
||||
}
|
||||
|
||||
if (isDTXnmNormal)
|
||||
{
|
||||
tex = DTXnmToRGBA(tex);
|
||||
tex.Apply(false, false);
|
||||
}
|
||||
|
||||
#if CPP
|
||||
data = tex.EncodeToPNG();
|
||||
#else
|
||||
if (isNewEncodeMethod)
|
||||
{
|
||||
data = (byte[])EncodeToPNGMethod.Invoke(null, new object[] { tex });
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (byte[])EncodeToPNGMethod.Invoke(tex, new object[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data == null || data.Length < 1)
|
||||
{
|
||||
ExplorerCore.LogWarning("Couldn't get any data for the texture!");
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllBytes(savepath, data);
|
||||
}
|
||||
}
|
||||
|
||||
// Converts DTXnm-format Normal Map to RGBA-format Normal Map.
|
||||
public static Texture2D DTXnmToRGBA(Texture2D tex)
|
||||
{
|
||||
Color[] colors = tex.GetPixels();
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
Color c = colors[i];
|
||||
|
||||
c.r = c.a * 2 - 1; // red <- alpha
|
||||
c.g = c.g * 2 - 1; // green is always the same
|
||||
|
||||
Vector2 rg = new Vector2(c.r, c.g); //this is the red-green vector
|
||||
c.b = Mathf.Sqrt(1 - Mathf.Clamp01(Vector2.Dot(rg, rg))); //recalculate the blue channel
|
||||
|
||||
colors[i] = new Color(
|
||||
(c.r * 0.5f) + 0.5f,
|
||||
(c.g * 0.5f) + 0.25f,
|
||||
(c.b * 0.5f) + 0.5f
|
||||
);
|
||||
}
|
||||
|
||||
var newtex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
|
||||
newtex.SetPixels(colors);
|
||||
|
||||
return newtex;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer
|
||||
namespace Explorer.Helpers
|
||||
{
|
||||
public class UnityHelpers
|
||||
{
|
||||
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Input
|
||||
{
|
||||
public abstract class AbstractInput
|
||||
{
|
||||
public abstract void Init();
|
||||
|
||||
public abstract Vector2 MousePosition { get; }
|
||||
|
||||
public abstract bool GetKeyDown(KeyCode key);
|
||||
public abstract bool GetKey(KeyCode key);
|
||||
|
||||
public abstract bool GetMouseButtonDown(int btn);
|
||||
public abstract bool GetMouseButton(int btn);
|
||||
}
|
||||
}
|
21
src/Input/IAbstractInput.cs
Normal file
21
src/Input/IAbstractInput.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Input
|
||||
{
|
||||
public interface IAbstractInput
|
||||
{
|
||||
void Init();
|
||||
|
||||
Vector2 MousePosition { get; }
|
||||
|
||||
bool GetKeyDown(KeyCode key);
|
||||
bool GetKey(KeyCode key);
|
||||
|
||||
bool GetMouseButtonDown(int btn);
|
||||
bool GetMouseButton(int btn);
|
||||
}
|
||||
}
|
@ -2,73 +2,87 @@
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.Input;
|
||||
using Explorer.Helpers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Unity style")]
|
||||
public static class InputManager
|
||||
{
|
||||
private static AbstractInput inputModule;
|
||||
private static IAbstractInput m_inputModule;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (InputSystem.TKeyboard != null || TryLoadModule("Unity.InputSystem", InputSystem.TKeyboard))
|
||||
if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null))
|
||||
{
|
||||
inputModule = new InputSystem();
|
||||
m_inputModule = new InputSystem();
|
||||
}
|
||||
else if (LegacyInput.TInput != null || TryLoadModule("UnityEngine.InputLegacyModule", LegacyInput.TInput))
|
||||
else if (LegacyInput.TInput != null || (ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") && LegacyInput.TInput != null))
|
||||
{
|
||||
inputModule = new LegacyInput();
|
||||
m_inputModule = new LegacyInput();
|
||||
}
|
||||
|
||||
if (inputModule == null)
|
||||
if (m_inputModule == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Could not find any Input module!");
|
||||
inputModule = new NoInput();
|
||||
m_inputModule = new NoInput();
|
||||
}
|
||||
|
||||
inputModule.Init();
|
||||
|
||||
bool TryLoadModule(string dll, Type check) => ReflectionHelpers.LoadModule(dll) && check != null;
|
||||
m_inputModule.Init();
|
||||
}
|
||||
|
||||
public static Vector3 MousePosition => inputModule.MousePosition;
|
||||
public static Vector3 MousePosition => m_inputModule.MousePosition;
|
||||
|
||||
public static bool GetKeyDown(KeyCode key) => inputModule.GetKeyDown(key);
|
||||
public static bool GetKey(KeyCode key) => inputModule.GetKey(key);
|
||||
public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
|
||||
public static bool GetKey(KeyCode key) => m_inputModule.GetKey(key);
|
||||
|
||||
public static bool GetMouseButtonDown(int btn) => inputModule.GetMouseButtonDown(btn);
|
||||
public static bool GetMouseButton(int btn) => inputModule.GetMouseButton(btn);
|
||||
public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
|
||||
public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
|
||||
|
||||
//#if CPP
|
||||
//#pragma warning disable IDE1006
|
||||
// // public extern static string compositionString { get; }
|
||||
#if CPP
|
||||
internal delegate void d_ResetInputAxes();
|
||||
public static void ResetInputAxes() => ICallHelper.GetICall<d_ResetInputAxes>("UnityEngine.Input::ResetInputAxes").Invoke();
|
||||
#else
|
||||
public static void ResetInputAxes() => UnityEngine.Input.ResetInputAxes();
|
||||
#endif
|
||||
|
||||
// internal delegate string get_compositionString_delegate();
|
||||
// internal static get_compositionString_delegate get_compositionString_iCall =
|
||||
// IL2CPP.ResolveICall<get_compositionString_delegate>("UnityEngine.Input::get_compositionString");
|
||||
#if CPP
|
||||
// public extern static string compositionString { get; }
|
||||
|
||||
// public static string compositionString => get_compositionString_iCall();
|
||||
internal delegate IntPtr d_get_compositionString();
|
||||
|
||||
// // public extern static Vector2 compositionCursorPos { get; set; }
|
||||
public static string compositionString
|
||||
{
|
||||
get
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<d_get_compositionString>("UnityEngine.Input::get_compositionString");
|
||||
return IL2CPP.Il2CppStringToManaged(iCall.Invoke());
|
||||
}
|
||||
}
|
||||
|
||||
// internal delegate Vector2 get_compositionCursorPos_delegate();
|
||||
// internal static get_compositionCursorPos_delegate get_compositionCursorPos_iCall =
|
||||
// IL2CPP.ResolveICall<get_compositionCursorPos_delegate>("UnityEngine.Input::get_compositionCursorPos");
|
||||
// public extern static Vector2 compositionCursorPos { get; set; }
|
||||
|
||||
// internal delegate void set_compositionCursorPos_delegate(Vector2 value);
|
||||
// internal static set_compositionCursorPos_delegate set_compositionCursorPos_iCall =
|
||||
// IL2CPP.ResolveICall<set_compositionCursorPos_delegate>("UnityEngine.Input::set_compositionCursorPos");
|
||||
internal delegate void d_get_compositionCursorPos(out Vector2 ret);
|
||||
internal delegate void d_set_compositionCursorPos(ref Vector2 value);
|
||||
|
||||
// public static Vector2 compositionCursorPos
|
||||
// {
|
||||
// get => get_compositionCursorPos_iCall();
|
||||
// set => set_compositionCursorPos_iCall(value);
|
||||
// }
|
||||
|
||||
//#pragma warning restore IDE1006
|
||||
//#endif
|
||||
public static Vector2 compositionCursorPos
|
||||
{
|
||||
get
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<d_get_compositionCursorPos>("UnityEngine.Input::get_compositionCursorPos_Injected");
|
||||
iCall.Invoke(out Vector2 ret);
|
||||
return ret;
|
||||
}
|
||||
set
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<d_set_compositionCursorPos>("UnityEngine.Input::set_compositionCursorPos_Injected");
|
||||
iCall.Invoke(ref value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -4,104 +4,105 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.Input
|
||||
{
|
||||
public class InputSystem : AbstractInput
|
||||
public class InputSystem : IAbstractInput
|
||||
{
|
||||
public static Type TKeyboard => _keyboard ?? (_keyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard"));
|
||||
private static Type _keyboard;
|
||||
public static Type TKeyboard => m_tKeyboard ?? (m_tKeyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard"));
|
||||
private static Type m_tKeyboard;
|
||||
|
||||
public static Type TMouse => _mouse ?? (_mouse = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Mouse"));
|
||||
private static Type _mouse;
|
||||
public static Type TMouse => m_tMouse ?? (m_tMouse = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Mouse"));
|
||||
private static Type m_tMouse;
|
||||
|
||||
public static Type TKey => _key ?? (_key = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Key"));
|
||||
private static Type _key;
|
||||
public static Type TKey => m_tKey ?? (m_tKey = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Key"));
|
||||
private static Type m_tKey;
|
||||
|
||||
private static PropertyInfo _btnIsPressedProp;
|
||||
private static PropertyInfo _btnWasPressedProp;
|
||||
private static PropertyInfo m_btnIsPressedProp;
|
||||
private static PropertyInfo m_btnWasPressedProp;
|
||||
|
||||
private static object CurrentKeyboard => _currentKeyboard ?? (_currentKeyboard = _kbCurrentProp.GetValue(null, null));
|
||||
private static object _currentKeyboard;
|
||||
private static PropertyInfo _kbCurrentProp;
|
||||
private static PropertyInfo _kbIndexer;
|
||||
private static object CurrentKeyboard => m_currentKeyboard ?? (m_currentKeyboard = m_kbCurrentProp.GetValue(null, null));
|
||||
private static object m_currentKeyboard;
|
||||
private static PropertyInfo m_kbCurrentProp;
|
||||
private static PropertyInfo m_kbIndexer;
|
||||
|
||||
private static object CurrentMouse => _currentMouse ?? (_currentMouse = _mouseCurrentProp.GetValue(null, null));
|
||||
private static object _currentMouse;
|
||||
private static PropertyInfo _mouseCurrentProp;
|
||||
private static object CurrentMouse => m_currentMouse ?? (m_currentMouse = m_mouseCurrentProp.GetValue(null, null));
|
||||
private static object m_currentMouse;
|
||||
private static PropertyInfo m_mouseCurrentProp;
|
||||
|
||||
private static object LeftMouseButton => _lmb ?? (_lmb = _leftButtonProp.GetValue(CurrentMouse, null));
|
||||
private static object _lmb;
|
||||
private static PropertyInfo _leftButtonProp;
|
||||
private static object LeftMouseButton => m_lmb ?? (m_lmb = m_leftButtonProp.GetValue(CurrentMouse, null));
|
||||
private static object m_lmb;
|
||||
private static PropertyInfo m_leftButtonProp;
|
||||
|
||||
private static object RightMouseButton => _rmb ?? (_rmb = _rightButtonProp.GetValue(CurrentMouse, null));
|
||||
private static object _rmb;
|
||||
private static PropertyInfo _rightButtonProp;
|
||||
private static object RightMouseButton => m_rmb ?? (m_rmb = m_rightButtonProp.GetValue(CurrentMouse, null));
|
||||
private static object m_rmb;
|
||||
private static PropertyInfo m_rightButtonProp;
|
||||
|
||||
private static object MousePositionInfo => _pos ?? (_pos = _positionProp.GetValue(CurrentMouse, null));
|
||||
private static object _pos;
|
||||
private static PropertyInfo _positionProp;
|
||||
private static MethodInfo _readVector2InputMethod;
|
||||
private static object MousePositionInfo => m_pos ?? (m_pos = m_positionProp.GetValue(CurrentMouse, null));
|
||||
private static object m_pos;
|
||||
private static PropertyInfo m_positionProp;
|
||||
private static MethodInfo m_readVector2InputMethod;
|
||||
|
||||
public override Vector2 MousePosition => (Vector2)_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
|
||||
public Vector2 MousePosition => (Vector2)m_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
|
||||
|
||||
public override bool GetKeyDown(KeyCode key)
|
||||
public bool GetKeyDown(KeyCode key)
|
||||
{
|
||||
var parsedKey = Enum.Parse(TKey, key.ToString());
|
||||
var actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey });
|
||||
var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey });
|
||||
|
||||
return (bool)_btnWasPressedProp.GetValue(actualKey, null);
|
||||
return (bool)m_btnWasPressedProp.GetValue(actualKey, null);
|
||||
}
|
||||
|
||||
public override bool GetKey(KeyCode key)
|
||||
public bool GetKey(KeyCode key)
|
||||
{
|
||||
var parsed = Enum.Parse(TKey, key.ToString());
|
||||
var actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
|
||||
var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
|
||||
|
||||
return (bool)_btnIsPressedProp.GetValue(actualKey, null);
|
||||
return (bool)m_btnIsPressedProp.GetValue(actualKey, null);
|
||||
}
|
||||
|
||||
public override bool GetMouseButtonDown(int btn)
|
||||
public bool GetMouseButtonDown(int btn)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case 0: return (bool)_btnWasPressedProp.GetValue(LeftMouseButton, null);
|
||||
case 1: return (bool)_btnWasPressedProp.GetValue(RightMouseButton, null);
|
||||
case 0: return (bool)m_btnWasPressedProp.GetValue(LeftMouseButton, null);
|
||||
case 1: return (bool)m_btnWasPressedProp.GetValue(RightMouseButton, null);
|
||||
// case 2: return (bool)_btnWasPressedProp.GetValue(MiddleMouseButton, null);
|
||||
default: throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool GetMouseButton(int btn)
|
||||
public bool GetMouseButton(int btn)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case 0: return (bool)_btnIsPressedProp.GetValue(LeftMouseButton, null);
|
||||
case 1: return (bool)_btnIsPressedProp.GetValue(RightMouseButton, null);
|
||||
case 0: return (bool)m_btnIsPressedProp.GetValue(LeftMouseButton, null);
|
||||
case 1: return (bool)m_btnIsPressedProp.GetValue(RightMouseButton, null);
|
||||
// case 2: return (bool)_btnIsPressedProp.GetValue(MiddleMouseButton, null);
|
||||
default: throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
public void Init()
|
||||
{
|
||||
ExplorerCore.Log("Initializing new InputSystem support...");
|
||||
|
||||
_kbCurrentProp = TKeyboard.GetProperty("current");
|
||||
_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey });
|
||||
m_kbCurrentProp = TKeyboard.GetProperty("current");
|
||||
m_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey });
|
||||
|
||||
var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl");
|
||||
_btnIsPressedProp = btnControl.GetProperty("isPressed");
|
||||
_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame");
|
||||
m_btnIsPressedProp = btnControl.GetProperty("isPressed");
|
||||
m_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame");
|
||||
|
||||
_mouseCurrentProp = TMouse.GetProperty("current");
|
||||
_leftButtonProp = TMouse.GetProperty("leftButton");
|
||||
_rightButtonProp = TMouse.GetProperty("rightButton");
|
||||
m_mouseCurrentProp = TMouse.GetProperty("current");
|
||||
m_leftButtonProp = TMouse.GetProperty("leftButton");
|
||||
m_rightButtonProp = TMouse.GetProperty("rightButton");
|
||||
|
||||
_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer")
|
||||
m_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer")
|
||||
.GetProperty("position");
|
||||
|
||||
_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
|
||||
m_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
|
||||
.MakeGenericType(typeof(Vector2))
|
||||
.GetMethod("ReadValue");
|
||||
}
|
||||
|
@ -4,39 +4,40 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.Input
|
||||
{
|
||||
public class LegacyInput : AbstractInput
|
||||
public class LegacyInput : IAbstractInput
|
||||
{
|
||||
public static Type TInput => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
|
||||
private static Type _input;
|
||||
public static Type TInput => m_tInput ?? (m_tInput = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
|
||||
private static Type m_tInput;
|
||||
|
||||
private static PropertyInfo _mousePositionProp;
|
||||
private static MethodInfo _getKeyMethod;
|
||||
private static MethodInfo _getKeyDownMethod;
|
||||
private static MethodInfo _getMouseButtonMethod;
|
||||
private static MethodInfo _getMouseButtonDownMethod;
|
||||
private static PropertyInfo m_mousePositionProp;
|
||||
private static MethodInfo m_getKeyMethod;
|
||||
private static MethodInfo m_getKeyDownMethod;
|
||||
private static MethodInfo m_getMouseButtonMethod;
|
||||
private static MethodInfo m_getMouseButtonDownMethod;
|
||||
|
||||
public override Vector2 MousePosition => (Vector3)_mousePositionProp.GetValue(null, null);
|
||||
public Vector2 MousePosition => (Vector3)m_mousePositionProp.GetValue(null, null);
|
||||
|
||||
public override bool GetKey(KeyCode key) => (bool)_getKeyMethod.Invoke(null, new object[] { key });
|
||||
public bool GetKey(KeyCode key) => (bool)m_getKeyMethod.Invoke(null, new object[] { key });
|
||||
|
||||
public override bool GetKeyDown(KeyCode key) => (bool)_getKeyDownMethod.Invoke(null, new object[] { key });
|
||||
public bool GetKeyDown(KeyCode key) => (bool)m_getKeyDownMethod.Invoke(null, new object[] { key });
|
||||
|
||||
public override bool GetMouseButton(int btn) => (bool)_getMouseButtonMethod.Invoke(null, new object[] { btn });
|
||||
public bool GetMouseButton(int btn) => (bool)m_getMouseButtonMethod.Invoke(null, new object[] { btn });
|
||||
|
||||
public override bool GetMouseButtonDown(int btn) => (bool)_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
|
||||
public bool GetMouseButtonDown(int btn) => (bool)m_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
|
||||
|
||||
public override void Init()
|
||||
public void Init()
|
||||
{
|
||||
ExplorerCore.Log("Initializing Legacy Input support...");
|
||||
|
||||
_mousePositionProp = TInput.GetProperty("mousePosition");
|
||||
_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
|
||||
_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
|
||||
_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) });
|
||||
_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
|
||||
m_mousePositionProp = TInput.GetProperty("mousePosition");
|
||||
m_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
|
||||
m_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
|
||||
m_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) });
|
||||
m_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,18 +8,16 @@ namespace Explorer.Input
|
||||
{
|
||||
// Just a stub for games where no Input module was able to load at all.
|
||||
|
||||
public class NoInput : AbstractInput
|
||||
public class NoInput : IAbstractInput
|
||||
{
|
||||
public override Vector2 MousePosition => Vector2.zero;
|
||||
public Vector2 MousePosition => Vector2.zero;
|
||||
|
||||
public override bool GetKey(KeyCode key) => false;
|
||||
public bool GetKey(KeyCode key) => false;
|
||||
public bool GetKeyDown(KeyCode key) => false;
|
||||
|
||||
public override bool GetKeyDown(KeyCode key) => false;
|
||||
public bool GetMouseButton(int btn) => false;
|
||||
public bool GetMouseButtonDown(int btn) => false;
|
||||
|
||||
public override bool GetMouseButton(int btn) => false;
|
||||
|
||||
public override bool GetMouseButtonDown(int btn) => false;
|
||||
|
||||
public override void Init() { }
|
||||
public void Init() { }
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using Explorer.UI.Shared;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Explorer.Unstrip.ImageConversion;
|
||||
#endif
|
||||
|
||||
namespace Explorer.Tests
|
||||
@ -15,16 +16,13 @@ namespace Explorer.Tests
|
||||
public static class StaticTestClass
|
||||
{
|
||||
public static int StaticProperty => 5;
|
||||
|
||||
public static int StaticField = 69;
|
||||
|
||||
public static List<string> StaticList = new List<string>
|
||||
{
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
};
|
||||
|
||||
public static void StaticMethod() { }
|
||||
|
||||
}
|
||||
@ -34,6 +32,14 @@ namespace Explorer.Tests
|
||||
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
||||
private static TestClass m_instance;
|
||||
|
||||
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
|
||||
|
||||
public static bool SetOnlyProperty
|
||||
{
|
||||
set => m_setOnlyProperty = value;
|
||||
}
|
||||
private static bool m_setOnlyProperty;
|
||||
|
||||
public Texture2D TestTexture = UIStyles.MakeTex(200, 200, Color.white);
|
||||
public static Sprite TestSprite;
|
||||
|
||||
@ -41,14 +47,6 @@ namespace Explorer.Tests
|
||||
public static int StaticField = 5;
|
||||
public int NonStaticField;
|
||||
|
||||
#if CPP
|
||||
public static IntPtr FindICall(string name) => il2cpp_resolve_icall(name);
|
||||
|
||||
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
|
||||
|
||||
#endif
|
||||
|
||||
#if CPP
|
||||
public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest;
|
||||
#endif
|
||||
@ -66,6 +64,10 @@ namespace Explorer.Tests
|
||||
GameObject.DontDestroyOnLoad(TestTexture);
|
||||
GameObject.DontDestroyOnLoad(TestSprite);
|
||||
|
||||
//// test loading a tex from file
|
||||
//var dataToLoad = System.IO.File.ReadAllBytes(@"Mods\Explorer\Tex_Nemundis_Nebula.png");
|
||||
//ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
|
||||
|
||||
ILHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
|
||||
ILHashSetTest.Add("1");
|
||||
ILHashSetTest.Add("2");
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
#if ML
|
||||
using Harmony;
|
||||
#else
|
||||
@ -17,32 +18,25 @@ namespace Explorer.UI
|
||||
}
|
||||
private static bool m_forceUnlock;
|
||||
|
||||
private static CursorLockMode m_lastLockMode;
|
||||
private static bool m_lastVisibleState;
|
||||
private static bool m_currentlySettingCursor = false;
|
||||
|
||||
public static bool ShouldForceMouse => ExplorerCore.ShowMenu && Unlock;
|
||||
|
||||
private static Type CursorType => m_cursorType ?? (m_cursorType = ReflectionHelpers.GetTypeByName("UnityEngine.Cursor"));
|
||||
private static CursorLockMode m_lastLockMode;
|
||||
private static bool m_lastVisibleState;
|
||||
|
||||
private static bool m_currentlySettingCursor = false;
|
||||
|
||||
private static Type CursorType
|
||||
=> m_cursorType
|
||||
?? (m_cursorType = ReflectionHelpers.GetTypeByName("UnityEngine.Cursor"));
|
||||
private static Type m_cursorType;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if Cursor class is loaded
|
||||
if (CursorType == null)
|
||||
{
|
||||
ExplorerCore.Log("Trying to manually load Cursor module...");
|
||||
|
||||
if (ReflectionHelpers.LoadModule("UnityEngine.CoreModule") && CursorType != null)
|
||||
{
|
||||
ExplorerCore.Log("Ok!");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Could not load UnityEngine.Cursor module!");
|
||||
}
|
||||
throw new Exception("Could not find Type 'UnityEngine.Cursor'!");
|
||||
}
|
||||
|
||||
// Get current cursor state and enable cursor
|
||||
@ -91,7 +85,8 @@ namespace Explorer.UI
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log($"[NON-FATAL] Couldn't patch a method: {e.Message}");
|
||||
string s = setter ? "set_" : "get_" ;
|
||||
ExplorerCore.Log($"Unable to patch Cursor.{s}{property}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.UI.Main;
|
||||
using Explorer.Unstrip.LayerMasks;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
@ -17,6 +19,8 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
public GameObject TargetGO;
|
||||
|
||||
public bool pendingDestroy;
|
||||
|
||||
private static bool m_hideControls;
|
||||
|
||||
// gui element holders
|
||||
@ -43,6 +47,8 @@ namespace Explorer.UI.Inspectors
|
||||
private bool m_autoUpdateTransform;
|
||||
private bool m_localContext;
|
||||
|
||||
private int m_layer;
|
||||
|
||||
private readonly List<Component> m_cachedDestroyList = new List<Component>();
|
||||
private string m_addComponentInput = "";
|
||||
|
||||
@ -104,16 +110,16 @@ namespace Explorer.UI.Inspectors
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pendingDestroy) return;
|
||||
|
||||
if (Target == null)
|
||||
{
|
||||
ExplorerCore.Log("Target is null!");
|
||||
DestroyWindow();
|
||||
DestroyOnException(new Exception("Target was destroyed."));
|
||||
return;
|
||||
}
|
||||
if (!TargetGO && !GetObjectAsGameObject())
|
||||
{
|
||||
ExplorerCore.Log("Target was destroyed!");
|
||||
DestroyWindow();
|
||||
DestroyOnException(new Exception("Target was destroyed."));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -132,6 +138,8 @@ namespace Explorer.UI.Inspectors
|
||||
TargetGO.transform.localScale = m_frozenScale;
|
||||
}
|
||||
|
||||
m_layer = TargetGO.layer;
|
||||
|
||||
// update child objects
|
||||
var childList = new List<Transform>();
|
||||
for (int i = 0; i < TargetGO.transform.childCount; i++)
|
||||
@ -162,7 +170,10 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
private void DestroyOnException(Exception e)
|
||||
{
|
||||
if (pendingDestroy) return;
|
||||
|
||||
ExplorerCore.Log($"Exception drawing GameObject Window: {e.GetType()}, {e.Message}");
|
||||
pendingDestroy = true;
|
||||
DestroyWindow();
|
||||
}
|
||||
|
||||
@ -204,6 +215,8 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
public override void WindowFunction(int windowID)
|
||||
{
|
||||
if (pendingDestroy) return;
|
||||
|
||||
try
|
||||
{
|
||||
var rect = WindowManager.TabView ? TabViewWindow.Instance.m_rect : this.m_rect;
|
||||
@ -211,12 +224,12 @@ namespace Explorer.UI.Inspectors
|
||||
if (!WindowManager.TabView)
|
||||
{
|
||||
Header();
|
||||
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||
GUIHelper.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||
}
|
||||
|
||||
scroll = GUIUnstrip.BeginScrollView(scroll);
|
||||
scroll = GUIHelper.BeginScrollView(scroll);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", new GUILayoutOption[0]);
|
||||
if (m_scene == UnityHelpers.ActiveSceneName)
|
||||
{
|
||||
@ -232,7 +245,7 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
string pathlabel = TargetGO.transform.GetGameObjectPath();
|
||||
if (TargetGO.transform.parent != null)
|
||||
@ -242,22 +255,24 @@ namespace Explorer.UI.Inspectors
|
||||
InspectGameObject(TargetGO.transform.parent);
|
||||
}
|
||||
}
|
||||
GUIUnstrip.TextArea(pathlabel, new GUILayoutOption[0]);
|
||||
GUIHelper.TextArea(pathlabel, new GUILayoutOption[0]);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Name:", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
GUIUnstrip.TextArea(m_name, new GUILayoutOption[0]);
|
||||
GUIHelper.TextArea(m_name, new GUILayoutOption[0]);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
LayerControls();
|
||||
|
||||
// --- Horizontal Columns section ---
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
|
||||
GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
|
||||
TransformList(rect);
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
|
||||
GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
|
||||
ComponentList(rect);
|
||||
GUILayout.EndVertical();
|
||||
|
||||
@ -265,13 +280,13 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
GameObjectControls();
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
|
||||
if (!WindowManager.TabView)
|
||||
{
|
||||
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
||||
|
||||
GUIUnstrip.EndArea();
|
||||
GUIHelper.EndArea();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -280,14 +295,42 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
}
|
||||
|
||||
private void LayerControls()
|
||||
{
|
||||
GUIHelper.BeginHorizontal();
|
||||
GUILayout.Label("Layer:", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
|
||||
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(30) }))
|
||||
{
|
||||
if (m_layer > 0)
|
||||
{
|
||||
m_layer--;
|
||||
if (TargetGO) TargetGO.layer = m_layer;
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(30) }))
|
||||
{
|
||||
if (m_layer < 32)
|
||||
{
|
||||
m_layer++;
|
||||
if (TargetGO) TargetGO.layer = m_layer;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Label($"{m_layer} (<color=cyan>{LayerMaskUnstrip.LayerToName(m_layer)}</color>)",
|
||||
new GUILayoutOption[] { GUILayout.Width(200) });
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void TransformList(Rect m_rect)
|
||||
{
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
m_transformScroll = GUIUnstrip.BeginScrollView(m_transformScroll);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
m_transformScroll = GUIHelper.BeginScrollView(m_transformScroll);
|
||||
|
||||
GUILayout.Label("<b><size=15>Children</size></b>", new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
ChildPages.DrawLimitInputArea();
|
||||
|
||||
if (ChildPages.ItemCount > ChildPages.ItemsPerPage)
|
||||
@ -295,7 +338,7 @@ namespace Explorer.UI.Inspectors
|
||||
ChildPages.CurrentPageLabel();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
@ -330,17 +373,17 @@ namespace Explorer.UI.Inspectors
|
||||
GUILayout.Label("<i>None</i>", new GUILayoutOption[0]);
|
||||
}
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void ComponentList(Rect m_rect)
|
||||
{
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
m_compScroll = GUIUnstrip.BeginScrollView(m_compScroll);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
m_compScroll = GUIHelper.BeginScrollView(m_compScroll);
|
||||
GUILayout.Label("<b><size=15>Components</size></b>", new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
CompPages.DrawLimitInputArea();
|
||||
|
||||
if (CompPages.ItemCount > CompPages.ItemsPerPage)
|
||||
@ -348,7 +391,7 @@ namespace Explorer.UI.Inspectors
|
||||
CompPages.CurrentPageLabel();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
@ -361,9 +404,9 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
var width = m_rect.width / 2 - 135f;
|
||||
m_addComponentInput = GUIUnstrip.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
|
||||
m_addComponentInput = GUIHelper.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
|
||||
if (GUILayout.Button("Add Comp", new GUILayoutOption[0]))
|
||||
{
|
||||
if (ReflectionHelpers.GetTypeByName(m_addComponentInput) is Type compType)
|
||||
@ -410,7 +453,7 @@ namespace Explorer.UI.Inspectors
|
||||
#else
|
||||
component.GetType();
|
||||
#endif
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
if (ReflectionHelpers.BehaviourType.IsAssignableFrom(type))
|
||||
{
|
||||
#if CPP
|
||||
@ -421,7 +464,7 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUnstrip.Space(26);
|
||||
GUIHelper.Space(26);
|
||||
}
|
||||
if (GUILayout.Button("<color=cyan>" + type.Name + "</color>", new GUILayoutOption[] { GUILayout.Width(m_rect.width / 2 - 100) }))
|
||||
{
|
||||
@ -445,7 +488,7 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
}
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
@ -477,7 +520,7 @@ namespace Explorer.UI.Inspectors
|
||||
{
|
||||
if (m_hideControls)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
|
||||
if (GUILayout.Button("^ Show ^", new GUILayoutOption[] { GUILayout.Width(75) }))
|
||||
{
|
||||
@ -488,9 +531,9 @@ namespace Explorer.UI.Inspectors
|
||||
return;
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
|
||||
if (GUILayout.Button("v Hide v", new GUILayoutOption[] { GUILayout.Width(75) }))
|
||||
{
|
||||
@ -498,7 +541,7 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
bool m_active = TargetGO.activeSelf;
|
||||
m_active = GUILayout.Toggle(m_active, (m_active ? "<color=lime>Enabled " : "<color=red>Disabled") + "</color>",
|
||||
new GUILayoutOption[] { GUILayout.Width(80) });
|
||||
@ -523,9 +566,9 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
m_setParentInput = GUIUnstrip.TextField(m_setParentInput, new GUILayoutOption[0]);
|
||||
m_setParentInput = GUIHelper.TextField(m_setParentInput, new GUILayoutOption[0]);
|
||||
if (GUILayout.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
if (GameObject.Find(m_setParentInput) is GameObject newparent)
|
||||
@ -544,13 +587,13 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false);
|
||||
m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true);
|
||||
m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
if (GUILayout.Button("<color=lime>Apply to Transform</color>", new GUILayoutOption[0]) || m_autoApplyTransform)
|
||||
{
|
||||
if (m_localContext)
|
||||
@ -576,7 +619,7 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
BoolToggle(ref m_autoApplyTransform, "Auto-apply to Transform?");
|
||||
BoolToggle(ref m_autoUpdateTransform, "Auto-update from transform?");
|
||||
GUILayout.EndHorizontal();
|
||||
@ -638,7 +681,7 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
private Vector3 TranslateControl(TranslateType mode, ref float amount, bool multByTime)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
|
||||
new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
|
||||
|
||||
@ -661,7 +704,7 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
Vector3 input = m_cachedInput[(int)mode];
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||
|
||||
GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
||||
@ -675,7 +718,7 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
var amountInput = amount.ToString("F3");
|
||||
amountInput = GUIUnstrip.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
amountInput = GUIHelper.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
if (float.TryParse(amountInput, out float f))
|
||||
{
|
||||
amount = f;
|
||||
@ -690,16 +733,16 @@ namespace Explorer.UI.Inspectors
|
||||
private void PlusMinusFloat(ref float f, float amount, bool multByTime)
|
||||
{
|
||||
string s = f.ToString("F3");
|
||||
s = GUIUnstrip.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
s = GUIHelper.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
if (float.TryParse(s, out float f2))
|
||||
{
|
||||
f = f2;
|
||||
}
|
||||
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
f -= multByTime ? amount * Time.deltaTime : amount;
|
||||
}
|
||||
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
f += multByTime ? amount * Time.deltaTime : amount;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.UI.Inspectors
|
||||
{
|
||||
|
@ -72,15 +72,15 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
public void DrawInstanceControls(Rect rect)
|
||||
{
|
||||
if (m_uObj)
|
||||
{
|
||||
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
//if (m_uObj)
|
||||
//{
|
||||
// GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
|
||||
//}
|
||||
//GUILayout.EndHorizontal();
|
||||
|
||||
if (m_uObj)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b>Tools:</b>", new GUILayoutOption[] { GUILayout.Width(80) });
|
||||
Buttons.InstantiateButton(m_uObj);
|
||||
if (m_component && m_component.gameObject is GameObject obj)
|
||||
@ -89,13 +89,17 @@ namespace Explorer.UI.Inspectors
|
||||
GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) });
|
||||
var charWidth = obj.name.Length * 15;
|
||||
var maxWidth = rect.width - 350;
|
||||
var labelWidth = charWidth < maxWidth ? charWidth : maxWidth;
|
||||
if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) }))
|
||||
var btnWidth = charWidth < maxWidth ? charWidth : maxWidth;
|
||||
if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(btnWidth) }))
|
||||
{
|
||||
WindowManager.InspectObject(obj, out bool _);
|
||||
}
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using Explorer.UI;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using Explorer.UI.Inspectors;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
@ -125,7 +126,7 @@ namespace Explorer.UI.Inspectors
|
||||
private void CacheMembers(Type[] types)
|
||||
{
|
||||
var list = new List<CacheMember>();
|
||||
var cachedSigs = new List<string>();
|
||||
var cachedSigs = new HashSet<string>();
|
||||
|
||||
foreach (var declaringType in types)
|
||||
{
|
||||
@ -208,16 +209,19 @@ namespace Explorer.UI.Inspectors
|
||||
continue;
|
||||
}
|
||||
|
||||
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||
|
||||
try
|
||||
{
|
||||
var cached = CacheFactory.GetCacheObject(member, target);
|
||||
|
||||
if (cached != null)
|
||||
{
|
||||
cachedSigs.Add(sig);
|
||||
list.Add(cached);
|
||||
cached.ReflectionException = exception;
|
||||
|
||||
if (string.IsNullOrEmpty(cached.ReflectionException))
|
||||
{
|
||||
cached.ReflectionException = exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -250,34 +254,31 @@ namespace Explorer.UI.Inspectors
|
||||
if (!WindowManager.TabView)
|
||||
{
|
||||
Header();
|
||||
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||
GUIHelper.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||
}
|
||||
|
||||
var asInstance = this as InstanceInspector;
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
var labelWidth = (asInstance != null && asInstance.m_uObj)
|
||||
? new GUILayoutOption[] { GUILayout.Width(245f) }
|
||||
: new GUILayoutOption[0];
|
||||
GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (asInstance != null)
|
||||
{
|
||||
asInstance.DrawInstanceControls(rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
UIStyles.HorizontalLine(Color.grey);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b>Search:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
|
||||
m_search = GUIUnstrip.TextField(m_search, new GUILayoutOption[0]);
|
||||
m_search = GUIHelper.TextField(m_search, new GUILayoutOption[0]);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b>Filter:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
|
||||
FilterTypeToggle(MemberTypes.All, "All");
|
||||
FilterTypeToggle(MemberTypes.Property, "Properties");
|
||||
@ -287,7 +288,7 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
if (this is InstanceInspector)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b>Scope:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
|
||||
FilterScopeToggle(MemberScopes.Both, "Both");
|
||||
FilterScopeToggle(MemberScopes.Instance, "Instance");
|
||||
@ -295,7 +296,7 @@ namespace Explorer.UI.Inspectors
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("<b>Values:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
|
||||
if (GUILayout.Button("Update", new GUILayoutOption[] { GUILayout.Width(100) }))
|
||||
{
|
||||
@ -308,12 +309,12 @@ namespace Explorer.UI.Inspectors
|
||||
GUI.color = Color.white;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.Space(10);
|
||||
GUIHelper.Space(10);
|
||||
|
||||
Pages.ItemCount = m_cachedMembersFiltered.Length;
|
||||
|
||||
// prev/next page buttons
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
@ -335,13 +336,13 @@ namespace Explorer.UI.Inspectors
|
||||
|
||||
// ====== BODY ======
|
||||
|
||||
scroll = GUIUnstrip.BeginScrollView(scroll);
|
||||
scroll = GUIHelper.BeginScrollView(scroll);
|
||||
|
||||
GUIUnstrip.Space(10);
|
||||
GUIHelper.Space(10);
|
||||
|
||||
UIStyles.HorizontalLine(Color.grey);
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
var members = this.m_cachedMembersFiltered;
|
||||
int start = Pages.CalculateOffsetIndex();
|
||||
@ -350,7 +351,7 @@ namespace Explorer.UI.Inspectors
|
||||
{
|
||||
var holder = members[j];
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
|
||||
try
|
||||
{
|
||||
holder.Draw(rect, 180f);
|
||||
@ -368,13 +369,13 @@ namespace Explorer.UI.Inspectors
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
|
||||
if (!WindowManager.TabView)
|
||||
{
|
||||
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
||||
|
||||
GUIUnstrip.EndArea();
|
||||
GUIHelper.EndArea();
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (e.Message.Contains("in a group with only"))
|
||||
|
@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.UI
|
||||
{
|
||||
@ -70,14 +71,14 @@ namespace Explorer.UI
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUnstrip.Space(labelWidth);
|
||||
GUIHelper.Space(labelWidth);
|
||||
}
|
||||
|
||||
var cacheMethod = OwnerCacheObject as CacheMethod;
|
||||
|
||||
if (cacheMember != null && cacheMember.HasParameters)
|
||||
{
|
||||
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.ExpandHeight(true) } );
|
||||
GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.ExpandHeight(true) } );
|
||||
|
||||
if (cacheMember.m_isEvaluating)
|
||||
{
|
||||
@ -91,7 +92,7 @@ namespace Explorer.UI
|
||||
cacheMember.DrawArgsInput();
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
||||
{
|
||||
if (cacheMethod != null)
|
||||
@ -121,8 +122,8 @@ namespace Explorer.UI
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(labelWidth);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(labelWidth);
|
||||
}
|
||||
else if (cacheMethod != null)
|
||||
{
|
||||
@ -132,8 +133,8 @@ namespace Explorer.UI
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(labelWidth);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(labelWidth);
|
||||
}
|
||||
|
||||
string typeName = $"<color={Syntax.Class_Instance}>{ValueType.FullName}</color>";
|
||||
@ -198,31 +199,51 @@ namespace Explorer.UI
|
||||
return m_toStringMethod;
|
||||
}
|
||||
|
||||
private string GetButtonLabel()
|
||||
public string GetButtonLabel()
|
||||
{
|
||||
if (Value == null) return null;
|
||||
|
||||
string label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
|
||||
var valueType = ReflectionHelpers.GetActualType(Value);
|
||||
|
||||
var classColor = ValueType.IsAbstract && ValueType.IsSealed
|
||||
? Syntax.Class_Static
|
||||
: Syntax.Class_Instance;
|
||||
string label;
|
||||
|
||||
string typeLabel = $"<color={classColor}>{ValueType.FullName}</color>";
|
||||
|
||||
if (Value is UnityEngine.Object)
|
||||
if (valueType == typeof(TextAsset))
|
||||
{
|
||||
label = label.Replace($"({ValueType.FullName})", $"({typeLabel})");
|
||||
var textAsset = Value as TextAsset;
|
||||
|
||||
label = textAsset.text;
|
||||
|
||||
if (label.Length > 10)
|
||||
{
|
||||
label = $"{label.Substring(0, 10)}...";
|
||||
}
|
||||
|
||||
label = $"\"{label}\" {textAsset.name} (<color={Syntax.Class_Instance}>UnityEngine.TextAsset</color>)";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!label.Contains(ValueType.FullName))
|
||||
label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
|
||||
|
||||
var classColor = valueType.IsAbstract && valueType.IsSealed
|
||||
? Syntax.Class_Static
|
||||
: Syntax.Class_Instance;
|
||||
|
||||
string typeLabel = $"<color={classColor}>{valueType.FullName}</color>";
|
||||
|
||||
if (Value is UnityEngine.Object)
|
||||
{
|
||||
label += $" ({typeLabel})";
|
||||
label = label.Replace($"({valueType.FullName})", $"({typeLabel})");
|
||||
}
|
||||
else
|
||||
{
|
||||
label = label.Replace(ValueType.FullName, typeLabel);
|
||||
if (!label.Contains(valueType.FullName))
|
||||
{
|
||||
label += $" ({typeLabel})";
|
||||
}
|
||||
else
|
||||
{
|
||||
label = label.Replace(valueType.FullName, typeLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
|
||||
namespace Explorer.UI
|
||||
{
|
||||
// TODO: Re-work class using InteractiveEnumerable or maybe InteractiveCollection for the Keys/Value lists.
|
||||
// Make the keys and values editable.
|
||||
|
||||
public class InteractiveDictionary : InteractiveValue, IExpandHeight
|
||||
{
|
||||
public bool IsExpanded { get; set; }
|
||||
@ -158,7 +162,7 @@ namespace Explorer.UI
|
||||
m_cachedValues = values.ToArray();
|
||||
}
|
||||
|
||||
private bool EnsureDictionaryIsSupported()
|
||||
public bool EnsureDictionaryIsSupported()
|
||||
{
|
||||
if (typeof(IDictionary).IsAssignableFrom(ValueType))
|
||||
{
|
||||
@ -177,6 +181,11 @@ namespace Explorer.UI
|
||||
.GetField("NativeClassPtr")
|
||||
.GetValue(null);
|
||||
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Il2CppSystem.Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(ptr)) is Il2CppSystem.Type;
|
||||
}
|
||||
}
|
||||
@ -228,7 +237,7 @@ namespace Explorer.UI
|
||||
}
|
||||
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
GUIUnstrip.Space(5);
|
||||
GUIHelper.Space(5);
|
||||
|
||||
if (IsExpanded)
|
||||
{
|
||||
@ -237,9 +246,9 @@ namespace Explorer.UI
|
||||
if (count > Pages.ItemsPerPage)
|
||||
{
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.Space(whitespace);
|
||||
|
||||
Pages.CurrentPageLabel();
|
||||
|
||||
@ -255,7 +264,7 @@ namespace Explorer.UI
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
GUIUnstrip.Space(5);
|
||||
GUIHelper.Space(5);
|
||||
}
|
||||
|
||||
int offset = Pages.CalculateOffsetIndex();
|
||||
@ -267,7 +276,7 @@ namespace Explorer.UI
|
||||
|
||||
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
//GUIUnstrip.Space(whitespace);
|
||||
|
||||
|
@ -6,6 +6,11 @@ using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using System.Linq;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer.UI
|
||||
{
|
||||
@ -293,7 +298,7 @@ namespace Explorer.UI
|
||||
}
|
||||
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
GUIUnstrip.Space(5);
|
||||
GUIHelper.Space(5);
|
||||
|
||||
if (IsExpanded)
|
||||
{
|
||||
@ -302,9 +307,9 @@ namespace Explorer.UI
|
||||
if (count > Pages.ItemsPerPage)
|
||||
{
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.Space(whitespace);
|
||||
|
||||
Pages.CurrentPageLabel();
|
||||
|
||||
@ -320,7 +325,7 @@ namespace Explorer.UI
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
GUIUnstrip.Space(5);
|
||||
GUIHelper.Space(5);
|
||||
}
|
||||
|
||||
int offset = Pages.CalculateOffsetIndex();
|
||||
@ -331,9 +336,9 @@ namespace Explorer.UI
|
||||
|
||||
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.Space(whitespace);
|
||||
|
||||
if (entry == null || entry.IValue == null)
|
||||
{
|
||||
|
@ -2,27 +2,50 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Explorer.Helpers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.UI
|
||||
{
|
||||
public class InteractiveSprite : InteractiveTexture2D
|
||||
{
|
||||
public override void GetTexture2D()
|
||||
private Sprite refSprite;
|
||||
|
||||
public override void UpdateValue()
|
||||
{
|
||||
#if CPP
|
||||
if (Value != null && Value.Il2CppCast(typeof(Sprite)) is Sprite sprite)
|
||||
{
|
||||
refSprite = sprite;
|
||||
}
|
||||
#else
|
||||
if (Value is Sprite sprite)
|
||||
#endif
|
||||
{
|
||||
currentTex = sprite.texture;
|
||||
texContent = new GUIContent
|
||||
{
|
||||
image = currentTex
|
||||
};
|
||||
refSprite = sprite;
|
||||
}
|
||||
#endif
|
||||
|
||||
base.UpdateValue();
|
||||
}
|
||||
|
||||
public override void GetTexture2D()
|
||||
{
|
||||
if (refSprite)
|
||||
{
|
||||
currentTex = refSprite.texture;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetGUIContent()
|
||||
{
|
||||
// Check if the Sprite.textureRect is just the entire texture
|
||||
if (refSprite.textureRect != new Rect(0, 0, currentTex.width, currentTex.height))
|
||||
{
|
||||
// It's not, do a sub-copy.
|
||||
currentTex = Texture2DHelpers.Copy(refSprite.texture, refSprite.textureRect);
|
||||
}
|
||||
|
||||
base.GetGUIContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
30
src/UI/InteractiveValue/Object/InteractiveTexture.cs
Normal file
30
src/UI/InteractiveValue/Object/InteractiveTexture.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.UI
|
||||
{
|
||||
// This class is possibly unnecessary.
|
||||
// It's just for CacheMembers that have 'Texture' as the value type, but is actually a Texture2D.
|
||||
|
||||
public class InteractiveTexture : InteractiveTexture2D
|
||||
{
|
||||
public override void GetTexture2D()
|
||||
{
|
||||
#if CPP
|
||||
if (Value != null && Value.Il2CppCast(typeof(Texture2D)) is Texture2D tex)
|
||||
#else
|
||||
if (Value is Texture2D tex)
|
||||
#endif
|
||||
{
|
||||
currentTex = tex;
|
||||
texContent = new GUIContent
|
||||
{
|
||||
image = currentTex
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ using Explorer.CacheObject;
|
||||
using Explorer.Config;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using Explorer.Unstrip.ImageConversion;
|
||||
#endif
|
||||
@ -42,35 +43,37 @@ namespace Explorer.UI
|
||||
if (Value is Texture2D tex)
|
||||
#endif
|
||||
{
|
||||
currentTex = tex;
|
||||
texContent = new GUIContent
|
||||
{
|
||||
image = currentTex
|
||||
};
|
||||
currentTex = tex;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetGUIContent()
|
||||
{
|
||||
texContent = new GUIContent
|
||||
{
|
||||
image = currentTex
|
||||
};
|
||||
}
|
||||
|
||||
public override void DrawValue(Rect window, float width)
|
||||
{
|
||||
GUIUnstrip.BeginVertical();
|
||||
GUIHelper.BeginVertical();
|
||||
|
||||
GUIUnstrip.BeginHorizontal();
|
||||
GUIHelper.BeginHorizontal();
|
||||
|
||||
if (currentTex)
|
||||
if (currentTex && !IsExpanded)
|
||||
{
|
||||
if (!IsExpanded)
|
||||
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||
{
|
||||
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||
{
|
||||
IsExpanded = true;
|
||||
}
|
||||
IsExpanded = true;
|
||||
GetGUIContent();
|
||||
}
|
||||
else
|
||||
}
|
||||
else if (currentTex)
|
||||
{
|
||||
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||
{
|
||||
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||
{
|
||||
IsExpanded = false;
|
||||
}
|
||||
IsExpanded = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,39 +105,32 @@ namespace Explorer.UI
|
||||
|
||||
private void DrawTextureControls()
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal();
|
||||
GUIHelper.BeginHorizontal();
|
||||
|
||||
GUILayout.Label("Save folder:", new GUILayoutOption[] { GUILayout.Width(80f) });
|
||||
saveFolder = GUIUnstrip.TextField(saveFolder, new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(10f);
|
||||
saveFolder = GUIHelper.TextField(saveFolder, new GUILayoutOption[0]);
|
||||
GUIHelper.Space(10f);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button("Save to PNG", new GUILayoutOption[] { GUILayout.Width(100f) }))
|
||||
{
|
||||
if (currentTex)
|
||||
var name = RemoveInvalidFilenameChars(currentTex.name ?? "");
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
var name = RemoveInvalidFilenameChars(currentTex.name ?? "");
|
||||
if (string.IsNullOrEmpty(name))
|
||||
if (OwnerCacheObject is CacheMember cacheMember)
|
||||
{
|
||||
if (OwnerCacheObject is CacheMember cacheMember)
|
||||
{
|
||||
name = cacheMember.MemInfo.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "UNTITLED";
|
||||
}
|
||||
name = cacheMember.MemInfo.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "UNTITLED";
|
||||
}
|
||||
|
||||
SaveTextureAsPNG(currentTex, saveFolder, name, false);
|
||||
|
||||
ExplorerCore.Log($@"Saved to {saveFolder}\{name}.png!");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplorerCore.Log("Cannot save a null texture!");
|
||||
}
|
||||
|
||||
Texture2DHelpers.SaveTextureAsPNG(currentTex, saveFolder, name, false);
|
||||
|
||||
ExplorerCore.Log($@"Saved to {saveFolder}\{name}.png!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,107 +144,6 @@ namespace Explorer.UI
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void SaveTextureAsPNG(Texture2D tex, string dir, string name, bool isDTXnmNormal = false)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
byte[] data;
|
||||
var savepath = dir + @"\" + name + ".png";
|
||||
|
||||
try
|
||||
{
|
||||
if (isDTXnmNormal)
|
||||
{
|
||||
tex = DTXnmToRGBA(tex);
|
||||
tex.Apply(false, false);
|
||||
}
|
||||
|
||||
data = tex.EncodeToPNG();
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
ExplorerCore.Log("Couldn't get data with EncodeToPNG (probably ReadOnly?), trying manually...");
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
var origFilter = tex.filterMode;
|
||||
tex.filterMode = FilterMode.Point;
|
||||
|
||||
RenderTexture rt = RenderTexture.GetTemporary(tex.width, tex.height);
|
||||
rt.filterMode = FilterMode.Point;
|
||||
RenderTexture.active = rt;
|
||||
Graphics.Blit(tex, rt);
|
||||
|
||||
Texture2D _newTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
|
||||
_newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
|
||||
|
||||
if (isDTXnmNormal)
|
||||
{
|
||||
_newTex = DTXnmToRGBA(_newTex);
|
||||
}
|
||||
|
||||
_newTex.Apply(false, false);
|
||||
|
||||
RenderTexture.active = null;
|
||||
tex.filterMode = origFilter;
|
||||
|
||||
data = _newTex.EncodeToPNG();
|
||||
//data = _newTex.GetRawTextureData();
|
||||
}
|
||||
|
||||
if (data == null || data.Length < 1)
|
||||
{
|
||||
ExplorerCore.LogWarning("Couldn't get any data for the texture!");
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CPP
|
||||
// The IL2CPP method will return invalid byte data.
|
||||
// However, we can just iterate into safe C# byte[] array.
|
||||
byte[] safeData = new byte[data.Length];
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
safeData[i] = (byte)data[i]; // not sure if cast is needed
|
||||
}
|
||||
|
||||
File.WriteAllBytes(savepath, safeData);
|
||||
#else
|
||||
File.WriteAllBytes(savepath, data);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Converts DTXnm-format Normal Map to RGBA-format Normal Map.
|
||||
public static Texture2D DTXnmToRGBA(Texture2D tex)
|
||||
{
|
||||
Color[] colors = tex.GetPixels();
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
Color c = colors[i];
|
||||
|
||||
c.r = c.a * 2 - 1; // red <- alpha
|
||||
c.g = c.g * 2 - 1; // green is always the same
|
||||
|
||||
Vector2 rg = new Vector2(c.r, c.g); //this is the red-green vector
|
||||
c.b = Mathf.Sqrt(1 - Mathf.Clamp01(Vector2.Dot(rg, rg))); //recalculate the blue channel
|
||||
|
||||
colors[i] = new Color(
|
||||
(c.r * 0.5f) + 0.5f,
|
||||
(c.g * 0.5f) + 0.25f,
|
||||
(c.b * 0.5f) + 0.5f
|
||||
);
|
||||
}
|
||||
|
||||
var newtex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
|
||||
newtex.SetPixels(colors);
|
||||
|
||||
return newtex;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -63,40 +63,40 @@ namespace Explorer.UI
|
||||
|
||||
var whitespace = CalcWhitespace(window);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
r = GUIUnstrip.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
r = GUIHelper.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
g = GUIUnstrip.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
g = GUIHelper.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
b = GUIUnstrip.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
b = GUIHelper.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
a = GUIUnstrip.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
a = GUIHelper.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// draw set value button
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,23 +75,23 @@ namespace Explorer.UI
|
||||
|
||||
for (int i = 0; i < EnumNames.Length; i++)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
|
||||
m_enabledFlags[i] = GUILayout.Toggle(m_enabledFlags[i], EnumNames[i], new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||
{
|
||||
SetFlagsFromInput();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,12 +80,13 @@ namespace Explorer.UI
|
||||
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
b = GUILayout.Toggle(b, label, new GUILayoutOption[0]);
|
||||
if (b != (bool)Value)
|
||||
{
|
||||
Value = b;
|
||||
OwnerCacheObject.SetValue();
|
||||
}
|
||||
Value = GUILayout.Toggle(b, label, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
DrawApplyButton();
|
||||
//if (b != (bool)Value)
|
||||
//{
|
||||
// Value = b;
|
||||
// OwnerCacheObject.SetValue();
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -97,27 +98,22 @@ namespace Explorer.UI
|
||||
|
||||
// all other non-bool values use TextField
|
||||
|
||||
GUIUnstrip.BeginVertical(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginVertical(new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
|
||||
m_valueToString = GUIUnstrip.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
}
|
||||
m_valueToString = GUIHelper.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
|
||||
|
||||
DrawApplyButton();
|
||||
|
||||
if (ModConfig.Instance.Bitwise_Support && m_canBitwiseOperate)
|
||||
{
|
||||
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]);
|
||||
}
|
||||
|
||||
GUIUnstrip.Space(10);
|
||||
GUIHelper.Space(10);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
@ -129,11 +125,29 @@ namespace Explorer.UI
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawApplyButton()
|
||||
{
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
||||
{
|
||||
if (m_isBool)
|
||||
{
|
||||
OwnerCacheObject.SetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBitwise()
|
||||
{
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
|
||||
@ -189,14 +203,14 @@ namespace Explorer.UI
|
||||
}
|
||||
}
|
||||
|
||||
m_bitwiseOperatorInput = GUIUnstrip.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
|
||||
m_bitwiseOperatorInput = GUIHelper.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
m_binaryInput = GUIUnstrip.TextField(m_binaryInput, new GUILayoutOption[0]);
|
||||
m_binaryInput = GUIHelper.TextField(m_binaryInput, new GUILayoutOption[0]);
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
if (GUILayout.Button("Apply", new GUILayoutOption[0]))
|
||||
|
@ -58,34 +58,34 @@ namespace Explorer.UI
|
||||
|
||||
var whitespace = CalcWhitespace(window);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
z = GUIHelper.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// draw set value button
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,40 +60,40 @@ namespace Explorer.UI
|
||||
|
||||
var whitespace = CalcWhitespace(window);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
w = GUIHelper.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
h = GUIUnstrip.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
h = GUIHelper.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// draw set value button
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,47 +100,47 @@ namespace Explorer.UI
|
||||
var whitespace = CalcWhitespace(window);
|
||||
|
||||
// always draw x and y
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (VectorSize > 2)
|
||||
{
|
||||
// draw z
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
z = GUIHelper.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
if (VectorSize > 3)
|
||||
{
|
||||
// draw w
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
w = GUIHelper.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// draw set value button
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIUnstrip.Space(whitespace);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.Space(whitespace);
|
||||
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||
{
|
||||
SetValueFromInput();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ using System.Reflection;
|
||||
using System.IO;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
using TextEditor = Explorer.Unstrip.IMGUI.TextEditorUnstrip;
|
||||
using Explorer.Unstrip.IMGUI;
|
||||
#endif
|
||||
|
||||
namespace Explorer.UI.Main
|
||||
@ -33,7 +35,7 @@ namespace Explorer.UI.Main
|
||||
public static TextEditor textEditor;
|
||||
private bool shouldRefocus;
|
||||
|
||||
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetCompletionStyle();
|
||||
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetAutocompleteStyle();
|
||||
private static GUIStyle autocompleteStyle;
|
||||
|
||||
public static readonly string[] DefaultUsing = new string[]
|
||||
@ -140,15 +142,15 @@ Help();";
|
||||
|
||||
GUILayout.Label("Enter code here as though it is a method body:", new GUILayoutOption[0]);
|
||||
|
||||
inputAreaScroll = GUIUnstrip.BeginScrollView(
|
||||
inputAreaScroll = GUIHelper.BeginScrollView(
|
||||
inputAreaScroll,
|
||||
new GUILayoutOption[] { GUILayout.Height(250), GUILayout.ExpandHeight(true) }
|
||||
new GUILayoutOption[] { GUILayout.Height(250), GUIHelper.ExpandHeight(true) }
|
||||
);
|
||||
|
||||
GUI.SetNextControlName(INPUT_CONTROL_NAME);
|
||||
m_input = GUIUnstrip.TextArea(m_input, new GUILayoutOption[] { GUILayout.ExpandHeight(true) });
|
||||
m_input = GUIHelper.TextArea(m_input, new GUILayoutOption[] { GUIHelper.ExpandHeight(true) });
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
|
||||
// EXECUTE BUTTON
|
||||
|
||||
@ -179,7 +181,7 @@ Help();";
|
||||
// SUGGESTIONS
|
||||
if (AutoCompletes.Count > 0)
|
||||
{
|
||||
autocompleteScroll = GUIUnstrip.BeginScrollView(autocompleteScroll, new GUILayoutOption[] { GUILayout.Height(150) });
|
||||
autocompleteScroll = GUIHelper.BeginScrollView(autocompleteScroll, new GUILayoutOption[] { GUILayout.Height(150) });
|
||||
|
||||
var origSkin = GUI.skin.button;
|
||||
GUI.skin.button = AutocompleteStyle;
|
||||
@ -196,7 +198,7 @@ Help();";
|
||||
|
||||
GUI.skin.button = origSkin;
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
}
|
||||
|
||||
if (shouldRefocus)
|
||||
@ -209,9 +211,9 @@ Help();";
|
||||
|
||||
GUILayout.Label("<b>Using directives:</b>", new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) });
|
||||
m_usingInput = GUIUnstrip.TextField(m_usingInput, new GUILayoutOption[] { GUILayout.Width(150) });
|
||||
m_usingInput = GUIHelper.TextField(m_usingInput, new GUILayoutOption[] { GUILayout.Width(150) });
|
||||
if (GUILayout.Button("<b><color=lime>Add</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
|
||||
{
|
||||
AddUsing(m_usingInput);
|
||||
@ -245,7 +247,8 @@ Help();";
|
||||
#endif
|
||||
|
||||
#if CPP
|
||||
textEditor = GUIUtility.GetStateObject(Il2CppType.Of<TextEditor>(), GUIUtility.keyboardControl).TryCast<TextEditor>();
|
||||
//textEditor = GUIUtility.GetStateObject(Il2CppType.Of<TextEditor>(), GUIUtility.keyboardControl).TryCast<TextEditor>();
|
||||
textEditor = (TextEditor)GUIUtilityUnstrip.GetMonoStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
|
||||
#else
|
||||
textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
|
||||
#endif
|
||||
@ -342,19 +345,21 @@ Help();";
|
||||
}
|
||||
|
||||
// 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),
|
||||
margin = new RectOffset(0, 0, 0, 0),
|
||||
padding = new RectOffset(0, 0, 0, 0),
|
||||
border = new RectOffset(),
|
||||
margin = new RectOffset(),
|
||||
padding = new RectOffset(),
|
||||
hover = { background = Texture2D.whiteTexture, textColor = Color.black },
|
||||
normal = { background = null },
|
||||
focused = { 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
|
||||
|
@ -56,34 +56,44 @@ namespace Explorer.UI.Main
|
||||
GUILayout.Label("<color=orange><size=16><b>Options</b></size></color>", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Menu Toggle Key:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
toggleKeyInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
UIStyles.HorizontalLine(Color.black, true);
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Default Window Size:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
defaultSizeInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
UIStyles.HorizontalLine(Color.black, true);
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Default Items per Page:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
defaultPageLimitInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
UIStyles.HorizontalLine(Color.black, true);
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Enable Bitwise Editing:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
bitwiseSupportInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
UIStyles.HorizontalLine(Color.black, true);
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Enable Tab View:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
tabViewInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
UIStyles.HorizontalLine(Color.black, true);
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label($"Default Output Path:", new GUILayoutOption[] { GUILayout.Width(215f) });
|
||||
defaultOutputPathInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
|
||||
GUILayout.EndHorizontal();
|
||||
@ -95,13 +105,13 @@ namespace Explorer.UI.Main
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUIUnstrip.Space(10f);
|
||||
GUIHelper.Space(10f);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label("<color=orange><size=16><b>Other</b></size></color>", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
|
||||
|
||||
if (GUILayout.Button("Inspect Test Class", new GUILayoutOption[0]))
|
||||
{
|
||||
|
@ -5,6 +5,8 @@ using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using Explorer.Helpers;
|
||||
using Explorer.Unstrip.Resources;
|
||||
|
||||
namespace Explorer.UI.Main
|
||||
{
|
||||
@ -19,8 +21,6 @@ namespace Explorer.UI.Main
|
||||
private float m_timeOfLastUpdate = -1f;
|
||||
private const int PASSIVE_UPDATE_INTERVAL = 1;
|
||||
|
||||
private static bool m_getRootObjectsFailed;
|
||||
|
||||
private static string m_currentScene = "";
|
||||
|
||||
// gameobject list
|
||||
@ -50,7 +50,7 @@ namespace Explorer.UI.Main
|
||||
if (m_searching)
|
||||
CancelSearch();
|
||||
|
||||
Update_Impl(true);
|
||||
Update_Impl();
|
||||
}
|
||||
|
||||
public void TraverseUp()
|
||||
@ -75,18 +75,13 @@ namespace Explorer.UI.Main
|
||||
public void CancelSearch()
|
||||
{
|
||||
m_searching = false;
|
||||
|
||||
if (m_getRootObjectsFailed && !m_currentTransform)
|
||||
{
|
||||
GetRootObjectsManual_Impl();
|
||||
}
|
||||
}
|
||||
|
||||
public List<CacheObjectBase> SearchSceneObjects(string _search)
|
||||
{
|
||||
var matches = new List<CacheObjectBase>();
|
||||
|
||||
foreach (var obj in Resources.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
|
||||
foreach (var obj in ResourcesUnstrip.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
|
||||
{
|
||||
#if CPP
|
||||
var go = obj.TryCast<GameObject>();
|
||||
@ -112,7 +107,7 @@ namespace Explorer.UI.Main
|
||||
Update_Impl();
|
||||
}
|
||||
|
||||
private void Update_Impl(bool manual = false)
|
||||
private void Update_Impl()
|
||||
{
|
||||
List<Transform> allTransforms = new List<Transform>();
|
||||
|
||||
@ -126,39 +121,23 @@ namespace Explorer.UI.Main
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_getRootObjectsFailed)
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
try
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
|
||||
if (scene.name == m_currentScene)
|
||||
{
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
var rootObjects =
|
||||
#if CPP
|
||||
Unstrip.Scenes.SceneUnstrip.GetRootGameObjects(scene)
|
||||
.Select(it => it.transform);
|
||||
#else
|
||||
scene.GetRootGameObjects().Select(it => it.transform);
|
||||
#endif
|
||||
allTransforms.AddRange(rootObjects);
|
||||
|
||||
if (scene.name == m_currentScene)
|
||||
{
|
||||
allTransforms.AddRange(scene.GetRootGameObjects()
|
||||
.Select(it => it.transform));
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,36 +157,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 --------- //
|
||||
|
||||
public override void DrawWindow()
|
||||
@ -216,7 +165,7 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
DrawHeaderArea();
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
DrawPageButtons();
|
||||
|
||||
@ -242,7 +191,7 @@ namespace Explorer.UI.Main
|
||||
|
||||
private void DrawHeaderArea()
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
// Current Scene label
|
||||
GUILayout.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) });
|
||||
@ -252,10 +201,10 @@ namespace Explorer.UI.Main
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// ----- GameObject Search -----
|
||||
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
GUILayout.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
|
||||
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[0]);
|
||||
m_searchInput = GUIHelper.TextField(m_searchInput, new GUILayoutOption[0]);
|
||||
|
||||
if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
@ -263,7 +212,7 @@ namespace Explorer.UI.Main
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.Space(5);
|
||||
GUIHelper.Space(5);
|
||||
}
|
||||
|
||||
private void SceneChangeButtons()
|
||||
@ -292,22 +241,19 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
int index = names.IndexOf(m_currentScene);
|
||||
index += changeWanted;
|
||||
if (index > scenes.Count - 1)
|
||||
|
||||
if (index >= 0 && index < SceneManager.sceneCount)
|
||||
{
|
||||
index = 0;
|
||||
m_currentScene = scenes[index].name;
|
||||
Update_Impl();
|
||||
}
|
||||
else if (index < 0)
|
||||
{
|
||||
index = scenes.Count - 1;
|
||||
}
|
||||
m_currentScene = scenes[index].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPageButtons()
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
@ -317,7 +263,7 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
Pages.TurnPage(Turn.Left, ref this.scroll);
|
||||
|
||||
Update_Impl(true);
|
||||
Update_Impl();
|
||||
}
|
||||
|
||||
Pages.CurrentPageLabel();
|
||||
@ -326,7 +272,7 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
Pages.TurnPage(Turn.Right, ref this.scroll);
|
||||
|
||||
Update_Impl(true);
|
||||
Update_Impl();
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,7 +284,7 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
if (m_currentTransform != null)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
|
||||
{
|
||||
TraverseUp();
|
||||
@ -356,14 +302,6 @@ namespace Explorer.UI.Main
|
||||
else
|
||||
{
|
||||
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)
|
||||
|
@ -6,6 +6,8 @@ using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Explorer.UI.Shared;
|
||||
using Explorer.CacheObject;
|
||||
using Explorer.Helpers;
|
||||
using Explorer.Unstrip.Resources;
|
||||
|
||||
namespace Explorer.UI.Main
|
||||
{
|
||||
@ -15,9 +17,13 @@ namespace Explorer.UI.Main
|
||||
|
||||
public override string Name { get => "Search"; }
|
||||
|
||||
private int MaxSearchResults = 5000;
|
||||
|
||||
private string m_searchInput = "";
|
||||
private string m_typeInput = "";
|
||||
|
||||
//private bool m_cachingResults;
|
||||
|
||||
private Vector2 resultsScroll = Vector2.zero;
|
||||
|
||||
public PageHelper Pages = new PageHelper();
|
||||
@ -58,6 +64,8 @@ namespace Explorer.UI.Main
|
||||
|
||||
private void CacheResults(IEnumerable results, bool isStaticClasses = false)
|
||||
{
|
||||
//m_cachingResults = true;
|
||||
|
||||
m_searchResults = new List<CacheObjectBase>();
|
||||
|
||||
foreach (var obj in results)
|
||||
@ -67,6 +75,9 @@ namespace Explorer.UI.Main
|
||||
#if CPP
|
||||
if (toCache is Il2CppSystem.Object ilObject)
|
||||
{
|
||||
var type = ReflectionHelpers.GetActualType(ilObject);
|
||||
ilObject = (Il2CppSystem.Object)ilObject.Il2CppCast(type);
|
||||
|
||||
toCache = ilObject.TryCast<GameObject>() ?? ilObject.TryCast<Transform>()?.gameObject ?? ilObject;
|
||||
}
|
||||
#else
|
||||
@ -76,6 +87,14 @@ namespace Explorer.UI.Main
|
||||
}
|
||||
#endif
|
||||
|
||||
if (toCache is TextAsset textAsset)
|
||||
{
|
||||
if (string.IsNullOrEmpty(textAsset.text))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var cache = CacheFactory.GetCacheObject(toCache);
|
||||
cache.IsStaticClassSearchResult = isStaticClasses;
|
||||
m_searchResults.Add(cache);
|
||||
@ -83,187 +102,22 @@ namespace Explorer.UI.Main
|
||||
|
||||
Pages.ItemCount = m_searchResults.Count;
|
||||
Pages.PageOffset = 0;
|
||||
|
||||
results = null;
|
||||
|
||||
//m_cachingResults = false;
|
||||
}
|
||||
|
||||
public override void DrawWindow()
|
||||
{
|
||||
try
|
||||
{
|
||||
// helpers
|
||||
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
GUILayout.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
|
||||
if (GUILayout.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
|
||||
{
|
||||
CacheResults(GetStaticInstances());
|
||||
}
|
||||
if (GUILayout.Button("Find Static Classes", new GUILayoutOption[] { GUILayout.Width(180) }))
|
||||
{
|
||||
CacheResults(GetStaticClasses(), true);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// search box
|
||||
SearchBox();
|
||||
|
||||
// results
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
int count = m_searchResults.Count;
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
if (count > Pages.ItemsPerPage)
|
||||
{
|
||||
// prev/next page buttons
|
||||
|
||||
if (Pages.ItemCount > Pages.ItemsPerPage)
|
||||
{
|
||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
Pages.TurnPage(Turn.Left, ref this.resultsScroll);
|
||||
}
|
||||
|
||||
Pages.CurrentPageLabel();
|
||||
|
||||
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
Pages.TurnPage(Turn.Right, ref this.resultsScroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
resultsScroll = GUIUnstrip.BeginScrollView(resultsScroll);
|
||||
|
||||
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
|
||||
|
||||
if (m_searchResults.Count > 0)
|
||||
{
|
||||
int offset = Pages.CalculateOffsetIndex();
|
||||
|
||||
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
|
||||
{
|
||||
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("<color=red><i>No results found!</i></color>", new GUILayoutOption[0]);
|
||||
}
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_searchResults.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchBox()
|
||||
{
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
// ----- GameObject Search -----
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label("<b><color=orange>Search</color></b>", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
ClassFilterToggle(TypeFilter.Object, "Object");
|
||||
ClassFilterToggle(TypeFilter.GameObject, "GameObject");
|
||||
ClassFilterToggle(TypeFilter.Component, "Component");
|
||||
ClassFilterToggle(TypeFilter.Custom, "Custom");
|
||||
GUILayout.EndHorizontal();
|
||||
if (TypeMode == TypeFilter.Custom)
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||
GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
m_typeInput = GUIUnstrip.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
SceneFilterToggle(SceneFilter.Any, "Any", 60);
|
||||
SceneFilterToggle(SceneFilter.This, "This Scene", 100);
|
||||
SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140);
|
||||
SceneFilterToggle(SceneFilter.None, "No Scene", 80);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
|
||||
{
|
||||
Search();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void ClassFilterToggle(TypeFilter mode, string label)
|
||||
{
|
||||
if (TypeMode == mode)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
|
||||
{
|
||||
TypeMode = mode;
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
private void SceneFilterToggle(SceneFilter mode, string label, float width)
|
||||
{
|
||||
if (SceneMode == mode)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
|
||||
{
|
||||
SceneMode = mode;
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
|
||||
// -------------- ACTUAL METHODS (not Gui draw) ----------------- //
|
||||
|
||||
// ======= search functions =======
|
||||
|
||||
private void Search()
|
||||
{
|
||||
Pages.PageOffset = 0;
|
||||
CacheResults(FindAllObjectsOfType(m_searchInput, m_typeInput));
|
||||
}
|
||||
//if (m_cachingResults)
|
||||
//{
|
||||
// ExplorerCore.Log("Cannot search now, we are already caching results...");
|
||||
// return;
|
||||
//}
|
||||
|
||||
Pages.PageOffset = 0;
|
||||
|
||||
private List<object> FindAllObjectsOfType(string searchQuery, string typeName)
|
||||
{
|
||||
#if CPP
|
||||
Il2CppSystem.Type searchType = null;
|
||||
|
||||
@ -272,24 +126,18 @@ namespace Explorer.UI.Main
|
||||
#endif
|
||||
if (TypeMode == TypeFilter.Custom)
|
||||
{
|
||||
try
|
||||
if (ReflectionHelpers.GetTypeByName(m_typeInput) is Type t)
|
||||
{
|
||||
if (ReflectionHelpers.GetTypeByName(typeName) is Type t)
|
||||
{
|
||||
#if CPP
|
||||
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
|
||||
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
|
||||
#else
|
||||
searchType = t;
|
||||
searchType = t;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Could not find a Type by the name of '{typeName}'!");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
ExplorerCore.Log("Exception getting Search Type: " + e.GetType() + ", " + e.Message);
|
||||
ExplorerCore.Log($"Could not find a Type by the name of '{m_typeInput}'!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (TypeMode == TypeFilter.Object)
|
||||
@ -311,21 +159,21 @@ namespace Explorer.UI.Main
|
||||
{
|
||||
ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!");
|
||||
}
|
||||
return new List<object>();
|
||||
return;
|
||||
}
|
||||
|
||||
var matches = new List<object>();
|
||||
|
||||
var allObjectsOfType = Resources.FindObjectsOfTypeAll(searchType);
|
||||
var allObjectsOfType = ResourcesUnstrip.FindObjectsOfTypeAll(searchType);
|
||||
|
||||
//ExplorerCore.Log("Found count: " + allObjectsOfType.Length);
|
||||
|
||||
int i = 0;
|
||||
foreach (var obj in allObjectsOfType)
|
||||
{
|
||||
if (i >= 2000) break;
|
||||
if (i >= MaxSearchResults) break;
|
||||
|
||||
if (searchQuery != "" && !obj.name.ToLower().Contains(searchQuery.ToLower()))
|
||||
if (m_searchInput != "" && !obj.name.ToLower().Contains(m_searchInput.ToLower()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -355,7 +203,7 @@ namespace Explorer.UI.Main
|
||||
i++;
|
||||
}
|
||||
|
||||
return matches;
|
||||
CacheResults(matches);
|
||||
}
|
||||
|
||||
public static bool FilterScene(object obj, SceneFilter filter)
|
||||
@ -394,8 +242,6 @@ namespace Explorer.UI.Main
|
||||
return false;
|
||||
}
|
||||
|
||||
// ====== other ========
|
||||
|
||||
private static bool FilterName(string name)
|
||||
{
|
||||
// Don't really want these instances.
|
||||
@ -497,5 +343,202 @@ namespace Explorer.UI.Main
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// =========== GUI DRAW ============= //
|
||||
|
||||
public override void DrawWindow()
|
||||
{
|
||||
try
|
||||
{
|
||||
// helpers
|
||||
GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
GUILayout.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
|
||||
if (GUILayout.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
|
||||
{
|
||||
CacheResults(GetStaticInstances());
|
||||
}
|
||||
if (GUILayout.Button("Find Static Classes", new GUILayoutOption[] { GUILayout.Width(180) }))
|
||||
{
|
||||
CacheResults(GetStaticClasses(), true);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
// search box
|
||||
SearchBox();
|
||||
|
||||
// results
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
int count = m_searchResults.Count;
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
Pages.DrawLimitInputArea();
|
||||
|
||||
if (count > Pages.ItemsPerPage)
|
||||
{
|
||||
// prev/next page buttons
|
||||
|
||||
if (Pages.ItemCount > Pages.ItemsPerPage)
|
||||
{
|
||||
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
Pages.TurnPage(Turn.Left, ref this.resultsScroll);
|
||||
}
|
||||
|
||||
Pages.CurrentPageLabel();
|
||||
|
||||
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
|
||||
{
|
||||
Pages.TurnPage(Turn.Right, ref this.resultsScroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
resultsScroll = GUIHelper.BeginScrollView(resultsScroll);
|
||||
|
||||
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
|
||||
|
||||
if (m_searchResults.Count > 0)
|
||||
{
|
||||
int offset = Pages.CalculateOffsetIndex();
|
||||
|
||||
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
|
||||
{
|
||||
if (i >= m_searchResults.Count) break;
|
||||
|
||||
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("<color=red><i>No results found!</i></color>", new GUILayoutOption[0]);
|
||||
}
|
||||
|
||||
GUIHelper.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!e.Message.Contains("in a group with only"))
|
||||
{
|
||||
ExplorerCore.Log("Exception drawing search results!");
|
||||
while (e != null)
|
||||
{
|
||||
ExplorerCore.Log(e);
|
||||
e = e.InnerException;
|
||||
}
|
||||
m_searchResults.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchBox()
|
||||
{
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
// ----- GameObject Search -----
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Label("<b><color=orange>Search</color></b>", new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
m_searchInput = GUIHelper.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
|
||||
|
||||
GUILayout.Label("Max Results:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
var s = MaxSearchResults.ToString();
|
||||
s = GUIHelper.TextField(s, new GUILayoutOption[] { GUILayout.Width(80) });
|
||||
if (int.TryParse(s, out int i))
|
||||
{
|
||||
MaxSearchResults = i;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
ClassFilterToggle(TypeFilter.Object, "Object");
|
||||
ClassFilterToggle(TypeFilter.GameObject, "GameObject");
|
||||
ClassFilterToggle(TypeFilter.Component, "Component");
|
||||
ClassFilterToggle(TypeFilter.Custom, "Custom");
|
||||
GUILayout.EndHorizontal();
|
||||
if (TypeMode == TypeFilter.Custom)
|
||||
{
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||
GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
m_typeInput = GUIHelper.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
SceneFilterToggle(SceneFilter.Any, "Any", 60);
|
||||
SceneFilterToggle(SceneFilter.This, "This Scene", 100);
|
||||
SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140);
|
||||
SceneFilterToggle(SceneFilter.None, "No Scene", 80);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
|
||||
{
|
||||
Search();
|
||||
}
|
||||
//if (m_cachingResults)
|
||||
//{
|
||||
// GUILayout.Label("Searching...", new GUILayoutOption[0]);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
|
||||
// {
|
||||
// Search();
|
||||
// }
|
||||
//}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void ClassFilterToggle(TypeFilter mode, string label)
|
||||
{
|
||||
if (TypeMode == mode)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
|
||||
{
|
||||
TypeMode = mode;
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
private void SceneFilterToggle(SceneFilter mode, string label, float width)
|
||||
{
|
||||
if (SceneMode == mode)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
|
||||
{
|
||||
SceneMode = mode;
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Explorer.UI
|
||||
return;
|
||||
}
|
||||
m_currentPage = index;
|
||||
GUIUnstrip.BringWindowToFront(MainWindowID);
|
||||
GUIHelper.BringWindowToFront(MainWindowID);
|
||||
GUI.FocusWindow(MainWindowID);
|
||||
}
|
||||
|
||||
@ -58,39 +58,39 @@ namespace Explorer.UI
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
MainRect = GUIUnstrip.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, ExplorerCore.NAME);
|
||||
MainRect = GUIHelper.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, ExplorerCore.NAME);
|
||||
}
|
||||
|
||||
private void MainWindow(int id)
|
||||
{
|
||||
GUI.DragWindow(new Rect(0, 0, MainRect.width - 90, 20));
|
||||
|
||||
if (GUIUnstrip.Button(new Rect(MainRect.width - 90, 2, 80, 20), $"Hide ({ModConfig.Instance.Main_Menu_Toggle})"))
|
||||
if (GUIHelper.Button(new Rect(MainRect.width - 90, 2, 80, 20), $"Hide ({ModConfig.Instance.Main_Menu_Toggle})"))
|
||||
{
|
||||
ExplorerCore.ShowMenu = false;
|
||||
return;
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box);
|
||||
GUIHelper.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box);
|
||||
|
||||
MainHeader();
|
||||
|
||||
var page = Pages[m_currentPage];
|
||||
|
||||
page.scroll = GUIUnstrip.BeginScrollView(page.scroll);
|
||||
page.scroll = GUIHelper.BeginScrollView(page.scroll);
|
||||
|
||||
page.DrawWindow();
|
||||
|
||||
GUIUnstrip.EndScrollView();
|
||||
GUIHelper.EndScrollView();
|
||||
|
||||
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
|
||||
|
||||
GUIUnstrip.EndArea();
|
||||
GUIHelper.EndArea();
|
||||
}
|
||||
|
||||
private void MainHeader()
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
for (int i = 0; i < Pages.Count; i++)
|
||||
{
|
||||
if (m_currentPage == i)
|
||||
@ -105,7 +105,7 @@ namespace Explorer.UI
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.color = Color.white;
|
||||
InspectUnderMouse.EnableInspect = GUILayout.Toggle(InspectUnderMouse.EnableInspect, "Inspect Under Mouse (Shift + RMB)", new GUILayoutOption[0]);
|
||||
|
||||
@ -117,7 +117,7 @@ namespace Explorer.UI
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//GUIUnstrip.Space(10);
|
||||
GUIUnstrip.Space(10);
|
||||
GUIHelper.Space(10);
|
||||
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace Explorer.UI.Shared
|
||||
|
||||
// ------ toggle active button ------
|
||||
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.skin.button.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
GUI.color = color;
|
||||
|
@ -94,7 +94,7 @@ namespace Explorer.UI.Shared
|
||||
{
|
||||
GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
var limit = this.ItemsPerPage.ToString();
|
||||
limit = GUIUnstrip.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
limit = GUIHelper.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i))
|
||||
{
|
||||
ItemsPerPage = i;
|
||||
|
@ -8,52 +8,60 @@ namespace Explorer.UI.Shared
|
||||
{
|
||||
public class ResizeDrag
|
||||
{
|
||||
#if CPP
|
||||
private static bool RESIZE_FAILED = false;
|
||||
#endif
|
||||
|
||||
public static bool IsResizing = false;
|
||||
public static bool IsMouseInResizeArea = false;
|
||||
|
||||
private static readonly GUIContent gcDrag = new GUIContent("<-- Drag to resize -->");
|
||||
private static bool isResizing = false;
|
||||
private static Rect m_currentResize;
|
||||
private static int m_currentWindow;
|
||||
|
||||
public static Rect ResizeWindow(Rect _rect, int ID)
|
||||
{
|
||||
#if CPP
|
||||
if (!RESIZE_FAILED)
|
||||
{
|
||||
var origRect = _rect;
|
||||
|
||||
try
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
#if ML
|
||||
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
#if BIE
|
||||
#if CPP // Temporary for BepInEx IL2CPP
|
||||
GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
#else
|
||||
GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
#endif
|
||||
#else
|
||||
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
#endif
|
||||
|
||||
var r = GUIUnstrip.GetLastRect();
|
||||
|
||||
var resizeDragArea = GUIHelper.GetLastRect();
|
||||
var mousePos = InputManager.MousePosition;
|
||||
|
||||
try
|
||||
{
|
||||
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
|
||||
if (r.Contains(mouse) && InputManager.GetMouseButtonDown(0))
|
||||
var mouse = GUIHelper.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
|
||||
if (resizeDragArea.Contains(mouse))
|
||||
{
|
||||
isResizing = true;
|
||||
m_currentWindow = ID;
|
||||
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
|
||||
IsMouseInResizeArea = true;
|
||||
|
||||
if (InputManager.GetMouseButtonDown(0))
|
||||
{
|
||||
IsResizing = true;
|
||||
m_currentWindow = ID;
|
||||
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
|
||||
}
|
||||
}
|
||||
else if (!InputManager.GetMouseButton(0))
|
||||
{
|
||||
isResizing = false;
|
||||
IsMouseInResizeArea = false;
|
||||
IsResizing = false;
|
||||
}
|
||||
|
||||
if (isResizing && ID == m_currentWindow)
|
||||
if (IsResizing && ID == m_currentWindow)
|
||||
{
|
||||
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x));
|
||||
_rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
|
||||
@ -81,74 +89,36 @@ namespace Explorer.UI.Shared
|
||||
//ExplorerCore.Log(e.StackTrace);
|
||||
return origRect;
|
||||
}
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
|
||||
GUILayout.Label("Resize window:", new GUILayoutOption[] { GUILayout.Width(100) });
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||
GUILayout.Label("<color=cyan>Width:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
_rect.width -= 5f;
|
||||
}
|
||||
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
_rect.width += 5f;
|
||||
}
|
||||
GUILayout.Label("<color=cyan>Height:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
_rect.height -= 5f;
|
||||
}
|
||||
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
if (GUIHelper.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||
{
|
||||
_rect.height += 5f;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
}
|
||||
|
||||
#else // mono
|
||||
|
||||
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
|
||||
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||||
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
|
||||
|
||||
//var r = GUILayoutUtility.GetLastRect();
|
||||
var r = GUILayoutUtility.GetLastRect();
|
||||
|
||||
var mousePos = InputManager.MousePosition;
|
||||
|
||||
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
|
||||
if (r.Contains(mouse) && InputManager.GetMouseButtonDown(0))
|
||||
{
|
||||
isResizing = true;
|
||||
m_currentWindow = ID;
|
||||
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
|
||||
}
|
||||
else if (!InputManager.GetMouseButton(0))
|
||||
{
|
||||
isResizing = false;
|
||||
}
|
||||
|
||||
if (isResizing && ID == m_currentWindow)
|
||||
{
|
||||
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x));
|
||||
_rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
|
||||
_rect.xMax = Mathf.Min(Screen.width, _rect.xMax); // modifying xMax affects width, not x
|
||||
_rect.yMax = Mathf.Min(Screen.height, _rect.yMax); // modifying yMax affects height, not y
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
#endif
|
||||
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
return _rect;
|
||||
|
@ -52,7 +52,7 @@ namespace Explorer.UI
|
||||
try
|
||||
{
|
||||
GUI.DragWindow(new Rect(0, 0, m_rect.width - 90, 20));
|
||||
if (GUIUnstrip.Button(new Rect(m_rect.width - 90, 2, 80, 20), "<color=red>Close All</color>"))
|
||||
if (GUIHelper.Button(new Rect(m_rect.width - 90, 2, 80, 20), "<color=red>Close All</color>"))
|
||||
{
|
||||
foreach (var window in WindowManager.Windows)
|
||||
{
|
||||
@ -61,20 +61,29 @@ namespace Explorer.UI
|
||||
return;
|
||||
}
|
||||
|
||||
GUIUnstrip.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
|
||||
GUIHelper.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
|
||||
|
||||
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
|
||||
int tabPerRow = Mathf.FloorToInt((float)((decimal)m_rect.width / 238));
|
||||
int tabPerRow = (int)Math.Floor(m_rect.width / 238);
|
||||
int rowCount = 0;
|
||||
for (int i = 0; i < WindowManager.Windows.Count; i++)
|
||||
{
|
||||
var window = WindowManager.Windows[i];
|
||||
|
||||
// Prevent trying to draw destroyed UnityEngine.Objects
|
||||
// before the WindowManager removes them.
|
||||
if (window.Target is UnityEngine.Object uObj && !uObj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rowCount >= tabPerRow)
|
||||
{
|
||||
rowCount = 0;
|
||||
GUILayout.EndHorizontal();
|
||||
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
|
||||
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
||||
}
|
||||
rowCount++;
|
||||
|
||||
@ -82,7 +91,6 @@ namespace Explorer.UI
|
||||
string color = focused ? "<color=lime>" : "<color=orange>";
|
||||
GUI.color = focused ? Color.green : Color.white;
|
||||
|
||||
var window = WindowManager.Windows[i];
|
||||
if (GUILayout.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) }))
|
||||
{
|
||||
TargetTabID = i;
|
||||
@ -101,7 +109,7 @@ namespace Explorer.UI
|
||||
|
||||
m_rect = ResizeDrag.ResizeWindow(m_rect, windowID);
|
||||
|
||||
GUIUnstrip.EndArea();
|
||||
GUIHelper.EndArea();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -11,6 +11,26 @@ namespace Explorer.UI
|
||||
|
||||
public static bool TabView = Config.ModConfig.Instance.Tab_View;
|
||||
|
||||
public static bool IsMouseInWindow
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ExplorerCore.ShowMenu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var window in Windows)
|
||||
{
|
||||
if (RectContainsMouse(window.m_rect))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return RectContainsMouse(MainMenu.MainRect);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<WindowBase> Windows = new List<WindowBase>();
|
||||
public static int CurrentWindowID { get; set; } = 500000;
|
||||
private static Rect m_lastWindowRect;
|
||||
@ -90,7 +110,7 @@ namespace Explorer.UI
|
||||
{
|
||||
if (!TabView)
|
||||
{
|
||||
GUIUnstrip.BringWindowToFront(window.windowID);
|
||||
GUIHelper.BringWindowToFront(window.windowID);
|
||||
GUI.FocusWindow(window.windowID);
|
||||
}
|
||||
else
|
||||
@ -123,26 +143,6 @@ namespace Explorer.UI
|
||||
return new_window;
|
||||
}
|
||||
|
||||
public static bool IsMouseInWindow
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ExplorerCore.ShowMenu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var window in Windows)
|
||||
{
|
||||
if (RectContainsMouse(window.m_rect))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return RectContainsMouse(MainMenu.MainRect);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool RectContainsMouse(Rect rect)
|
||||
{
|
||||
var mousePos = InputManager.MousePosition;
|
||||
|
175
src/Unstrip/IMGUI/GUIHelper.cs
Normal file
175
src/Unstrip/IMGUI/GUIHelper.cs
Normal file
@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
#if CPP
|
||||
using Explorer.Unstrip.IMGUI;
|
||||
#endif
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
// All the pre-processor directive stuff is in this class to keep it separate.
|
||||
// This is so Mono build can use this class and not have to worry.
|
||||
|
||||
public class GUIHelper
|
||||
{
|
||||
|
||||
internal static GUILayoutOption ExpandHeight(bool expand)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.ExpandHeight(expand);
|
||||
#else
|
||||
return GUILayout.ExpandHeight(expand);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BeginHorizontal(params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, GUIStyle.none, options);
|
||||
|
||||
public static void BeginHorizontal(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, style, options);
|
||||
|
||||
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.BeginLayoutDirection(false, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginHorizontal(content, style, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BeginVertical(params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, GUIStyle.none, options);
|
||||
|
||||
public static void BeginVertical(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, style, options);
|
||||
|
||||
public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.BeginLayoutDirection(true, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginVertical(content, style, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static Rect GetLastRect()
|
||||
{
|
||||
#if CPP
|
||||
return LayoutUtilityUnstrip.GetLastRect();
|
||||
#else
|
||||
return GUILayoutUtility.GetLastRect();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string TextField(string text, GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.TextField(text, options, false);
|
||||
#else
|
||||
return GUILayout.TextField(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string TextArea(string text, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.TextField(text, options, true);
|
||||
#else
|
||||
return GUILayout.TextArea(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Window(id, rect, windowFunc, GUIContent.Temp(title), GUI.skin.window);
|
||||
#else
|
||||
return GUI.Window(id, rect, windowFunc, title);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool Button(Rect rect, string title)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Button(rect, GUIContent.Temp(title), GUI.skin.button);
|
||||
#else
|
||||
return GUI.Button(rect, title);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BringWindowToFront(int id)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.BringWindowToFront(id);
|
||||
#else
|
||||
GUI.BringWindowToFront(id);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.ScreenToGUIPoint(screenPoint);
|
||||
#else
|
||||
return GUIUtility.ScreenToGUIPoint(screenPoint);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Space(float pixels)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.Space(pixels);
|
||||
#else
|
||||
GUILayout.Space(pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool RepeatButton(string text, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options);
|
||||
#else
|
||||
return GUILayout.RepeatButton(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BeginArea(Rect screenRect, GUIStyle style)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.BeginArea(screenRect, GUIContent.none, style);
|
||||
#else
|
||||
GUILayout.BeginArea(screenRect, style);
|
||||
#endif
|
||||
}
|
||||
|
||||
static public void EndArea()
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.EndArea();
|
||||
#else
|
||||
GUILayout.EndArea();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUIUnstrip.BeginScrollView(scroll, options);
|
||||
#else
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void EndScrollView(bool handleScrollWheel = true)
|
||||
{
|
||||
#if CPP
|
||||
GUIUnstrip.EndScrollView(handleScrollWheel);
|
||||
#else
|
||||
GUILayout.EndScrollView();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -1,162 +1,786 @@
|
||||
using System;
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
#if CPP
|
||||
using Explorer.Unstrip.IMGUI;
|
||||
#endif
|
||||
using UnityEngineInternal;
|
||||
using UnhollowerRuntimeLib;
|
||||
|
||||
namespace Explorer
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
// Also contains some stuff from GUI.
|
||||
// This class was meant to be temporary but who knows.
|
||||
|
||||
public class GUIUnstrip
|
||||
{
|
||||
public static void BeginHorizontal(params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, GUIStyle.none, options);
|
||||
#region Properties
|
||||
public static int s_ScrollControlId;
|
||||
|
||||
public static void BeginHorizontal(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, style, options);
|
||||
public static bool ScrollFailed = false;
|
||||
public static bool ManualUnstripFailed = false;
|
||||
|
||||
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
public static Stack<object> ScrollStack => m_scrollStack ?? GetScrollStack();
|
||||
public static Stack<object> m_scrollStack;
|
||||
//public static PropertyInfo m_scrollViewStatesInfo;
|
||||
|
||||
public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle();
|
||||
public static GUIStyle m_spaceStyle;
|
||||
|
||||
public static DateTime nextScrollStepTime;
|
||||
|
||||
public static MethodInfo ScreenToGuiPointMethod;
|
||||
public static bool m_screenToGuiAttemped;
|
||||
|
||||
public static MethodInfo m_bringWindowToFrontMethod;
|
||||
public static bool m_bringWindowFrontAttempted;
|
||||
|
||||
private static Stack<object> GetScrollStack()
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginLayoutDirection(false, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginHorizontal(content, style, options);
|
||||
#endif
|
||||
m_scrollStack = new Stack<object>();
|
||||
|
||||
return m_scrollStack;
|
||||
}
|
||||
|
||||
public static void BeginVertical(params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, GUIStyle.none, options);
|
||||
|
||||
public static void BeginVertical(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, style, options);
|
||||
|
||||
public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
private static GUIStyle GetSpaceStyle()
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginLayoutDirection(true, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginVertical(content, style, options);
|
||||
#endif
|
||||
try
|
||||
{
|
||||
m_spaceStyle = typeof(GUILayoutUtility)
|
||||
.GetProperty("s_SpaceStyle")
|
||||
.GetValue(null, null)
|
||||
.Il2CppCast(typeof(GUIStyle))
|
||||
as GUIStyle;
|
||||
|
||||
if (m_spaceStyle == null) throw new Exception();
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (m_spaceStyle == null)
|
||||
{
|
||||
m_spaceStyle = new GUIStyle();
|
||||
}
|
||||
m_spaceStyle.stretchWidth = false;
|
||||
return m_spaceStyle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static Rect GetLastRect()
|
||||
#region GUILayout Methods
|
||||
|
||||
public static GUILayoutOption ExpandWidth(bool expand)
|
||||
{
|
||||
#if CPP
|
||||
return Internal_LayoutUtility.GetLastRect();
|
||||
#else
|
||||
return GUILayoutUtility.GetLastRect();
|
||||
#endif
|
||||
var ilValue = new Il2CppSystem.Int32
|
||||
{
|
||||
m_value = (!expand) ? 0 : 1
|
||||
};
|
||||
|
||||
var option = new GUILayoutOption(GUILayoutOption.Type.stretchWidth, ilValue.BoxIl2CppObject());
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
public static string TextField(string text, GUILayoutOption[] options)
|
||||
public static GUILayoutOption ExpandHeight(bool expand)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.TextField(text, options);
|
||||
#else
|
||||
return GUILayout.TextField(text, options);
|
||||
#endif
|
||||
var ilValue = new Il2CppSystem.Int32
|
||||
{
|
||||
m_value = (!expand) ? 0 : 1
|
||||
};
|
||||
|
||||
var option = new GUILayoutOption(GUILayoutOption.Type.stretchHeight, ilValue.BoxIl2CppObject());
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
|
||||
public static void BeginLayoutDirection(bool vertical, GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Window(id, rect, windowFunc, GUIContent.Temp(title), GUI.skin.window);
|
||||
#else
|
||||
return GUI.Window(id, rect, windowFunc, title);
|
||||
#endif
|
||||
var g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
|
||||
g.isVertical = vertical;
|
||||
if (style != GUIStyle.none || content != GUIContent.none)
|
||||
GUI.Box(g.rect, content, style);
|
||||
}
|
||||
|
||||
public static bool Button(Rect rect, string title)
|
||||
public static string TextField(string text, GUILayoutOption[] options, bool multiLine)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Button(rect, GUIContent.Temp(title), GUI.skin.button);
|
||||
#else
|
||||
return GUI.Button(rect, title);
|
||||
#endif
|
||||
text = text ?? string.Empty;
|
||||
|
||||
var skin = multiLine ? GUI.skin.textArea : GUI.skin.textField;
|
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Keyboard);
|
||||
GUIContent guicontent = GUIContent.Temp(text);
|
||||
bool flag = GUIUtility.keyboardControl != controlID;
|
||||
if (flag)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
// guicontent = GUIContent.Temp(text + GUIUtility.compositionString);
|
||||
}
|
||||
Rect rect = LayoutUtilityUnstrip.GetRect(guicontent, skin, options);
|
||||
bool flag2 = GUIUtility.keyboardControl == controlID;
|
||||
if (flag2)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
DoTextField(rect, controlID, guicontent, multiLine, -1, skin);
|
||||
return guicontent.text;
|
||||
}
|
||||
|
||||
public static string TextArea(string text, params GUILayoutOption[] options)
|
||||
internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style)
|
||||
{
|
||||
#if CPP
|
||||
return GUILayout.DoTextField(text, -1, true, GUI.skin.textArea, options);
|
||||
#else
|
||||
return GUILayout.TextArea(text, options);
|
||||
#endif
|
||||
if (GUIUtilityUnstrip.GetMonoStateObject(typeof(TextEditorUnstrip), id) is TextEditorUnstrip textEditor)
|
||||
{
|
||||
if (maxLength >= 0 && content.text.Length > maxLength)
|
||||
{
|
||||
content.text = content.text.Substring(0, maxLength);
|
||||
}
|
||||
textEditor.m_Content.text = content.text;
|
||||
textEditor.SaveBackup();
|
||||
textEditor.position = position;
|
||||
textEditor.style = style;
|
||||
textEditor.multiline = multiline;
|
||||
textEditor.controlID = id;
|
||||
textEditor.DetectFocusChange();
|
||||
HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
|
||||
textEditor.UpdateScrollOffsetIfNeeded(Event.current);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BringWindowToFront(int id)
|
||||
private static void HandleTextFieldEventForDesktop(Rect position, int id, GUIContent content, bool multiline, int maxLength,
|
||||
GUIStyle style, TextEditorUnstrip editor)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BringWindowToFront(id);
|
||||
#else
|
||||
GUI.BringWindowToFront(id);
|
||||
#endif
|
||||
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(TextEditorUnstrip.DblClickSnapping.WORDS);
|
||||
editor.MouseDragSelectsWholeWords(true);
|
||||
}
|
||||
if (Event.current.clickCount == 3 && GUI.skin.settings.tripleClickSelectsLine)
|
||||
{
|
||||
editor.SelectCurrentParagraph();
|
||||
editor.MouseDragSelectsWholeWords(true);
|
||||
editor.DblClickSnap(TextEditorUnstrip.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 Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.ScreenToGUIPoint(screenPoint);
|
||||
#else
|
||||
return GUIUtility.ScreenToGUIPoint(screenPoint);
|
||||
#endif
|
||||
return GUI.DoRepeatButton(LayoutUtilityUnstrip.GetRect(content, style, options), content, style, FocusType.Passive);
|
||||
}
|
||||
|
||||
public static void Space(float pixels)
|
||||
{
|
||||
#if CPP
|
||||
Internal.Space(pixels);
|
||||
#else
|
||||
GUILayout.Space(pixels);
|
||||
#endif
|
||||
if (GUILayoutUtility.current.topLevel.isVertical)
|
||||
LayoutUtilityUnstrip.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
|
||||
else
|
||||
LayoutUtilityUnstrip.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
|
||||
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RepeatButton(string text, params GUILayoutOption[] options)
|
||||
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options);
|
||||
#else
|
||||
return GUILayout.RepeatButton(text, options);
|
||||
#endif
|
||||
if (!m_screenToGuiAttemped)
|
||||
{
|
||||
m_screenToGuiAttemped = true;
|
||||
ScreenToGuiPointMethod = typeof(GUIUtility).GetMethod("ScreenToGUIPoint");
|
||||
}
|
||||
if (ScreenToGuiPointMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.ScreenToGUIPoint'!");
|
||||
}
|
||||
return (Vector2)ScreenToGuiPointMethod.Invoke(null, new object[] { screenPoint });
|
||||
}
|
||||
|
||||
public static void BeginArea(Rect screenRect, GUIStyle style)
|
||||
public static void BringWindowToFront(int id)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginArea(screenRect, GUIContent.none, style);
|
||||
#else
|
||||
GUILayout.BeginArea(screenRect, style);
|
||||
#endif
|
||||
if (!m_bringWindowFrontAttempted)
|
||||
{
|
||||
m_bringWindowFrontAttempted = true;
|
||||
m_bringWindowToFrontMethod = typeof(GUI).GetMethod("BringWindowToFront");
|
||||
}
|
||||
if (m_bringWindowToFrontMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.BringWindowToFront'!");
|
||||
}
|
||||
m_bringWindowToFrontMethod.Invoke(null, new object[] { id });
|
||||
}
|
||||
|
||||
static public void EndArea()
|
||||
public static void BeginArea(Rect screenRect, GUIContent content, GUIStyle style)
|
||||
{
|
||||
#if CPP
|
||||
Internal.EndArea();
|
||||
#else
|
||||
GUILayout.EndArea();
|
||||
#endif
|
||||
var g = BeginLayoutArea(style, typeof(GUILayoutGroup));
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
g.resetCoords = true;
|
||||
g.minWidth = g.maxWidth = screenRect.width;
|
||||
g.minHeight = g.maxHeight = screenRect.height;
|
||||
g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax);
|
||||
}
|
||||
|
||||
BeginGroup(g.rect, content, style);
|
||||
}
|
||||
|
||||
internal static GUILayoutGroup BeginLayoutArea(GUIStyle style, Type layoutType)
|
||||
{
|
||||
EventType type = Event.current.type;
|
||||
GUILayoutGroup guilayoutGroup;
|
||||
if (type != EventType.Used && type != EventType.Layout)
|
||||
{
|
||||
guilayoutGroup = GUILayoutUtility.current.windows.GetNext().TryCast<GUILayoutGroup>();
|
||||
guilayoutGroup.ResetCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType);
|
||||
guilayoutGroup.style = style;
|
||||
GUILayoutUtility.current.windows.Add(guilayoutGroup);
|
||||
}
|
||||
GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup);
|
||||
GUILayoutUtility.current.topLevel = guilayoutGroup;
|
||||
return guilayoutGroup;
|
||||
}
|
||||
|
||||
public static void BeginGroup(Rect position, GUIContent content, GUIStyle style)
|
||||
{
|
||||
BeginGroup(position, content, style, Vector2.zero);
|
||||
}
|
||||
|
||||
internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset)
|
||||
{
|
||||
int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive);
|
||||
|
||||
if (content != GUIContent.none || style != GUIStyle.none)
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.Repaint:
|
||||
style.Draw(position, content, id);
|
||||
break;
|
||||
default:
|
||||
if (position.Contains(Event.current.mousePosition))
|
||||
GUIUtility.mouseUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
GUIClip.Push(position, scrollOffset, Vector2.zero, false);
|
||||
}
|
||||
|
||||
public static void EndArea()
|
||||
{
|
||||
if (Event.current.type == EventType.Used)
|
||||
return;
|
||||
GUILayoutUtility.current.layoutGroups.Pop();
|
||||
GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast<GUILayoutGroup>();
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scrolling
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.BeginScrollView(scroll, options);
|
||||
#else
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
#endif
|
||||
// First, just try normal way, may not have been stripped or was unstripped successfully.
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ScrollFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try manual implementation.
|
||||
if (!ManualUnstripFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return BeginScrollView_ImplLayout(scroll,
|
||||
false,
|
||||
false,
|
||||
GUI.skin.horizontalScrollbar,
|
||||
GUI.skin.verticalScrollbar,
|
||||
GUI.skin.scrollView,
|
||||
options);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log("Exception on manual BeginScrollView: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
||||
ManualUnstripFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorry! No scrolling for you.
|
||||
return scroll;
|
||||
}
|
||||
|
||||
public static void EndScrollView(bool handleScrollWheel = true)
|
||||
internal static void EndScrollView(bool handleScrollWheel)
|
||||
{
|
||||
#if CPP
|
||||
Internal.EndScrollView(handleScrollWheel);
|
||||
#else
|
||||
GUILayout.EndScrollView();
|
||||
#endif
|
||||
// Only end the scroll view for the relevant BeginScrollView option, if any.
|
||||
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (!ManualUnstripFailed)
|
||||
{
|
||||
GUILayoutUtility.EndLayoutGroup();
|
||||
|
||||
if (ScrollStack.Count <= 0) return;
|
||||
|
||||
var scrollExt = ScrollStack.Peek() as ScrollViewStateUnstrip;
|
||||
|
||||
//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();
|
||||
|
||||
ScrollStack.Pop();
|
||||
|
||||
var position = scrollExt.position;
|
||||
|
||||
if (handleScrollWheel && Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition))
|
||||
{
|
||||
var pos = scrollExt.scrollPosition;
|
||||
pos.x = Mathf.Clamp(scrollExt.scrollPosition.x + Event.current.delta.x * 20f, 0f, scrollExt.viewRect.width - scrollExt.visibleRect.width);
|
||||
pos.y = Mathf.Clamp(scrollExt.scrollPosition.y + Event.current.delta.y * 20f, 0f, scrollExt.viewRect.height - scrollExt.visibleRect.height);
|
||||
|
||||
if (scrollExt.scrollPosition.x < 0f)
|
||||
{
|
||||
pos.x = 0f;
|
||||
}
|
||||
if (pos.y < 0f)
|
||||
{
|
||||
pos.y = 0f;
|
||||
}
|
||||
|
||||
scrollExt.apply = true;
|
||||
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||
{
|
||||
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<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
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
ScrollViewStateUnstrip scrollExt;
|
||||
try
|
||||
{
|
||||
scrollExt = (ScrollViewStateUnstrip)GUIUtilityUnstrip.GetMonoStateObject(typeof(ScrollViewStateUnstrip), controlID);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
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(scrollExt);
|
||||
|
||||
Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
|
||||
EventType type = Event.current.type;
|
||||
if (type != EventType.Layout)
|
||||
{
|
||||
if (type != EventType.Used)
|
||||
{
|
||||
bool flag = alwaysShowVertical;
|
||||
bool flag2 = alwaysShowHorizontal;
|
||||
if (flag2 || viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
if (flag || viewRect.height > screenRect.height)
|
||||
{
|
||||
rect.width = position.width - verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
|
||||
screenRect.width -= verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
flag = true;
|
||||
if (!flag2 && viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint && background != GUIStyle.none)
|
||||
{
|
||||
background.Draw(position, position.Contains(Event.current.mousePosition), false, flag2 && flag, false);
|
||||
}
|
||||
if (flag2 && horizontalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.x = HorizontalScroll(
|
||||
new Rect(
|
||||
position.x,
|
||||
position.yMax - horizontalScrollbar.fixedHeight,
|
||||
screenRect.width,
|
||||
horizontalScrollbar.fixedHeight),
|
||||
scrollPosition.x,
|
||||
Mathf.Min(screenRect.width, viewRect.width),
|
||||
0f,
|
||||
viewRect.width,
|
||||
horizontalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.x = ((horizontalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.x, 0f, Mathf.Max(viewRect.width - position.width, 0f))
|
||||
: 0f);
|
||||
}
|
||||
if (flag && verticalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.y = VerticalScroll(
|
||||
new Rect(
|
||||
screenRect.xMax + (float)verticalScrollbar.margin.left,
|
||||
screenRect.y,
|
||||
verticalScrollbar.fixedWidth,
|
||||
screenRect.height),
|
||||
scrollPosition.y,
|
||||
Mathf.Min(screenRect.height, viewRect.height),
|
||||
0f,
|
||||
viewRect.height,
|
||||
verticalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.y = ((verticalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(viewRect.height - position.height, 0f))
|
||||
: 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
}
|
||||
GUIClip.Push(screenRect,
|
||||
new Vector2(
|
||||
Mathf.Round(-scrollPosition.x - viewRect.x),
|
||||
Mathf.Round(-scrollPosition.y - viewRect.y)),
|
||||
Vector2.zero,
|
||||
false
|
||||
);
|
||||
|
||||
return scrollPosition;
|
||||
}
|
||||
|
||||
public static float HorizontalScroll(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, leftValue, rightValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "leftbutton"),
|
||||
GUI.skin.GetStyle(style.name + "rightbutton"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static float VerticalScroll(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, topValue, bottomValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "upbutton"),
|
||||
GUI.skin.GetStyle(style.name + "downbutton"),
|
||||
false);
|
||||
}
|
||||
|
||||
private static float Scroller(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider,
|
||||
GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz)
|
||||
{
|
||||
GUIUtility.CheckOnGUI();
|
||||
int controlID = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
Rect position2;
|
||||
Rect rect;
|
||||
Rect rect2;
|
||||
if (horiz)
|
||||
{
|
||||
position2 = new Rect(position.x + leftButton.fixedWidth,
|
||||
position.y,
|
||||
position.width - leftButton.fixedWidth - rightButton.fixedWidth,
|
||||
position.height);
|
||||
|
||||
rect = new Rect(position.x, position.y, leftButton.fixedWidth, position.height);
|
||||
rect2 = new Rect(position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
position2 = new Rect(position.x,
|
||||
position.y + leftButton.fixedHeight,
|
||||
position.width,
|
||||
position.height - leftButton.fixedHeight - rightButton.fixedHeight);
|
||||
|
||||
rect = new Rect(position.x, position.y, position.width, leftButton.fixedHeight);
|
||||
rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight);
|
||||
}
|
||||
|
||||
value = Slider(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID);
|
||||
|
||||
bool flag = Event.current.type == EventType.MouseUp;
|
||||
if (ScrollerRepeatButton(controlID, rect, leftButton))
|
||||
{
|
||||
value -= 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (ScrollerRepeatButton(controlID, rect2, rightButton))
|
||||
{
|
||||
value += 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (flag && Event.current.type == EventType.Used)
|
||||
{
|
||||
s_ScrollControlId = 0;
|
||||
}
|
||||
if (leftValue < rightValue)
|
||||
{
|
||||
value = Mathf.Clamp(value, leftValue, rightValue - size);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Mathf.Clamp(value, rightValue, leftValue - size);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider,
|
||||
GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
}
|
||||
var sliderHandler = new SliderHandlerUnstrip(position, value, size, start, end, slider, thumb, horiz, id);
|
||||
return sliderHandler.Handle();
|
||||
}
|
||||
|
||||
private static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle style)
|
||||
{
|
||||
bool result = false;
|
||||
if (GUI.DoRepeatButton(rect, GUIContent.none, style, FocusType.Passive))
|
||||
{
|
||||
bool flag = s_ScrollControlId != scrollerID;
|
||||
s_ScrollControlId = scrollerID;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
}
|
||||
else if (DateTime.Now >= nextScrollStepTime)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
GUI.InternalRepaintEditorWindow();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Extensions
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static Rect Unstripped_GetLast(this GUILayoutGroup group)
|
||||
{
|
||||
Rect result;
|
||||
if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count)
|
||||
{
|
||||
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
|
||||
result = guilayoutEntry.rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GUILayoutEntry.kDummyRect;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
|
67
src/Unstrip/IMGUI/GUIUtilityUnstrip.cs
Normal file
67
src/Unstrip/IMGUI/GUIUtilityUnstrip.cs
Normal file
@ -0,0 +1,67 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class GUIUtilityUnstrip
|
||||
{
|
||||
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
|
@ -1,688 +0,0 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngineInternal;
|
||||
using UnhollowerRuntimeLib;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal
|
||||
{
|
||||
#region Properties
|
||||
public static int s_ScrollControlId;
|
||||
|
||||
public static bool ScrollFailed = false;
|
||||
public static bool ManualUnstripFailed = false;
|
||||
|
||||
public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack();
|
||||
public static PropertyInfo m_scrollViewStatesInfo;
|
||||
public static GenericStack m_scrollStack;
|
||||
|
||||
public static Dictionary<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 m_spaceStyle;
|
||||
|
||||
public static DateTime nextScrollStepTime;
|
||||
|
||||
public static MethodInfo ScreenToGuiPointMethod;
|
||||
public static bool m_screenToGuiAttemped;
|
||||
|
||||
public static MethodInfo m_bringWindowToFrontMethod;
|
||||
public static bool m_bringWindowFrontAttempted;
|
||||
|
||||
private static GenericStack GetScrollStack()
|
||||
{
|
||||
if (m_scrollViewStatesInfo == null)
|
||||
{
|
||||
if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo)
|
||||
{
|
||||
m_scrollViewStatesInfo = scrollStatesInfo;
|
||||
}
|
||||
else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo)
|
||||
{
|
||||
m_scrollViewStatesInfo = s_scrollStatesInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack)
|
||||
{
|
||||
m_scrollStack = stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scrollStack = new GenericStack();
|
||||
}
|
||||
|
||||
return m_scrollStack;
|
||||
}
|
||||
|
||||
private static Dictionary<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()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_spaceStyle = typeof(GUILayoutUtility)
|
||||
.GetProperty("s_SpaceStyle")
|
||||
.GetValue(null, null)
|
||||
.Il2CppCast(typeof(GUIStyle))
|
||||
as GUIStyle;
|
||||
|
||||
if (m_spaceStyle == null) throw new Exception();
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (m_spaceStyle == null)
|
||||
{
|
||||
m_spaceStyle = new GUIStyle();
|
||||
}
|
||||
m_spaceStyle.stretchWidth = false;
|
||||
return m_spaceStyle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUILayout Methods
|
||||
|
||||
public static void BeginLayoutDirection(bool vertical, GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
var g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
|
||||
g.isVertical = vertical;
|
||||
if (style != GUIStyle.none || content != GUIContent.none)
|
||||
GUI.Box(g.rect, content, style);
|
||||
}
|
||||
|
||||
public static string TextField(string text, GUILayoutOption[] options)
|
||||
{
|
||||
text = text ?? string.Empty;
|
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Keyboard);
|
||||
GUIContent guicontent = GUIContent.Temp(text);
|
||||
bool flag = GUIUtility.keyboardControl != controlID;
|
||||
if (flag)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
// guicontent = GUIContent.Temp(text + GUIUtility.compositionString);
|
||||
}
|
||||
Rect rect = Internal_LayoutUtility.GetRect(guicontent, GUI.skin.textField, options);
|
||||
bool flag2 = GUIUtility.keyboardControl == controlID;
|
||||
if (flag2)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField);
|
||||
return guicontent.text;
|
||||
}
|
||||
|
||||
internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style)
|
||||
{
|
||||
if (GetStateObject(Il2CppType.Of<TextEditor>(), id).TryCast<TextEditor>() is TextEditor textEditor)
|
||||
{
|
||||
if (maxLength >= 0 && content.text.Length > maxLength)
|
||||
{
|
||||
content.text = content.text.Substring(0, maxLength);
|
||||
}
|
||||
textEditor.m_Content.text = content.text;
|
||||
textEditor.SaveBackup();
|
||||
textEditor.position = position;
|
||||
textEditor.style = style;
|
||||
textEditor.multiline = multiline;
|
||||
textEditor.controlID = id;
|
||||
textEditor.DetectFocusChange();
|
||||
GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
|
||||
textEditor.UpdateScrollOffsetIfNeeded(Event.current);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive);
|
||||
}
|
||||
|
||||
public static void Space(float pixels)
|
||||
{
|
||||
if (GUILayoutUtility.current.topLevel.isVertical)
|
||||
Internal_LayoutUtility.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
|
||||
else
|
||||
Internal_LayoutUtility.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
|
||||
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
{
|
||||
if (!m_screenToGuiAttemped)
|
||||
{
|
||||
m_screenToGuiAttemped = true;
|
||||
ScreenToGuiPointMethod = typeof(GUIUtility).GetMethod("ScreenToGUIPoint");
|
||||
}
|
||||
if (ScreenToGuiPointMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.ScreenToGUIPoint'!");
|
||||
}
|
||||
return (Vector2)ScreenToGuiPointMethod.Invoke(null, new object[] { screenPoint });
|
||||
}
|
||||
|
||||
public static void BringWindowToFront(int id)
|
||||
{
|
||||
if (!m_bringWindowFrontAttempted)
|
||||
{
|
||||
m_bringWindowFrontAttempted = true;
|
||||
m_bringWindowToFrontMethod = typeof(GUI).GetMethod("BringWindowToFront");
|
||||
}
|
||||
if (m_bringWindowToFrontMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.BringWindowToFront'!");
|
||||
}
|
||||
m_bringWindowToFrontMethod.Invoke(null, new object[] { id });
|
||||
}
|
||||
|
||||
public static void BeginArea(Rect screenRect, GUIContent content, GUIStyle style)
|
||||
{
|
||||
var g = BeginLayoutArea(style, typeof(GUILayoutGroup));
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
g.resetCoords = true;
|
||||
g.minWidth = g.maxWidth = screenRect.width;
|
||||
g.minHeight = g.maxHeight = screenRect.height;
|
||||
g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax);
|
||||
}
|
||||
|
||||
BeginGroup(g.rect, content, style);
|
||||
}
|
||||
|
||||
internal static GUILayoutGroup BeginLayoutArea(GUIStyle style, Type layoutType)
|
||||
{
|
||||
EventType type = Event.current.type;
|
||||
GUILayoutGroup guilayoutGroup;
|
||||
if (type != EventType.Used && type != EventType.Layout)
|
||||
{
|
||||
guilayoutGroup = GUILayoutUtility.current.windows.GetNext().TryCast<GUILayoutGroup>();
|
||||
guilayoutGroup.ResetCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType);
|
||||
guilayoutGroup.style = style;
|
||||
GUILayoutUtility.current.windows.Add(guilayoutGroup);
|
||||
}
|
||||
GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup);
|
||||
GUILayoutUtility.current.topLevel = guilayoutGroup;
|
||||
return guilayoutGroup;
|
||||
}
|
||||
|
||||
public static void BeginGroup(Rect position, GUIContent content, GUIStyle style)
|
||||
{
|
||||
BeginGroup(position, content, style, Vector2.zero);
|
||||
}
|
||||
|
||||
internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset)
|
||||
{
|
||||
int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive);
|
||||
|
||||
if (content != GUIContent.none || style != GUIStyle.none)
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.Repaint:
|
||||
style.Draw(position, content, id);
|
||||
break;
|
||||
default:
|
||||
if (position.Contains(Event.current.mousePosition))
|
||||
GUIUtility.mouseUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
GUIClip.Push(position, scrollOffset, Vector2.zero, false);
|
||||
}
|
||||
|
||||
public static void EndArea()
|
||||
{
|
||||
if (Event.current.type == EventType.Used)
|
||||
return;
|
||||
GUILayoutUtility.current.layoutGroups.Pop();
|
||||
GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast<GUILayoutGroup>();
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scrolling
|
||||
|
||||
private static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID)
|
||||
{
|
||||
Il2CppSystem.Object obj;
|
||||
if (StateCache.ContainsKey(controlID))
|
||||
{
|
||||
obj = StateCache[controlID];
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = Il2CppSystem.Activator.CreateInstance(type);
|
||||
StateCache.Add(controlID, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
{
|
||||
// First, just try normal way, may not have been stripped or was unstripped successfully.
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ScrollFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try manual implementation.
|
||||
if (!ManualUnstripFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return BeginScrollView_ImplLayout(scroll,
|
||||
false,
|
||||
false,
|
||||
GUI.skin.horizontalScrollbar,
|
||||
GUI.skin.verticalScrollbar,
|
||||
GUI.skin.scrollView,
|
||||
options);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log("Exception on manual BeginScrollView: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
||||
ManualUnstripFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorry! No scrolling for you.
|
||||
return scroll;
|
||||
}
|
||||
|
||||
internal static void EndScrollView(bool handleScrollWheel)
|
||||
{
|
||||
// Only end the scroll view for the relevant BeginScrollView option, if any.
|
||||
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (!ManualUnstripFailed)
|
||||
{
|
||||
GUILayoutUtility.EndLayoutGroup();
|
||||
|
||||
if (ScrollStack.Count <= 0) return;
|
||||
|
||||
var state = ScrollStack.Peek().TryCast<ScrollViewState>();
|
||||
var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
|
||||
|
||||
if (scrollExt == null) throw new Exception("Could not get scrollExt!");
|
||||
|
||||
GUIClip.Pop();
|
||||
|
||||
ScrollStack.Pop();
|
||||
|
||||
var position = scrollExt.position;
|
||||
|
||||
if (handleScrollWheel && Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition))
|
||||
{
|
||||
var pos = scrollExt.scrollPosition;
|
||||
pos.x = Mathf.Clamp(scrollExt.scrollPosition.x + Event.current.delta.x * 20f, 0f, scrollExt.viewRect.width - scrollExt.visibleRect.width);
|
||||
pos.y = Mathf.Clamp(scrollExt.scrollPosition.y + Event.current.delta.y * 20f, 0f, scrollExt.viewRect.height - scrollExt.visibleRect.height);
|
||||
|
||||
if (scrollExt.scrollPosition.x < 0f)
|
||||
{
|
||||
pos.x = 0f;
|
||||
}
|
||||
if (pos.y < 0f)
|
||||
{
|
||||
pos.y = 0f;
|
||||
}
|
||||
|
||||
scrollExt.apply = true;
|
||||
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||
{
|
||||
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<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
|
||||
);
|
||||
}
|
||||
|
||||
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
||||
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
||||
{
|
||||
// GUIUtility.CheckOnGUI();
|
||||
|
||||
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
|
||||
|
||||
var scrollViewState = GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID)
|
||||
.TryCast<ScrollViewState>();
|
||||
|
||||
if (scrollViewState == null)
|
||||
return scrollPosition;
|
||||
|
||||
var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer);
|
||||
|
||||
if (scrollExt == null)
|
||||
return scrollPosition;
|
||||
|
||||
bool apply = scrollExt.apply;
|
||||
if (apply)
|
||||
{
|
||||
scrollPosition = scrollExt.scrollPosition;
|
||||
scrollExt.apply = false;
|
||||
}
|
||||
|
||||
scrollExt.position = position;
|
||||
|
||||
scrollExt.scrollPosition = scrollPosition;
|
||||
scrollExt.visibleRect = scrollExt.viewRect = viewRect;
|
||||
|
||||
var rect = scrollExt.visibleRect;
|
||||
rect.width = position.width;
|
||||
rect.height = position.height;
|
||||
|
||||
ScrollStack.Push(scrollViewState);
|
||||
|
||||
Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
|
||||
EventType type = Event.current.type;
|
||||
if (type != EventType.Layout)
|
||||
{
|
||||
if (type != EventType.Used)
|
||||
{
|
||||
bool flag = alwaysShowVertical;
|
||||
bool flag2 = alwaysShowHorizontal;
|
||||
if (flag2 || viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
if (flag || viewRect.height > screenRect.height)
|
||||
{
|
||||
rect.width = position.width - verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
|
||||
screenRect.width -= verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
flag = true;
|
||||
if (!flag2 && viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint && background != GUIStyle.none)
|
||||
{
|
||||
background.Draw(position, position.Contains(Event.current.mousePosition), false, flag2 && flag, false);
|
||||
}
|
||||
if (flag2 && horizontalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.x = HorizontalScroll(
|
||||
new Rect(
|
||||
position.x,
|
||||
position.yMax - horizontalScrollbar.fixedHeight,
|
||||
screenRect.width,
|
||||
horizontalScrollbar.fixedHeight),
|
||||
scrollPosition.x,
|
||||
Mathf.Min(screenRect.width, viewRect.width),
|
||||
0f,
|
||||
viewRect.width,
|
||||
horizontalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.x = ((horizontalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.x, 0f, Mathf.Max(viewRect.width - position.width, 0f))
|
||||
: 0f);
|
||||
}
|
||||
if (flag && verticalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.y = VerticalScroll(
|
||||
new Rect(
|
||||
screenRect.xMax + (float)verticalScrollbar.margin.left,
|
||||
screenRect.y,
|
||||
verticalScrollbar.fixedWidth,
|
||||
screenRect.height),
|
||||
scrollPosition.y,
|
||||
Mathf.Min(screenRect.height, viewRect.height),
|
||||
0f,
|
||||
viewRect.height,
|
||||
verticalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.y = ((verticalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(viewRect.height - position.height, 0f))
|
||||
: 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
}
|
||||
GUIClip.Push(screenRect,
|
||||
new Vector2(
|
||||
Mathf.Round(-scrollPosition.x - viewRect.x),
|
||||
Mathf.Round(-scrollPosition.y - viewRect.y)),
|
||||
Vector2.zero,
|
||||
false
|
||||
);
|
||||
|
||||
return scrollPosition;
|
||||
}
|
||||
|
||||
public static float HorizontalScroll(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, leftValue, rightValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "leftbutton"),
|
||||
GUI.skin.GetStyle(style.name + "rightbutton"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static float VerticalScroll(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, topValue, bottomValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "upbutton"),
|
||||
GUI.skin.GetStyle(style.name + "downbutton"),
|
||||
false);
|
||||
}
|
||||
|
||||
private static float Scroller(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider,
|
||||
GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz)
|
||||
{
|
||||
GUIUtility.CheckOnGUI();
|
||||
int controlID = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
Rect position2;
|
||||
Rect rect;
|
||||
Rect rect2;
|
||||
if (horiz)
|
||||
{
|
||||
position2 = new Rect(position.x + leftButton.fixedWidth,
|
||||
position.y,
|
||||
position.width - leftButton.fixedWidth - rightButton.fixedWidth,
|
||||
position.height);
|
||||
|
||||
rect = new Rect(position.x, position.y, leftButton.fixedWidth, position.height);
|
||||
rect2 = new Rect(position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
position2 = new Rect(position.x,
|
||||
position.y + leftButton.fixedHeight,
|
||||
position.width,
|
||||
position.height - leftButton.fixedHeight - rightButton.fixedHeight);
|
||||
|
||||
rect = new Rect(position.x, position.y, position.width, leftButton.fixedHeight);
|
||||
rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight);
|
||||
}
|
||||
|
||||
value = Slider(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID);
|
||||
|
||||
bool flag = Event.current.type == EventType.MouseUp;
|
||||
if (ScrollerRepeatButton(controlID, rect, leftButton))
|
||||
{
|
||||
value -= 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (ScrollerRepeatButton(controlID, rect2, rightButton))
|
||||
{
|
||||
value += 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (flag && Event.current.type == EventType.Used)
|
||||
{
|
||||
s_ScrollControlId = 0;
|
||||
}
|
||||
if (leftValue < rightValue)
|
||||
{
|
||||
value = Mathf.Clamp(value, leftValue, rightValue - size);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Mathf.Clamp(value, rightValue, leftValue - size);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider,
|
||||
GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
}
|
||||
var sliderHandler = new Internal_SliderHandler(position, value, size, start, end, slider, thumb, horiz, id);
|
||||
return sliderHandler.Handle();
|
||||
}
|
||||
|
||||
private static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle style)
|
||||
{
|
||||
bool result = false;
|
||||
if (GUI.DoRepeatButton(rect, GUIContent.none, style, FocusType.Passive))
|
||||
{
|
||||
bool flag = s_ScrollControlId != scrollerID;
|
||||
s_ScrollControlId = scrollerID;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
}
|
||||
else if (DateTime.Now >= nextScrollStepTime)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
GUI.InternalRepaintEditorWindow();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Extensions
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static Rect Unstripped_GetLast(this GUILayoutGroup group)
|
||||
{
|
||||
Rect result;
|
||||
if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count)
|
||||
{
|
||||
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
|
||||
result = guilayoutEntry.rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GUILayoutEntry.kDummyRect;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
@ -1,29 +0,0 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_ScrollViewState
|
||||
{
|
||||
public Rect position;
|
||||
public Rect visibleRect;
|
||||
public Rect viewRect;
|
||||
public Vector2 scrollPosition;
|
||||
public bool apply;
|
||||
|
||||
public static Dictionary<IntPtr, Internal_ScrollViewState> Dict = new Dictionary<IntPtr, Internal_ScrollViewState>();
|
||||
|
||||
public static Internal_ScrollViewState FromPointer(IntPtr ptr)
|
||||
{
|
||||
if (!Dict.ContainsKey(ptr))
|
||||
{
|
||||
Dict.Add(ptr, new Internal_ScrollViewState());
|
||||
}
|
||||
|
||||
return Dict[ptr];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_SliderState
|
||||
{
|
||||
public float dragStartPos;
|
||||
public float dragStartValue;
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_LayoutUtility
|
||||
public class LayoutUtilityUnstrip
|
||||
{
|
||||
public static Rect GetRect(float width, float height, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
89
src/Unstrip/IMGUI/ScrollViewStateUnstrip.cs
Normal file
89
src/Unstrip/IMGUI/ScrollViewStateUnstrip.cs
Normal file
@ -0,0 +1,89 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class ScrollViewStateUnstrip
|
||||
{
|
||||
public Rect position;
|
||||
public Rect visibleRect;
|
||||
public Rect viewRect;
|
||||
public Vector2 scrollPosition;
|
||||
public bool apply;
|
||||
|
||||
public void ScrollTo(Rect pos)
|
||||
{
|
||||
this.ScrollTowards(pos, float.PositiveInfinity);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -5,7 +5,7 @@ using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public struct Internal_SliderHandler
|
||||
public struct SliderHandlerUnstrip
|
||||
{
|
||||
public static int ScrollTroughSide
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace Explorer.Unstrip.IMGUI
|
||||
private readonly bool horiz;
|
||||
private readonly int id;
|
||||
|
||||
public Internal_SliderHandler(Rect position, float currentValue, float size, float start,
|
||||
public SliderHandlerUnstrip(Rect position, float currentValue, float size, float start,
|
||||
float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
this.position = position;
|
||||
@ -118,9 +118,9 @@ namespace Explorer.Unstrip.IMGUI
|
||||
GUI.changed = true;
|
||||
if (this.SupportsPageMovements())
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
ext.isDragging = false;
|
||||
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
var state = GetSliderState();
|
||||
state.isDragging = false;
|
||||
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
ScrollTroughSide = this.CurrentScrollTroughSide();
|
||||
result = this.PageMovementValue();
|
||||
}
|
||||
@ -144,8 +144,8 @@ namespace Explorer.Unstrip.IMGUI
|
||||
}
|
||||
else
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
if (!ext.isDragging)
|
||||
var state = GetSliderState();
|
||||
if (!state.isDragging)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
@ -153,8 +153,8 @@ namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
GUI.changed = true;
|
||||
this.CurrentEvent().Use();
|
||||
float num = this.MousePosition() - ext.dragStartPos;
|
||||
float value = ext.dragStartValue + num / this.ValuesPerPixel();
|
||||
float num = this.MousePosition() - state.dragStartPos;
|
||||
float value = state.dragStartValue + num / this.ValuesPerPixel();
|
||||
result = this.Clamp(value);
|
||||
}
|
||||
}
|
||||
@ -194,7 +194,7 @@ namespace Explorer.Unstrip.IMGUI
|
||||
else
|
||||
{
|
||||
GUI.InternalRepaintEditorWindow();
|
||||
if (DateTime.Now < Internal.nextScrollStepTime)
|
||||
if (DateTime.Now < GUIUnstrip.nextScrollStepTime)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
@ -204,10 +204,10 @@ namespace Explorer.Unstrip.IMGUI
|
||||
}
|
||||
else
|
||||
{
|
||||
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
if (this.SupportsPageMovements())
|
||||
{
|
||||
Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false;
|
||||
GetSliderState().isDragging = false;
|
||||
GUI.changed = true;
|
||||
result = this.PageMovementValue();
|
||||
}
|
||||
@ -303,15 +303,15 @@ namespace Explorer.Unstrip.IMGUI
|
||||
|
||||
private void StartDraggingWithValue(float dragStartValue)
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
ext.dragStartPos = this.MousePosition();
|
||||
ext.dragStartValue = dragStartValue;
|
||||
ext.isDragging = true;
|
||||
var state = GetSliderState();
|
||||
state.dragStartPos = this.MousePosition();
|
||||
state.dragStartValue = dragStartValue;
|
||||
state.isDragging = true;
|
||||
}
|
||||
|
||||
private SliderState GetSliderState()
|
||||
private SliderStateUnstrip GetSliderState()
|
||||
{
|
||||
return GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>();
|
||||
return (SliderStateUnstrip)GUIUtilityUnstrip.GetMonoStateObject(typeof(SliderStateUnstrip), this.id);
|
||||
}
|
||||
|
||||
private Rect ThumbRect()
|
14
src/Unstrip/IMGUI/SliderStateUnstrip.cs
Normal file
14
src/Unstrip/IMGUI/SliderStateUnstrip.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class SliderStateUnstrip
|
||||
{
|
||||
public float dragStartPos;
|
||||
public float dragStartValue;
|
||||
public bool isDragging;
|
||||
}
|
||||
}
|
1557
src/Unstrip/IMGUI/TextEditorUnstrip.cs
Normal file
1557
src/Unstrip/IMGUI/TextEditorUnstrip.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,10 @@ using System.Text;
|
||||
using UnhollowerBaseLib;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using Explorer.Helpers;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
|
||||
namespace Explorer.Unstrip.ImageConversion
|
||||
{
|
||||
@ -13,29 +17,47 @@ namespace Explorer.Unstrip.ImageConversion
|
||||
{
|
||||
// byte[] ImageConversion.EncodeToPNG(this Texture2D image);
|
||||
|
||||
internal delegate byte[] d_EncodeToPNG(IntPtr tex);
|
||||
|
||||
public static byte[] EncodeToPNG(this Texture2D tex)
|
||||
{
|
||||
return EncodeToPNG_iCall(tex.Pointer);
|
||||
}
|
||||
var data = ICallHelper.GetICall<d_EncodeToPNG>("UnityEngine.ImageConversion::EncodeToPNG")
|
||||
.Invoke(tex.Pointer);
|
||||
|
||||
internal delegate byte[] EncodeToPNG_delegate(IntPtr tex);
|
||||
internal static EncodeToPNG_delegate EncodeToPNG_iCall =
|
||||
IL2CPP.ResolveICall<EncodeToPNG_delegate>("UnityEngine.ImageConversion::EncodeToPNG");
|
||||
// The Il2Cpp EncodeToPNG() method does return System.Byte[],
|
||||
// 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];
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
safeData[i] = (byte)data[i];
|
||||
}
|
||||
|
||||
return safeData;
|
||||
}
|
||||
|
||||
// bool ImageConversion.LoadImage(this Texture2D tex, byte[] data, bool markNonReadable);
|
||||
|
||||
internal delegate bool d_LoadImage(IntPtr tex, IntPtr data, bool markNonReadable);
|
||||
|
||||
public static bool LoadImage(this Texture2D tex, byte[] data, bool markNonReadable)
|
||||
{
|
||||
return LoadImage_iCall(tex.Pointer, data, markNonReadable);
|
||||
var il2cppArray = new Il2CppStructArray<byte>(data.Length);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
il2cppArray[i] = data[i];
|
||||
}
|
||||
|
||||
var ret = ICallHelper.GetICall<d_LoadImage>("UnityEngine.ImageConversion::LoadImage")
|
||||
.Invoke(tex.Pointer, il2cppArray.Pointer, markNonReadable);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal delegate bool LoadImage_delegate(IntPtr tex, byte[] data, bool markNonReadable);
|
||||
internal static LoadImage_delegate LoadImage_iCall =
|
||||
IL2CPP.ResolveICall<LoadImage_delegate>("UnityEngine.ImageConversion::LoadImage");
|
||||
// Helper for LoadImage from filepath
|
||||
|
||||
// Helper for LoadImage
|
||||
|
||||
public static bool LoadImage(this Texture2D tex, string filePath, bool markNonReadable)
|
||||
public static bool LoadImage(Texture2D tex, string filePath, bool markNonReadable)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
|
27
src/Unstrip/LayerMask/LayerMaskUnstrip.cs
Normal file
27
src/Unstrip/LayerMask/LayerMaskUnstrip.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Explorer.Helpers;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer.Unstrip.LayerMasks
|
||||
{
|
||||
public static class LayerMaskUnstrip
|
||||
{
|
||||
#if CPP
|
||||
internal delegate IntPtr d_LayerToName(int layer);
|
||||
|
||||
public static string LayerToName(int layer)
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<d_LayerToName>("UnityEngine.LayerMask::LayerToName");
|
||||
return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer));
|
||||
}
|
||||
#else
|
||||
public static string LayerToName(int layer) => LayerMask.LayerToName(layer);
|
||||
#endif
|
||||
}
|
||||
}
|
39
src/Unstrip/Resources/ResourcesUnstrip.cs
Normal file
39
src/Unstrip/Resources/ResourcesUnstrip.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Explorer.Helpers;
|
||||
using UnityEngine;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer.Unstrip.Resources
|
||||
{
|
||||
public class ResourcesUnstrip
|
||||
{
|
||||
#if CPP
|
||||
internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type);
|
||||
|
||||
public static UnityEngine.Object[] FindObjectsOfTypeAll(Il2CppSystem.Type type)
|
||||
{
|
||||
var arrayPtr = ICallHelper.GetICall<d_FindObjectsOfTypeAll>("UnityEngine.Resources::FindObjectsOfTypeAll")
|
||||
.Invoke(type.Pointer);
|
||||
|
||||
var array = new Il2CppReferenceArray<UnityEngine.Object>(arrayPtr);
|
||||
|
||||
var ret = new UnityEngine.Object[array.Length];
|
||||
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
ret[i] = array[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
public static UnityEngine.Object[] FindObjectsOfTypeAll(Type type) => UnityEngine.Resources.FindObjectsOfTypeAll(type);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Explorer.Helpers;
|
||||
using UnhollowerBaseLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
@ -12,28 +13,29 @@ namespace Explorer.Unstrip.Scenes
|
||||
public class SceneUnstrip
|
||||
{
|
||||
//Scene.GetRootGameObjects();
|
||||
|
||||
internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
|
||||
|
||||
public static GameObject[] GetRootGameObjects(Scene scene)
|
||||
{
|
||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount_Internal(scene));
|
||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(scene));
|
||||
|
||||
GetRootGameObjectsInternal_iCall(scene.handle, list.Pointer);
|
||||
var iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
||||
|
||||
iCall.Invoke(scene.handle, list.Pointer);
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
internal delegate void GetRootGameObjectsInternal_delegate(int handle, IntPtr list);
|
||||
internal static GetRootGameObjectsInternal_delegate GetRootGameObjectsInternal_iCall =
|
||||
IL2CPP.ResolveICall<GetRootGameObjectsInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
||||
|
||||
//Scene.rootCount;
|
||||
public static int GetRootCount_Internal(UnityEngine.SceneManagement.Scene scene)
|
||||
{
|
||||
return GetRootCountInternal_iCall(scene.handle);
|
||||
}
|
||||
|
||||
internal delegate int GetRootCountInternal_delegate(int handle);
|
||||
internal static GetRootCountInternal_delegate GetRootCountInternal_iCall =
|
||||
IL2CPP.ResolveICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
|
||||
|
||||
public static int GetRootCount(Scene scene)
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
|
||||
return iCall.Invoke(scene.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user