mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 22:27:45 +08:00
Some progress on inspector rewrites, most of the framework figured out now.
This commit is contained in:
parent
07ddba3c3d
commit
a2ff37e36d
@ -35,26 +35,6 @@
|
|||||||
// // ActiveInstance.m_widthUpdateWanted = true;
|
// // ActiveInstance.m_widthUpdateWanted = true;
|
||||||
// //}
|
// //}
|
||||||
|
|
||||||
// // Blacklists
|
|
||||||
// private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
|
|
||||||
// {
|
|
||||||
//#if CPP
|
|
||||||
// // these cause a crash in IL2CPP
|
|
||||||
// "Type.DeclaringMethod",
|
|
||||||
// "Rigidbody2D.Cast",
|
|
||||||
// "Collider2D.Cast",
|
|
||||||
// "Collider2D.Raycast",
|
|
||||||
// "Texture2D.SetPixelDataImpl",
|
|
||||||
// "Camera.CalculateProjectionMatrixFromPhysicalProperties",
|
|
||||||
//#endif
|
|
||||||
// };
|
|
||||||
// private static readonly HashSet<string> bl_methodNameStartsWith = new HashSet<string>
|
|
||||||
// {
|
|
||||||
// // these are redundant, just adds noise, properties are supported directly
|
|
||||||
// "get_",
|
|
||||||
// "set_",
|
|
||||||
// };
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
// #region INSTANCE
|
// #region INSTANCE
|
||||||
@ -131,6 +111,26 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// // Blacklists
|
||||||
|
// private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
|
||||||
|
// {
|
||||||
|
//#if CPP
|
||||||
|
// // these cause a crash in IL2CPP
|
||||||
|
// "Type.DeclaringMethod",
|
||||||
|
// "Rigidbody2D.Cast",
|
||||||
|
// "Collider2D.Cast",
|
||||||
|
// "Collider2D.Raycast",
|
||||||
|
// "Texture2D.SetPixelDataImpl",
|
||||||
|
// "Camera.CalculateProjectionMatrixFromPhysicalProperties",
|
||||||
|
//#endif
|
||||||
|
// };
|
||||||
|
// private static readonly HashSet<string> bl_methodNameStartsWith = new HashSet<string>
|
||||||
|
// {
|
||||||
|
// // these are redundant, just adds noise, properties are supported directly
|
||||||
|
// "get_",
|
||||||
|
// "set_",
|
||||||
|
// };
|
||||||
|
|
||||||
// internal bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
|
// internal bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
|
||||||
// internal bool IsBlacklisted(MethodInfo method) => bl_methodNameStartsWith.Any(it => method.Name.StartsWith(it));
|
// internal bool IsBlacklisted(MethodInfo method) => bl_methodNameStartsWith.Any(it => method.Name.StartsWith(it));
|
||||||
|
|
||||||
|
33
src/UI/Inspectors/CacheObject/CacheField.cs
Normal file
33
src/UI/Inspectors/CacheObject/CacheField.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||||
|
{
|
||||||
|
public class CacheField : CacheMember
|
||||||
|
{
|
||||||
|
public FieldInfo FieldInfo { get; internal set; }
|
||||||
|
|
||||||
|
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||||
|
{
|
||||||
|
base.Initialize(inspector, declaringType, member, returnType);
|
||||||
|
|
||||||
|
CanWrite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TryEvaluate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Value = FieldInfo.GetValue(this.ParentInspector.Target.TryCast(this.DeclaringType));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HadException = true;
|
||||||
|
LastException = ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
315
src/UI/Inspectors/CacheObject/CacheMember.cs
Normal file
315
src/UI/Inspectors/CacheObject/CacheMember.cs
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.UI.Inspectors.CacheObject.Views;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||||
|
{
|
||||||
|
public abstract class CacheMember : CacheObjectBase
|
||||||
|
{
|
||||||
|
public ReflectionInspector ParentInspector { get; internal set; }
|
||||||
|
|
||||||
|
public Type DeclaringType { get; private set; }
|
||||||
|
public string NameForFiltering { get; private set; }
|
||||||
|
|
||||||
|
public object Value { get; protected set; }
|
||||||
|
public Type FallbackType { get; private set; }
|
||||||
|
|
||||||
|
public bool HasEvaluated { get; protected set; }
|
||||||
|
public bool HasArguments { get; protected set; }
|
||||||
|
public bool Evaluating { get; protected set; }
|
||||||
|
public bool CanWrite { get; protected set; }
|
||||||
|
public bool HadException { get; protected set; }
|
||||||
|
public Exception LastException { get; protected set; }
|
||||||
|
|
||||||
|
public string MemberLabelText { get; private set; }
|
||||||
|
public string TypeLabelText { get; protected set; }
|
||||||
|
public string ValueLabelText { get; protected set; }
|
||||||
|
|
||||||
|
public virtual void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||||
|
{
|
||||||
|
this.DeclaringType = declaringType;
|
||||||
|
this.ParentInspector = inspector;
|
||||||
|
this.FallbackType = returnType;
|
||||||
|
this.MemberLabelText = SignatureHighlighter.ParseFullSyntax(declaringType, false, member);
|
||||||
|
this.NameForFiltering = $"{declaringType.Name}.{member.Name}";
|
||||||
|
this.TypeLabelText = SignatureHighlighter.HighlightTypeName(returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCell(CacheMemberCell cell)
|
||||||
|
{
|
||||||
|
cell.MemberLabel.text = MemberLabelText;
|
||||||
|
cell.TypeLabel.text = TypeLabelText;
|
||||||
|
|
||||||
|
if (HasArguments && !HasEvaluated)
|
||||||
|
{
|
||||||
|
// todo
|
||||||
|
cell.ValueLabel.text = "Not yet evalulated";
|
||||||
|
}
|
||||||
|
else if (!HasEvaluated)
|
||||||
|
Evaluate();
|
||||||
|
|
||||||
|
if (HadException)
|
||||||
|
{
|
||||||
|
cell.InspectButton.Button.gameObject.SetActive(false);
|
||||||
|
cell.ValueLabel.gameObject.SetActive(true);
|
||||||
|
cell.ValueLabel.supportRichText = true;
|
||||||
|
cell.ValueLabel.text = $"<color=red>{ReflectionUtility.ReflectionExToString(LastException)}</color>";
|
||||||
|
}
|
||||||
|
else if (Value.IsNullOrDestroyed())
|
||||||
|
{
|
||||||
|
cell.InspectButton.Button.gameObject.SetActive(false);
|
||||||
|
cell.ValueLabel.gameObject.SetActive(true);
|
||||||
|
cell.ValueLabel.supportRichText = true;
|
||||||
|
cell.ValueLabel.text = ValueLabelText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cell.ValueLabel.supportRichText = false;
|
||||||
|
cell.ValueLabel.text = ValueLabelText;
|
||||||
|
|
||||||
|
var valueType = Value.GetActualType();
|
||||||
|
if (valueType.IsPrimitive || valueType == typeof(decimal))
|
||||||
|
{
|
||||||
|
cell.InspectButton.Button.gameObject.SetActive(false);
|
||||||
|
cell.ValueLabel.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
else if (valueType == typeof(string))
|
||||||
|
{
|
||||||
|
cell.InspectButton.Button.gameObject.SetActive(false);
|
||||||
|
cell.ValueLabel.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cell.InspectButton.Button.gameObject.SetActive(true);
|
||||||
|
cell.ValueLabel.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void TryEvaluate();
|
||||||
|
|
||||||
|
public void Evaluate()
|
||||||
|
{
|
||||||
|
TryEvaluate();
|
||||||
|
|
||||||
|
if (!HadException)
|
||||||
|
{
|
||||||
|
ValueLabelText = ToStringUtility.ToString(Value, FallbackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
HasEvaluated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Cache Member Util
|
||||||
|
|
||||||
|
public static bool CanProcessArgs(ParameterInfo[] parameters)
|
||||||
|
{
|
||||||
|
foreach (var param in parameters)
|
||||||
|
{
|
||||||
|
var pType = param.ParameterType;
|
||||||
|
|
||||||
|
if (pType.IsByRef && pType.HasElementType)
|
||||||
|
pType = pType.GetElementType();
|
||||||
|
|
||||||
|
if (pType != null && (pType.IsPrimitive || pType == typeof(string)))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type _type, ReflectionInspector _inspector)
|
||||||
|
{
|
||||||
|
var list = new List<CacheMember>();
|
||||||
|
var cachedSigs = new HashSet<string>();
|
||||||
|
|
||||||
|
var types = ReflectionUtility.GetAllBaseTypes(_type);
|
||||||
|
|
||||||
|
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||||
|
if (!_inspector.StaticOnly)
|
||||||
|
flags |= BindingFlags.Instance;
|
||||||
|
|
||||||
|
var infos = new List<MemberInfo>();
|
||||||
|
|
||||||
|
foreach (var declaringType in types)
|
||||||
|
{
|
||||||
|
var target = inspectorTarget;
|
||||||
|
if (!_inspector.StaticOnly)
|
||||||
|
target = target.TryCast(declaringType);
|
||||||
|
|
||||||
|
infos.Clear();
|
||||||
|
infos.AddRange(declaringType.GetMethods(flags));
|
||||||
|
infos.AddRange(declaringType.GetProperties(flags));
|
||||||
|
infos.AddRange(declaringType.GetFields(flags));
|
||||||
|
|
||||||
|
foreach (var member in infos)
|
||||||
|
{
|
||||||
|
if (member.DeclaringType != declaringType)
|
||||||
|
continue;
|
||||||
|
TryCacheMember(member, list, cachedSigs, declaringType, _inspector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeList = types.ToList();
|
||||||
|
|
||||||
|
var sorted = new List<CacheMember>();
|
||||||
|
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));
|
||||||
|
sorted.AddRange(list.Where(it => it is CacheMethod)
|
||||||
|
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||||
|
.ThenBy(it => it.NameForFiltering));
|
||||||
|
|
||||||
|
return sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TryCacheMember(MemberInfo member, List<CacheMember> list, HashSet<string> cachedSigs,
|
||||||
|
Type declaringType, ReflectionInspector _inspector, bool ignoreMethodBlacklist = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sig = GetSig(member);
|
||||||
|
|
||||||
|
if (IsBlacklisted(sig))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||||
|
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
||||||
|
|
||||||
|
CacheMember cached;
|
||||||
|
Type returnType;
|
||||||
|
switch (member.MemberType)
|
||||||
|
{
|
||||||
|
case MemberTypes.Method:
|
||||||
|
{
|
||||||
|
var mi = member as MethodInfo;
|
||||||
|
if (!ignoreMethodBlacklist && IsBlacklisted(mi))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var args = mi.GetParameters();
|
||||||
|
if (!CanProcessArgs(args))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sig += AppendArgsToSig(args);
|
||||||
|
if (cachedSigs.Contains(sig))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cached = new CacheMethod() { MethodInfo = mi };
|
||||||
|
returnType = mi.ReturnType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MemberTypes.Property:
|
||||||
|
{
|
||||||
|
var pi = member as PropertyInfo;
|
||||||
|
|
||||||
|
var args = pi.GetIndexParameters();
|
||||||
|
if (!CanProcessArgs(args))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pi.CanRead && pi.CanWrite)
|
||||||
|
{
|
||||||
|
// write-only property, cache the set method instead.
|
||||||
|
var setMethod = pi.GetSetMethod(true);
|
||||||
|
if (setMethod != null)
|
||||||
|
TryCacheMember(setMethod, list, cachedSigs, declaringType, _inspector, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sig += AppendArgsToSig(args);
|
||||||
|
if (cachedSigs.Contains(sig))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cached = new CacheProperty() { PropertyInfo = pi };
|
||||||
|
returnType = pi.PropertyType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MemberTypes.Field:
|
||||||
|
{
|
||||||
|
var fi = member as FieldInfo;
|
||||||
|
cached = new CacheField() { FieldInfo = fi };
|
||||||
|
returnType = fi.FieldType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedSigs.Add(sig);
|
||||||
|
|
||||||
|
cached.Initialize(_inspector, declaringType, member, returnType);
|
||||||
|
|
||||||
|
list.Add(cached);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
|
||||||
|
ExplorerCore.Log(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}";
|
||||||
|
|
||||||
|
internal static string AppendArgsToSig(ParameterInfo[] args)
|
||||||
|
{
|
||||||
|
string ret = " (";
|
||||||
|
foreach (var param in args)
|
||||||
|
ret += $"{param.ParameterType.Name} {param.Name}, ";
|
||||||
|
ret += ")";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blacklists
|
||||||
|
private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
|
||||||
|
{
|
||||||
|
// these cause a crash in IL2CPP
|
||||||
|
#if CPP
|
||||||
|
"Type.DeclaringMethod",
|
||||||
|
"Rigidbody2D.Cast",
|
||||||
|
"Collider2D.Cast",
|
||||||
|
"Collider2D.Raycast",
|
||||||
|
"Texture2D.SetPixelDataImpl",
|
||||||
|
"Camera.CalculateProjectionMatrixFromPhysicalProperties",
|
||||||
|
#endif
|
||||||
|
// These were deprecated a long time ago, still show up in some games for some reason
|
||||||
|
"MonoBehaviour.allowPrefabModeInPlayMode",
|
||||||
|
"MonoBehaviour.runInEditMode",
|
||||||
|
"Component.animation",
|
||||||
|
"Component.audio",
|
||||||
|
"Component.camera",
|
||||||
|
"Component.collider",
|
||||||
|
"Component.collider2D",
|
||||||
|
"Component.constantForce",
|
||||||
|
"Component.hingeJoint",
|
||||||
|
"Component.light",
|
||||||
|
"Component.networkView",
|
||||||
|
"Component.particleSystem",
|
||||||
|
"Component.renderer",
|
||||||
|
"Component.rigidbody",
|
||||||
|
"Component.rigidbody2D",
|
||||||
|
};
|
||||||
|
private static readonly HashSet<string> bl_methodNameStartsWith = new HashSet<string>
|
||||||
|
{
|
||||||
|
// these are redundant
|
||||||
|
"get_",
|
||||||
|
"set_",
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
|
||||||
|
internal static bool IsBlacklisted(MethodInfo method) => bl_methodNameStartsWith.Any(it => method.Name.StartsWith(it));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
33
src/UI/Inspectors/CacheObject/CacheMethod.cs
Normal file
33
src/UI/Inspectors/CacheObject/CacheMethod.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||||
|
{
|
||||||
|
public class CacheMethod : CacheMember
|
||||||
|
{
|
||||||
|
public MethodInfo MethodInfo { get; internal set; }
|
||||||
|
|
||||||
|
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||||
|
{
|
||||||
|
base.Initialize(inspector, declaringType, member, returnType);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TryEvaluate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("TODO");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HadException = true;
|
||||||
|
LastException = ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
src/UI/Inspectors/CacheObject/CacheObjectBase.cs
Normal file
12
src/UI/Inspectors/CacheObject/CacheObjectBase.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||||
|
{
|
||||||
|
public abstract class CacheObjectBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
33
src/UI/Inspectors/CacheObject/CacheProperty.cs
Normal file
33
src/UI/Inspectors/CacheObject/CacheProperty.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||||
|
{
|
||||||
|
public class CacheProperty : CacheMember
|
||||||
|
{
|
||||||
|
public PropertyInfo PropertyInfo { get; internal set; }
|
||||||
|
|
||||||
|
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||||
|
{
|
||||||
|
base.Initialize(inspector, declaringType, member, returnType);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TryEvaluate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Value = PropertyInfo.GetValue(ParentInspector.Target.TryCast(DeclaringType), null);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HadException = true;
|
||||||
|
LastException = ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs
Normal file
106
src/UI/Inspectors/CacheObject/Views/CacheMemberCell.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.Widgets;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject.Views
|
||||||
|
{
|
||||||
|
public class CacheMemberCell : ICell
|
||||||
|
{
|
||||||
|
#region ICell
|
||||||
|
|
||||||
|
public float DefaultHeight => 30f;
|
||||||
|
|
||||||
|
public GameObject UIRoot => uiRoot;
|
||||||
|
public GameObject uiRoot;
|
||||||
|
|
||||||
|
public bool Enabled => m_enabled;
|
||||||
|
private bool m_enabled;
|
||||||
|
|
||||||
|
public RectTransform Rect => m_rect;
|
||||||
|
private RectTransform m_rect;
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
{
|
||||||
|
m_enabled = false;
|
||||||
|
uiRoot.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enable()
|
||||||
|
{
|
||||||
|
m_enabled = true;
|
||||||
|
uiRoot.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public ReflectionInspector CurrentOwner { get; set; }
|
||||||
|
public int CurrentDataIndex { get; set; }
|
||||||
|
|
||||||
|
public LayoutElement MemberLayout;
|
||||||
|
public LayoutElement ReturnTypeLayout;
|
||||||
|
public LayoutElement RightGroupLayout;
|
||||||
|
|
||||||
|
public Text MemberLabel;
|
||||||
|
public Text TypeLabel;
|
||||||
|
|
||||||
|
public GameObject RightGroupHolder;
|
||||||
|
public ButtonRef InspectButton;
|
||||||
|
public Text ValueLabel;
|
||||||
|
|
||||||
|
public GameObject SubContentHolder;
|
||||||
|
|
||||||
|
public GameObject CreateContent(GameObject parent)
|
||||||
|
{
|
||||||
|
uiRoot = UIFactory.CreateUIObject("CacheMemberCell", parent, new Vector2(100, 30));
|
||||||
|
m_rect = uiRoot.GetComponent<RectTransform>();
|
||||||
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(uiRoot, true, true, true, true, 2, 0);
|
||||||
|
UIFactory.SetLayoutElement(uiRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 600);
|
||||||
|
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
|
|
||||||
|
var separator = UIFactory.CreateUIObject("TopSeperator", uiRoot);
|
||||||
|
UIFactory.SetLayoutElement(separator, minHeight: 1, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
separator.AddComponent<Image>().color = Color.black;
|
||||||
|
|
||||||
|
var horiRow = UIFactory.CreateUIObject("HoriGroup", uiRoot);
|
||||||
|
UIFactory.SetLayoutElement(horiRow, minHeight: 29, flexibleHeight: 150, flexibleWidth: 9999);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horiRow, false, true, true, true, 5, 2, childAlignment: TextAnchor.UpperLeft);
|
||||||
|
horiRow.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
|
|
||||||
|
MemberLabel = UIFactory.CreateLabel(horiRow, "MemberLabel", "<notset>", TextAnchor.UpperLeft);
|
||||||
|
MemberLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
|
UIFactory.SetLayoutElement(MemberLabel.gameObject, minHeight: 25, minWidth: 20, flexibleHeight: 300, flexibleWidth: 0);
|
||||||
|
MemberLayout = MemberLabel.GetComponent<LayoutElement>();
|
||||||
|
|
||||||
|
TypeLabel = UIFactory.CreateLabel(horiRow, "ReturnLabel", "<notset>", TextAnchor.UpperLeft);
|
||||||
|
TypeLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
|
UIFactory.SetLayoutElement(TypeLabel.gameObject, minHeight: 25, flexibleHeight: 150, minWidth: 20, flexibleWidth: 0);
|
||||||
|
ReturnTypeLayout = TypeLabel.GetComponent<LayoutElement>();
|
||||||
|
|
||||||
|
RightGroupHolder = UIFactory.CreateUIObject("RightGroup", horiRow);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(RightGroupHolder, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
|
||||||
|
UIFactory.SetLayoutElement(RightGroupHolder, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 150);
|
||||||
|
RightGroupLayout = RightGroupHolder.GetComponent<LayoutElement>();
|
||||||
|
|
||||||
|
InspectButton = UIFactory.CreateButton(RightGroupHolder, "InspectButton", "Inspect", new Color(0.23f, 0.23f, 0.23f));
|
||||||
|
UIFactory.SetLayoutElement(InspectButton.Button.gameObject, minWidth: 60, flexibleWidth: 0, minHeight: 25);
|
||||||
|
|
||||||
|
ValueLabel = UIFactory.CreateLabel(RightGroupHolder, "ValueLabel", "Value goes here", TextAnchor.MiddleLeft);
|
||||||
|
ValueLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
|
UIFactory.SetLayoutElement(ValueLabel.gameObject, minHeight: 25, flexibleHeight: 150, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
// Subcontent (todo?)
|
||||||
|
|
||||||
|
SubContentHolder = UIFactory.CreateUIObject("SubContent", uiRoot);
|
||||||
|
UIFactory.SetLayoutElement(SubContentHolder.gameObject, minHeight: 30, flexibleHeight: 500, minWidth: 100, flexibleWidth: 9999);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(SubContentHolder, true, false, true, true, 2, childAlignment: TextAnchor.UpperLeft);
|
||||||
|
|
||||||
|
SubContentHolder.SetActive(false);
|
||||||
|
|
||||||
|
return uiRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/UI/Inspectors/CacheObject/Views/CacheObjectCell.cs
Normal file
11
src/UI/Inspectors/CacheObject/Views/CacheObjectCell.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.CacheObject.Views
|
||||||
|
{
|
||||||
|
class CacheObjectCell
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.UI.ObjectPool;
|
using UnityExplorer.UI.ObjectPool;
|
||||||
|
using UnityExplorer.UI.Panels;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
using UnityExplorer.UI.Widgets;
|
using UnityExplorer.UI.Widgets;
|
||||||
|
|
||||||
@ -25,6 +27,137 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
public ButtonListSource<Component> ComponentList;
|
public ButtonListSource<Component> ComponentList;
|
||||||
private ScrollPool<ButtonCell> componentScroll;
|
private ScrollPool<ButtonCell> componentScroll;
|
||||||
|
|
||||||
|
private readonly List<GameObject> _rootEntries = new List<GameObject>();
|
||||||
|
|
||||||
|
public override void OnBorrowedFromPool(object target)
|
||||||
|
{
|
||||||
|
base.OnBorrowedFromPool(target);
|
||||||
|
|
||||||
|
Target = target as GameObject;
|
||||||
|
|
||||||
|
NameText.text = Target.name;
|
||||||
|
Tab.TabText.text = $"[G] {Target.name}";
|
||||||
|
|
||||||
|
RuntimeProvider.Instance.StartCoroutine(InitCoroutine());
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator InitCoroutine()
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(InspectorPanel.Instance.ContentRect);
|
||||||
|
|
||||||
|
TransformTree.Rebuild();
|
||||||
|
|
||||||
|
ComponentList.ScrollPool.Rebuild();
|
||||||
|
UpdateComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnReturnToPool()
|
||||||
|
{
|
||||||
|
base.OnReturnToPool();
|
||||||
|
|
||||||
|
// release component and transform lists
|
||||||
|
this.TransformTree.ScrollPool.ReturnCells();
|
||||||
|
this.TransformTree.ScrollPool.SetUninitialized();
|
||||||
|
|
||||||
|
this.ComponentList.ScrollPool.ReturnCells();
|
||||||
|
this.ComponentList.ScrollPool.SetUninitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float timeOfLastUpdate;
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
if (!this.IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Target.IsNullOrDestroyed(false))
|
||||||
|
{
|
||||||
|
InspectorManager.ReleaseInspector(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.time - timeOfLastUpdate > 1f)
|
||||||
|
{
|
||||||
|
timeOfLastUpdate = Time.time;
|
||||||
|
|
||||||
|
// Refresh children and components
|
||||||
|
TransformTree.RefreshData(true, false);
|
||||||
|
|
||||||
|
UpdateComponents();
|
||||||
|
|
||||||
|
Tab.TabText.text = $"[G] {Target.name}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<GameObject> GetTransformEntries()
|
||||||
|
{
|
||||||
|
_rootEntries.Clear();
|
||||||
|
for (int i = 0; i < Target.transform.childCount; i++)
|
||||||
|
_rootEntries.Add(Target.transform.GetChild(i).gameObject);
|
||||||
|
return _rootEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<Component> _componentEntries = new List<Component>();
|
||||||
|
|
||||||
|
private List<Component> GetComponentEntries()
|
||||||
|
{
|
||||||
|
return _componentEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> compToStringCache = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
private void SetComponentCell(ButtonCell cell, int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= _componentEntries.Count)
|
||||||
|
{
|
||||||
|
cell.Disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.Enable();
|
||||||
|
|
||||||
|
var comp = _componentEntries[index];
|
||||||
|
var type = comp.GetActualType();
|
||||||
|
|
||||||
|
if (!compToStringCache.ContainsKey(type.AssemblyQualifiedName))
|
||||||
|
{
|
||||||
|
compToStringCache.Add(type.AssemblyQualifiedName,
|
||||||
|
$"<color={SignatureHighlighter.NAMESPACE}>{type.Namespace}</color>.{SignatureHighlighter.HighlightTypeName(type)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.Button.ButtonText.text = compToStringCache[type.AssemblyQualifiedName];
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldDisplay(Component comp, string filter) => true;
|
||||||
|
|
||||||
|
private void OnComponentClicked(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= _componentEntries.Count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var comp = _componentEntries[index];
|
||||||
|
if (comp)
|
||||||
|
InspectorManager.Inspect(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateComponents()
|
||||||
|
{
|
||||||
|
_componentEntries.Clear();
|
||||||
|
var comps = Target.GetComponents<Component>();
|
||||||
|
foreach (var comp in comps)
|
||||||
|
_componentEntries.Add(comp);
|
||||||
|
|
||||||
|
ComponentList.RefreshData();
|
||||||
|
ComponentList.ScrollPool.RefreshCells(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnCloseClicked()
|
||||||
|
{
|
||||||
|
InspectorManager.ReleaseInspector(this);
|
||||||
|
}
|
||||||
|
|
||||||
public override GameObject CreateContent(GameObject parent)
|
public override GameObject CreateContent(GameObject parent)
|
||||||
{
|
{
|
||||||
uiRoot = UIFactory.CreateVerticalGroup(Pool<GameObjectInspector>.Instance.InactiveHolder,
|
uiRoot = UIFactory.CreateVerticalGroup(Pool<GameObjectInspector>.Instance.InactiveHolder,
|
||||||
@ -54,120 +187,5 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
|
|
||||||
return uiRoot;
|
return uiRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<GameObject> _rootEntries = new List<GameObject>();
|
|
||||||
|
|
||||||
private IEnumerable<GameObject> GetTransformEntries()
|
|
||||||
{
|
|
||||||
_rootEntries.Clear();
|
|
||||||
for (int i = 0; i < Target.transform.childCount; i++)
|
|
||||||
_rootEntries.Add(Target.transform.GetChild(i).gameObject);
|
|
||||||
return _rootEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly List<Component> _componentEntries = new List<Component>();
|
|
||||||
|
|
||||||
private List<Component> GetComponentEntries()
|
|
||||||
{
|
|
||||||
return _componentEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, string> compToStringCache = new Dictionary<Type, string>();
|
|
||||||
|
|
||||||
private void SetComponentCell(ButtonCell cell, int index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= _componentEntries.Count)
|
|
||||||
{
|
|
||||||
cell.Disable();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell.Enable();
|
|
||||||
|
|
||||||
var comp = _componentEntries[index];
|
|
||||||
var type = comp.GetActualType();
|
|
||||||
|
|
||||||
if (!compToStringCache.ContainsKey(type))
|
|
||||||
{
|
|
||||||
compToStringCache.Add(type,
|
|
||||||
$"<color={SignatureHighlighter.NAMESPACE}>{type.Namespace}</color>.{SignatureHighlighter.HighlightTypeName(type)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
cell.Button.ButtonText.text = compToStringCache[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ShouldDisplay(Component comp, string filter) => true;
|
|
||||||
|
|
||||||
private void OnComponentClicked(int index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= _componentEntries.Count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var comp = _componentEntries[index];
|
|
||||||
if (comp)
|
|
||||||
InspectorManager.Inspect(comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnBorrowedFromPool(object target)
|
|
||||||
{
|
|
||||||
base.OnBorrowedFromPool(target);
|
|
||||||
|
|
||||||
Target = target as GameObject;
|
|
||||||
|
|
||||||
NameText.text = Target.name;
|
|
||||||
this.Tab.TabText.text = $"[G] {Target.name}";
|
|
||||||
|
|
||||||
TransformTree.Rebuild();
|
|
||||||
|
|
||||||
ComponentList.ScrollPool.Rebuild();
|
|
||||||
UpdateComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnReturnToPool()
|
|
||||||
{
|
|
||||||
base.OnReturnToPool();
|
|
||||||
|
|
||||||
// release component and transform lists
|
|
||||||
this.TransformTree.ScrollPool.ReturnCells();
|
|
||||||
this.TransformTree.ScrollPool.SetUninitialized();
|
|
||||||
|
|
||||||
this.ComponentList.ScrollPool.ReturnCells();
|
|
||||||
this.ComponentList.ScrollPool.SetUninitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
private float timeOfLastUpdate;
|
|
||||||
|
|
||||||
public override void Update()
|
|
||||||
{
|
|
||||||
// todo update tab title? or put that in InspectorBase update?
|
|
||||||
|
|
||||||
if (!this.IsActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Time.time - timeOfLastUpdate > 1f)
|
|
||||||
{
|
|
||||||
timeOfLastUpdate = Time.time;
|
|
||||||
|
|
||||||
// Refresh children and components
|
|
||||||
TransformTree.RefreshData(true, false);
|
|
||||||
|
|
||||||
UpdateComponents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateComponents()
|
|
||||||
{
|
|
||||||
_componentEntries.Clear();
|
|
||||||
foreach (var comp in Target.GetComponents<Component>())
|
|
||||||
_componentEntries.Add(comp);
|
|
||||||
|
|
||||||
ComponentList.RefreshData();
|
|
||||||
ComponentList.ScrollPool.RefreshCells(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnCloseClicked()
|
|
||||||
{
|
|
||||||
InspectorManager.ReleaseInspector(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
src/UI/Inspectors/IValues/IValueTest.cs
Normal file
28
src/UI/Inspectors/IValues/IValueTest.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.ObjectPool;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Inspectors.IValues
|
||||||
|
{
|
||||||
|
public class IValueTest : IPooledObject
|
||||||
|
{
|
||||||
|
public GameObject UIRoot => uiRoot;
|
||||||
|
private GameObject uiRoot;
|
||||||
|
|
||||||
|
public float DefaultHeight => -1f;
|
||||||
|
|
||||||
|
public GameObject CreateContent(GameObject parent)
|
||||||
|
{
|
||||||
|
uiRoot = UIFactory.CreateUIObject(this.GetType().Name, parent);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(uiRoot, true, true, true, true, 3, childAlignment: TextAnchor.MiddleLeft);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return uiRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,16 +10,17 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
{
|
{
|
||||||
public abstract class InspectorBase : IPooledObject
|
public abstract class InspectorBase : IPooledObject
|
||||||
{
|
{
|
||||||
public InspectorTab Tab { get; internal set; }
|
|
||||||
public bool IsActive { get; internal set; }
|
public bool IsActive { get; internal set; }
|
||||||
|
|
||||||
|
public InspectorTab Tab { get; internal set; }
|
||||||
|
|
||||||
public abstract GameObject UIRoot { get; }
|
public abstract GameObject UIRoot { get; }
|
||||||
|
|
||||||
private static readonly Color _enabledTabColor = new Color(0.2f, 0.4f, 0.2f);
|
private static readonly Color _enabledTabColor = new Color(0.2f, 0.4f, 0.2f);
|
||||||
private static readonly Color _disabledTabColor = new Color(0.25f, 0.25f, 0.25f);
|
private static readonly Color _disabledTabColor = new Color(0.25f, 0.25f, 0.25f);
|
||||||
|
|
||||||
public float DefaultHeight => -1f;
|
public float DefaultHeight => -1f;
|
||||||
public abstract GameObject CreateContent(GameObject content);
|
public abstract GameObject CreateContent(GameObject parent);
|
||||||
|
|
||||||
public abstract void Update();
|
public abstract void Update();
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.UI.ObjectPool;
|
using UnityExplorer.UI.ObjectPool;
|
||||||
using UnityExplorer.UI.Panels;
|
using UnityExplorer.UI.Panels;
|
||||||
|
|
||||||
@ -14,18 +15,23 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
|
|
||||||
public static InspectorBase ActiveInspector { get; private set; }
|
public static InspectorBase ActiveInspector { get; private set; }
|
||||||
|
|
||||||
|
public static float PanelWidth;
|
||||||
|
|
||||||
public static void Inspect(object obj)
|
public static void Inspect(object obj)
|
||||||
{
|
{
|
||||||
|
if (obj.IsNullOrDestroyed())
|
||||||
|
return;
|
||||||
|
|
||||||
obj = obj.TryCast();
|
obj = obj.TryCast();
|
||||||
if (obj is GameObject)
|
if (obj is GameObject)
|
||||||
CreateInspector<GameObjectInspector>(obj);
|
CreateInspector<GameObjectInspector>(obj);
|
||||||
else
|
else
|
||||||
CreateInspector<InstanceInspector>(obj);
|
CreateInspector<ReflectionInspector>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Inspect(Type type)
|
public static void InspectStatic(Type type)
|
||||||
{
|
{
|
||||||
CreateInspector<StaticInspector>(type);
|
CreateInspector<ReflectionInspector>(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetInspectorActive(InspectorBase inspector)
|
public static void SetInspectorActive(InspectorBase inspector)
|
||||||
@ -42,17 +48,19 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
ActiveInspector.OnSetInactive();
|
ActiveInspector.OnSetInactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateInspector<T>(object target) where T : InspectorBase
|
private static void CreateInspector<T>(object target, bool staticReflection = false) where T : InspectorBase
|
||||||
{
|
{
|
||||||
var inspector = Pool<T>.Borrow();
|
var inspector = Pool<T>.Borrow();
|
||||||
Inspectors.Add(inspector);
|
Inspectors.Add(inspector);
|
||||||
|
|
||||||
|
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
|
||||||
inspector.UIRoot.transform.SetParent(InspectorPanel.Instance.ContentHolder.transform, false);
|
inspector.UIRoot.transform.SetParent(InspectorPanel.Instance.ContentHolder.transform, false);
|
||||||
|
|
||||||
|
if (inspector is ReflectionInspector reflectInspector)
|
||||||
|
reflectInspector.StaticOnly = staticReflection;
|
||||||
|
|
||||||
inspector.OnBorrowedFromPool(target);
|
inspector.OnBorrowedFromPool(target);
|
||||||
SetInspectorActive(inspector);
|
SetInspectorActive(inspector);
|
||||||
|
|
||||||
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase
|
internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase
|
||||||
@ -65,15 +73,21 @@ namespace UnityExplorer.UI.Inspectors
|
|||||||
|
|
||||||
internal static void Update()
|
internal static void Update()
|
||||||
{
|
{
|
||||||
foreach (var inspector in Inspectors)
|
for (int i = Inspectors.Count - 1; i >= 0; i--)
|
||||||
{
|
Inspectors[i].Update();
|
||||||
inspector.Update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void OnPanelResized()
|
internal static void OnPanelResized(float width)
|
||||||
{
|
{
|
||||||
|
PanelWidth = width;
|
||||||
|
|
||||||
|
foreach (var obj in Inspectors)
|
||||||
|
{
|
||||||
|
if (obj is ReflectionInspector inspector)
|
||||||
|
{
|
||||||
|
inspector.SetLayouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,265 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.Inspectors.CacheObject;
|
||||||
|
using UnityExplorer.UI.Inspectors.CacheObject.Views;
|
||||||
|
using UnityExplorer.UI.ObjectPool;
|
||||||
|
using UnityExplorer.UI.Panels;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.Widgets;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Inspectors
|
namespace UnityExplorer.UI.Inspectors
|
||||||
{
|
{
|
||||||
public class InstanceInspector : ReflectionInspector { }
|
public class ReflectionInspector : InspectorBase, IPoolDataSource<CacheMemberCell>
|
||||||
|
|
||||||
public class StaticInspector : ReflectionInspector { }
|
|
||||||
|
|
||||||
public class ReflectionInspector : InspectorBase
|
|
||||||
{
|
{
|
||||||
public override GameObject UIRoot => throw new NotImplementedException();
|
public bool StaticOnly { get; internal set; }
|
||||||
|
public bool AutoUpdate { get; internal set; }
|
||||||
|
|
||||||
public override GameObject CreateContent(GameObject content)
|
public object Target { get; private set; }
|
||||||
|
public Type TargetType { get; private set; }
|
||||||
|
|
||||||
|
public ScrollPool<CacheMemberCell> MemberScrollPool { get; private set; }
|
||||||
|
|
||||||
|
private List<CacheMember> members = new List<CacheMember>();
|
||||||
|
private readonly List<CacheMember> filteredMembers = new List<CacheMember>();
|
||||||
|
private readonly List<int> filteredIndices = new List<int>();
|
||||||
|
|
||||||
|
public override GameObject UIRoot => uiRoot;
|
||||||
|
private GameObject uiRoot;
|
||||||
|
|
||||||
|
public Text NameText;
|
||||||
|
public Text AssemblyText;
|
||||||
|
|
||||||
|
private LayoutElement memberTitleLayout;
|
||||||
|
private LayoutElement typeTitleLayout;
|
||||||
|
|
||||||
|
public override void OnBorrowedFromPool(object target)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
base.OnBorrowedFromPool(target);
|
||||||
|
|
||||||
|
SetTitleLayouts();
|
||||||
|
SetTarget(target);
|
||||||
|
|
||||||
|
RuntimeProvider.Instance.StartCoroutine(InitCoroutine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerator InitCoroutine()
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(InspectorPanel.Instance.ContentRect);
|
||||||
|
|
||||||
|
MemberScrollPool.RecreateHeightCache();
|
||||||
|
MemberScrollPool.Rebuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetTarget(object target)
|
||||||
|
{
|
||||||
|
string prefix;
|
||||||
|
if (StaticOnly)
|
||||||
|
{
|
||||||
|
Target = null;
|
||||||
|
TargetType = target as Type;
|
||||||
|
prefix = "[S]";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Target = target;
|
||||||
|
TargetType = target.GetActualType();
|
||||||
|
prefix = "[R]";
|
||||||
|
}
|
||||||
|
|
||||||
|
NameText.text = SignatureHighlighter.ParseFullSyntax(TargetType, true);
|
||||||
|
|
||||||
|
string asmText;
|
||||||
|
if (TargetType.Assembly != null && !string.IsNullOrEmpty(TargetType.Assembly.Location))
|
||||||
|
asmText = Path.GetFileName(TargetType.Assembly.Location);
|
||||||
|
else
|
||||||
|
asmText = $"{TargetType.Assembly.GetName().Name} <color=grey><i>(in memory)</i></color>";
|
||||||
|
AssemblyText.text = $"<color=grey>Assembly:</color> {asmText}";
|
||||||
|
|
||||||
|
Tab.TabText.text = $"{prefix} {SignatureHighlighter.HighlightTypeName(TargetType)}";
|
||||||
|
|
||||||
|
this.members = CacheMember.GetCacheMembers(Target, TargetType, this);
|
||||||
|
FilterMembers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FilterMembers()
|
||||||
|
{
|
||||||
|
// todo
|
||||||
|
for (int i = 0; i < members.Count; i++)
|
||||||
|
{
|
||||||
|
var member = members[i];
|
||||||
|
filteredMembers.Add(member);
|
||||||
|
filteredIndices.Add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnReturnToPool()
|
||||||
|
{
|
||||||
|
base.OnReturnToPool();
|
||||||
|
|
||||||
|
members.Clear();
|
||||||
|
filteredMembers.Clear();
|
||||||
|
filteredIndices.Clear();
|
||||||
|
|
||||||
|
// release all cachememberviews
|
||||||
|
MemberScrollPool.ReturnCells();
|
||||||
|
MemberScrollPool.SetUninitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnSetActive()
|
||||||
|
{
|
||||||
|
base.OnSetActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnSetInactive()
|
||||||
|
{
|
||||||
|
base.OnSetInactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float timeOfLastUpdate;
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (!this.IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!StaticOnly && Target.IsNullOrDestroyed(false))
|
||||||
|
{
|
||||||
|
InspectorManager.ReleaseInspector(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutoUpdate && Time.time - timeOfLastUpdate > 1f)
|
||||||
|
{
|
||||||
|
timeOfLastUpdate = Time.time;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnCloseClicked()
|
protected override void OnCloseClicked()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
InspectorManager.ReleaseInspector(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region IPoolDataSource
|
||||||
|
|
||||||
|
public int ItemCount => filteredMembers.Count;
|
||||||
|
|
||||||
|
public int GetRealIndexOfTempIndex(int tempIndex)
|
||||||
|
{
|
||||||
|
if (filteredIndices.Count <= tempIndex)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return filteredIndices[tempIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCellBorrowed(CacheMemberCell cell)
|
||||||
|
{
|
||||||
|
cell.CurrentOwner = this;
|
||||||
|
|
||||||
|
// todo add listeners
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCellReturned(CacheMemberCell cell)
|
||||||
|
{
|
||||||
|
// todo remove listeners
|
||||||
|
|
||||||
|
// return ivalue
|
||||||
|
|
||||||
|
cell.CurrentOwner = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCell(CacheMemberCell cell, int index)
|
||||||
|
{
|
||||||
|
index = GetRealIndexOfTempIndex(index);
|
||||||
|
|
||||||
|
if (index < 0 || index >= filteredMembers.Count)
|
||||||
|
{
|
||||||
|
cell.Disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
members[index].SetCell(cell);
|
||||||
|
|
||||||
|
SetCellLayout(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableCell(CacheMemberCell cell, int index)
|
||||||
|
{
|
||||||
|
// need to do anything?
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float MemLabelWidth => Math.Min(400f, 0.35f * InspectorManager.PanelWidth - 5);
|
||||||
|
private static float ReturnLabelWidth => Math.Min(225f, 0.25f * InspectorManager.PanelWidth - 5);
|
||||||
|
private static float RightGroupWidth => InspectorManager.PanelWidth - MemLabelWidth - ReturnLabelWidth - 50;
|
||||||
|
|
||||||
|
private void SetTitleLayouts()
|
||||||
|
{
|
||||||
|
memberTitleLayout.minWidth = MemLabelWidth;
|
||||||
|
typeTitleLayout.minWidth = ReturnLabelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCellLayout(CacheMemberCell cell)
|
||||||
|
{
|
||||||
|
cell.MemberLayout.minWidth = MemLabelWidth;
|
||||||
|
cell.ReturnTypeLayout.minWidth = ReturnLabelWidth;
|
||||||
|
cell.RightGroupLayout.minWidth = RightGroupWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetLayouts()
|
||||||
|
{
|
||||||
|
SetTitleLayouts();
|
||||||
|
|
||||||
|
foreach (var cell in MemberScrollPool.CellPool)
|
||||||
|
SetCellLayout(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override GameObject CreateContent(GameObject parent)
|
||||||
|
{
|
||||||
|
uiRoot = UIFactory.CreateVerticalGroup(parent, "ReflectionInspector", true, true, true, true, 5,
|
||||||
|
new Vector4(4, 4, 4, 4), new Color(0.12f, 0.12f, 0.12f));
|
||||||
|
|
||||||
|
NameText = UIFactory.CreateLabel(uiRoot, "Title", "not set", TextAnchor.MiddleLeft, fontSize: 20);
|
||||||
|
UIFactory.SetLayoutElement(NameText.gameObject, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
AssemblyText = UIFactory.CreateLabel(uiRoot, "AssemblyLabel", "not set", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(AssemblyText.gameObject, minHeight: 25, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
var listTitles = UIFactory.CreateUIObject("ListTitles", uiRoot);
|
||||||
|
UIFactory.SetLayoutElement(listTitles, minHeight: 25);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(listTitles, true, true, true, true, 5, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
var memberTitle = UIFactory.CreateLabel(listTitles, "MemberTitle", "Member Name", TextAnchor.LowerLeft, Color.grey, fontSize: 15);
|
||||||
|
memberTitleLayout = memberTitle.gameObject.AddComponent<LayoutElement>();
|
||||||
|
|
||||||
|
var typeTitle = UIFactory.CreateLabel(listTitles, "TypeTitle", "Type", TextAnchor.LowerLeft, Color.grey, fontSize: 15);
|
||||||
|
typeTitleLayout = typeTitle.gameObject.AddComponent<LayoutElement>();
|
||||||
|
|
||||||
|
var valueTitle = UIFactory.CreateLabel(listTitles, "ValueTitle", "Value", TextAnchor.LowerLeft, Color.grey, fontSize: 15);
|
||||||
|
UIFactory.SetLayoutElement(valueTitle.gameObject, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
MemberScrollPool = UIFactory.CreateScrollPool<CacheMemberCell>(uiRoot, "MemberList", out GameObject scrollObj,
|
||||||
|
out GameObject scrollContent, new Color(0.09f, 0.09f, 0.09f));
|
||||||
|
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||||
|
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
||||||
|
|
||||||
|
MemberScrollPool.Initialize(this);
|
||||||
|
|
||||||
|
//InspectorPanel.Instance.UIRoot.GetComponent<Mask>().enabled = false;
|
||||||
|
//MemberScrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||||
|
|
||||||
|
return uiRoot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,29 +6,44 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace UnityExplorer.UI.ObjectPool
|
namespace UnityExplorer.UI.ObjectPool
|
||||||
{
|
{
|
||||||
public interface IObjectPool { }
|
// Abstract non-generic class, handles the pool dictionary and interfacing with the generic pools.
|
||||||
|
public abstract class Pool
|
||||||
public class Pool<T> : IObjectPool where T : IPooledObject
|
|
||||||
{
|
{
|
||||||
// internal pool management
|
protected static readonly Dictionary<Type, Pool> pools = new Dictionary<Type, Pool>();
|
||||||
|
|
||||||
private static readonly Dictionary<Type, IObjectPool> pools = new Dictionary<Type, IObjectPool>();
|
public static Pool GetPool(Type type)
|
||||||
|
|
||||||
public static Pool<T> GetPool()
|
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
if (!pools.TryGetValue(type, out Pool pool))
|
||||||
if (!pools.ContainsKey(type))
|
pool = CreatePool(type);
|
||||||
CreatePool();
|
|
||||||
return (Pool<T>)pools[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pool<T> CreatePool()
|
|
||||||
{
|
|
||||||
var pool = new Pool<T>();
|
|
||||||
pools.Add(typeof(T), pool);
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Pool CreatePool(Type type)
|
||||||
|
{
|
||||||
|
Pool pool = (Pool)Activator.CreateInstance(typeof(Pool<>).MakeGenericType(new[] { type }));
|
||||||
|
pools.Add(type, pool);
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPooledObject Borrow(Type type)
|
||||||
|
{
|
||||||
|
return GetPool(type).TryBorrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Return(Type type, IPooledObject obj)
|
||||||
|
{
|
||||||
|
GetPool(type).TryReturn(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IPooledObject TryBorrow();
|
||||||
|
protected abstract void TryReturn(IPooledObject obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each generic implementation has its own pool, business logic is here
|
||||||
|
public class Pool<T> : Pool where T : IPooledObject
|
||||||
|
{
|
||||||
|
public static Pool<T> GetPool() => (Pool<T>)GetPool(typeof(T));
|
||||||
|
|
||||||
public static T Borrow()
|
public static T Borrow()
|
||||||
{
|
{
|
||||||
return GetPool().BorrowObject();
|
return GetPool().BorrowObject();
|
||||||
@ -43,7 +58,7 @@ namespace UnityExplorer.UI.ObjectPool
|
|||||||
|
|
||||||
public static Pool<T> Instance
|
public static Pool<T> Instance
|
||||||
{
|
{
|
||||||
get => s_instance ?? CreatePool();
|
get => s_instance ?? (Pool<T>)CreatePool(typeof(T));
|
||||||
}
|
}
|
||||||
private static Pool<T> s_instance;
|
private static Pool<T> s_instance;
|
||||||
|
|
||||||
@ -58,9 +73,7 @@ namespace UnityExplorer.UI.ObjectPool
|
|||||||
InactiveHolder.hideFlags |= HideFlags.HideAndDontSave;
|
InactiveHolder.hideFlags |= HideFlags.HideAndDontSave;
|
||||||
InactiveHolder.SetActive(false);
|
InactiveHolder.SetActive(false);
|
||||||
|
|
||||||
// Create an instance (not content) to grab the default height.
|
// Create an instance (not content) to grab the default height
|
||||||
// Tiny bit wasteful, but not a big deal, only happens once per type
|
|
||||||
// and its just the C# wrapper class being created.
|
|
||||||
var obj = (T)Activator.CreateInstance(typeof(T));
|
var obj = (T)Activator.CreateInstance(typeof(T));
|
||||||
DefaultHeight = obj.DefaultHeight;
|
DefaultHeight = obj.DefaultHeight;
|
||||||
}
|
}
|
||||||
@ -71,7 +84,7 @@ namespace UnityExplorer.UI.ObjectPool
|
|||||||
private readonly HashSet<T> available = new HashSet<T>();
|
private readonly HashSet<T> available = new HashSet<T>();
|
||||||
private readonly HashSet<T> borrowed = new HashSet<T>();
|
private readonly HashSet<T> borrowed = new HashSet<T>();
|
||||||
|
|
||||||
public int AvailableObjects => available.Count;
|
public int AvailableCount => available.Count;
|
||||||
|
|
||||||
private void IncrementPool()
|
private void IncrementPool()
|
||||||
{
|
{
|
||||||
@ -102,5 +115,9 @@ namespace UnityExplorer.UI.ObjectPool
|
|||||||
available.Add(obj);
|
available.Add(obj);
|
||||||
obj.UIRoot.transform.SetParent(InactiveHolder.transform, false);
|
obj.UIRoot.transform.SetParent(InactiveHolder.transform, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IPooledObject TryBorrow() => Borrow();
|
||||||
|
|
||||||
|
protected override void TryReturn(IPooledObject obj) => Return((T)obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace UnityExplorer.UI.Panels
|
|||||||
|
|
||||||
public GameObject NavbarHolder;
|
public GameObject NavbarHolder;
|
||||||
public GameObject ContentHolder;
|
public GameObject ContentHolder;
|
||||||
|
public RectTransform ContentRect;
|
||||||
|
|
||||||
public static float CurrentPanelWidth => Instance.mainPanelRect.rect.width;
|
public static float CurrentPanelWidth => Instance.mainPanelRect.rect.width;
|
||||||
|
|
||||||
@ -38,12 +39,14 @@ namespace UnityExplorer.UI.Panels
|
|||||||
{
|
{
|
||||||
base.OnFinishResize(panel);
|
base.OnFinishResize(panel);
|
||||||
|
|
||||||
InspectorManager.OnPanelResized();
|
InspectorManager.OnPanelResized(panel.rect.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadSaveData()
|
public override void LoadSaveData()
|
||||||
{
|
{
|
||||||
ApplySaveData(ConfigManager.GameObjectInspectorData.Value);
|
ApplySaveData(ConfigManager.GameObjectInspectorData.Value);
|
||||||
|
|
||||||
|
InspectorManager.PanelWidth = this.mainPanelRect.rect.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveToConfigManager()
|
public override void SaveToConfigManager()
|
||||||
@ -77,6 +80,7 @@ namespace UnityExplorer.UI.Panels
|
|||||||
this.ContentHolder = UIFactory.CreateVerticalGroup(this.content, "ContentHolder", true, true, true, true, 0, default,
|
this.ContentHolder = UIFactory.CreateVerticalGroup(this.content, "ContentHolder", true, true, true, true, 0, default,
|
||||||
new Color(0.1f, 0.1f, 0.1f));
|
new Color(0.1f, 0.1f, 0.1f));
|
||||||
UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999);
|
||||||
|
ContentRect = ContentHolder.GetComponent<RectTransform>();
|
||||||
|
|
||||||
UIManager.SetPanelActive(PanelType, false);
|
UIManager.SetPanelActive(PanelType, false);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
public SceneExplorer SceneExplorer;
|
public SceneExplorer SceneExplorer;
|
||||||
public ObjectSearch ObjectSearch;
|
public ObjectSearch ObjectSearch;
|
||||||
|
|
||||||
|
public override bool ShouldSaveActiveState => true;
|
||||||
|
|
||||||
public int SelectedTab = -1;
|
public int SelectedTab = -1;
|
||||||
private readonly List<UIModel> tabPages = new List<UIModel>();
|
private readonly List<UIModel> tabPages = new List<UIModel>();
|
||||||
private readonly List<ButtonRef> tabButtons = new List<ButtonRef>();
|
private readonly List<ButtonRef> tabButtons = new List<ButtonRef>();
|
||||||
|
@ -7,10 +7,10 @@ using UnityEngine;
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
using UnityExplorer.UI.Panels;
|
using UnityExplorer.UI.Models;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Models
|
namespace UnityExplorer.UI.Panels
|
||||||
{
|
{
|
||||||
public abstract class UIPanel : UIBehaviourModel
|
public abstract class UIPanel : UIBehaviourModel
|
||||||
{
|
{
|
||||||
@ -135,6 +135,7 @@ namespace UnityExplorer.UI.Models
|
|||||||
closeBtn.OnClick += () =>
|
closeBtn.OnClick += () =>
|
||||||
{
|
{
|
||||||
UIManager.SetPanelActive(this.PanelType, false);
|
UIManager.SetPanelActive(this.PanelType, false);
|
||||||
|
SaveToConfigManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!CanDrag)
|
if (!CanDrag)
|
||||||
@ -185,7 +186,7 @@ namespace UnityExplorer.UI.Models
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $"{(ShouldSaveActiveState ? Enabled : false)}" +
|
return $"{ShouldSaveActiveState && Enabled}" +
|
||||||
$"|{mainPanelRect.RectAnchorsToString()}" +
|
$"|{mainPanelRect.RectAnchorsToString()}" +
|
||||||
$"|{mainPanelRect.RectPositionToString()}";
|
$"|{mainPanelRect.RectPositionToString()}";
|
||||||
}
|
}
|
@ -732,7 +732,7 @@ namespace UnityExplorer.UI
|
|||||||
SetLayoutGroup<HorizontalLayoutGroup>(mainObj, false, true, true, true);
|
SetLayoutGroup<HorizontalLayoutGroup>(mainObj, false, true, true, true);
|
||||||
|
|
||||||
GameObject viewportObj = CreateUIObject("Viewport", mainObj);
|
GameObject viewportObj = CreateUIObject("Viewport", mainObj);
|
||||||
SetLayoutElement(viewportObj, flexibleWidth: 9999);
|
SetLayoutElement(viewportObj, flexibleWidth: 9999, flexibleHeight: 9999);
|
||||||
var viewportRect = viewportObj.GetComponent<RectTransform>();
|
var viewportRect = viewportObj.GetComponent<RectTransform>();
|
||||||
viewportRect.anchorMin = Vector2.zero;
|
viewportRect.anchorMin = Vector2.zero;
|
||||||
viewportRect.anchorMax = Vector2.one;
|
viewportRect.anchorMax = Vector2.one;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -54,25 +55,18 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
syntaxBuilder.Clear();
|
syntaxBuilder.Clear();
|
||||||
|
|
||||||
if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter))
|
if (includeNamespace && !string.IsNullOrEmpty(type.Namespace))
|
||||||
{
|
syntaxBuilder.Append($"<color={NAMESPACE}>{type.Namespace}</color>.");
|
||||||
syntaxBuilder.Append($"<color={CONST_VAR}>{type.Name}</color>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (includeNamespace && !string.IsNullOrEmpty(type.Namespace))
|
|
||||||
syntaxBuilder.Append($"<color={NAMESPACE}>{type.Namespace}</color>.");
|
|
||||||
|
|
||||||
var declaring = type.DeclaringType;
|
var declaring = type.DeclaringType;
|
||||||
while (declaring != null)
|
while (declaring != null)
|
||||||
{
|
{
|
||||||
syntaxBuilder.Append(HighlightTypeName(declaring) + ".");
|
syntaxBuilder.Append(HighlightTypeName(declaring) + ".");
|
||||||
declaring = declaring.DeclaringType;
|
declaring = declaring.DeclaringType;
|
||||||
}
|
|
||||||
|
|
||||||
syntaxBuilder.Append(HighlightTypeName(type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syntaxBuilder.Append(HighlightTypeName(type));
|
||||||
|
|
||||||
if (memberInfo != null)
|
if (memberInfo != null)
|
||||||
{
|
{
|
||||||
syntaxBuilder.Append('.');
|
syntaxBuilder.Append('.');
|
||||||
@ -96,37 +90,73 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
private static readonly Dictionary<string, string> typeToRichType = new Dictionary<string, string>();
|
private static readonly Dictionary<string, string> typeToRichType = new Dictionary<string, string>();
|
||||||
|
|
||||||
public static string HighlightTypeName(Type type)
|
public static string HighlightTypeName(Type type, bool includeNamespace = false, bool includeDllName = false)
|
||||||
{
|
{
|
||||||
if (typeToRichType.ContainsKey(type.AssemblyQualifiedName))
|
string ret = HighlightType(type);
|
||||||
return typeToRichType[type.AssemblyQualifiedName];
|
|
||||||
|
if (includeNamespace && !string.IsNullOrEmpty(type.Namespace))
|
||||||
|
ret = $"<color={NAMESPACE}>{type.Namespace}</color>.{ret}";
|
||||||
|
|
||||||
|
if (includeDllName)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(type.Assembly.Location))
|
||||||
|
ret = $"{ret} ({Path.GetFileName(type.Assembly.Location)})";
|
||||||
|
else
|
||||||
|
ret = $"{ret} ({type.Assembly.GetName().Name})";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string HighlightType(Type type)
|
||||||
|
{
|
||||||
|
string key = type.ToString();
|
||||||
|
if (typeToRichType.ContainsKey(key))
|
||||||
|
return typeToRichType[key];
|
||||||
|
|
||||||
var typeName = type.Name;
|
var typeName = type.Name;
|
||||||
|
|
||||||
var args = type.GetGenericArguments();
|
bool isArray = false;
|
||||||
|
if (typeName.EndsWith("[]"))
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
{
|
||||||
// remove the `N from the end of the type name
|
isArray = true;
|
||||||
// this could actually be >9 in some cases, so get the length of the length string and use that.
|
typeName = typeName.Substring(0, typeName.Length - 2);
|
||||||
// eg, if it was "List`15", we would remove the ending 3 chars
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlight the base name itself
|
if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter))
|
||||||
// do this after removing the `N suffix, so only the name itself is in the color tags.
|
{
|
||||||
typeName = $"<color={GetClassColor(type)}>{typeName}</color>";
|
typeName = $"<color={CONST_VAR}>{typeName}</color>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
|
||||||
// parse the generic args, if any
|
if (args.Length > 0)
|
||||||
if (args.Length > 0)
|
{
|
||||||
typeName += ParseGenericArgs(args);
|
// remove the `N from the end of the type name
|
||||||
|
// this could actually be >9 in some cases, so get the length of the length string and use that.
|
||||||
|
// eg, if it was "List`15", we would remove the ending 3 chars
|
||||||
|
|
||||||
typeToRichType.Add(type.AssemblyQualifiedName, typeName);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// highlight the base name itself
|
||||||
|
// do this after removing the `N suffix, so only the name itself is in the color tags.
|
||||||
|
typeName = $"<color={GetClassColor(type)}>{typeName}</color>";
|
||||||
|
|
||||||
|
// parse the generic args, if any
|
||||||
|
if (args.Length > 0)
|
||||||
|
typeName += ParseGenericArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArray)
|
||||||
|
typeName += "[]";
|
||||||
|
|
||||||
|
typeToRichType.Add(key, typeName);
|
||||||
|
|
||||||
return typeName;
|
return typeName;
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ namespace UnityExplorer.UI.Utility
|
|||||||
{
|
{
|
||||||
public static class ToStringUtility
|
public static class ToStringUtility
|
||||||
{
|
{
|
||||||
internal static Dictionary<Type, MethodInfo> toStringMethods = new Dictionary<Type, MethodInfo>();
|
internal static Dictionary<string, MethodInfo> toStringMethods = new Dictionary<string, MethodInfo>();
|
||||||
internal static Dictionary<Type, MethodInfo> toStringFormattedMethods = new Dictionary<Type, MethodInfo>();
|
internal static Dictionary<string, MethodInfo> toStringFormattedMethods = new Dictionary<string, MethodInfo>();
|
||||||
|
|
||||||
// string allocs
|
// string allocs
|
||||||
private static readonly StringBuilder _stringBuilder = new StringBuilder(16384);
|
private static readonly StringBuilder _stringBuilder = new StringBuilder(16384);
|
||||||
@ -20,18 +20,54 @@ namespace UnityExplorer.UI.Utility
|
|||||||
private const string nullString = "<color=grey>[null]</color>";
|
private const string nullString = "<color=grey>[null]</color>";
|
||||||
private const string destroyedString = "<color=red>[Destroyed]</color>";
|
private const string destroyedString = "<color=red>[Destroyed]</color>";
|
||||||
|
|
||||||
public static string ToString(object value, Type fallbackType, bool includeNamespace = true, bool includeName = true)
|
public static string ToString(object value, Type type)
|
||||||
|
{
|
||||||
|
if (value.IsNullOrDestroyed())
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return nullString;
|
||||||
|
else // destroyed unity object
|
||||||
|
return destroyedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toStringMethods.ContainsKey(type.AssemblyQualifiedName))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var formatMethod = type.GetMethod("ToString", new Type[] { typeof(string) });
|
||||||
|
formatMethod.Invoke(value, new object[] { "F3" });
|
||||||
|
toStringFormattedMethods.Add(type.AssemblyQualifiedName, formatMethod);
|
||||||
|
toStringMethods.Add(type.AssemblyQualifiedName, null);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
var toStringMethod = type.GetMethod("ToString", new Type[0]);
|
||||||
|
toStringMethods.Add(type.AssemblyQualifiedName, toStringMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
|
||||||
|
return toString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToStringWithType(object value, Type fallbackType, bool includeNamespace = true)
|
||||||
{
|
{
|
||||||
if (value == null && fallbackType == null)
|
if (value == null && fallbackType == null)
|
||||||
return unknownString;
|
return unknownString;
|
||||||
|
|
||||||
Type type = value?.GetActualType() ?? fallbackType;
|
Type type = value?.GetActualType() ?? fallbackType;
|
||||||
|
|
||||||
// todo SB this too
|
|
||||||
string richType = SignatureHighlighter.ParseFullSyntax(type, includeNamespace);
|
string richType = SignatureHighlighter.ParseFullSyntax(type, includeNamespace);
|
||||||
|
|
||||||
if (!includeName)
|
//if (!includeName)
|
||||||
return richType;
|
// return richType;
|
||||||
|
|
||||||
_stringBuilder.Clear();
|
_stringBuilder.Clear();
|
||||||
|
|
||||||
@ -58,33 +94,9 @@ namespace UnityExplorer.UI.Utility
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!toStringMethods.ContainsKey(type))
|
var toString = ToString(value, type);
|
||||||
{
|
|
||||||
var toStringMethod = type.GetMethod("ToString", new Type[0]);
|
|
||||||
var formatMethod = type.GetMethod("ToString", new Type[] { typeof(string) });
|
|
||||||
|
|
||||||
if (formatMethod != null)
|
if (toString == type.FullName || toString == $"Il2Cpp{type.FullName}" || type.FullName == $"Il2Cpp{toString}")
|
||||||
{
|
|
||||||
try { formatMethod.Invoke(value, new object[] { "F3" }); }
|
|
||||||
catch { formatMethod = null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
toStringMethods.Add(type, toStringMethod);
|
|
||||||
toStringFormattedMethods.Add(type, formatMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
var f3Method = toStringFormattedMethods[type];
|
|
||||||
var stdMethod = toStringMethods[type];
|
|
||||||
|
|
||||||
value = value.TryCast(type);
|
|
||||||
|
|
||||||
string toString;
|
|
||||||
if (f3Method != null)
|
|
||||||
toString = (string)f3Method.Invoke(value, new object[] { "F3" });
|
|
||||||
else
|
|
||||||
toString = (string)stdMethod.Invoke(value, new object[0]);
|
|
||||||
|
|
||||||
if (toString == type.FullName || toString == $"Il2Cpp{type.FullName}")
|
|
||||||
{
|
{
|
||||||
// the ToString was just the default object.ToString(), use our
|
// the ToString was just the default object.ToString(), use our
|
||||||
// syntax highlighted type name instead.
|
// syntax highlighted type name instead.
|
||||||
@ -99,36 +111,6 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
AppendRichType(_stringBuilder, richType);
|
AppendRichType(_stringBuilder, richType);
|
||||||
}
|
}
|
||||||
|
|
||||||
////string toString;
|
|
||||||
|
|
||||||
//
|
|
||||||
//toString = toString ?? "";
|
|
||||||
//
|
|
||||||
//string typeName = type.FullName;
|
|
||||||
//if (typeName.StartsWith("Il2CppSystem."))
|
|
||||||
// typeName = typeName.Substring(6, typeName.Length - 6);
|
|
||||||
//
|
|
||||||
//toString = ReflectionProvider.Instance.ProcessTypeFullNameInString(type, toString, ref typeName);
|
|
||||||
//
|
|
||||||
//// If the ToString is just the type name, use our syntax highlighted type name instead.
|
|
||||||
//if (toString == typeName)
|
|
||||||
//{
|
|
||||||
// label = richType;
|
|
||||||
//}
|
|
||||||
//else // Otherwise, parse the result and put our highlighted name in.
|
|
||||||
//{
|
|
||||||
// if (toString.Length > 200)
|
|
||||||
// toString = toString.Substring(0, 200) + "...";
|
|
||||||
//
|
|
||||||
// label = toString;
|
|
||||||
//
|
|
||||||
// var unityType = $"({type.FullName})";
|
|
||||||
// if (value is UnityEngine.Object && label.Contains(unityType))
|
|
||||||
// label = label.Replace(unityType, $"({richType})");
|
|
||||||
// else
|
|
||||||
// label += $" ({richType})";
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _stringBuilder.ToString();
|
return _stringBuilder.ToString();
|
||||||
|
@ -7,8 +7,8 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Models;
|
|
||||||
using UnityExplorer.UI.ObjectPool;
|
using UnityExplorer.UI.ObjectPool;
|
||||||
|
using UnityExplorer.UI.Panels;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets.AutoComplete
|
namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||||
{
|
{
|
||||||
|
@ -15,13 +15,13 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public Action<int> OnClick;
|
public Action<int> OnClick;
|
||||||
public int CurrentDataIndex;
|
public int CurrentDataIndex;
|
||||||
|
|
||||||
public GameObject UIRoot => uiRoot;
|
|
||||||
public GameObject uiRoot;
|
|
||||||
|
|
||||||
public ButtonRef Button;
|
public ButtonRef Button;
|
||||||
|
|
||||||
#region ICell
|
#region ICell
|
||||||
|
|
||||||
|
public GameObject UIRoot => uiRoot;
|
||||||
|
public GameObject uiRoot;
|
||||||
|
|
||||||
public bool Enabled => m_enabled;
|
public bool Enabled => m_enabled;
|
||||||
private bool m_enabled;
|
private bool m_enabled;
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
Button.OnClick += () => { OnClick?.Invoke(CurrentDataIndex); };
|
Button.OnClick += () => { OnClick?.Invoke(CurrentDataIndex); };
|
||||||
|
|
||||||
return m_rect.gameObject;
|
return uiRoot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,9 +97,9 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
string text;
|
string text;
|
||||||
if (m_context == SearchContext.StaticClass)
|
if (m_context == SearchContext.StaticClass)
|
||||||
text = SignatureHighlighter.HighlightTypeName(currentResults[index].GetActualType());
|
text = SignatureHighlighter.HighlightTypeName(currentResults[index] as Type, true, true);
|
||||||
else
|
else
|
||||||
text = ToStringUtility.ToString(currentResults[index], currentResults[index].GetActualType());
|
text = ToStringUtility.ToStringWithType(currentResults[index], currentResults[index]?.GetActualType());
|
||||||
|
|
||||||
cachedCellTexts.Add(index, text);
|
cachedCellTexts.Add(index, text);
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
private void OnCellClicked(int dataIndex)
|
private void OnCellClicked(int dataIndex)
|
||||||
{
|
{
|
||||||
if (m_context == SearchContext.StaticClass)
|
if (m_context == SearchContext.StaticClass)
|
||||||
InspectorManager.Inspect(currentResults[dataIndex] as Type);
|
InspectorManager.InspectStatic(currentResults[dataIndex] as Type);
|
||||||
else
|
else
|
||||||
InspectorManager.Inspect(currentResults[dataIndex]);
|
InspectorManager.Inspect(currentResults[dataIndex]);
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,6 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public int cellIndex, dataIndex;
|
public int cellIndex, dataIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public abstract class ScrollPool : UIBehaviourModel
|
|
||||||
//{
|
|
||||||
// public abstract IPoolDataSource DataSource { get; set; }
|
|
||||||
// public abstract RectTransform PrototypeCell { get; }
|
|
||||||
//
|
|
||||||
// public abstract void Initialize(IPoolDataSource dataSource);
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An object-pooled ScrollRect, attempts to support content of any size and provide a scrollbar for it.
|
/// An object-pooled ScrollRect, attempts to support content of any size and provide a scrollbar for it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,12 +28,16 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public IPoolDataSource<T> DataSource { get; set; }
|
public IPoolDataSource<T> DataSource { get; set; }
|
||||||
|
|
||||||
|
public readonly List<T> CellPool = new List<T>();
|
||||||
|
|
||||||
|
internal DataHeightCache<T> HeightCache;
|
||||||
|
|
||||||
public float PrototypeHeight => _protoHeight ?? (float)(_protoHeight = Pool<T>.Instance.DefaultHeight);
|
public float PrototypeHeight => _protoHeight ?? (float)(_protoHeight = Pool<T>.Instance.DefaultHeight);
|
||||||
private float? _protoHeight;
|
private float? _protoHeight;
|
||||||
|
|
||||||
//private float PrototypeHeight => DefaultHeight.rect.height;
|
//private float PrototypeHeight => DefaultHeight.rect.height;
|
||||||
|
|
||||||
public int ExtraPoolCells => 6;
|
public int ExtraPoolCells => 10;
|
||||||
public float RecycleThreshold => PrototypeHeight * ExtraPoolCells;
|
public float RecycleThreshold => PrototypeHeight * ExtraPoolCells;
|
||||||
public float HalfThreshold => RecycleThreshold * 0.5f;
|
public float HalfThreshold => RecycleThreshold * 0.5f;
|
||||||
|
|
||||||
@ -76,10 +71,6 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
private int bottomDataIndex;
|
private int bottomDataIndex;
|
||||||
private int TopDataIndex => Math.Max(0, bottomDataIndex - CellPool.Count + 1);
|
private int TopDataIndex => Math.Max(0, bottomDataIndex - CellPool.Count + 1);
|
||||||
|
|
||||||
private readonly List<T> CellPool = new List<T>();
|
|
||||||
|
|
||||||
internal DataHeightCache<T> HeightCache;
|
|
||||||
|
|
||||||
private float TotalDataHeight => HeightCache.TotalHeight + contentLayout.padding.top + contentLayout.padding.bottom;
|
private float TotalDataHeight => HeightCache.TotalHeight + contentLayout.padding.top + contentLayout.padding.bottom;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -269,12 +260,12 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
if (andResetDataIndex)
|
if (andResetDataIndex)
|
||||||
bottomDataIndex = CellPool.Count - 1;
|
bottomDataIndex = CellPool.Count - 1;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
|
||||||
|
|
||||||
// after creating pool, set displayed cells.
|
// after creating pool, set displayed cells.
|
||||||
var enumerator = GetPoolEnumerator();
|
var enumerator = GetPoolEnumerator();
|
||||||
while (enumerator.MoveNext())
|
while (enumerator.MoveNext())
|
||||||
SetCell(CellPool[enumerator.Current.cellIndex], enumerator.Current.dataIndex);
|
SetCell(CellPool[enumerator.Current.cellIndex], enumerator.Current.dataIndex);
|
||||||
|
|
||||||
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>ret = cell pool was extended</summary>
|
/// <summary>ret = cell pool was extended</summary>
|
||||||
@ -303,13 +294,13 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
WritingLocked = true;
|
WritingLocked = true;
|
||||||
|
|
||||||
// Disable cells so DataSource can handle its content if need be
|
//// Disable cells so DataSource can handle its content if need be
|
||||||
var enumerator = GetPoolEnumerator();
|
//var enumerator = GetPoolEnumerator();
|
||||||
while (enumerator.MoveNext())
|
//while (enumerator.MoveNext())
|
||||||
{
|
//{
|
||||||
var curr = enumerator.Current;
|
// var curr = enumerator.Current;
|
||||||
DataSource.DisableCell(CellPool[curr.cellIndex], curr.dataIndex);
|
// DataSource.DisableCell(CellPool[curr.cellIndex], curr.dataIndex);
|
||||||
}
|
//}
|
||||||
|
|
||||||
bottomDataIndex += cellsRequired;
|
bottomDataIndex += cellsRequired;
|
||||||
int maxDataIndex = Math.Max(CellPool.Count + cellsRequired - 1, DataSource.ItemCount - 1);
|
int maxDataIndex = Math.Max(CellPool.Count + cellsRequired - 1, DataSource.ItemCount - 1);
|
||||||
@ -438,14 +429,16 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
private void OnValueChangedListener(Vector2 val)
|
private void OnValueChangedListener(Vector2 val)
|
||||||
{
|
{
|
||||||
if (WritingLocked)
|
if (WritingLocked || !m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (InputManager.MouseScrollDelta != Vector2.zero)
|
if (InputManager.MouseScrollDelta != Vector2.zero)
|
||||||
ScrollRect.StopMovement();
|
ScrollRect.StopMovement();
|
||||||
|
|
||||||
if (!SetRecycleViewBounds(true))
|
SetRecycleViewBounds(true);
|
||||||
RefreshCells(false);
|
|
||||||
|
//if (!SetRecycleViewBounds(true))
|
||||||
|
// RefreshCells(false);
|
||||||
|
|
||||||
float yChange = (ScrollRect.content.anchoredPosition - prevAnchoredPos).y;
|
float yChange = (ScrollRect.content.anchoredPosition - prevAnchoredPos).y;
|
||||||
float adjust = 0f;
|
float adjust = 0f;
|
||||||
@ -605,7 +598,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
private void OnSliderValueChanged(float val)
|
private void OnSliderValueChanged(float val)
|
||||||
{
|
{
|
||||||
if (this.WritingLocked)
|
if (this.WritingLocked || !m_initialized)
|
||||||
return;
|
return;
|
||||||
this.WritingLocked = true;
|
this.WritingLocked = true;
|
||||||
|
|
||||||
|
@ -230,10 +230,18 @@
|
|||||||
<Compile Include="Inspectors_OLD\Reflection\InstanceInspector.cs" />
|
<Compile Include="Inspectors_OLD\Reflection\InstanceInspector.cs" />
|
||||||
<Compile Include="Inspectors_OLD\Reflection\ReflectionInspector.cs" />
|
<Compile Include="Inspectors_OLD\Reflection\ReflectionInspector.cs" />
|
||||||
<Compile Include="Inspectors_OLD\Reflection\StaticInspector.cs" />
|
<Compile Include="Inspectors_OLD\Reflection\StaticInspector.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\CacheField.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\CacheMember.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\CacheMethod.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\CacheObjectBase.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\CacheProperty.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\Views\CacheMemberCell.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\CacheObject\Views\CacheObjectCell.cs" />
|
||||||
<Compile Include="UI\Inspectors\GameObjectInspector.cs" />
|
<Compile Include="UI\Inspectors\GameObjectInspector.cs" />
|
||||||
<Compile Include="UI\Inspectors\InspectorManager.cs" />
|
<Compile Include="UI\Inspectors\InspectorManager.cs" />
|
||||||
<Compile Include="UI\Inspectors\InspectorTab.cs" />
|
<Compile Include="UI\Inspectors\InspectorTab.cs" />
|
||||||
<Compile Include="UI\Inspectors\InspectorBase.cs" />
|
<Compile Include="UI\Inspectors\InspectorBase.cs" />
|
||||||
|
<Compile Include="UI\Inspectors\IValues\IValueTest.cs" />
|
||||||
<Compile Include="UI\Inspectors\ReflectionInspector.cs" />
|
<Compile Include="UI\Inspectors\ReflectionInspector.cs" />
|
||||||
<Compile Include="UI\ObjectPool\IPooledObject.cs" />
|
<Compile Include="UI\ObjectPool\IPooledObject.cs" />
|
||||||
<Compile Include="UI\ObjectPool\Pool.cs" />
|
<Compile Include="UI\ObjectPool\Pool.cs" />
|
||||||
@ -282,7 +290,7 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="UI\Models\UIBehaviourModel.cs" />
|
<Compile Include="UI\Models\UIBehaviourModel.cs" />
|
||||||
<Compile Include="UI\Models\UIModel.cs" />
|
<Compile Include="UI\Models\UIModel.cs" />
|
||||||
<Compile Include="UI\Models\UIPanel.cs" />
|
<Compile Include="UI\Panels\UIPanel.cs" />
|
||||||
<Compile Include="UI\Panels\InspectorPanel.cs" />
|
<Compile Include="UI\Panels\InspectorPanel.cs" />
|
||||||
<Compile Include="UI\Panels\ObjectExplorer.cs" />
|
<Compile Include="UI\Panels\ObjectExplorer.cs" />
|
||||||
<Compile Include="UI\UIFactory.cs" />
|
<Compile Include="UI\UIFactory.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user