diff --git a/src/Core/Config/InternalConfigHandler.cs b/src/Core/Config/InternalConfigHandler.cs
index 331e533..e3ebdf0 100644
--- a/src/Core/Config/InternalConfigHandler.cs
+++ b/src/Core/Config/InternalConfigHandler.cs
@@ -52,8 +52,6 @@ namespace UnityExplorer.Core.Config
{
try
{
- ExplorerCore.Log("Loading internal data");
-
if (!File.Exists(INI_PATH))
return false;
@@ -67,8 +65,6 @@ namespace UnityExplorer.Core.Config
configElement.BoxedValue = StringToConfigValue(config.Value, configElement.ElementType);
}
- ExplorerCore.Log("Loaded");
-
return true;
}
catch (Exception ex)
diff --git a/src/Core/Input/CursorUnlocker.cs b/src/Core/Input/CursorUnlocker.cs
index c1e8f95..a76f82b 100644
--- a/src/Core/Input/CursorUnlocker.cs
+++ b/src/Core/Input/CursorUnlocker.cs
@@ -78,13 +78,6 @@ namespace UnityExplorer.Core.Input
}
}
- public static void UpdateIfNeeded()
- {
- if ((!ShouldActuallyUnlock && (Cursor.visible || Cursor.lockState == CursorLockMode.None))
- || (ShouldActuallyUnlock && (!Cursor.visible || Cursor.lockState != CursorLockMode.None)))
- UpdateCursorControl();
- }
-
public static void UpdateCursorControl()
{
try
@@ -143,9 +136,6 @@ namespace UnityExplorer.Core.Input
public static void ReleaseEventSystem()
{
- if (EventSystem.current != UIManager.EventSys)
- return;
-
if (InputManager.CurrentType == InputType.InputSystem)
return;
@@ -225,4 +215,198 @@ namespace UnityExplorer.Core.Input
}
}
}
-}
\ No newline at end of file
+}
+
+// Was rewriting but something broke, not looking into it right now.
+
+//using System;
+//using UnityEngine;
+//using UnityEngine.EventSystems;
+//using UnityExplorer.Core.Input;
+//using BF = System.Reflection.BindingFlags;
+//using UnityExplorer.Core.Config;
+//using UnityExplorer.Core;
+//using UnityExplorer.UI;
+//using System.Collections;
+//#if ML
+//using Harmony;
+//#else
+//using HarmonyLib;
+//#endif
+
+//namespace UnityExplorer.Core.Input
+//{
+// public class CursorUnlocker
+// {
+// public static bool Unlock
+// {
+// get => unlock;
+// set
+// {
+// unlock = value;
+// UpdateCursorControl();
+// }
+// }
+// private static bool unlock;
+
+// public static bool ShouldActuallyUnlock => UIManager.ShowMenu && Unlock;
+
+// private static CursorLockMode lastLockMode;
+// private static bool lastVisibleState;
+
+// private static bool currentlySetting = false;
+
+// private static Type CursorType
+// => cursorType
+// ?? (cursorType = ReflectionUtility.GetTypeByName("UnityEngine.Cursor"));
+// private static Type cursorType;
+
+// public static void Init()
+// {
+// SetupPatches();
+
+// UpdateCursorControl();
+
+// Unlock = ConfigManager.Force_Unlock_Mouse.Value;
+// ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; };
+
+// if (ConfigManager.Aggressive_Force_Unlock.Value)
+// RuntimeProvider.Instance.StartCoroutine(ForceUnlockCoroutine());
+// }
+
+// private static readonly WaitForEndOfFrame _waitForEndOfFrame = new WaitForEndOfFrame();
+
+// private static IEnumerator ForceUnlockCoroutine()
+// {
+// while (true)
+// {
+// yield return _waitForEndOfFrame;
+
+// UpdateCursorControl();
+// }
+// }
+
+// public static void UpdateCursorControl()
+// {
+// currentlySetting = true;
+
+// if (ShouldActuallyUnlock)
+// {
+// if (Cursor.lockState != CursorLockMode.None)
+// Cursor.lockState = CursorLockMode.None;
+// if (!Cursor.visible)
+// Cursor.visible = true;
+
+// SetEventSystem();
+// }
+// else
+// {
+// if (Cursor.lockState != lastLockMode)
+// Cursor.lockState = lastLockMode;
+// if (Cursor.visible != lastVisibleState)
+// Cursor.visible = lastVisibleState;
+
+// ReleaseEventSystem();
+// }
+
+// currentlySetting = false;
+// }
+
+// // Event system overrides
+
+// private static bool m_settingEventSystem;
+// private static EventSystem m_lastEventSystem;
+// private static BaseInputModule m_lastInputModule;
+
+// public static void SetEventSystem()
+// {
+// if (InputManager.CurrentType == InputType.InputSystem
+// || !UIManager.EventSys
+// || EventSystem.current == UIManager.EventSys)
+// return;
+
+// if (EventSystem.current && EventSystem.current != UIManager.EventSys)
+// {
+// m_lastEventSystem = EventSystem.current;
+// m_lastEventSystem.enabled = false;
+// }
+
+// // Set to our current system
+// m_settingEventSystem = true;
+// UIManager.EventSys.enabled = true;
+// EventSystem.current = UIManager.EventSys;
+// InputManager.ActivateUIModule();
+// m_settingEventSystem = false;
+// }
+
+// public static void ReleaseEventSystem()
+// {
+// if (InputManager.CurrentType == InputType.InputSystem
+// || !UIManager.EventSys
+// || EventSystem.current != UIManager.EventSys
+// || !m_lastEventSystem)
+// return;
+
+// if (m_lastEventSystem.gameObject.activeInHierarchy)
+// {
+// m_lastEventSystem.enabled = true;
+
+// m_settingEventSystem = true;
+// EventSystem.current = m_lastEventSystem;
+// m_lastInputModule?.ActivateModule();
+// m_settingEventSystem = false;
+// }
+// }
+
+// // Patches
+
+// private static void SetupPatches()
+// {
+// if (CursorType == null)
+// throw new Exception("Could not load Type 'UnityEngine.Cursor'!");
+
+// lastLockMode = Cursor.lockState;
+// lastVisibleState = Cursor.visible;
+
+// // Let mod loader handle actual patching (only necessary until ML 0.3.1)
+// ExplorerCore.Loader.SetupCursorPatches();
+// }
+
+// public static void Prefix_EventSystem_set_current(ref EventSystem value)
+// {
+// if (!m_settingEventSystem && value != UIManager.EventSys)
+// {
+// m_lastEventSystem = value;
+// m_lastInputModule = value?.currentInputModule;
+
+// if (ShouldActuallyUnlock)
+// {
+// value = UIManager.EventSys;
+// value.enabled = true;
+// }
+// }
+// }
+
+// public static void Prefix_set_lockState(ref CursorLockMode value)
+// {
+// if (!currentlySetting)
+// {
+// lastLockMode = value;
+
+// if (ShouldActuallyUnlock)
+// value = CursorLockMode.None;
+// }
+// }
+
+// public static void Prefix_set_visible(ref bool value)
+// {
+// if (!currentlySetting)
+// {
+// lastVisibleState = value;
+
+// if (ShouldActuallyUnlock)
+// value = true;
+// }
+// }
+// }
+//}
\ No newline at end of file
diff --git a/src/Core/ReflectionUtility.cs b/src/Core/ReflectionUtility.cs
index 208b701..150aaab 100644
--- a/src/Core/ReflectionUtility.cs
+++ b/src/Core/ReflectionUtility.cs
@@ -57,7 +57,13 @@ namespace UnityExplorer
/// The object to cast
/// The object, cast to the underlying Type if possible, otherwise the original object.
public static object TryCast(this object obj)
- => ReflectionProvider.Instance.Cast(obj, GetActualType(obj));
+ {
+ var type = GetActualType(obj);
+
+ if (type.IsValueType)
+ return obj;
+ return ReflectionProvider.Instance.Cast(obj, type);
+ }
///
/// Cast an object to a Type, if possible.
@@ -66,10 +72,19 @@ namespace UnityExplorer
/// The Type to cast to
/// The object, cast to the Type provided if possible, otherwise the original object.
public static object TryCast(this object obj, Type castTo)
- => ReflectionProvider.Instance.Cast(obj, castTo);
+ {
+ if (castTo.IsValueType)
+ return obj;
+ return ReflectionProvider.Instance.Cast(obj, castTo);
+ }
public static T TryCast(this object obj)
- => ReflectionProvider.Instance.TryCast(obj);
+ {
+ var type = typeof(T);
+ if (type.IsValueType)
+ return (T)obj;
+ return ReflectionProvider.Instance.TryCast(obj);
+ }
///
/// Check if the provided Type is assignable to IEnumerable.
diff --git a/src/Core/Runtime/Il2Cpp/AssetBundle.cs b/src/Core/Runtime/Il2Cpp/AssetBundle.cs
index 9ad4301..52dbb0f 100644
--- a/src/Core/Runtime/Il2Cpp/AssetBundle.cs
+++ b/src/Core/Runtime/Il2Cpp/AssetBundle.cs
@@ -19,9 +19,7 @@ namespace UnityExplorer
public static AssetBundle LoadFromFile(string path)
{
var iCall = ICallManager.GetICall("UnityEngine.AssetBundle::LoadFromFile_Internal");
-
var ptr = iCall.Invoke(IL2CPP.ManagedStringToIl2Cpp(path), 0u, 0UL);
-
return new AssetBundle(ptr);
}
@@ -30,12 +28,20 @@ namespace UnityExplorer
public static AssetBundle LoadFromMemory(byte[] binary, uint crc = 0)
{
var iCall = ICallManager.GetICall("UnityEngine.AssetBundle::LoadFromMemory_Internal");
-
var ptr = iCall(((Il2CppStructArray) binary).Pointer, crc);
-
return new AssetBundle(ptr);
}
+ // static void UnloadAllAssetBundles(bool unloadAllObjects);
+
+ internal delegate void d_UnloadAllAssetBundles(bool unloadAllObjects);
+
+ public static void UnloadAllAssetBundles(bool unloadAllObjects)
+ {
+ var iCall = ICallManager.GetICall("UnityEngine.AssetBundle::UnloadAllAssetBundles");
+ iCall.Invoke(unloadAllObjects);
+ }
+
// ~~~~~~~~~~~~ Instance ~~~~~~~~~~~~
private readonly IntPtr m_bundlePtr = IntPtr.Zero;
@@ -71,6 +77,15 @@ namespace UnityExplorer
return new UnityEngine.Object(ptr).TryCast();
}
+
+ // public extern void Unload(bool unloadAllLoadedObjects);
+ internal delegate void d_Unload(IntPtr _this, bool unloadAllLoadedObjects);
+
+ public void Unload(bool unloadAssets = true)
+ {
+ var iCall = ICallManager.GetICall("UnityEngine.AssetBundle::Unload");
+ iCall.Invoke(this.m_bundlePtr, unloadAssets);
+ }
}
}
#endif
\ No newline at end of file
diff --git a/src/Core/Runtime/Il2Cpp/Il2CppReflection.cs b/src/Core/Runtime/Il2Cpp/Il2CppReflection.cs
index 8eb479c..c96e58e 100644
--- a/src/Core/Runtime/Il2Cpp/Il2CppReflection.cs
+++ b/src/Core/Runtime/Il2Cpp/Il2CppReflection.cs
@@ -133,35 +133,37 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
var type = obj.GetType();
- if (obj is Il2CppSystem.Object cppObject)
+ try
{
- // weird specific case - if the object is an Il2CppSystem.Type, then return so manually.
- if (cppObject is CppType)
- return typeof(CppType);
-
- if (!string.IsNullOrEmpty(type.Namespace))
+ if ((Il2CppSystem.Object)obj is Il2CppSystem.Object cppObject)
{
- // Il2CppSystem-namespace objects should just return GetType,
- // because using GetIl2CppType returns the System namespace type instead.
- if (type.Namespace.StartsWith("System.") || type.Namespace.StartsWith("Il2CppSystem."))
- return cppObject.GetType();
+ // weird specific case - if the object is an Il2CppSystem.Type, then return so manually.
+ if (cppObject is CppType)
+ return typeof(CppType);
+
+ if (type.FullName.StartsWith("System.") || type.FullName.StartsWith("Il2CppSystem."))
+ return type;
+
+ var cppType = cppObject.GetIl2CppType();
+
+ // check if type is injected
+ IntPtr classPtr = il2cpp_object_get_class(cppObject.Pointer);
+ if (RuntimeSpecificsStore.IsInjected(classPtr))
+ {
+ var typeByName = ReflectionUtility.GetTypeByName(cppType.FullName);
+ if (typeByName != null)
+ return typeByName;
+ }
+
+ // this should be fine for all other il2cpp objects
+ var getType = GetMonoType(cppType);
+ if (getType != null)
+ return getType;
}
-
- var cppType = cppObject.GetIl2CppType();
-
- // check if type is injected
- IntPtr classPtr = il2cpp_object_get_class(cppObject.Pointer);
- if (RuntimeSpecificsStore.IsInjected(classPtr))
- {
- var typeByName = ReflectionUtility.GetTypeByName(cppType.FullName);
- if (typeByName != null)
- return typeByName;
- }
-
- // this should be fine for all other il2cpp objects
- var getType = GetMonoType(cppType);
- if (getType != null)
- return getType;
+ }
+ catch // (Exception ex)
+ {
+ // ExplorerCore.LogWarning("Exception in GetActualType: " + ex);
}
return type;
diff --git a/src/Core/Tests/TestClass.cs b/src/Core/Tests/TestClass.cs
index c44a08c..2c95315 100644
--- a/src/Core/Tests/TestClass.cs
+++ b/src/Core/Tests/TestClass.cs
@@ -103,6 +103,11 @@ namespace UnityExplorer.Tests
public static Il2CppSystem.Collections.Hashtable testHashset;
public static Il2CppSystem.Collections.Generic.List testList;
+
+
+ //public static Il2CppSystem.Nullable NullableQuaternion;
+ //public static Il2CppSystem.Nullable NullableInt = new Il2CppSystem.Nullable(5);
+ //public static Il2CppSystem.Nullable NullableBool = new Il2CppSystem.Nullable(false);
#endif
static TestClass()
@@ -111,6 +116,9 @@ namespace UnityExplorer.Tests
BigList.Add(i.ToString());
#if CPP
+ //NullableQuaternion = new Il2CppSystem.Nullable();
+ //NullableQuaternion.value = Quaternion.identity;
+
testHashset = new Il2CppSystem.Collections.Hashtable();
testHashset.Add("key1", "itemOne");
testHashset.Add("key2", "itemTwo");
diff --git a/src/UI/Inspectors/CacheObject/CacheField.cs b/src/UI/Inspectors/CacheObject/CacheField.cs
index 9de77a3..267345e 100644
--- a/src/UI/Inspectors/CacheObject/CacheField.cs
+++ b/src/UI/Inspectors/CacheObject/CacheField.cs
@@ -20,16 +20,20 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
base.SetInspectorOwner(inspector, member);
}
- protected override void TryEvaluate()
+ protected override object TryEvaluate()
{
try
{
- Value = FieldInfo.GetValue(this.Owner.Target.TryCast(this.DeclaringType));
+ var ret = FieldInfo.GetValue(this.Owner.Target.TryCast(this.DeclaringType));
+ HadException = false;
+ LastException = null;
+ return ret;
}
catch (Exception ex)
{
HadException = true;
LastException = ex;
+ return null;
}
}
@@ -37,7 +41,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
{
try
{
- FieldInfo.SetValue(FieldInfo.IsStatic ? null : Owner.Target, value);
+ FieldInfo.SetValue(FieldInfo.IsStatic ? null : Owner.Target.TryCast(this.DeclaringType), value);
}
catch (Exception ex)
{
diff --git a/src/UI/Inspectors/CacheObject/CacheKeyValuePair.cs b/src/UI/Inspectors/CacheObject/CacheKeyValuePair.cs
index e7641b8..349cb3a 100644
--- a/src/UI/Inspectors/CacheObject/CacheKeyValuePair.cs
+++ b/src/UI/Inspectors/CacheObject/CacheKeyValuePair.cs
@@ -42,7 +42,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
{
KeyInputWanted = true;
KeyInputText = key.ToString();
- KeyInputTypeText = SignatureHighlighter.ParseFullType(type, false);
+ KeyInputTypeText = SignatureHighlighter.ParseType(type, false);
}
else
{
diff --git a/src/UI/Inspectors/CacheObject/CacheMember.cs b/src/UI/Inspectors/CacheObject/CacheMember.cs
index b5a83a8..4e61c1c 100644
--- a/src/UI/Inspectors/CacheObject/CacheMember.cs
+++ b/src/UI/Inspectors/CacheObject/CacheMember.cs
@@ -5,6 +5,7 @@ using System.Reflection;
using System.Text;
using UnityEngine;
using UnityExplorer.UI.Inspectors.CacheObject.Views;
+using UnityExplorer.UI.ObjectPool;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Inspectors.CacheObject
@@ -17,9 +18,11 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
public abstract Type DeclaringType { get; }
public string NameForFiltering { get; protected set; }
- public override bool HasArguments => Arguments?.Length > 0;
- public ParameterInfo[] Arguments { get; protected set; }
- public bool Evaluating { get; protected set; }
+ public override bool HasArguments => Arguments?.Length > 0 || GenericArguments.Length > 0;
+ public ParameterInfo[] Arguments { get; protected set; } = new ParameterInfo[0];
+ public Type[] GenericArguments { get; protected set; } = new Type[0];
+ public EvaluateWidget Evaluator { get; protected set; }
+ public bool Evaluating => Evaluator != null && Evaluator.UIRoot.activeSelf;
public virtual void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
{
@@ -28,17 +31,43 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
this.NameForFiltering = $"{member.DeclaringType.Name}.{member.Name}";
}
- protected abstract void TryEvaluate();
+ public override void ReleasePooledObjects()
+ {
+ base.ReleasePooledObjects();
+
+ if (this.Evaluator != null)
+ {
+ this.Evaluator.OnReturnToPool();
+ Pool.Return(this.Evaluator);
+ this.Evaluator = null;
+ }
+ }
+
+ internal override void HidePooledObjects()
+ {
+ base.HidePooledObjects();
+
+ if (this.Evaluator != null)
+ this.Evaluator.UIRoot.transform.SetParent(Pool.Instance.InactiveHolder.transform, false);
+ }
+
+ protected abstract object TryEvaluate();
protected abstract void TrySetValue(object value);
+ public void EvaluateAndSetCell()
+ {
+ Evaluate();
+ if (CellView != null)
+ SetCell(CellView);
+ }
+
///
/// Evaluate when first shown (if ShouldAutoEvaluate), or else when Evaluate button is clicked, or auto-updated.
///
public void Evaluate()
{
- TryEvaluate();
- SetValueFromSource(Value);
+ SetValueFromSource(TryEvaluate());
}
public override void SetUserValue(object value)
@@ -58,6 +87,9 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
//memCell.UpdateToggle.gameObject.SetActive(ShouldAutoEvaluate);
}
+ private static readonly Color evalEnabledColor = new Color(0.15f, 0.25f, 0.15f);
+ private static readonly Color evalDisabledColor = new Color(0.15f, 0.15f, 0.15f);
+
protected override bool SetCellEvaluateState(CacheObjectCell objectcell)
{
var cell = objectcell as CacheMemberCell;
@@ -68,15 +100,27 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
//cell.UpdateToggle.gameObject.SetActive(false);
cell.EvaluateButton.Button.gameObject.SetActive(true);
if (HasArguments)
- cell.EvaluateButton.ButtonText.text = $"Evaluate ({Arguments.Length})";
+ {
+ if (!Evaluating)
+ cell.EvaluateButton.ButtonText.text = $"Evaluate ({Arguments.Length + GenericArguments.Length})";
+ else
+ {
+ cell.EvaluateButton.ButtonText.text = "Hide";
+ Evaluator.UIRoot.transform.SetParent(cell.EvaluateHolder.transform, false);
+ RuntimeProvider.Instance.SetColorBlock(cell.EvaluateButton.Button, evalEnabledColor, evalEnabledColor * 1.3f);
+ }
+ }
else
cell.EvaluateButton.ButtonText.text = "Evaluate";
+
+ if (!Evaluating)
+ RuntimeProvider.Instance.SetColorBlock(cell.EvaluateButton.Button, evalDisabledColor, evalDisabledColor * 1.3f);
}
- else
- {
- //cell.UpdateToggle.gameObject.SetActive(true);
- //cell.UpdateToggle.isOn = AutoUpdateWanted;
- }
+ //else
+ //{
+ // cell.UpdateToggle.gameObject.SetActive(true);
+ // cell.UpdateToggle.isOn = AutoUpdateWanted;
+ //}
if (State == ValueState.NotEvaluated && !ShouldAutoEvaluate)
{
@@ -93,6 +137,35 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
return false;
}
+
+ public void OnEvaluateClicked()
+ {
+ if (!HasArguments)
+ {
+ EvaluateAndSetCell();
+ }
+ else
+ {
+ if (Evaluator == null)
+ {
+ this.Evaluator = Pool.Borrow();
+ Evaluator.OnBorrowedFromPool(this);
+ Evaluator.UIRoot.transform.SetParent((CellView as CacheMemberCell).EvaluateHolder.transform, false);
+ SetCellEvaluateState(CellView);
+ }
+ else
+ {
+ if (Evaluator.UIRoot.activeSelf)
+ Evaluator.UIRoot.SetActive(false);
+ else
+ Evaluator.UIRoot.SetActive(true);
+
+ SetCellEvaluateState(CellView);
+ }
+ }
+ }
+
+
#region Cache Member Util
public static bool CanProcessArgs(ParameterInfo[] parameters)
diff --git a/src/UI/Inspectors/CacheObject/CacheMethod.cs b/src/UI/Inspectors/CacheObject/CacheMethod.cs
index 3985466..23d4625 100644
--- a/src/UI/Inspectors/CacheObject/CacheMethod.cs
+++ b/src/UI/Inspectors/CacheObject/CacheMethod.cs
@@ -19,18 +19,35 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
base.SetInspectorOwner(inspector, member);
Arguments = MethodInfo.GetParameters();
+ if (MethodInfo.IsGenericMethod)
+ GenericArguments = MethodInfo.GetGenericArguments();
}
- protected override void TryEvaluate()
+ protected override object TryEvaluate()
{
try
{
- throw new NotImplementedException("TODO");
+ var methodInfo = MethodInfo;
+
+ if (methodInfo.IsGenericMethod)
+ methodInfo = MethodInfo.MakeGenericMethod(Evaluator.TryParseGenericArguments());
+
+ var target = MethodInfo.IsStatic ? null : Owner.Target.TryCast(DeclaringType);
+
+ if (Arguments.Length > 0)
+ return methodInfo.Invoke(target, Evaluator.TryParseArguments());
+
+ var ret = methodInfo.Invoke(target, new object[0]);
+
+ HadException = false;
+ LastException = null;
+ return ret;
}
catch (Exception ex)
{
HadException = true;
LastException = ex;
+ return null;
}
}
diff --git a/src/UI/Inspectors/CacheObject/CacheObjectBase.cs b/src/UI/Inspectors/CacheObject/CacheObjectBase.cs
index 1e979ed..e9dfefe 100644
--- a/src/UI/Inspectors/CacheObject/CacheObjectBase.cs
+++ b/src/UI/Inspectors/CacheObject/CacheObjectBase.cs
@@ -128,7 +128,6 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
///
protected virtual void ProcessOnEvaluate()
{
-
if (HadException)
State = ValueState.Exception;
else if (Value.IsNullOrDestroyed())
@@ -166,7 +165,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
switch (State)
{
case ValueState.NotEvaluated:
- label = $"{NOT_YET_EVAL} ({SignatureHighlighter.ParseFullType(FallbackType, true)})"; break;
+ label = $"{NOT_YET_EVAL} ({SignatureHighlighter.ParseType(FallbackType, true)})"; break;
case ValueState.Exception:
label = $"{ReflectionUtility.ReflectionExToString(LastException)}"; break;
case ValueState.Boolean:
@@ -228,7 +227,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
break;
case ValueState.Enum:
SetIValueState();
- SetValueState(cell, new ValueStateArgs(true, subContentButtonActive: true));
+ SetValueState(cell, new ValueStateArgs(true, subContentButtonActive: CanWrite));
break;
case ValueState.Collection:
case ValueState.Dictionary:
@@ -258,11 +257,12 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
cell.TypeLabel.gameObject.SetActive(args.typeLabelActive);
if (args.typeLabelActive)
- cell.TypeLabel.text = SignatureHighlighter.ParseFullType(Value.GetActualType(), false);
+ cell.TypeLabel.text = SignatureHighlighter.ParseType(Value.GetActualType(), false);
cell.Toggle.gameObject.SetActive(args.toggleActive);
if (args.toggleActive)
{
+ cell.Toggle.interactable = CanWrite;
cell.Toggle.isOn = (bool)Value;
cell.ToggleText.text = Value.ToString();
}
@@ -329,7 +329,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
IValue = null;
}
- internal void HideIValue()
+ internal virtual void HidePooledObjects()
{
if (this.IValue == null)
return;
diff --git a/src/UI/Inspectors/CacheObject/CacheProperty.cs b/src/UI/Inspectors/CacheObject/CacheProperty.cs
index 1981a09..104372a 100644
--- a/src/UI/Inspectors/CacheObject/CacheProperty.cs
+++ b/src/UI/Inspectors/CacheObject/CacheProperty.cs
@@ -21,16 +21,26 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
Arguments = PropertyInfo.GetIndexParameters();
}
- protected override void TryEvaluate()
+ protected override object TryEvaluate()
{
try
{
- Value = PropertyInfo.GetValue(Owner.Target.TryCast(DeclaringType), null);
+ bool _static = PropertyInfo.GetAccessors(true)[0].IsStatic;
+ var target = _static ? null : Owner.Target.TryCast(DeclaringType);
+
+ if (HasArguments)
+ return PropertyInfo.GetValue(target, this.Evaluator.TryParseArguments());
+
+ var ret = PropertyInfo.GetValue(target, null);
+ HadException = false;
+ LastException = null;
+ return ret;
}
catch (Exception ex)
{
HadException = true;
LastException = ex;
+ return null;
}
}
@@ -41,9 +51,13 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
try
{
- // TODO property indexers
+ bool _static = PropertyInfo.GetAccessors(true)[0].IsStatic;
+ var target = _static ? null : Owner.Target.TryCast(DeclaringType);
- PropertyInfo.SetValue(PropertyInfo.GetSetMethod().IsStatic ? null : Owner.Target, value, null);
+ if (HasArguments)
+ PropertyInfo.SetValue(target, value, Evaluator.TryParseArguments());
+ else
+ PropertyInfo.SetValue(target, value, null);
}
catch (Exception ex)
{
diff --git a/src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs b/src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs
index 599e0f0..5afde1d 100644
--- a/src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs
+++ b/src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs
@@ -21,7 +21,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject.Views
protected virtual void EvaluateClicked()
{
- // TODO
+ this.MemberOccupant.OnEvaluateClicked();
}
protected override void ConstructEvaluateHolder(GameObject parent)
diff --git a/src/UI/Inspectors/CacheObject/Views/EvaluateWidget.cs b/src/UI/Inspectors/CacheObject/Views/EvaluateWidget.cs
new file mode 100644
index 0000000..e54bc35
--- /dev/null
+++ b/src/UI/Inspectors/CacheObject/Views/EvaluateWidget.cs
@@ -0,0 +1,257 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using UnityEngine;
+using UnityEngine.UI;
+using UnityExplorer.UI.ObjectPool;
+using UnityExplorer.UI.Utility;
+
+namespace UnityExplorer.UI.Inspectors.CacheObject.Views
+{
+ public class EvaluateWidget : IPooledObject
+ {
+ public CacheMember Owner { get; set; }
+
+ public GameObject UIRoot { get; set; }
+ public float DefaultHeight => -1f;
+
+ private ParameterInfo[] arguments;
+ private string[] argumentInput;
+
+ private GameObject argHolder;
+ private readonly List argRows = new List();
+ private readonly List argLabels = new List();
+
+ private Type[] genericArguments;
+ private string[] genericInput;
+
+ private GameObject genericArgHolder;
+ private readonly List genericArgRows = new List();
+ private readonly List genericArgLabels = new List();
+
+ private readonly List inputFieldCache = new List();
+
+ public void OnBorrowedFromPool(CacheMember owner)
+ {
+ this.Owner = owner;
+
+ arguments = owner.Arguments;
+ argumentInput = new string[arguments.Length];
+
+ genericArguments = owner.GenericArguments;
+ genericInput = new string[genericArguments.Length];
+
+ SetArgRows();
+
+ this.UIRoot.SetActive(true);
+ }
+
+ public void OnReturnToPool()
+ {
+ foreach (var input in inputFieldCache)
+ input.text = "";
+
+ this.Owner = null;
+ }
+
+ public Type[] TryParseGenericArguments()
+ {
+ Type[] outArgs = new Type[genericArguments.Length];
+
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ outArgs[i] = ReflectionUtility.GetTypeByName(genericInput[i])
+ ?? throw new Exception($"Could not find any type by name '{genericInput[i]}'!");
+ }
+
+ return outArgs;
+ }
+
+ public object[] TryParseArguments()
+ {
+ object[] outArgs = new object[arguments.Length];
+
+ for (int i = 0; i < arguments.Length; i++)
+ {
+ var arg = arguments[i];
+ var input = argumentInput[i];
+
+ var type = arg.ParameterType;
+ if (type.IsByRef)
+ type = type.GetElementType();
+
+ if (type == typeof(string))
+ {
+ outArgs[i] = input;
+ continue;
+ }
+
+ if (string.IsNullOrEmpty(input))
+ {
+ if (arg.IsOptional)
+ outArgs[i] = arg.DefaultValue;
+ else
+ outArgs[i] = null;
+ continue;
+ }
+
+ try
+ {
+ var parse = ReflectionUtility.GetMethodInfo(type, "Parse", new Type[] { typeof(string) });
+ outArgs[i] = parse.Invoke(null, new object[] { input });
+ }
+ catch (Exception ex)
+ {
+ ExplorerCore.LogWarning($"Cannot parse argument '{arg.Name}' ({arg.ParameterType.Name}), {ex.GetType().Name}: {ex.Message}");
+ outArgs[i] = null;
+ }
+ }
+
+ return outArgs;
+ }
+
+ private void SetArgRows()
+ {
+ if (genericArguments.Any())
+ {
+ genericArgHolder.SetActive(true);
+ SetupGenericArgs();
+ }
+ else
+ genericArgHolder.SetActive(false);
+
+ if (arguments.Any())
+ {
+ argHolder.SetActive(true);
+ SetupArgs();
+ }
+ else
+ argHolder.SetActive(false);
+ }
+
+ private void SetupGenericArgs()
+ {
+ for (int i = 0; i < genericArguments.Length || i < genericArgRows.Count; i++)
+ {
+ if (i >= genericArguments.Length)
+ {
+ if (i >= genericArgRows.Count)
+ break;
+ else
+ // exceeded actual args, but still iterating so there must be views left, disable them
+ genericArgRows[i].SetActive(false);
+ continue;
+ }
+
+ var arg = genericArguments[i];
+
+ if (i >= genericArgRows.Count)
+ AddArgRow(i, true);
+
+ genericArgRows[i].SetActive(true);
+
+ var sb = new StringBuilder($"{arg.Name}");
+
+ var constraints = arg.GetGenericParameterConstraints();
+ for (int j = 0; j < constraints.Length; j++)
+ {
+ if (j == 0) sb.Append(' ').Append('(');
+ else sb.Append(',').Append(' ');
+
+ sb.Append(SignatureHighlighter.ParseType(constraints[i]));
+
+ if (j + 1 == constraints.Length)
+ sb.Append(')');
+ }
+
+ genericArgLabels[i].text = sb.ToString();
+ }
+ }
+
+ private void SetupArgs()
+ {
+ for (int i = 0; i < arguments.Length || i < argRows.Count; i++)
+ {
+ if (i >= arguments.Length)
+ {
+ if (i >= argRows.Count)
+ break;
+ else
+ // exceeded actual args, but still iterating so there must be views left, disable them
+ argRows[i].SetActive(false);
+ continue;
+ }
+
+ var arg = arguments[i];
+
+ if (i >= argRows.Count)
+ AddArgRow(i, false);
+
+ argRows[i].SetActive(true);
+ argLabels[i].text = $"{SignatureHighlighter.ParseType(arg.ParameterType)} {arg.Name}";
+ }
+ }
+
+ private void AddArgRow(int index, bool generic)
+ {
+ if (!generic)
+ AddArgRow(index, argHolder, argRows, argLabels, argumentInput);
+ else
+ AddArgRow(index, genericArgHolder, genericArgRows, genericArgLabels, genericInput);
+ }
+
+ private void AddArgRow(int index, GameObject parent, List objectList, List labelList, string[] inputArray)
+ {
+ var horiGroup = UIFactory.CreateUIObject("ArgRow_" + index, parent);
+ UIFactory.SetLayoutElement(horiGroup, minHeight: 25, flexibleHeight: 50, minWidth: 50, flexibleWidth: 9999);
+ UIFactory.SetLayoutGroup(horiGroup, false, false, true, true, 5);
+ objectList.Add(horiGroup);
+
+ var label = UIFactory.CreateLabel(horiGroup, "ArgLabel", "not set", TextAnchor.MiddleLeft);
+ UIFactory.SetLayoutElement(label.gameObject, minWidth: 40, flexibleWidth: 90, minHeight: 25, flexibleHeight: 50);
+ labelList.Add(label);
+ label.horizontalOverflow = HorizontalWrapMode.Wrap;
+
+ var inputObj = UIFactory.CreateInputField(horiGroup, "InputField", "...", out InputField inputField);
+ UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleHeight: 0, minWidth: 100, flexibleWidth: 1000);
+ inputField.lineType = InputField.LineType.MultiLineNewline;
+ inputField.onValueChanged.AddListener((string val) => { inputArray[index] = val; });
+ inputFieldCache.Add(inputField);
+ }
+
+ public GameObject CreateContent(GameObject parent)
+ {
+ UIRoot = UIFactory.CreateVerticalGroup(parent, "EvaluateWidget", false, false, true, true, 3, new Vector4(2, 2, 2, 2),
+ new Color(0.15f, 0.15f, 0.15f));
+ UIFactory.SetLayoutElement(UIRoot, minWidth: 50, flexibleWidth: 9999, minHeight: 50, flexibleHeight: 800);
+
+ // generic args
+ this.genericArgHolder = UIFactory.CreateUIObject("GenericHolder", UIRoot);
+ UIFactory.SetLayoutElement(genericArgHolder, flexibleWidth: 1000);
+ var genericsTitle = UIFactory.CreateLabel(genericArgHolder, "GenericsTitle", "Generic Arguments", TextAnchor.MiddleLeft);
+ UIFactory.SetLayoutElement(genericsTitle.gameObject, minHeight: 25, flexibleWidth: 1000);
+ UIFactory.SetLayoutGroup(genericArgHolder, false, false, true, true, 3);
+ UIFactory.SetLayoutElement(genericArgHolder, minHeight: 25, flexibleHeight: 750, minWidth: 50, flexibleWidth: 9999);
+
+ // args
+ this.argHolder = UIFactory.CreateUIObject("ArgHolder", UIRoot);
+ UIFactory.SetLayoutElement(argHolder, flexibleWidth: 1000);
+ var argsTitle = UIFactory.CreateLabel(argHolder, "ArgsTitle", "Arguments", TextAnchor.MiddleLeft);
+ UIFactory.SetLayoutElement(argsTitle.gameObject, minHeight: 25, flexibleWidth: 1000);
+ UIFactory.SetLayoutGroup(argHolder, false, false, true, true, 3);
+ UIFactory.SetLayoutElement(argHolder, minHeight: 25, flexibleHeight: 750, minWidth: 50, flexibleWidth: 9999);
+
+ // evaluate button
+ var evalButton = UIFactory.CreateButton(UIRoot, "EvaluateButton", "Evaluate", new Color(0.2f, 0.2f, 0.2f));
+ UIFactory.SetLayoutElement(evalButton.Button.gameObject, minHeight: 25, minWidth: 150, flexibleWidth: 0);
+ evalButton.OnClick += () =>
+ {
+ Owner.EvaluateAndSetCell();
+ };
+
+ return UIRoot;
+ }
+ }
+}
diff --git a/src/UI/Inspectors/GameObjectInspector.cs b/src/UI/Inspectors/GameObjectInspector.cs
index 5c23cbd..5a81d75 100644
--- a/src/UI/Inspectors/GameObjectInspector.cs
+++ b/src/UI/Inspectors/GameObjectInspector.cs
@@ -121,7 +121,7 @@ namespace UnityExplorer.UI.Inspectors
if (!compToStringCache.ContainsKey(type.AssemblyQualifiedName))
{
- compToStringCache.Add(type.AssemblyQualifiedName, SignatureHighlighter.ParseFullType(type, true));
+ compToStringCache.Add(type.AssemblyQualifiedName, SignatureHighlighter.ParseType(type, true));
}
cell.Button.ButtonText.text = compToStringCache[type.AssemblyQualifiedName];
diff --git a/src/UI/Inspectors/ICacheObjectController.cs b/src/UI/Inspectors/ICacheObjectController.cs
index 383e075..fa33141 100644
--- a/src/UI/Inspectors/ICacheObjectController.cs
+++ b/src/UI/Inspectors/ICacheObjectController.cs
@@ -8,7 +8,7 @@ namespace UnityExplorer.UI.Inspectors
{
public interface ICacheObjectController
{
- CacheObjectBase ParentCacheObject { get; } // TODO
+ CacheObjectBase ParentCacheObject { get; }
object Target { get; }
Type TargetType { get; }
diff --git a/src/UI/Inspectors/IValues/InteractiveDictionary.cs b/src/UI/Inspectors/IValues/InteractiveDictionary.cs
index 46f6aa2..84ae0e5 100644
--- a/src/UI/Inspectors/IValues/InteractiveDictionary.cs
+++ b/src/UI/Inspectors/IValues/InteractiveDictionary.cs
@@ -39,6 +39,8 @@ namespace UnityExplorer.UI.Inspectors.IValues
public override void OnBorrowed(CacheObjectBase owner)
{
base.OnBorrowed(owner);
+
+ DictScrollPool.Refresh(true, true);
}
public override void ReleaseFromOwner()
@@ -83,7 +85,7 @@ namespace UnityExplorer.UI.Inspectors.IValues
CacheEntries(value);
- TopLabel.text = $"[{cachedEntries.Count}] {SignatureHighlighter.ParseFullType(type, false)}";
+ TopLabel.text = $"[{cachedEntries.Count}] {SignatureHighlighter.ParseType(type, false)}";
}
@@ -172,7 +174,7 @@ namespace UnityExplorer.UI.Inspectors.IValues
{
if (cell.Occupant != null)
{
- cell.Occupant.HideIValue();
+ cell.Occupant.HidePooledObjects();
cell.Occupant.CellView = null;
cell.Occupant = null;
}
diff --git a/src/UI/Inspectors/IValues/InteractiveList.cs b/src/UI/Inspectors/IValues/InteractiveList.cs
index 1eb44ed..3354f55 100644
--- a/src/UI/Inspectors/IValues/InteractiveList.cs
+++ b/src/UI/Inspectors/IValues/InteractiveList.cs
@@ -35,6 +35,8 @@ namespace UnityExplorer.UI.Inspectors.IValues
public override void OnBorrowed(CacheObjectBase owner)
{
base.OnBorrowed(owner);
+
+ ListScrollPool.Refresh(true, true);
}
public override void ReleaseFromOwner()
@@ -72,7 +74,7 @@ namespace UnityExplorer.UI.Inspectors.IValues
CacheEntries(value);
- TopLabel.text = $"[{cachedEntries.Count}] {SignatureHighlighter.ParseFullType(type, false)}";
+ TopLabel.text = $"[{cachedEntries.Count}] {SignatureHighlighter.ParseType(type, false)}";
}
//this.ScrollPoolLayout.minHeight = Math.Min(400f, 35f * values.Count);
@@ -169,7 +171,7 @@ namespace UnityExplorer.UI.Inspectors.IValues
{
if (cell.Occupant != null)
{
- cell.Occupant.HideIValue();
+ cell.Occupant.HidePooledObjects();
cell.Occupant.CellView = null;
cell.Occupant = null;
}
diff --git a/src/UI/Inspectors/ReflectionInspector.cs b/src/UI/Inspectors/ReflectionInspector.cs
index e53dbc1..1e14a24 100644
--- a/src/UI/Inspectors/ReflectionInspector.cs
+++ b/src/UI/Inspectors/ReflectionInspector.cs
@@ -30,7 +30,7 @@ namespace UnityExplorer.UI.Inspectors
private List members = new List();
private readonly List filteredMembers = new List();
- private readonly HashSet displayedMembers = new HashSet();
+ // private readonly HashSet displayedMembers = new HashSet();
public Text NameText;
public Text AssemblyText;
@@ -65,7 +65,6 @@ namespace UnityExplorer.UI.Inspectors
members.Clear();
filteredMembers.Clear();
- displayedMembers.Clear();
autoUpdateToggle.isOn = false;
AutoUpdateWanted = false;
@@ -88,7 +87,7 @@ namespace UnityExplorer.UI.Inspectors
prefix = "[R]";
}
- Tab.TabText.text = $"{prefix} {SignatureHighlighter.ParseFullType(TargetType)}";
+ Tab.TabText.text = $"{prefix} {SignatureHighlighter.ParseType(TargetType)}";
NameText.text = SignatureHighlighter.ParseFullSyntax(TargetType, true);
@@ -156,8 +155,11 @@ namespace UnityExplorer.UI.Inspectors
private void UpdateDisplayedMembers()// bool onlyAutoUpdate)
{
bool shouldRefresh = false;
- foreach (var member in displayedMembers)
+ foreach (var cell in MemberScrollPool.CellPool)
{
+ if (!cell.Enabled || cell.Occupant == null)
+ continue;
+ var member = cell.MemberOccupant;
if (member.ShouldAutoEvaluate) // && (!onlyAutoUpdate || member.AutoUpdateWanted))
{
shouldRefresh = true;
@@ -185,9 +187,6 @@ namespace UnityExplorer.UI.Inspectors
{
if (cell.Occupant != null)
{
- if (displayedMembers.Contains(cell.MemberOccupant))
- displayedMembers.Remove(cell.MemberOccupant);
-
cell.Occupant.CellView = null;
cell.Occupant = null;
}
@@ -202,15 +201,13 @@ namespace UnityExplorer.UI.Inspectors
{
if (cell.Occupant != null)
{
- cell.Occupant.HideIValue();
- displayedMembers.Remove(cell.MemberOccupant);
+ cell.Occupant.HidePooledObjects();
cell.Occupant.CellView = null;
cell.Occupant = null;
}
cell.Occupant = member;
member.CellView = cell;
- displayedMembers.Add(member);
}
member.SetCell(cell);
diff --git a/src/UI/ObjectExplorer/ObjectSearch.cs b/src/UI/ObjectExplorer/ObjectSearch.cs
index 8d0006f..69c6f5a 100644
--- a/src/UI/ObjectExplorer/ObjectSearch.cs
+++ b/src/UI/ObjectExplorer/ObjectSearch.cs
@@ -97,7 +97,7 @@ namespace UnityExplorer.UI.Panels
{
string text;
if (m_context == SearchContext.StaticClass)
- text = SignatureHighlighter.ParseFullType(currentResults[index] as Type, true, true);
+ text = SignatureHighlighter.ParseType(currentResults[index] as Type, true, true);
else
text = ToStringUtility.ToStringWithType(currentResults[index], currentResults[index]?.GetActualType());
diff --git a/src/UI/ObjectExplorer/SceneExplorer.cs b/src/UI/ObjectExplorer/SceneExplorer.cs
index 8d8e8e3..c72fe33 100644
--- a/src/UI/ObjectExplorer/SceneExplorer.cs
+++ b/src/UI/ObjectExplorer/SceneExplorer.cs
@@ -41,10 +41,10 @@ namespace UnityExplorer.UI.Panels
private readonly Dictionary sceneToDropdownOption = new Dictionary();
private IEnumerable GetRootEntries() => SceneHandler.CurrentRootObjects;
-
+
public void Update()
{
- if (AutoUpdate && Time.realtimeSinceStartup - timeOfLastUpdate >= 1f)
+ if ((AutoUpdate || !SceneHandler.InspectingAssetScene) && Time.realtimeSinceStartup - timeOfLastUpdate >= 1f)
{
timeOfLastUpdate = Time.realtimeSinceStartup;
UpdateTree();
@@ -65,7 +65,7 @@ namespace UnityExplorer.UI.Panels
SceneHandler.SelectedScene = SceneHandler.LoadedScenes[value];
SceneHandler.Update();
Tree.RefreshData(true);
- //OnSelectedSceneChanged(SceneHandler.SelectedScene.Value);
+ OnSelectedSceneChanged(SceneHandler.SelectedScene.Value);
}
private void SceneHandler_OnInspectedSceneChanged(Scene scene)
@@ -83,14 +83,14 @@ namespace UnityExplorer.UI.Panels
sceneDropdown.captionText.text = opt.text;
}
- //OnSelectedSceneChanged(scene);
+ OnSelectedSceneChanged(scene);
}
- //private void OnSelectedSceneChanged(Scene scene)
- //{
- // if (refreshRow)
- // refreshRow.SetActive(!scene.IsValid());
- //}
+ private void OnSelectedSceneChanged(Scene scene)
+ {
+ if (refreshRow)
+ refreshRow.SetActive(!scene.IsValid());
+ }
private void SceneHandler_OnLoadedScenesChanged(ReadOnlyCollection loadedScenes)
{
diff --git a/src/UI/Panels/ObjectExplorer.cs b/src/UI/Panels/ObjectExplorer.cs
index b6efd3d..88b6096 100644
--- a/src/UI/Panels/ObjectExplorer.cs
+++ b/src/UI/Panels/ObjectExplorer.cs
@@ -40,7 +40,7 @@ namespace UnityExplorer.UI.Panels
content.SetActive(true);
var button = tabButtons[tabIndex];
- RuntimeProvider.Instance.SetColorBlock(button.Button, UIManager.navButtonEnabledColor, UIManager.navButtonEnabledColor * 1.2f);
+ RuntimeProvider.Instance.SetColorBlock(button.Button, UIManager.enabledButtonColor, UIManager.enabledButtonColor * 1.2f);
SelectedTab = tabIndex;
SaveToConfigManager();
@@ -49,7 +49,7 @@ namespace UnityExplorer.UI.Panels
private void DisableTab(int tabIndex)
{
tabPages[tabIndex].SetActive(false);
- RuntimeProvider.Instance.SetColorBlock(tabButtons[tabIndex].Button, UIManager.navButtonDisabledColor, UIManager.navButtonDisabledColor * 1.2f);
+ RuntimeProvider.Instance.SetColorBlock(tabButtons[tabIndex].Button, UIManager.disabledButtonColor, UIManager.disabledButtonColor * 1.2f);
}
public override void Update()
@@ -97,10 +97,11 @@ namespace UnityExplorer.UI.Panels
public override void SetDefaultPosAndAnchors()
{
+ // todo proper default size
mainPanelRect.localPosition = Vector2.zero;
mainPanelRect.pivot = new Vector2(0f, 1f);
- mainPanelRect.anchorMin = new Vector2(0.1f, 0.2f);
- mainPanelRect.anchorMax = new Vector2(0.25f, 0.9f);
+ mainPanelRect.anchorMin = new Vector2(0.1f, 0.25f);
+ mainPanelRect.anchorMax = new Vector2(0.25f, 0.8f);
//mainPanelRect.anchorMin = Vector3.zero;
diff --git a/src/UI/Panels/PanelDragger.cs b/src/UI/Panels/PanelDragger.cs
index 0bc6437..be1ed0b 100644
--- a/src/UI/Panels/PanelDragger.cs
+++ b/src/UI/Panels/PanelDragger.cs
@@ -227,19 +227,6 @@ namespace UnityExplorer.UI.Panels
Vector3 pos = Panel.localPosition;
pos += (Vector3)diff;
Panel.localPosition = pos;
-
- // TODO prevent dragging the navbar outside the window completely.
- // this was not that, but should do that.
-
- //var halfHeight = Panel.rect.height * 0.5f;
- //var halfWidth = Panel.rect.width * 0.5f;
- //if (Panel.MinY() - halfHeight + 25 < 0
- // || Panel.MinX() - halfWidth + 25 < 0
- // || Panel.MaxY() + halfWidth - 25 > Screen.height
- // || Panel.MinX() + halfWidth - 25 > Screen.width)
- //{
- // Panel.localPosition -= (Vector3)diff;
- //}
}
public void OnEndDrag()
diff --git a/src/UI/Panels/UIPanel.cs b/src/UI/Panels/UIPanel.cs
index 649f32b..6193323 100644
--- a/src/UI/Panels/UIPanel.cs
+++ b/src/UI/Panels/UIPanel.cs
@@ -114,9 +114,9 @@ namespace UnityExplorer.UI.Panels
if (NavButtonWanted)
{
if (active)
- RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.navButtonEnabledColor, UIManager.navButtonEnabledColor * 1.2f);
+ RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.enabledButtonColor, UIManager.enabledButtonColor * 1.2f);
else
- RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.navButtonDisabledColor, UIManager.navButtonDisabledColor * 1.2f);
+ RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.disabledButtonColor, UIManager.disabledButtonColor * 1.2f);
}
}
@@ -136,7 +136,7 @@ namespace UnityExplorer.UI.Panels
NavButton = UIFactory.CreateButton(UIManager.NavbarButtonHolder, $"Button_{PanelType}", Name);
UIFactory.SetLayoutElement(NavButton.Button.gameObject, minWidth: 118, flexibleWidth: 0);
- RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.navButtonDisabledColor, UIManager.navButtonDisabledColor * 1.2f);
+ RuntimeProvider.Instance.SetColorBlock(NavButton.Button, UIManager.disabledButtonColor, UIManager.disabledButtonColor * 1.2f);
NavButton.OnClick += () =>
{
UIManager.TogglePanel(PanelType);
diff --git a/src/UI/UIFactory.cs b/src/UI/UIFactory.cs
index dddb91c..db51a7a 100644
--- a/src/UI/UIFactory.cs
+++ b/src/UI/UIFactory.cs
@@ -729,9 +729,7 @@ namespace UnityExplorer.UI
contentRect.pivot = new Vector2(0.5f, 1f);
contentRect.sizeDelta = new Vector2(0f, 0f);
contentRect.offsetMax = new Vector2(0f, 0f);
-
SetLayoutGroup(content, true, false, true, true, 0, 2, 2, 2, 2, TextAnchor.UpperCenter);
-
content.AddComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var scrollRect = mainObj.AddComponent();
diff --git a/src/UI/UIManager.cs b/src/UI/UIManager.cs
index 920cab8..0cfd857 100644
--- a/src/UI/UIManager.cs
+++ b/src/UI/UIManager.cs
@@ -53,8 +53,8 @@ namespace UnityExplorer.UI
public static RectTransform NavBarRect;
public static GameObject NavbarButtonHolder;
- internal static readonly Color navButtonEnabledColor = new Color(0.2f, 0.4f, 0.28f);
- internal static readonly Color navButtonDisabledColor = new Color(0.25f, 0.25f, 0.25f);
+ internal static readonly Color enabledButtonColor = new Color(0.2f, 0.4f, 0.28f);
+ internal static readonly Color disabledButtonColor = new Color(0.25f, 0.25f, 0.25f);
public const int MAX_INPUTFIELD_CHARS = 16000;
diff --git a/src/UI/Utility/SignatureHighlighter.cs b/src/UI/Utility/SignatureHighlighter.cs
index 2b73d0d..458276b 100644
--- a/src/UI/Utility/SignatureHighlighter.cs
+++ b/src/UI/Utility/SignatureHighlighter.cs
@@ -35,6 +35,12 @@ namespace UnityExplorer.UI.Utility
public const string LOCAL_ARG = "#a6e9e9";
+ internal const string ARRAY_TOKEN = "[]";
+ internal const string OPEN_COLOR = "{ns}.");
-
- // Declaring type
-
- var declaring = type.DeclaringType;
- while (declaring != null)
+ if (!isGeneric)
{
- syntaxBuilder.Append(HighlightType(declaring));
- syntaxBuilder.Append('.');
- declaring = declaring.DeclaringType;
+ if (includeNamespace && GetNamespace(type, out string ns))
+ syntaxBuilder.Append(OPEN_COLOR).Append(NAMESPACE).Append('>').Append(ns).Append(CLOSE_COLOR).Append('.');
+
+ // Declaring type
+
+ var declaring = type.DeclaringType;
+ while (declaring != null)
+ {
+ syntaxBuilder.Append(HighlightType(declaring));
+ syntaxBuilder.Append('.');
+ declaring = declaring.DeclaringType;
+ }
}
// Highlight the type name
@@ -96,68 +105,101 @@ namespace UnityExplorer.UI.Utility
{
syntaxBuilder.Append('.');
- string memColor = GetMemberInfoColor(memberInfo, out bool isStatic);
+ //string memColor = GetMemberInfoColor(memberInfo, out bool isStatic);
+
+ //if (isStatic)
+ // syntaxBuilder.Append(OPEN_ITALIC);
+
+ //syntaxBuilder.Append($"{memberInfo.Name}{CLOSE_COLOR}");
+ int start = syntaxBuilder.Length - 1;
+ syntaxBuilder.Append(OPEN_COLOR)
+ .Append(GetMemberInfoColor(memberInfo, out bool isStatic))
+ .Append('>')
+ .Append(memberInfo.Name)
+ .Append(CLOSE_COLOR);
if (isStatic)
- syntaxBuilder.Append("");
-
- syntaxBuilder.Append($"{memberInfo.Name}");
-
- if (isStatic)
- syntaxBuilder.Append("");
+ {
+ syntaxBuilder.Insert(start, OPEN_ITALIC);
+ syntaxBuilder.Append(CLOSE_ITALIC);
+ }
if (memberInfo is MethodInfo method)
{
var args = method.GetGenericArguments();
if (args.Length > 0)
- syntaxBuilder.Append($"<{ParseGenericArgs(args, true)}>");
+ //syntaxBuilder.Append($"<{ParseGenericArgs(args, true)}>");
+ syntaxBuilder.Append('<').Append(ParseGenericArgs(args, true)).Append('>');
}
}
return syntaxBuilder.ToString();
}
- public static string ParseFullType(Type type, bool includeNamespace = false, bool includeDllName = false)
+ public static string ParseType(Type type, bool includeNamespace = false, bool includeDllName = false)
{
- string ret = HighlightType(type);
+ var sb = new StringBuilder();
bool isGeneric = type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter);
if (!isGeneric && includeNamespace && GetNamespace(type, out string ns))
- ret = $"{ns}.{ret}";
+ //sb.Append($"{ns}{CLOSE_COLOR}.");
+ sb.Append(OPEN_COLOR).Append(NAMESPACE).Append('>').Append(ns).Append(CLOSE_COLOR).Append('.');
+
+ sb.Append(HighlightType(type));
if (includeDllName)
{
if (!string.IsNullOrEmpty(type.Assembly.Location))
- ret = $"{ret} ({Path.GetFileName(type.Assembly.Location)})";
+ //sb.Append($" ({Path.GetFileName(type.Assembly.Location)})");
+ sb.Append(' ').Append('(').Append(Path.GetFileName(type.Assembly.Location)).Append(')');
else
- ret = $"{ret} ({type.Assembly.GetName().Name})";
+ //sb.Append($" ({type.Assembly.GetName().Name})");
+ sb.Append(' ').Append('(').Append(type.Assembly.GetName().Name).Append(')');
}
- return ret;
+ return sb.ToString();
}
private static readonly Dictionary typeToRichType = new Dictionary();
+ private static bool EndsWith(this StringBuilder sb, string _string)
+ {
+ int len = _string.Length;
+
+ if (sb.Length < len)
+ return false;
+
+ int stringpos = 0;
+ for (int i = sb.Length - len; i < sb.Length; i++, stringpos++)
+ {
+ if (sb[i] != _string[stringpos])
+ return false;
+ }
+ return true;
+ }
+
private static string HighlightType(Type type)
{
string key = type.ToString();
if (typeToRichType.ContainsKey(key))
return typeToRichType[key];
-
- var typeName = type.Name;
+
+ var sb = new StringBuilder(type.Name);
bool isArray = false;
- if (typeName.EndsWith("[]"))
+ if (sb.EndsWith(ARRAY_TOKEN))
{
isArray = true;
- typeName = typeName.Substring(0, typeName.Length - 2);
+ sb.Remove(sb.Length - 2, 2);
type = type.GetElementType();
}
if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter))
{
- typeName = $"{typeName}";
+ //typeName = $"{typeName}";
+ sb.Insert(0, $"");
+ sb.Append(CLOSE_COLOR);
}
else
{
@@ -172,27 +214,33 @@ namespace UnityExplorer.UI.Utility
int suffixLen = 1 + args.Length.ToString().Length;
// make sure the typename actually has expected "`N" format.
- if (typeName[typeName.Length - suffixLen] == '`')
- typeName = typeName.Substring(0, typeName.Length - suffixLen);
+ if (sb[sb.Length - suffixLen] == '`')
+ //typeName = typeName.Substring(0, typeName.Length - suffixLen);
+ sb.Remove(sb.Length - suffixLen, suffixLen);
}
// highlight the base name itself
// do this after removing the `N suffix, so only the name itself is in the color tags.
- typeName = $"{typeName}";
+ //typeName = $"{typeName}";
+ sb.Insert(0, $"{OPEN_COLOR}{GetClassColor(type)}>");
+ sb.Append(CLOSE_COLOR);
// parse the generic args, if any
if (args.Length > 0)
{
- typeName += $"<{ParseGenericArgs(args)}>";
+ //typeName += $"<{ParseGenericArgs(args)}>";
+ sb.Append('<').Append(ParseGenericArgs(args)).Append('>');
}
}
if (isArray)
- typeName += "[]";
+ //typeName += "[]";
+ sb.Append('[').Append(']');
- typeToRichType.Add(key, typeName);
+ var ret = sb.ToString();
+ typeToRichType.Add(key, ret);
- return typeName;
+ return ret;
}
public static string ParseGenericArgs(Type[] args, bool isGenericParams = false)
@@ -200,24 +248,27 @@ namespace UnityExplorer.UI.Utility
if (args.Length < 1)
return string.Empty;
- string ret = "";
+ //string ret = "";
+ var sb = new StringBuilder();
for (int i = 0; i < args.Length; i++)
{
if (i > 0)
- ret += ", ";
+ //ret += ", ";
+ sb.Append(',').Append(' ');
if (isGenericParams)
{
- ret += $"{args[i].Name}";
+ //ret += $"{args[i].Name}";
+ sb.Append(OPEN_COLOR).Append(CONST).Append('>').Append(args[i].Name).Append(CLOSE_COLOR);
continue;
}
- // using HighlightTypeName makes it recursive, so we can parse nested generic args.
- ret += ParseFullType(args[i]);
+ //ret += ParseType(args[i]);
+ sb.Append(ParseType(args[i]));
}
- return ret;
+ return sb.ToString();
}
public static string GetMemberInfoColor(MemberInfo memberInfo, out bool isStatic)
diff --git a/src/UI/Utility/ToStringUtility.cs b/src/UI/Utility/ToStringUtility.cs
index 433c481..4577a11 100644
--- a/src/UI/Utility/ToStringUtility.cs
+++ b/src/UI/Utility/ToStringUtility.cs
@@ -30,9 +30,6 @@ namespace UnityExplorer.UI.Utility
string richType = SignatureHighlighter.ParseFullSyntax(type, includeNamespace);
- //if (!includeName)
- // return richType;
-
_stringBuilder.Clear();
if (value.IsNullOrDestroyed())
@@ -142,10 +139,20 @@ namespace UnityExplorer.UI.Utility
value = value.TryCast(type);
string toString;
- if (toStringFormattedMethods.TryGetValue(type.AssemblyQualifiedName, out MethodInfo f3method))
- toString = (string)f3method.Invoke(value, new object[] { "F3" });
- else
- toString = (string)toStringMethods[type.AssemblyQualifiedName].Invoke(value, new object[0]);
+ try
+ {
+ if (toStringFormattedMethods.TryGetValue(type.AssemblyQualifiedName, out MethodInfo f3method))
+ toString = (string)f3method.Invoke(value, new object[] { "F3" });
+ else
+ toString = (string)toStringMethods[type.AssemblyQualifiedName].Invoke(value, new object[0]);
+ }
+ catch (Exception ex)
+ {
+ toString = ex.ReflectionExToString();
+ }
+
+ string _ = null;
+ toString = ReflectionProvider.Instance.ProcessTypeFullNameInString(type, toString, ref _);
return toString;
}
diff --git a/src/UI/Widgets/ScrollPool/UIExtensions.cs b/src/UI/Widgets/ScrollPool/UIExtensions.cs
index bac135e..364fd7a 100644
--- a/src/UI/Widgets/ScrollPool/UIExtensions.cs
+++ b/src/UI/Widgets/ScrollPool/UIExtensions.cs
@@ -24,7 +24,7 @@ namespace UnityExplorer.UI
public static float MinY(this RectTransform rect) => rect.position.y;
- public static float MaxX(this RectTransform rect) => rect.position.x - rect.rect.width;
+ public static float MaxX(this RectTransform rect) => rect.position.x + rect.rect.width;
public static float MinX(this RectTransform rect) => rect.position.x;
}
diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj
index 82e5f8d..b47ef84 100644
--- a/src/UnityExplorer.csproj
+++ b/src/UnityExplorer.csproj
@@ -246,6 +246,7 @@
+