mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 22:27:45 +08:00
Implemented Interactive List/Dictionary support (todo IL2CPP)
This commit is contained in:
parent
02eca61f40
commit
41f0b0ed55
@ -105,7 +105,7 @@ The following helper methods are available:
|
|||||||
{
|
{
|
||||||
if (!m_fixwanted)
|
if (!m_fixwanted)
|
||||||
{
|
{
|
||||||
EventSystem.current.SetSelectedGameObject(CSConsolePage.Instance.m_codeEditor.InputField.gameObject, null);
|
EventSystem.current.SetSelectedGameObject(InputField.gameObject, null);
|
||||||
m_fixwanted = true;
|
m_fixwanted = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -18,7 +18,7 @@ namespace UnityExplorer.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = false)
|
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
|
||||||
{
|
{
|
||||||
var unityObj = obj as Object;
|
var unityObj = obj as Object;
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
|
@ -23,7 +23,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
Target = target;
|
Target = target;
|
||||||
|
|
||||||
if (Target.IsNullOrDestroyed())
|
if (Target.IsNullOrDestroyed(false))
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
return;
|
return;
|
||||||
@ -46,7 +46,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
public virtual void Update()
|
public virtual void Update()
|
||||||
{
|
{
|
||||||
if (Target.IsNullOrDestroyed())
|
if (Target.IsNullOrDestroyed(false))
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
return;
|
return;
|
||||||
|
@ -45,7 +45,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
#endif
|
#endif
|
||||||
UnityEngine.Object unityObj = obj as UnityEngine.Object;
|
UnityEngine.Object unityObj = obj as UnityEngine.Object;
|
||||||
|
|
||||||
if (obj.IsNullOrDestroyed())
|
if (obj.IsNullOrDestroyed(false))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,68 @@
|
|||||||
//using System;
|
using System;
|
||||||
//using System.Collections;
|
using System.Collections;
|
||||||
//using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
//using System.Linq;
|
using System.Linq;
|
||||||
//using System.Text;
|
using System.Text;
|
||||||
//using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
//namespace UnityExplorer.Inspectors.Reflection
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
//{
|
{
|
||||||
// public class CacheEnumerated : CacheObjectBase
|
public class CacheEnumerated : CacheObjectBase, INestedValue
|
||||||
// {
|
{
|
||||||
// public int Index { get; set; }
|
public override Type FallbackType => ParentEnumeration.m_baseEntryType;
|
||||||
// public IList RefIList { get; set; }
|
public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite;
|
||||||
// public InteractiveEnumerable ParentEnumeration { get; set; }
|
|
||||||
|
|
||||||
// public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite;
|
public int Index { get; set; }
|
||||||
|
public IList RefIList { get; set; }
|
||||||
|
public InteractiveEnumerable ParentEnumeration { get; set; }
|
||||||
|
|
||||||
// public override void SetValue()
|
public CacheEnumerated(int index, InteractiveEnumerable parentEnumeration, IList refIList, GameObject parentContent)
|
||||||
// {
|
{
|
||||||
// RefIList[Index] = IValue.Value;
|
this.ParentEnumeration = parentEnumeration;
|
||||||
// ParentEnumeration.Value = RefIList;
|
this.Index = index;
|
||||||
|
this.RefIList = refIList;
|
||||||
|
this.m_parentContent = parentContent;
|
||||||
|
}
|
||||||
|
|
||||||
// ParentEnumeration.OwnerCacheObject.SetValue();
|
public override void CreateIValue(object value, Type fallbackType)
|
||||||
// }
|
{
|
||||||
// }
|
IValue = InteractiveValue.Create(value, fallbackType);
|
||||||
//}
|
IValue.OwnerCacheObject = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetValue()
|
||||||
|
{
|
||||||
|
RefIList[Index] = IValue.Value;
|
||||||
|
ParentEnumeration.Value = RefIList;
|
||||||
|
|
||||||
|
ParentEnumeration.OwnerCacheObject.SetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSubcontentHeight()
|
||||||
|
{
|
||||||
|
ParentEnumeration.UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void ConstructUI()
|
||||||
|
{
|
||||||
|
base.ConstructUI();
|
||||||
|
|
||||||
|
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
|
||||||
|
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||||
|
rowGroup.padding.left = 5;
|
||||||
|
rowGroup.padding.right = 2;
|
||||||
|
|
||||||
|
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
||||||
|
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
|
||||||
|
indexLayout.minWidth = 20;
|
||||||
|
indexLayout.flexibleWidth = 30;
|
||||||
|
indexLayout.minHeight = 25;
|
||||||
|
var indexText = indexLabelObj.GetComponent<Text>();
|
||||||
|
indexText.text = this.Index + ":";
|
||||||
|
|
||||||
|
IValue.m_mainContentParent = rowObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,23 +7,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
public static class CacheFactory
|
public static class CacheFactory
|
||||||
{
|
{
|
||||||
// Don't think I need these with new structure.
|
|
||||||
// Will possibly need something for CacheEnumerated / InteractiveEnumeration though.
|
|
||||||
|
|
||||||
//public static CacheObjectBase GetCacheObject(object obj)
|
|
||||||
//{
|
|
||||||
// if (obj == null) return null;
|
|
||||||
|
|
||||||
// return GetCacheObject(obj, ReflectionHelpers.GetActualType(obj));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public static CacheObjectBase GetCacheObject(object obj, Type type)
|
|
||||||
//{
|
|
||||||
// var ret = new CacheObjectBase();
|
|
||||||
// ret.InitValue(obj, type);
|
|
||||||
// return ret;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
|
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
|
||||||
{
|
{
|
||||||
CacheMember ret;
|
CacheMember ret;
|
||||||
|
@ -12,11 +12,11 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
public override bool IsStatic => (MemInfo as FieldInfo).IsStatic;
|
public override bool IsStatic => (MemInfo as FieldInfo).IsStatic;
|
||||||
|
|
||||||
|
public override Type FallbackType => (MemInfo as FieldInfo).FieldType;
|
||||||
|
|
||||||
public CacheField(FieldInfo fieldInfo, object declaringInstance) : base(fieldInfo, declaringInstance)
|
public CacheField(FieldInfo fieldInfo, object declaringInstance) : base(fieldInfo, declaringInstance)
|
||||||
{
|
{
|
||||||
base.InitValue(null, fieldInfo.FieldType);
|
CreateIValue(null, fieldInfo.FieldType);
|
||||||
|
|
||||||
UpdateValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateReflection()
|
public override void UpdateReflection()
|
||||||
|
@ -15,35 +15,34 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
public abstract class CacheMember : CacheObjectBase
|
public abstract class CacheMember : CacheObjectBase
|
||||||
{
|
{
|
||||||
|
public override bool IsMember => true;
|
||||||
|
|
||||||
|
public override Type FallbackType { get; }
|
||||||
|
|
||||||
public MemberInfo MemInfo { get; set; }
|
public MemberInfo MemInfo { get; set; }
|
||||||
public Type DeclaringType { get; set; }
|
public Type DeclaringType { get; set; }
|
||||||
public object DeclaringInstance { get; set; }
|
public object DeclaringInstance { get; set; }
|
||||||
|
|
||||||
public virtual bool IsStatic { get; private set; }
|
public virtual bool IsStatic { get; private set; }
|
||||||
|
|
||||||
public override bool IsMember => true;
|
public string ReflectionException { get; set; }
|
||||||
|
|
||||||
public override bool HasParameters => ParamCount > 0;
|
|
||||||
public virtual int ParamCount => m_arguments.Length;
|
|
||||||
|
|
||||||
public override bool HasEvaluated => m_evaluated;
|
|
||||||
|
|
||||||
public string RichTextName => m_richTextName ?? GetRichTextName();
|
|
||||||
private string m_richTextName;
|
|
||||||
|
|
||||||
public string NameForFiltering => m_nameForFilter ?? (m_nameForFilter = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}".ToLower());
|
|
||||||
private string m_nameForFilter;
|
|
||||||
|
|
||||||
public override bool CanWrite => m_canWrite ?? GetCanWrite();
|
public override bool CanWrite => m_canWrite ?? GetCanWrite();
|
||||||
private bool? m_canWrite;
|
private bool? m_canWrite;
|
||||||
|
|
||||||
public string ReflectionException { get; set; }
|
public override bool HasParameters => ParamCount > 0;
|
||||||
|
public virtual int ParamCount => m_arguments.Length;
|
||||||
|
public override bool HasEvaluated => m_evaluated;
|
||||||
public bool m_evaluated = false;
|
public bool m_evaluated = false;
|
||||||
public bool m_isEvaluating;
|
public bool m_isEvaluating;
|
||||||
public ParameterInfo[] m_arguments = new ParameterInfo[0];
|
public ParameterInfo[] m_arguments = new ParameterInfo[0];
|
||||||
public string[] m_argumentInput = new string[0];
|
public string[] m_argumentInput = new string[0];
|
||||||
|
|
||||||
|
public string NameForFiltering => m_nameForFilter ?? (m_nameForFilter = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}".ToLower());
|
||||||
|
private string m_nameForFilter;
|
||||||
|
|
||||||
|
public string RichTextName => m_richTextName ?? GetRichTextName();
|
||||||
|
private string m_richTextName;
|
||||||
|
|
||||||
public CacheMember(MemberInfo memberInfo, object declaringInstance)
|
public CacheMember(MemberInfo memberInfo, object declaringInstance)
|
||||||
{
|
{
|
||||||
MemInfo = memberInfo;
|
MemInfo = memberInfo;
|
||||||
@ -51,6 +50,14 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
DeclaringInstance = declaringInstance;
|
DeclaringInstance = declaringInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void CreateIValue(object value, Type fallbackType)
|
||||||
|
{
|
||||||
|
IValue = InteractiveValue.Create(value, fallbackType);
|
||||||
|
IValue.OwnerCacheObject = this;
|
||||||
|
IValue.m_mainContentParent = this.m_rightGroup;
|
||||||
|
IValue.m_subContentParent = this.m_subContent;
|
||||||
|
}
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
if (!HasParameters || m_isEvaluating)
|
if (!HasParameters || m_isEvaluating)
|
||||||
@ -122,7 +129,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No input, see if there is a default value.
|
// No input, see if there is a default value.
|
||||||
if (HasDefaultValue(m_arguments[i]))
|
if (m_arguments[i].IsOptional)
|
||||||
{
|
{
|
||||||
parsedArgs.Add(m_arguments[i].DefaultValue);
|
parsedArgs.Add(m_arguments[i].DefaultValue);
|
||||||
continue;
|
continue;
|
||||||
@ -135,8 +142,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
return parsedArgs.ToArray();
|
return parsedArgs.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasDefaultValue(ParameterInfo arg) => arg.DefaultValue != DBNull.Value;
|
|
||||||
|
|
||||||
private bool GetCanWrite()
|
private bool GetCanWrite()
|
||||||
{
|
{
|
||||||
if (MemInfo is FieldInfo fi)
|
if (MemInfo is FieldInfo fi)
|
||||||
@ -159,7 +164,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var baseType = this.IValue.ValueType;
|
var baseType = ReflectionHelpers.GetActualType(IValue.Value) ?? IValue.FallbackType;
|
||||||
|
|
||||||
var gArgs = baseType.GetGenericArguments();
|
var gArgs = baseType.GetGenericArguments();
|
||||||
if (gArgs.Length < 1)
|
if (gArgs.Length < 1)
|
||||||
@ -214,13 +219,12 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
m_rightLayout.preferredWidth = valueWidth;
|
m_rightLayout.preferredWidth = valueWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal GameObject m_leftGroup;
|
|
||||||
internal GameObject m_rightGroup;
|
|
||||||
internal Text m_memLabelText;
|
|
||||||
internal RectTransform m_topRowRect;
|
internal RectTransform m_topRowRect;
|
||||||
|
internal Text m_memLabelText;
|
||||||
|
internal GameObject m_leftGroup;
|
||||||
internal LayoutElement m_leftLayout;
|
internal LayoutElement m_leftLayout;
|
||||||
|
internal GameObject m_rightGroup;
|
||||||
internal LayoutElement m_rightLayout;
|
internal LayoutElement m_rightLayout;
|
||||||
internal GameObject m_subContent;
|
|
||||||
|
|
||||||
internal override void ConstructUI()
|
internal override void ConstructUI()
|
||||||
{
|
{
|
||||||
@ -292,31 +296,15 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
rightGroup.childForceExpandWidth = false;
|
rightGroup.childForceExpandWidth = false;
|
||||||
rightGroup.childControlHeight = true;
|
rightGroup.childControlHeight = true;
|
||||||
rightGroup.childControlWidth = true;
|
rightGroup.childControlWidth = true;
|
||||||
rightGroup.spacing = 4;
|
rightGroup.spacing = 2;
|
||||||
rightGroup.padding.top = 2;
|
rightGroup.padding.top = 4;
|
||||||
rightGroup.padding.bottom = 2;
|
rightGroup.padding.bottom = 2;
|
||||||
|
|
||||||
ConstructArgInput(out GameObject argsHolder);
|
ConstructArgInput(out GameObject argsHolder);
|
||||||
|
|
||||||
ConstructEvaluateButtons(argsHolder);
|
ConstructEvaluateButtons(argsHolder);
|
||||||
|
|
||||||
// subcontent
|
IValue.m_mainContentParent = m_rightGroup;
|
||||||
|
|
||||||
m_subContent = UIFactory.CreateHorizontalGroup(m_parentContent, new Color(1, 1, 1, 0));
|
|
||||||
var subGroup = m_subContent.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
subGroup.childForceExpandWidth = true;
|
|
||||||
subGroup.childControlWidth = true;
|
|
||||||
var subLayout = m_subContent.AddComponent<LayoutElement>();
|
|
||||||
subLayout.minHeight = 50;
|
|
||||||
subLayout.flexibleHeight = 500;
|
|
||||||
subLayout.minWidth = 125;
|
|
||||||
subLayout.flexibleWidth = 9000;
|
|
||||||
|
|
||||||
m_subContent.SetActive(false);
|
|
||||||
|
|
||||||
// Construct InteractiveValue's actual UI
|
|
||||||
|
|
||||||
IValue.ConstructUI(m_rightGroup, m_subContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ConstructArgInput(out GameObject argsHolder)
|
internal void ConstructArgInput(out GameObject argsHolder)
|
||||||
@ -418,13 +406,13 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
|
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
|
||||||
evalButton.colors = colors;
|
evalButton.colors = colors;
|
||||||
|
|
||||||
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.6f, 0.3f, 0.3f));
|
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var cancelLayout = cancelButtonObj.AddComponent<LayoutElement>();
|
var cancelLayout = cancelButtonObj.AddComponent<LayoutElement>();
|
||||||
cancelLayout.minWidth = 100;
|
cancelLayout.minWidth = 100;
|
||||||
cancelLayout.minHeight = 22;
|
cancelLayout.minHeight = 22;
|
||||||
cancelLayout.flexibleWidth = 0;
|
cancelLayout.flexibleWidth = 0;
|
||||||
var cancelText = cancelButtonObj.GetComponentInChildren<Text>();
|
var cancelText = cancelButtonObj.GetComponentInChildren<Text>();
|
||||||
cancelText.text = "Cancel";
|
cancelText.text = "Close";
|
||||||
|
|
||||||
cancelButtonObj.SetActive(false);
|
cancelButtonObj.SetActive(false);
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
//private CacheObjectBase m_cachedReturnValue;
|
//private CacheObjectBase m_cachedReturnValue;
|
||||||
|
|
||||||
|
public override Type FallbackType => (MemInfo as MethodInfo).ReturnType;
|
||||||
|
|
||||||
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
|
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
|
||||||
|
|
||||||
public override bool IsStatic => (MemInfo as MethodInfo).IsStatic;
|
public override bool IsStatic => (MemInfo as MethodInfo).IsStatic;
|
||||||
@ -37,12 +39,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
m_arguments = methodInfo.GetParameters();
|
m_arguments = methodInfo.GetParameters();
|
||||||
m_argumentInput = new string[m_arguments.Length];
|
m_argumentInput = new string[m_arguments.Length];
|
||||||
|
|
||||||
base.InitValue(null, methodInfo.ReturnType);
|
CreateIValue(null, methodInfo.ReturnType);
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
|
||||||
{
|
|
||||||
base.UpdateValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateReflection()
|
public override void UpdateReflection()
|
||||||
@ -78,10 +75,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
ReflectionException = ReflectionHelpers.ExceptionToString(e);
|
ReflectionException = ReflectionHelpers.ExceptionToString(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo do InitValue again for new value, in case type changed fundamentally.
|
|
||||||
|
|
||||||
IValue.Value = ret;
|
IValue.Value = ret;
|
||||||
IValue.OnValueUpdated();
|
UpdateValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodInfo MakeGenericMethodFromInput()
|
private MethodInfo MakeGenericMethodFromInput()
|
||||||
|
@ -10,7 +10,7 @@ using UnityEngine.UI;
|
|||||||
|
|
||||||
namespace UnityExplorer.Inspectors.Reflection
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
{
|
{
|
||||||
public class CacheObjectBase
|
public abstract class CacheObjectBase
|
||||||
{
|
{
|
||||||
public InteractiveValue IValue;
|
public InteractiveValue IValue;
|
||||||
|
|
||||||
@ -19,26 +19,9 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
public virtual bool IsMember => false;
|
public virtual bool IsMember => false;
|
||||||
public virtual bool HasEvaluated => true;
|
public virtual bool HasEvaluated => true;
|
||||||
|
|
||||||
// TODO
|
public abstract Type FallbackType { get; }
|
||||||
public virtual void InitValue(object value, Type valueType)
|
|
||||||
{
|
|
||||||
if (valueType == null && value == null)
|
|
||||||
{
|
|
||||||
ExplorerCore.LogWarning("CacheObjectBase: Trying to init with no default value or valueType!");
|
|
||||||
ExplorerCore.Log(Environment.StackTrace);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// temp (havent made rest of InteractiveValue classes yet, just using base class always)
|
public abstract void CreateIValue(object value, Type fallbackType);
|
||||||
|
|
||||||
valueType = ReflectionHelpers.GetActualType(value) ?? valueType;
|
|
||||||
|
|
||||||
IValue = new InteractiveValue(valueType)
|
|
||||||
{
|
|
||||||
OwnerCacheObject = this
|
|
||||||
};
|
|
||||||
UpdateValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Enable()
|
public virtual void Enable()
|
||||||
{
|
{
|
||||||
@ -54,11 +37,31 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
public virtual void Disable()
|
public virtual void Disable()
|
||||||
{
|
{
|
||||||
m_mainContent.SetActive(false);
|
m_mainContent?.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
GameObject.Destroy(this.m_mainContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UpdateValue()
|
public virtual void UpdateValue()
|
||||||
{
|
{
|
||||||
|
var value = IValue.Value;
|
||||||
|
|
||||||
|
// see if current value has changed types fundamentally
|
||||||
|
var type = value == null
|
||||||
|
? FallbackType
|
||||||
|
: ReflectionHelpers.GetActualType(value);
|
||||||
|
var ivalueType = InteractiveValue.GetIValueForType(type);
|
||||||
|
|
||||||
|
if (ivalueType != IValue.IValueType)
|
||||||
|
{
|
||||||
|
IValue.OnDestroy();
|
||||||
|
CreateIValue(value, FallbackType);
|
||||||
|
m_subContent.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
IValue.OnValueUpdated();
|
IValue.OnValueUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +71,9 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
internal bool m_constructedUI;
|
internal bool m_constructedUI;
|
||||||
internal GameObject m_parentContent;
|
internal GameObject m_parentContent;
|
||||||
|
internal RectTransform m_mainRect;
|
||||||
internal GameObject m_mainContent;
|
internal GameObject m_mainContent;
|
||||||
|
internal GameObject m_subContent;
|
||||||
|
|
||||||
// Make base UI holder for CacheObject, this doesnt actually display anything.
|
// Make base UI holder for CacheObject, this doesnt actually display anything.
|
||||||
internal virtual void ConstructUI()
|
internal virtual void ConstructUI()
|
||||||
@ -76,16 +81,36 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
m_constructedUI = true;
|
m_constructedUI = true;
|
||||||
|
|
||||||
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f));
|
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f));
|
||||||
var rowGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
|
m_mainContent.name = "CacheObjectBase.MainContent";
|
||||||
rowGroup.childForceExpandWidth = true;
|
m_mainRect = m_mainContent.GetComponent<RectTransform>();
|
||||||
rowGroup.childControlWidth = true;
|
m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
rowGroup.childForceExpandHeight = false;
|
var mainGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
|
||||||
rowGroup.childControlHeight = true;
|
mainGroup.childForceExpandWidth = true;
|
||||||
var rowLayout = m_mainContent.AddComponent<LayoutElement>();
|
mainGroup.childControlWidth = true;
|
||||||
rowLayout.minHeight = 25;
|
mainGroup.childForceExpandHeight = true;
|
||||||
rowLayout.flexibleHeight = 500;
|
mainGroup.childControlHeight = true;
|
||||||
rowLayout.minWidth = 200;
|
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
|
||||||
rowLayout.flexibleWidth = 5000;
|
mainLayout.minHeight = 25;
|
||||||
|
mainLayout.flexibleHeight = 9999;
|
||||||
|
mainLayout.minWidth = 200;
|
||||||
|
mainLayout.flexibleWidth = 5000;
|
||||||
|
|
||||||
|
// subcontent
|
||||||
|
|
||||||
|
m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, new Color(0.085f, 0.085f, 0.085f));
|
||||||
|
m_subContent.name = "CacheObjectBase.SubContent";
|
||||||
|
var subGroup = m_subContent.GetComponent<VerticalLayoutGroup>();
|
||||||
|
subGroup.childForceExpandWidth = true;
|
||||||
|
subGroup.childForceExpandHeight = false;
|
||||||
|
var subLayout = m_subContent.AddComponent<LayoutElement>();
|
||||||
|
subLayout.minHeight = 30;
|
||||||
|
subLayout.flexibleHeight = 9999;
|
||||||
|
subLayout.minWidth = 125;
|
||||||
|
subLayout.flexibleWidth = 9000;
|
||||||
|
|
||||||
|
m_subContent.SetActive(false);
|
||||||
|
|
||||||
|
IValue.m_subContentParent = m_subContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
76
src/Inspectors/Reflection/CacheObject/CachePaired.cs
Normal file
76
src/Inspectors/Reflection/CacheObject/CachePaired.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
|
||||||
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
|
{
|
||||||
|
public enum PairTypes
|
||||||
|
{
|
||||||
|
Key,
|
||||||
|
Value
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CachePaired : CacheObjectBase, INestedValue
|
||||||
|
{
|
||||||
|
public override Type FallbackType => PairType == PairTypes.Key
|
||||||
|
? ParentDictionary.m_typeOfKeys
|
||||||
|
: ParentDictionary.m_typeofValues;
|
||||||
|
|
||||||
|
public override bool CanWrite => false; // todo?
|
||||||
|
|
||||||
|
public PairTypes PairType;
|
||||||
|
public int Index { get; private set; }
|
||||||
|
public InteractiveDictionary ParentDictionary { get; private set; }
|
||||||
|
internal IDictionary RefIDIct;
|
||||||
|
|
||||||
|
public CachePaired(int index, InteractiveDictionary parentDict, IDictionary refIDict, PairTypes pairType, GameObject parentContent)
|
||||||
|
{
|
||||||
|
Index = index;
|
||||||
|
ParentDictionary = parentDict;
|
||||||
|
RefIDIct = refIDict;
|
||||||
|
this.PairType = pairType;
|
||||||
|
this.m_parentContent = parentContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CreateIValue(object value, Type fallbackType)
|
||||||
|
{
|
||||||
|
IValue = InteractiveValue.Create(value, fallbackType);
|
||||||
|
IValue.OwnerCacheObject = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSubcontentHeight()
|
||||||
|
{
|
||||||
|
ParentDictionary.UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
internal override void ConstructUI()
|
||||||
|
{
|
||||||
|
base.ConstructUI();
|
||||||
|
|
||||||
|
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
|
||||||
|
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||||
|
rowGroup.padding.left = 5;
|
||||||
|
rowGroup.padding.right = 2;
|
||||||
|
|
||||||
|
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
||||||
|
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
|
||||||
|
indexLayout.minWidth = 80;
|
||||||
|
indexLayout.flexibleWidth = 30;
|
||||||
|
indexLayout.minHeight = 25;
|
||||||
|
var indexText = indexLabelObj.GetComponent<Text>();
|
||||||
|
indexText.text = $"{this.PairType} {this.Index}:";
|
||||||
|
|
||||||
|
IValue.m_mainContentParent = rowObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
public class CacheProperty : CacheMember
|
public class CacheProperty : CacheMember
|
||||||
{
|
{
|
||||||
|
public override Type FallbackType => (MemInfo as PropertyInfo).PropertyType;
|
||||||
|
|
||||||
public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic;
|
public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic;
|
||||||
|
|
||||||
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance) : base(propertyInfo, declaringInstance)
|
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance) : base(propertyInfo, declaringInstance)
|
||||||
@ -17,9 +19,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
this.m_arguments = propertyInfo.GetIndexParameters();
|
this.m_arguments = propertyInfo.GetIndexParameters();
|
||||||
this.m_argumentInput = new string[m_arguments.Length];
|
this.m_argumentInput = new string[m_arguments.Length];
|
||||||
|
|
||||||
base.InitValue(null, propertyInfo.PropertyType);
|
CreateIValue(null, propertyInfo.PropertyType);
|
||||||
|
|
||||||
UpdateValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateReflection()
|
public override void UpdateReflection()
|
||||||
|
12
src/Inspectors/Reflection/CacheObject/INestedValue.cs
Normal file
12
src/Inspectors/Reflection/CacheObject/INestedValue.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
|
{
|
||||||
|
public interface INestedValue
|
||||||
|
{
|
||||||
|
void UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,284 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Config;
|
||||||
|
using UnityExplorer.Helpers;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Shared;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
|
{
|
||||||
|
public class InteractiveDictionary : InteractiveValue
|
||||||
|
{
|
||||||
|
public InteractiveDictionary(object value, Type valueType) : base(value, valueType)
|
||||||
|
{
|
||||||
|
if (valueType.IsGenericType)
|
||||||
|
{
|
||||||
|
var gArgs = valueType.GetGenericArguments();
|
||||||
|
m_typeOfKeys = gArgs[0];
|
||||||
|
m_typeofValues = gArgs[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_typeOfKeys = typeof(object);
|
||||||
|
m_typeofValues = typeof(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IValueTypes IValueType => IValueTypes.Dictionary;
|
||||||
|
public override bool HasSubContent => true;
|
||||||
|
public override bool WantInspectBtn => false;
|
||||||
|
|
||||||
|
internal IDictionary RefIDictionary;
|
||||||
|
|
||||||
|
internal Type m_typeOfKeys;
|
||||||
|
internal Type m_typeofValues;
|
||||||
|
|
||||||
|
internal readonly List<KeyValuePair<CachePaired, CachePaired>> m_entries
|
||||||
|
= new List<KeyValuePair<CachePaired, CachePaired>>();
|
||||||
|
|
||||||
|
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
||||||
|
= new KeyValuePair<CachePaired, CachePaired>[ModConfig.Instance.Default_Page_Limit];
|
||||||
|
|
||||||
|
//internal readonly List<CacheKeyValuePair> m_entries = new List<CacheKeyValuePair>();
|
||||||
|
//internal CacheKeyValuePair[] m_displayedEntries = new CacheKeyValuePair[ModConfig.Instance.Default_Page_Limit];
|
||||||
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
base.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnValueUpdated()
|
||||||
|
{
|
||||||
|
base.OnValueUpdated();
|
||||||
|
|
||||||
|
if (!Value.IsNullOrDestroyed())
|
||||||
|
{
|
||||||
|
RefIDictionary = Value as IDictionary;
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_baseLabel.text = base.GetLabelForValue();
|
||||||
|
RefIDictionary = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_subContentParent.activeSelf)
|
||||||
|
{
|
||||||
|
GetCacheEntries();
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_recacheWanted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void OnPageTurned()
|
||||||
|
{
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UpdateLabel()
|
||||||
|
{
|
||||||
|
string count = "?";
|
||||||
|
if (m_recacheWanted && RefIDictionary != null)
|
||||||
|
count = RefIDictionary.Count.ToString();
|
||||||
|
else if (!m_recacheWanted)
|
||||||
|
count = m_entries.Count.ToString();
|
||||||
|
|
||||||
|
m_baseLabel.text = $"[{count}] {m_richValueType}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetCacheEntries()
|
||||||
|
{
|
||||||
|
if (m_entries.Any())
|
||||||
|
{
|
||||||
|
// maybe improve this, probably could be more efficient i guess
|
||||||
|
|
||||||
|
foreach (var pair in m_entries)
|
||||||
|
{
|
||||||
|
pair.Key.Destroy();
|
||||||
|
pair.Value.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_entries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RefIDictionary != null)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (var key in RefIDictionary.Keys)
|
||||||
|
{
|
||||||
|
var value = RefIDictionary[key];
|
||||||
|
|
||||||
|
//if (index >= m_rowHolders.Count)
|
||||||
|
//{
|
||||||
|
// AddRowHolder();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//var holder = m_rowHolders[index];
|
||||||
|
|
||||||
|
var cacheKey = new CachePaired(index, this, this.RefIDictionary, PairTypes.Key, m_listContent);
|
||||||
|
cacheKey.CreateIValue(key, this.m_typeOfKeys);
|
||||||
|
cacheKey.Disable();
|
||||||
|
|
||||||
|
var cacheValue = new CachePaired(index, this, this.RefIDictionary, PairTypes.Value, m_listContent);
|
||||||
|
cacheValue.CreateIValue(value, this.m_typeofValues);
|
||||||
|
cacheValue.Disable();
|
||||||
|
|
||||||
|
//holder.SetActive(false);
|
||||||
|
|
||||||
|
m_entries.Add(new KeyValuePair<CachePaired, CachePaired>(cacheKey, cacheValue));
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshDisplay()
|
||||||
|
{
|
||||||
|
var entries = m_entries;
|
||||||
|
m_pageHandler.ListCount = entries.Count;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_displayedEntries.Length; i++)
|
||||||
|
{
|
||||||
|
var entry = m_displayedEntries[i];
|
||||||
|
if (entry.Key != null && entry.Value != null)
|
||||||
|
{
|
||||||
|
//m_rowHolders[i].SetActive(false);
|
||||||
|
entry.Key.Disable();
|
||||||
|
entry.Value.Disable();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries.Count < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var itemIndex in m_pageHandler)
|
||||||
|
{
|
||||||
|
if (itemIndex >= entries.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var entry = entries[itemIndex];
|
||||||
|
m_displayedEntries[itemIndex - m_pageHandler.StartIndex] = entry;
|
||||||
|
|
||||||
|
//m_rowHolders[itemIndex].SetActive(true);
|
||||||
|
entry.Key.Enable();
|
||||||
|
entry.Value.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void OnToggleSubcontent(bool active)
|
||||||
|
{
|
||||||
|
base.OnToggleSubcontent(active);
|
||||||
|
|
||||||
|
if (active && m_recacheWanted)
|
||||||
|
{
|
||||||
|
m_recacheWanted = false;
|
||||||
|
GetCacheEntries();
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSubcontentHeight()
|
||||||
|
{
|
||||||
|
Canvas.ForceUpdateCanvases();
|
||||||
|
|
||||||
|
float totalHeight = 0f;
|
||||||
|
if (m_subContentParent.activeSelf)
|
||||||
|
{
|
||||||
|
foreach (var itemIndex in m_pageHandler)
|
||||||
|
{
|
||||||
|
if (itemIndex >= m_entries.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var entry = m_entries[itemIndex];
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Key.m_mainRect);
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Value.m_mainRect);
|
||||||
|
|
||||||
|
totalHeight += Mathf.Max(entry.Key.m_mainRect.rect.height, entry.Value.m_mainRect.rect.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
|
||||||
|
//m_mainLayout.minHeight = totalHeight;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
|
||||||
|
|
||||||
|
if (OwnerCacheObject is INestedValue nestedValue)
|
||||||
|
{
|
||||||
|
// nested enumerable
|
||||||
|
nestedValue.UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
internal GameObject m_listContent;
|
||||||
|
internal LayoutElement m_listLayout;
|
||||||
|
|
||||||
|
internal PageHandler m_pageHandler;
|
||||||
|
|
||||||
|
//internal List<GameObject> m_rowHolders = new List<GameObject>();
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||||
|
{
|
||||||
|
base.ConstructUI(parent, subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConstructSubcontent()
|
||||||
|
{
|
||||||
|
base.ConstructSubcontent();
|
||||||
|
|
||||||
|
m_pageHandler = new PageHandler(null);
|
||||||
|
m_pageHandler.ConstructUI(m_subContentParent);
|
||||||
|
m_pageHandler.OnPageChanged += OnPageTurned;
|
||||||
|
|
||||||
|
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
m_listContent = scrollObj;
|
||||||
|
|
||||||
|
var scrollRect = scrollObj.GetComponent<RectTransform>();
|
||||||
|
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
||||||
|
|
||||||
|
m_listLayout = OwnerCacheObject.m_mainContent.GetComponent<LayoutElement>();
|
||||||
|
m_listLayout.minHeight = 25;
|
||||||
|
m_listLayout.flexibleHeight = 0;
|
||||||
|
OwnerCacheObject.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
|
||||||
|
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
|
||||||
|
scrollGroup.childForceExpandHeight = true;
|
||||||
|
scrollGroup.childControlHeight = true;
|
||||||
|
scrollGroup.spacing = 2;
|
||||||
|
scrollGroup.padding.top = 5;
|
||||||
|
scrollGroup.padding.left = 5;
|
||||||
|
scrollGroup.padding.right = 5;
|
||||||
|
scrollGroup.padding.bottom = 5;
|
||||||
|
|
||||||
|
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
|
||||||
|
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||||
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//internal void AddRowHolder()
|
||||||
|
//{
|
||||||
|
// var obj = UIFactory.CreateHorizontalGroup(m_listContent, new Color(0.15f, 0.15f, 0.15f));
|
||||||
|
|
||||||
|
// m_rowHolders.Add(obj);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,234 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Config;
|
||||||
|
using UnityExplorer.Helpers;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Shared;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
|
{
|
||||||
|
public class InteractiveEnumerable : InteractiveValue
|
||||||
|
{
|
||||||
|
public InteractiveEnumerable(object value, Type valueType) : base(value, valueType)
|
||||||
|
{
|
||||||
|
if (valueType.IsGenericType)
|
||||||
|
m_baseEntryType = valueType.GetGenericArguments()[0];
|
||||||
|
else
|
||||||
|
m_baseEntryType = typeof(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IValueTypes IValueType => IValueTypes.Enumerable;
|
||||||
|
|
||||||
|
public override bool HasSubContent => true;
|
||||||
|
public override bool WantInspectBtn => false;
|
||||||
|
|
||||||
|
internal IEnumerable RefIEnumerable;
|
||||||
|
internal IList RefIList;
|
||||||
|
|
||||||
|
internal readonly Type m_baseEntryType;
|
||||||
|
|
||||||
|
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
|
||||||
|
internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ModConfig.Instance.Default_Page_Limit];
|
||||||
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
|
public override void OnValueUpdated()
|
||||||
|
{
|
||||||
|
base.OnValueUpdated();
|
||||||
|
|
||||||
|
if (!Value.IsNullOrDestroyed())
|
||||||
|
{
|
||||||
|
RefIEnumerable = Value as IEnumerable; // todo il2cpp
|
||||||
|
RefIList = Value as IList;
|
||||||
|
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_baseLabel.text = base.GetLabelForValue();
|
||||||
|
|
||||||
|
RefIEnumerable = null;
|
||||||
|
RefIList = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_subContentParent.activeSelf)
|
||||||
|
{
|
||||||
|
GetCacheEntries();
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_recacheWanted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPageTurned()
|
||||||
|
{
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UpdateLabel()
|
||||||
|
{
|
||||||
|
string count = "?";
|
||||||
|
if (m_recacheWanted && RefIList != null)
|
||||||
|
count = RefIList.Count.ToString();
|
||||||
|
else if (!m_recacheWanted)
|
||||||
|
count = m_entries.Count.ToString();
|
||||||
|
|
||||||
|
m_baseLabel.text = $"[{count}] {m_richValueType}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetCacheEntries()
|
||||||
|
{
|
||||||
|
if (m_entries.Any())
|
||||||
|
{
|
||||||
|
// maybe improve this, probably could be more efficient i guess
|
||||||
|
|
||||||
|
foreach (var entry in m_entries)
|
||||||
|
entry.Destroy();
|
||||||
|
|
||||||
|
m_entries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RefIEnumerable != null)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var entry in RefIEnumerable)
|
||||||
|
{
|
||||||
|
var cache = new CacheEnumerated(index, this, RefIList, this.m_listContent);
|
||||||
|
cache.CreateIValue(entry, m_baseEntryType);
|
||||||
|
m_entries.Add(cache);
|
||||||
|
|
||||||
|
cache.Disable();
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshDisplay()
|
||||||
|
{
|
||||||
|
var entries = m_entries;
|
||||||
|
m_pageHandler.ListCount = entries.Count;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_displayedEntries.Length; i++)
|
||||||
|
{
|
||||||
|
var entry = m_displayedEntries[i];
|
||||||
|
if (entry != null)
|
||||||
|
entry.Disable();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries.Count < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var itemIndex in m_pageHandler)
|
||||||
|
{
|
||||||
|
if (itemIndex >= entries.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CacheEnumerated entry = entries[itemIndex];
|
||||||
|
m_displayedEntries[itemIndex - m_pageHandler.StartIndex] = entry;
|
||||||
|
entry.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void OnToggleSubcontent(bool active)
|
||||||
|
{
|
||||||
|
base.OnToggleSubcontent(active);
|
||||||
|
|
||||||
|
if (active && m_recacheWanted)
|
||||||
|
{
|
||||||
|
m_recacheWanted = false;
|
||||||
|
GetCacheEntries();
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSubcontentHeight()
|
||||||
|
{
|
||||||
|
Canvas.ForceUpdateCanvases();
|
||||||
|
|
||||||
|
float totalHeight = 0f;
|
||||||
|
if (m_subContentParent.activeSelf)
|
||||||
|
{
|
||||||
|
foreach (var itemIndex in m_pageHandler)
|
||||||
|
{
|
||||||
|
if (itemIndex >= m_entries.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var entry = m_entries[itemIndex];
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.m_mainRect);
|
||||||
|
totalHeight += entry.m_mainRect.rect.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
|
||||||
|
//m_mainLayout.minHeight = totalHeight;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
|
||||||
|
|
||||||
|
if (OwnerCacheObject is INestedValue nestedValue)
|
||||||
|
{
|
||||||
|
// nested enumerable
|
||||||
|
nestedValue.UpdateSubcontentHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
internal GameObject m_listContent;
|
||||||
|
internal LayoutElement m_listLayout;
|
||||||
|
|
||||||
|
internal PageHandler m_pageHandler;
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||||
|
{
|
||||||
|
base.ConstructUI(parent, subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConstructSubcontent()
|
||||||
|
{
|
||||||
|
base.ConstructSubcontent();
|
||||||
|
|
||||||
|
m_pageHandler = new PageHandler(null);
|
||||||
|
m_pageHandler.ConstructUI(m_subContentParent);
|
||||||
|
m_pageHandler.OnPageChanged += OnPageTurned;
|
||||||
|
|
||||||
|
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
m_listContent = scrollObj;
|
||||||
|
|
||||||
|
var scrollRect = scrollObj.GetComponent<RectTransform>();
|
||||||
|
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
||||||
|
|
||||||
|
m_listLayout = OwnerCacheObject.m_mainContent.GetComponent<LayoutElement>();
|
||||||
|
m_listLayout.minHeight = 25;
|
||||||
|
m_listLayout.flexibleHeight = 0;
|
||||||
|
OwnerCacheObject.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
|
||||||
|
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
|
||||||
|
scrollGroup.childForceExpandHeight = true;
|
||||||
|
scrollGroup.childControlHeight = true;
|
||||||
|
scrollGroup.spacing = 2;
|
||||||
|
scrollGroup.padding.top = 5;
|
||||||
|
scrollGroup.padding.left = 5;
|
||||||
|
scrollGroup.padding.right = 5;
|
||||||
|
scrollGroup.padding.bottom = 5;
|
||||||
|
|
||||||
|
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
|
||||||
|
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||||
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -10,20 +10,66 @@ using UnityExplorer.UI;
|
|||||||
|
|
||||||
namespace UnityExplorer.Inspectors.Reflection
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
{
|
{
|
||||||
|
// WIP
|
||||||
|
public enum IValueTypes
|
||||||
|
{
|
||||||
|
Any,
|
||||||
|
Enumerable,
|
||||||
|
Dictionary,
|
||||||
|
}
|
||||||
|
|
||||||
public class InteractiveValue
|
public class InteractiveValue
|
||||||
{
|
{
|
||||||
public InteractiveValue(Type valueType)
|
// ~~~~~~~~~ Static ~~~~~~~~~
|
||||||
|
|
||||||
|
// WIP
|
||||||
|
internal static Dictionary<IValueTypes, Type> s_typeDict = new Dictionary<IValueTypes, Type>
|
||||||
{
|
{
|
||||||
this.ValueType = valueType;
|
{ IValueTypes.Any, typeof(InteractiveValue) },
|
||||||
|
{ IValueTypes.Dictionary, typeof(InteractiveDictionary) },
|
||||||
|
{ IValueTypes.Enumerable, typeof(InteractiveEnumerable) },
|
||||||
|
};
|
||||||
|
|
||||||
|
// WIP
|
||||||
|
public static IValueTypes GetIValueForType(Type type)
|
||||||
|
{
|
||||||
|
if (type.IsPrimitive || type == typeof(string))
|
||||||
|
return IValueTypes.Any; // TODO Primitive
|
||||||
|
else if (typeof(Transform).IsAssignableFrom(type))
|
||||||
|
return IValueTypes.Any; // TODO Transform
|
||||||
|
else if (ReflectionHelpers.IsDictionary(type))
|
||||||
|
return IValueTypes.Dictionary;
|
||||||
|
else if (ReflectionHelpers.IsEnumerable(type))
|
||||||
|
return IValueTypes.Enumerable;
|
||||||
|
else
|
||||||
|
return IValueTypes.Any;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InteractiveValue Create(object value, Type fallbackType)
|
||||||
|
{
|
||||||
|
var type = ReflectionHelpers.GetActualType(value) ?? fallbackType;
|
||||||
|
var iType = GetIValueForType(type);
|
||||||
|
|
||||||
|
return (InteractiveValue)Activator.CreateInstance(s_typeDict[iType], new object[] { value, type });
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~ Instance ~~~~~~~~~
|
||||||
|
|
||||||
|
public InteractiveValue(object value, Type valueType)
|
||||||
|
{
|
||||||
|
this.Value = value;
|
||||||
|
this.FallbackType = valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheObjectBase OwnerCacheObject;
|
public CacheObjectBase OwnerCacheObject;
|
||||||
|
|
||||||
public object Value { get; set; }
|
public object Value { get; set; }
|
||||||
public readonly Type ValueType;
|
public readonly Type FallbackType;
|
||||||
|
|
||||||
|
public virtual IValueTypes IValueType => IValueTypes.Any;
|
||||||
|
|
||||||
// might not need
|
|
||||||
public virtual bool HasSubContent => false;
|
public virtual bool HasSubContent => false;
|
||||||
|
public virtual bool WantInspectBtn => true;
|
||||||
|
|
||||||
public string RichTextValue => m_richValue ?? GetLabelForValue();
|
public string RichTextValue => m_richValue ?? GetLabelForValue();
|
||||||
internal string m_richValue;
|
internal string m_richValue;
|
||||||
@ -32,42 +78,100 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
public MethodInfo ToStringMethod => m_toStringMethod ?? GetToStringMethod();
|
public MethodInfo ToStringMethod => m_toStringMethod ?? GetToStringMethod();
|
||||||
internal MethodInfo m_toStringMethod;
|
internal MethodInfo m_toStringMethod;
|
||||||
|
|
||||||
public virtual void Init()
|
public bool m_UIConstructed;
|
||||||
|
|
||||||
|
public virtual void OnDestroy()
|
||||||
{
|
{
|
||||||
OnValueUpdated();
|
if (this.m_valueContent)
|
||||||
|
{
|
||||||
|
m_valueContent.transform.SetParent(null, false);
|
||||||
|
m_valueContent.SetActive(false);
|
||||||
|
GameObject.Destroy(this.m_valueContent.gameObject);
|
||||||
|
|
||||||
|
//if (OwnerCacheObject.m_subContent)
|
||||||
|
//{
|
||||||
|
// var subTrans = this.OwnerCacheObject.m_subContent.transform;
|
||||||
|
// for (int i = subTrans.childCount - 1; i >= 0; i--)
|
||||||
|
// {
|
||||||
|
// var child = subTrans.GetChild(i);
|
||||||
|
// GameObject.Destroy(child.gameObject);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnValueUpdated()
|
public virtual void OnValueUpdated()
|
||||||
{
|
{
|
||||||
if (!m_text)
|
if (!m_UIConstructed)
|
||||||
return;
|
ConstructUI(m_mainContentParent, m_subContentParent);
|
||||||
|
|
||||||
if (OwnerCacheObject is CacheMember ownerMember && !string.IsNullOrEmpty(ownerMember.ReflectionException))
|
if (OwnerCacheObject is CacheMember ownerMember && !string.IsNullOrEmpty(ownerMember.ReflectionException))
|
||||||
{
|
{
|
||||||
m_text.text = "<color=red>" + ownerMember.ReflectionException + "</color>";
|
m_baseLabel.text = "<color=red>" + ownerMember.ReflectionException + "</color>";
|
||||||
Value = null;
|
Value = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetLabelForValue();
|
GetLabelForValue();
|
||||||
m_text.text = RichTextValue;
|
m_baseLabel.text = RichTextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldShowInspect = !Value.IsNullOrDestroyed(true);
|
bool shouldShowBtns = !Value.IsNullOrDestroyed();
|
||||||
if (m_inspectButton.activeSelf != shouldShowInspect)
|
|
||||||
m_inspectButton.SetActive(shouldShowInspect);
|
if (WantInspectBtn && m_inspectButton.activeSelf != shouldShowBtns)
|
||||||
|
m_inspectButton.SetActive(shouldShowBtns);
|
||||||
|
|
||||||
|
if (HasSubContent)
|
||||||
|
{
|
||||||
|
if (m_subExpandBtn.gameObject.activeSelf != shouldShowBtns)
|
||||||
|
m_subExpandBtn.gameObject.SetActive(shouldShowBtns);
|
||||||
|
|
||||||
|
if (!shouldShowBtns && m_subContentParent.activeSelf)
|
||||||
|
ToggleSubcontent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ConstructSubcontent()
|
||||||
|
{
|
||||||
|
m_subContentConstructed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleSubcontent()
|
||||||
|
{
|
||||||
|
if (!this.m_subContentParent.activeSelf)
|
||||||
|
{
|
||||||
|
this.m_subContentParent.SetActive(true);
|
||||||
|
this.m_subContentParent.transform.SetAsLastSibling();
|
||||||
|
m_subExpandBtn.GetComponentInChildren<Text>().text = "▼";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.m_subContentParent.SetActive(false);
|
||||||
|
m_subExpandBtn.GetComponentInChildren<Text>().text = "▲";
|
||||||
|
}
|
||||||
|
|
||||||
|
OnToggleSubcontent(m_subContentParent.activeSelf);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal virtual void OnToggleSubcontent(bool toggle)
|
||||||
|
{
|
||||||
|
if (!m_subContentConstructed)
|
||||||
|
ConstructSubcontent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLabelForValue()
|
public string GetLabelForValue()
|
||||||
{
|
{
|
||||||
var valueType = Value?.GetType() ?? this.ValueType;
|
var valueType = Value?.GetType() ?? this.FallbackType;
|
||||||
|
|
||||||
m_richValueType = UISyntaxHighlight.ParseFullSyntax(valueType, true);
|
m_richValueType = UISyntaxHighlight.ParseFullSyntax(valueType, true);
|
||||||
|
|
||||||
if (OwnerCacheObject is CacheMember cm && !cm.HasEvaluated)
|
if (OwnerCacheObject is CacheMember cm && !cm.HasEvaluated)
|
||||||
return $"<i><color=grey>Not yet evaluated</color> ({m_richValueType})</i>";
|
return $"<i><color=grey>Not yet evaluated</color> ({m_richValueType})</i>";
|
||||||
|
|
||||||
if (Value == null) return $"<color=grey>null</color> ({m_richValueType})";
|
if (Value.IsNullOrDestroyed())
|
||||||
|
{
|
||||||
|
return $"<color=grey>null</color> ({m_richValueType})";
|
||||||
|
}
|
||||||
|
|
||||||
string label;
|
string label;
|
||||||
|
|
||||||
@ -135,31 +239,58 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
#region UI CONSTRUCTION
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
internal GameObject m_mainContent;
|
internal GameObject m_mainContentParent;
|
||||||
internal GameObject m_inspectButton;
|
|
||||||
internal Text m_text;
|
|
||||||
internal GameObject m_subContentParent;
|
internal GameObject m_subContentParent;
|
||||||
|
|
||||||
|
internal GameObject m_valueContent;
|
||||||
|
internal GameObject m_inspectButton;
|
||||||
|
internal Text m_baseLabel;
|
||||||
|
|
||||||
|
internal Button m_subExpandBtn;
|
||||||
|
internal bool m_subContentConstructed;
|
||||||
|
|
||||||
public virtual void ConstructUI(GameObject parent, GameObject subGroup)
|
public virtual void ConstructUI(GameObject parent, GameObject subGroup)
|
||||||
{
|
{
|
||||||
m_mainContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
m_UIConstructed = true;
|
||||||
var mainGroup = m_mainContent.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
m_valueContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
||||||
|
m_valueContent.name = "InteractiveValue.ValueContent";
|
||||||
|
var mainRect = m_valueContent.GetComponent<RectTransform>();
|
||||||
|
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
var mainGroup = m_valueContent.GetComponent<HorizontalLayoutGroup>();
|
||||||
|
mainGroup.childForceExpandWidth = false;
|
||||||
mainGroup.childControlWidth = true;
|
mainGroup.childControlWidth = true;
|
||||||
mainGroup.childForceExpandHeight = false;
|
mainGroup.childForceExpandHeight = false;
|
||||||
mainGroup.childControlHeight = true;
|
mainGroup.childControlHeight = true;
|
||||||
mainGroup.spacing = 4;
|
mainGroup.spacing = 4;
|
||||||
mainGroup.childAlignment = TextAnchor.UpperLeft;
|
mainGroup.childAlignment = TextAnchor.UpperLeft;
|
||||||
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
|
var mainLayout = m_valueContent.AddComponent<LayoutElement>();
|
||||||
mainLayout.flexibleWidth = 9000;
|
mainLayout.flexibleWidth = 9000;
|
||||||
mainLayout.minWidth = 175;
|
mainLayout.minWidth = 175;
|
||||||
mainLayout.minHeight = 25;
|
mainLayout.minHeight = 25;
|
||||||
mainLayout.flexibleHeight = 0;
|
mainLayout.flexibleHeight = 0;
|
||||||
|
|
||||||
|
// subcontent expand button TODO
|
||||||
|
if (HasSubContent)
|
||||||
|
{
|
||||||
|
var subBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f));
|
||||||
|
var btnLayout = subBtnObj.AddComponent<LayoutElement>();
|
||||||
|
btnLayout.minHeight = 25;
|
||||||
|
btnLayout.minWidth = 25;
|
||||||
|
btnLayout.flexibleWidth = 0;
|
||||||
|
btnLayout.flexibleHeight = 0;
|
||||||
|
var btnText = subBtnObj.GetComponentInChildren<Text>();
|
||||||
|
btnText.text = "▲";
|
||||||
|
m_subExpandBtn = subBtnObj.GetComponent<Button>();
|
||||||
|
m_subExpandBtn.onClick.AddListener(() =>
|
||||||
|
{
|
||||||
|
ToggleSubcontent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// inspect button
|
// inspect button
|
||||||
|
|
||||||
m_inspectButton = UIFactory.CreateButton(m_mainContent, new Color(0.3f, 0.3f, 0.3f, 0.2f));
|
m_inspectButton = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f, 0.2f));
|
||||||
var inspectLayout = m_inspectButton.AddComponent<LayoutElement>();
|
var inspectLayout = m_inspectButton.AddComponent<LayoutElement>();
|
||||||
inspectLayout.minWidth = 60;
|
inspectLayout.minWidth = 60;
|
||||||
inspectLayout.minHeight = 25;
|
inspectLayout.minHeight = 25;
|
||||||
@ -172,16 +303,16 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
inspectBtn.onClick.AddListener(OnInspectClicked);
|
inspectBtn.onClick.AddListener(OnInspectClicked);
|
||||||
void OnInspectClicked()
|
void OnInspectClicked()
|
||||||
{
|
{
|
||||||
if (!Value.IsNullOrDestroyed())
|
if (!Value.IsNullOrDestroyed(false))
|
||||||
InspectorManager.Instance.Inspect(this.Value);
|
InspectorManager.Instance.Inspect(this.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inspectButton.SetActive(false);
|
m_inspectButton.SetActive(false);
|
||||||
|
|
||||||
// value label / tostring
|
// value label
|
||||||
|
|
||||||
var labelObj = UIFactory.CreateLabel(m_mainContent, TextAnchor.MiddleLeft);
|
var labelObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft);
|
||||||
m_text = labelObj.GetComponent<Text>();
|
m_baseLabel = labelObj.GetComponent<Text>();
|
||||||
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
||||||
labelLayout.flexibleWidth = 9000;
|
labelLayout.flexibleWidth = 9000;
|
||||||
labelLayout.minHeight = 25;
|
labelLayout.minHeight = 25;
|
||||||
|
@ -13,10 +13,6 @@ using UnityExplorer.Config;
|
|||||||
|
|
||||||
namespace UnityExplorer.Inspectors
|
namespace UnityExplorer.Inspectors
|
||||||
{
|
{
|
||||||
// TODO:
|
|
||||||
// - Filters
|
|
||||||
// - Helper tools for Target object (for UnityEngine.Objects, Components, Textures, and maybe a general ToString helper)
|
|
||||||
|
|
||||||
public class ReflectionInspector : InspectorBase
|
public class ReflectionInspector : InspectorBase
|
||||||
{
|
{
|
||||||
#region STATIC
|
#region STATIC
|
||||||
@ -95,8 +91,6 @@ namespace UnityExplorer.Inspectors
|
|||||||
internal bool m_widthUpdateWanted;
|
internal bool m_widthUpdateWanted;
|
||||||
internal bool m_widthUpdateWaiting;
|
internal bool m_widthUpdateWaiting;
|
||||||
|
|
||||||
// Ctor
|
|
||||||
|
|
||||||
public ReflectionInspector(object target) : base(target)
|
public ReflectionInspector(object target) : base(target)
|
||||||
{
|
{
|
||||||
if (this is StaticInspector)
|
if (this is StaticInspector)
|
||||||
@ -113,8 +107,6 @@ namespace UnityExplorer.Inspectors
|
|||||||
FilterMembers();
|
FilterMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods
|
|
||||||
|
|
||||||
public override void SetActive()
|
public override void SetActive()
|
||||||
{
|
{
|
||||||
base.SetActive();
|
base.SetActive();
|
||||||
@ -310,14 +302,14 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
|
||||||
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
|
||||||
|
|
||||||
// make sure member type is Field, Method or Property (4 / 8 / 16)
|
// make sure member type is Field, Method or Property (4 / 8 / 16)
|
||||||
int m = (int)member.MemberType;
|
int m = (int)member.MemberType;
|
||||||
if (m < 4 || m > 16)
|
if (m < 4 || m > 16)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||||
|
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
||||||
|
|
||||||
var pi = member as PropertyInfo;
|
var pi = member as PropertyInfo;
|
||||||
var mi = member as MethodInfo;
|
var mi = member as MethodInfo;
|
||||||
|
|
||||||
@ -338,28 +330,20 @@ namespace UnityExplorer.Inspectors
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
{
|
|
||||||
AppendParams(mi.GetParameters());
|
AppendParams(mi.GetParameters());
|
||||||
}
|
|
||||||
else if (pi != null)
|
else if (pi != null)
|
||||||
{
|
|
||||||
AppendParams(pi.GetIndexParameters());
|
AppendParams(pi.GetIndexParameters());
|
||||||
}
|
|
||||||
|
|
||||||
void AppendParams(ParameterInfo[] _args)
|
void AppendParams(ParameterInfo[] _args)
|
||||||
{
|
{
|
||||||
sig += " (";
|
sig += " (";
|
||||||
foreach (var param in _args)
|
foreach (var param in _args)
|
||||||
{
|
|
||||||
sig += $"{param.ParameterType.Name} {param.Name}, ";
|
sig += $"{param.ParameterType.Name} {param.Name}, ";
|
||||||
}
|
|
||||||
sig += ")";
|
sig += ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedSigs.Contains(sig))
|
if (cachedSigs.Contains(sig))
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -385,10 +369,18 @@ namespace UnityExplorer.Inspectors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var typeList = types.ToList();
|
||||||
|
|
||||||
var sorted = new List<CacheMember>();
|
var sorted = new List<CacheMember>();
|
||||||
sorted.AddRange(list.Where(x => x is CacheMethod));
|
sorted.AddRange(list.Where(it => it is CacheMethod)
|
||||||
sorted.AddRange(list.Where(x => x is CacheProperty));
|
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||||
sorted.AddRange(list.Where(x => x is CacheField));
|
.ThenBy(it => it.NameForFiltering));
|
||||||
|
sorted.AddRange(list.Where(it => it is CacheProperty)
|
||||||
|
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||||
|
.ThenBy(it => it.NameForFiltering));
|
||||||
|
sorted.AddRange(list.Where(it => it is CacheField)
|
||||||
|
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||||
|
.ThenBy(it => it.NameForFiltering));
|
||||||
|
|
||||||
m_allMembers = sorted.ToArray();
|
m_allMembers = sorted.ToArray();
|
||||||
|
|
||||||
@ -623,6 +615,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
scrollGroup.spacing = 3;
|
scrollGroup.spacing = 3;
|
||||||
scrollGroup.padding.left = 0;
|
scrollGroup.padding.left = 0;
|
||||||
scrollGroup.padding.right = 0;
|
scrollGroup.padding.right = 0;
|
||||||
|
scrollGroup.childForceExpandHeight = true;
|
||||||
|
|
||||||
m_pageHandler = new PageHandler(m_sliderScroller);
|
m_pageHandler = new PageHandler(m_sliderScroller);
|
||||||
m_pageHandler.ConstructUI(Content);
|
m_pageHandler.ConstructUI(Content);
|
||||||
|
@ -26,27 +26,71 @@ namespace UnityExplorer.Tests
|
|||||||
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
||||||
private static TestClass m_instance;
|
private static TestClass m_instance;
|
||||||
|
|
||||||
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
|
public Dictionary<string, List<string>> AComboTest = new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"key",
|
||||||
|
new List<string>
|
||||||
|
{
|
||||||
|
"1",
|
||||||
|
"2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public object AmbigObject;
|
||||||
|
|
||||||
|
public List<List<List<string>>> ANestedNestedList = new List<List<List<string>>>
|
||||||
|
{
|
||||||
|
new List<List<string>>
|
||||||
|
{
|
||||||
|
new List<string>
|
||||||
|
{
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
},
|
||||||
|
new List<string>
|
||||||
|
{
|
||||||
|
"three",
|
||||||
|
"four"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new List<List<string>>
|
||||||
|
{
|
||||||
|
new List<string>
|
||||||
|
{
|
||||||
|
"five",
|
||||||
|
"six"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static bool SetOnlyProperty
|
public static bool SetOnlyProperty
|
||||||
{
|
{
|
||||||
set => m_setOnlyProperty = value;
|
set => m_setOnlyProperty = value;
|
||||||
}
|
}
|
||||||
private static bool m_setOnlyProperty;
|
private static bool m_setOnlyProperty;
|
||||||
|
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
|
||||||
|
|
||||||
public Texture TestTexture;
|
public Texture TestTexture;
|
||||||
public static Sprite TestSprite;
|
public static Sprite TestSprite;
|
||||||
|
|
||||||
public static int StaticProperty => 5;
|
|
||||||
public static int StaticField = 5;
|
|
||||||
public int NonStaticField;
|
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest;
|
public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public TestClass()
|
public TestClass()
|
||||||
{
|
{
|
||||||
|
int a = 0;
|
||||||
|
foreach (var list in ANestedNestedList)
|
||||||
|
{
|
||||||
|
foreach (var list2 in list)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
list2.Add(a++.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
TestTexture = UIManager.MakeSolidTexture(Color.white, 200, 200);
|
TestTexture = UIManager.MakeSolidTexture(Color.white, 200, 200);
|
||||||
TestTexture.name = "TestTexture";
|
TestTexture.name = "TestTexture";
|
||||||
|
@ -27,7 +27,7 @@ namespace UnityExplorer.UI.Shared
|
|||||||
|
|
||||||
public event Action OnPageChanged;
|
public event Action OnPageChanged;
|
||||||
|
|
||||||
private SliderScrollbar m_scrollbar;
|
private readonly SliderScrollbar m_scrollbar;
|
||||||
|
|
||||||
// For now this is just set when the PageHandler is created, based on config.
|
// For now this is just set when the PageHandler is created, based on config.
|
||||||
// At some point I might make it possible to change this after creation again.
|
// At some point I might make it possible to change this after creation again.
|
||||||
@ -147,7 +147,9 @@ namespace UnityExplorer.UI.Shared
|
|||||||
}
|
}
|
||||||
if (didTurn)
|
if (didTurn)
|
||||||
{
|
{
|
||||||
|
if (m_scrollbar != null)
|
||||||
m_scrollbar.m_scrollbar.value = 1;
|
m_scrollbar.m_scrollbar.value = 1;
|
||||||
|
|
||||||
OnPageChanged?.Invoke();
|
OnPageChanged?.Invoke();
|
||||||
RefreshUI();
|
RefreshUI();
|
||||||
}
|
}
|
||||||
|
71
src/UI/Shared/ScrollRectEx.cs
Normal file
71
src/UI/Shared/ScrollRectEx.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//using UnityEngine;
|
||||||
|
//using System.Collections;
|
||||||
|
//using UnityEngine.UI;
|
||||||
|
//using System;
|
||||||
|
//using UnityEngine.EventSystems;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////// kinda works, not really
|
||||||
|
|
||||||
|
|
||||||
|
//public class ScrollRectEx : ScrollRect, IEventSystemHandler
|
||||||
|
//{
|
||||||
|
// internal SliderScrollbar sliderScrollbar;
|
||||||
|
|
||||||
|
// private bool ShouldRouteToParent(PointerEventData data)
|
||||||
|
// => !sliderScrollbar.IsActive
|
||||||
|
// || sliderScrollbar.m_slider.value < 0.001f && data.delta.y > 0
|
||||||
|
// || sliderScrollbar.m_slider.value == 1f && data.delta.y < 0;
|
||||||
|
|
||||||
|
// private void DoForParents<T>(Action<T> action) where T : IEventSystemHandler
|
||||||
|
// {
|
||||||
|
// Transform parent = transform.parent;
|
||||||
|
// while (parent != null)
|
||||||
|
// {
|
||||||
|
// foreach (var component in parent.GetComponents<Component>())
|
||||||
|
// {
|
||||||
|
// if (component is T)
|
||||||
|
// action((T)(IEventSystemHandler)component);
|
||||||
|
// }
|
||||||
|
// parent = parent.parent;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void OnScroll(PointerEventData data)
|
||||||
|
// {
|
||||||
|
// if (ShouldRouteToParent(data))
|
||||||
|
// DoForParents<IScrollHandler>((parent) => { parent.OnScroll(data); });
|
||||||
|
// else
|
||||||
|
// base.OnScroll(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void OnInitializePotentialDrag(PointerEventData eventData)
|
||||||
|
// {
|
||||||
|
// DoForParents<IInitializePotentialDragHandler>((parent) => { parent.OnInitializePotentialDrag(eventData); });
|
||||||
|
// base.OnInitializePotentialDrag(eventData);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void OnDrag(PointerEventData data)
|
||||||
|
// {
|
||||||
|
// if (ShouldRouteToParent(data))
|
||||||
|
// DoForParents<IDragHandler>((parent) => { parent.OnDrag(data); });
|
||||||
|
// else
|
||||||
|
// base.OnDrag(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void OnBeginDrag(UnityEngine.EventSystems.PointerEventData data)
|
||||||
|
// {
|
||||||
|
// if (ShouldRouteToParent(data))
|
||||||
|
// DoForParents<IBeginDragHandler>((parent) => { parent.OnBeginDrag(data); });
|
||||||
|
// else
|
||||||
|
// base.OnBeginDrag(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void OnEndDrag(UnityEngine.EventSystems.PointerEventData data)
|
||||||
|
// {
|
||||||
|
// if (ShouldRouteToParent(data))
|
||||||
|
// DoForParents<IEndDragHandler>((parent) => { parent.OnEndDrag(data); });
|
||||||
|
// else
|
||||||
|
// base.OnEndDrag(data);
|
||||||
|
// }
|
||||||
|
//}
|
@ -13,6 +13,8 @@ public class SliderScrollbar
|
|||||||
{
|
{
|
||||||
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
||||||
|
|
||||||
|
public bool IsActive { get; private set; }
|
||||||
|
|
||||||
internal readonly Scrollbar m_scrollbar;
|
internal readonly Scrollbar m_scrollbar;
|
||||||
internal readonly Slider m_slider;
|
internal readonly Slider m_slider;
|
||||||
internal readonly RectTransform m_scrollRect;
|
internal readonly RectTransform m_scrollRect;
|
||||||
@ -51,16 +53,20 @@ public class SliderScrollbar
|
|||||||
internal void RefreshVisibility()
|
internal void RefreshVisibility()
|
||||||
{
|
{
|
||||||
if (!m_slider.gameObject.activeInHierarchy)
|
if (!m_slider.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
IsActive = false;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
|
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
|
||||||
var obj = this.m_slider.handleRect.gameObject;
|
var obj = this.m_slider.handleRect.gameObject;
|
||||||
|
|
||||||
if (obj.activeSelf != shouldShow)
|
if (IsActive != shouldShow)
|
||||||
{
|
{
|
||||||
obj.SetActive(shouldShow);
|
IsActive = shouldShow;
|
||||||
|
obj.SetActive(IsActive);
|
||||||
|
|
||||||
if (shouldShow)
|
if (IsActive)
|
||||||
this.m_slider.Set(this.m_scrollbar.value, false);
|
this.m_slider.Set(this.m_scrollbar.value, false);
|
||||||
else
|
else
|
||||||
m_slider.Set(1f, false);
|
m_slider.Set(1f, false);
|
||||||
|
@ -542,7 +542,7 @@ namespace UnityExplorer.UI
|
|||||||
templateImage.type = Image.Type.Sliced;
|
templateImage.type = Image.Type.Sliced;
|
||||||
templateImage.color = new Color(0.15f, 0.15f, 0.15f, 1.0f);
|
templateImage.color = new Color(0.15f, 0.15f, 0.15f, 1.0f);
|
||||||
|
|
||||||
ScrollRect scrollRect = templateObj.AddComponent<ScrollRect>();
|
var scrollRect = templateObj.AddComponent<ScrollRect>();
|
||||||
scrollRect.scrollSensitivity = 35;
|
scrollRect.scrollSensitivity = 35;
|
||||||
scrollRect.content = contentObj.GetComponent<RectTransform>();
|
scrollRect.content = contentObj.GetComponent<RectTransform>();
|
||||||
scrollRect.viewport = viewportObj.GetComponent<RectTransform>();
|
scrollRect.viewport = viewportObj.GetComponent<RectTransform>();
|
||||||
@ -626,7 +626,7 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
var mainLayout = mainObj.AddComponent<LayoutElement>();
|
var mainLayout = mainObj.AddComponent<LayoutElement>();
|
||||||
mainLayout.minWidth = 100;
|
mainLayout.minWidth = 100;
|
||||||
mainLayout.minHeight = 100;
|
mainLayout.minHeight = 30;
|
||||||
mainLayout.flexibleWidth = 5000;
|
mainLayout.flexibleWidth = 5000;
|
||||||
mainLayout.flexibleHeight = 5000;
|
mainLayout.flexibleHeight = 5000;
|
||||||
|
|
||||||
@ -709,6 +709,8 @@ namespace UnityExplorer.UI
|
|||||||
// Create a custom DynamicScrollbar module
|
// Create a custom DynamicScrollbar module
|
||||||
scroller = new SliderScrollbar(hiddenScroll, scrollSlider);
|
scroller = new SliderScrollbar(hiddenScroll, scrollSlider);
|
||||||
|
|
||||||
|
//scrollRect.sliderScrollbar = scroller;
|
||||||
|
|
||||||
return mainObj;
|
return mainObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,17 +30,14 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
internal static string GetClassColor(Type type)
|
internal static string GetClassColor(Type type)
|
||||||
{
|
{
|
||||||
string classColor;
|
|
||||||
if (type.IsAbstract && type.IsSealed)
|
if (type.IsAbstract && type.IsSealed)
|
||||||
classColor = Class_Static;
|
return Class_Static;
|
||||||
else if (type.IsEnum || type.IsGenericParameter)
|
else if (type.IsEnum || type.IsGenericParameter)
|
||||||
classColor = Enum;
|
return Enum;
|
||||||
else if (type.IsValueType)
|
else if (type.IsValueType)
|
||||||
classColor = StructGreen;
|
return StructGreen;
|
||||||
else
|
else
|
||||||
classColor = Class_Instance;
|
return Class_Instance;
|
||||||
|
|
||||||
return classColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null)
|
public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null)
|
||||||
|
@ -330,6 +330,7 @@
|
|||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheEnumerated.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheEnumerated.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheFactory.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheFactory.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheField.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheField.cs" />
|
||||||
|
<Compile Include="Inspectors\Reflection\CacheObject\CachePaired.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheMember.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheMember.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheMethod.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheMethod.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\CacheObject\CacheProperty.cs" />
|
<Compile Include="Inspectors\Reflection\CacheObject\CacheProperty.cs" />
|
||||||
@ -344,6 +345,9 @@
|
|||||||
<Compile Include="Inspectors\GameObjects\ChildList.cs" />
|
<Compile Include="Inspectors\GameObjects\ChildList.cs" />
|
||||||
<Compile Include="Inspectors\GameObjects\ComponentList.cs" />
|
<Compile Include="Inspectors\GameObjects\ComponentList.cs" />
|
||||||
<Compile Include="Inspectors\GameObjects\GameObjectControls.cs" />
|
<Compile Include="Inspectors\GameObjects\GameObjectControls.cs" />
|
||||||
|
<Compile Include="Inspectors\Reflection\CacheObject\INestedValue.cs" />
|
||||||
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveDictionary.cs" />
|
||||||
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveEnumerable.cs" />
|
||||||
<Compile Include="UI\ForceUnlockCursor.cs" />
|
<Compile Include="UI\ForceUnlockCursor.cs" />
|
||||||
<Compile Include="Input\IHandleInput.cs" />
|
<Compile Include="Input\IHandleInput.cs" />
|
||||||
<Compile Include="Tests\Tests.cs" />
|
<Compile Include="Tests\Tests.cs" />
|
||||||
@ -379,6 +383,7 @@
|
|||||||
<Compile Include="UI\PanelDragger.cs" />
|
<Compile Include="UI\PanelDragger.cs" />
|
||||||
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveValue.cs" />
|
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveValue.cs" />
|
||||||
<Compile Include="UI\Shared\InputFieldScroller.cs" />
|
<Compile Include="UI\Shared\InputFieldScroller.cs" />
|
||||||
|
<Compile Include="UI\Shared\ScrollRectEx.cs" />
|
||||||
<Compile Include="UI\Shared\SliderScrollbar.cs" />
|
<Compile Include="UI\Shared\SliderScrollbar.cs" />
|
||||||
<Compile Include="UI\Shared\PageHandler.cs" />
|
<Compile Include="UI\Shared\PageHandler.cs" />
|
||||||
<Compile Include="UI\UISyntaxHighlight.cs" />
|
<Compile Include="UI\UISyntaxHighlight.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user