InteractiveBool, Il2Cpp>Mono type dict cache, some UI fixes

This commit is contained in:
sinaioutlander 2020-11-16 00:50:06 +11:00
parent 41f0b0ed55
commit 8acc85061d
21 changed files with 323 additions and 234 deletions

View File

@ -388,11 +388,11 @@ The following helper methods are available:
autoIndentToggle.onValueChanged.AddListener(OnIndentChanged); autoIndentToggle.onValueChanged.AddListener(OnIndentChanged);
void OnIndentChanged(bool val) => EnableAutoIndent = val; void OnIndentChanged(bool val) => EnableAutoIndent = val;
autoIndentToggleText.text = "Auto-indent"; autoIndentToggleText.text = "Auto-indent on Enter";
autoIndentToggleText.alignment = TextAnchor.UpperLeft; autoIndentToggleText.alignment = TextAnchor.UpperLeft;
var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>(); var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>();
autoIndentLayout.minWidth = 120; autoIndentLayout.minWidth = 180;
autoIndentLayout.flexibleWidth = 0; autoIndentLayout.flexibleWidth = 0;
autoIndentLayout.minHeight = 25; autoIndentLayout.minHeight = 25;

View File

@ -8,7 +8,7 @@ using UnityEngine;
using BF = System.Reflection.BindingFlags; using BF = System.Reflection.BindingFlags;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
#if CPP #if CPP
using ILType = Il2CppSystem.Type; using CppType = Il2CppSystem.Type;
using UnhollowerBaseLib; using UnhollowerBaseLib;
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -61,16 +61,16 @@ namespace UnityExplorer.Helpers
#if CPP #if CPP
if (obj is Il2CppSystem.Object ilObject) if (obj is Il2CppSystem.Object ilObject)
{ {
if (obj is ILType) if (ilObject is CppType)
return typeof(ILType); return typeof(CppType);
if (!string.IsNullOrEmpty(type.Namespace)) if (!string.IsNullOrEmpty(type.Namespace))
{ {
// Il2CppSystem-namespace objects should just return GetType, // Il2CppSystem-namespace objects should just return GetType,
// because using GetIl2CppType returns the System namespace type instead. // because using GetIl2CppType returns the System namespace type instead.
if (type.Namespace.StartsWith("System.") || type.Namespace.StartsWith("Il2CppSystem.")) if (type.Namespace.StartsWith("System.") || type.Namespace.StartsWith("Il2CppSystem."))
return ilObject.GetType(); return ilObject.GetType();
} }
var il2cppType = ilObject.GetIl2CppType(); var il2cppType = ilObject.GetIl2CppType();
@ -79,8 +79,8 @@ namespace UnityExplorer.Helpers
if (RuntimeSpecificsStore.IsInjected(classPtr)) if (RuntimeSpecificsStore.IsInjected(classPtr))
return GetTypeByName(il2cppType.FullName); return GetTypeByName(il2cppType.FullName);
var getType = Type.GetType(il2cppType.AssemblyQualifiedName); // this should be fine for all other il2cpp objects
var getType = GetMonoType(il2cppType);
if (getType != null) if (getType != null)
return getType; return getType;
} }
@ -89,6 +89,18 @@ namespace UnityExplorer.Helpers
} }
#if CPP #if CPP
private static readonly Dictionary<CppType, Type> Il2CppToMonoType = new Dictionary<CppType, Type>();
public static Type GetMonoType(CppType cppType)
{
if (Il2CppToMonoType.ContainsKey(cppType))
return Il2CppToMonoType[cppType];
var getType = Type.GetType(cppType.AssemblyQualifiedName);
Il2CppToMonoType.Add(cppType, getType);
return getType;
}
private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>(); private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>();
public static object Il2CppCast(this object obj, Type castTo) public static object Il2CppCast(this object obj, Type castTo)

View File

@ -4,7 +4,6 @@ using System.Linq;
using UnityExplorer.Helpers; using UnityExplorer.Helpers;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Shared; using UnityExplorer.UI.Shared;
//using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Input; using UnityExplorer.Input;

View File

@ -496,25 +496,6 @@ namespace UnityExplorer.Inspectors.GameObjects
valueLabelLayout.flexibleWidth = 0; valueLabelLayout.flexibleWidth = 0;
valueLabelLayout.minHeight = 25; valueLabelLayout.minHeight = 25;
// Slider
var sliderObj = UIFactory.CreateSlider(rowObject);
sliderObj.transform.Find("Fill Area").gameObject.SetActive(false);
var sliderLayout = sliderObj.AddComponent<LayoutElement>();
sliderLayout.minHeight = 20;
sliderLayout.flexibleHeight = 0;
sliderLayout.minWidth = 200;
sliderLayout.flexibleWidth = 9000;
var slider = sliderObj.GetComponent<Slider>();
var sliderColors = slider.colors;
sliderColors.normalColor = new Color(0.65f, 0.65f, 0.65f);
slider.colors = sliderColors;
slider.minValue = -2;
slider.maxValue = 2;
slider.value = 0;
slider.onValueChanged.AddListener((float val) => { OnSliderControlChanged(val, slider, type, vectorValue); });
editor.sliders[(int)vectorValue] = slider;
// input field // input field
var inputHolder = UIFactory.CreateVerticalGroup(rowObject, new Color(1, 1, 1, 0)); var inputHolder = UIFactory.CreateVerticalGroup(rowObject, new Color(1, 1, 1, 0));
@ -549,6 +530,25 @@ namespace UnityExplorer.Inspectors.GameObjects
applyBtn.onClick.AddListener(() => { OnVectorControlInputApplied(type, vectorValue); }); applyBtn.onClick.AddListener(() => { OnVectorControlInputApplied(type, vectorValue); });
// Slider
var sliderObj = UIFactory.CreateSlider(rowObject);
sliderObj.transform.Find("Fill Area").gameObject.SetActive(false);
var sliderLayout = sliderObj.AddComponent<LayoutElement>();
sliderLayout.minHeight = 20;
sliderLayout.flexibleHeight = 0;
sliderLayout.minWidth = 200;
sliderLayout.flexibleWidth = 9000;
var slider = sliderObj.GetComponent<Slider>();
var sliderColors = slider.colors;
sliderColors.normalColor = new Color(0.65f, 0.65f, 0.65f);
slider.colors = sliderColors;
slider.minValue = -2;
slider.maxValue = 2;
slider.value = 0;
slider.onValueChanged.AddListener((float val) => { OnSliderControlChanged(val, slider, type, vectorValue); });
editor.sliders[(int)vectorValue] = slider;
return rowObject; return rowObject;
} }

View File

@ -9,7 +9,7 @@ using UnityEngine.UI;
namespace UnityExplorer.Inspectors.Reflection namespace UnityExplorer.Inspectors.Reflection
{ {
public class CacheEnumerated : CacheObjectBase, INestedValue public class CacheEnumerated : CacheObjectBase
{ {
public override Type FallbackType => ParentEnumeration.m_baseEntryType; public override Type FallbackType => ParentEnumeration.m_baseEntryType;
public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite; public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite;
@ -40,11 +40,6 @@ namespace UnityExplorer.Inspectors.Reflection
ParentEnumeration.OwnerCacheObject.SetValue(); ParentEnumeration.OwnerCacheObject.SetValue();
} }
public void UpdateSubcontentHeight()
{
ParentEnumeration.UpdateSubcontentHeight();
}
internal override void ConstructUI() internal override void ConstructUI()
{ {
base.ConstructUI(); base.ConstructUI();

View File

@ -1,60 +0,0 @@
using System;
using System.Reflection;
using UnityEngine;
using UnityExplorer.Helpers;
namespace UnityExplorer.Inspectors.Reflection
{
public static class CacheFactory
{
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
{
CacheMember ret;
if (member is MethodInfo mi && CanProcessArgs(mi.GetParameters()))
{
ret = new CacheMethod(mi, declaringInstance);
}
else if (member is PropertyInfo pi && CanProcessArgs(pi.GetIndexParameters()))
{
ret = new CacheProperty(pi, declaringInstance);
}
else if (member is FieldInfo fi)
{
ret = new CacheField(fi, declaringInstance);
}
else
{
return null;
}
ret.m_parentContent = parentUIContent;
return ret;
}
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;
}
}
}

View File

@ -50,6 +50,23 @@ namespace UnityExplorer.Inspectors.Reflection
DeclaringInstance = declaringInstance; DeclaringInstance = declaringInstance;
} }
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 override void CreateIValue(object value, Type fallbackType) public override void CreateIValue(object value, Type fallbackType)
{ {
IValue = InteractiveValue.Create(value, fallbackType); IValue = InteractiveValue.Create(value, fallbackType);

View File

@ -63,6 +63,8 @@ namespace UnityExplorer.Inspectors.Reflection
} }
IValue.OnValueUpdated(); IValue.OnValueUpdated();
IValue.RefreshElementsAfterUpdate();
} }
public virtual void SetValue() => throw new NotImplementedException(); public virtual void SetValue() => throw new NotImplementedException();

View File

@ -16,7 +16,7 @@ namespace UnityExplorer.Inspectors.Reflection
Value Value
} }
public class CachePaired : CacheObjectBase, INestedValue public class CachePaired : CacheObjectBase
{ {
public override Type FallbackType => PairType == PairTypes.Key public override Type FallbackType => PairType == PairTypes.Key
? ParentDictionary.m_typeOfKeys ? ParentDictionary.m_typeOfKeys
@ -27,13 +27,13 @@ namespace UnityExplorer.Inspectors.Reflection
public PairTypes PairType; public PairTypes PairType;
public int Index { get; private set; } public int Index { get; private set; }
public InteractiveDictionary ParentDictionary { get; private set; } public InteractiveDictionary ParentDictionary { get; private set; }
internal IDictionary RefIDIct; internal IDictionary RefIDict;
public CachePaired(int index, InteractiveDictionary parentDict, IDictionary refIDict, PairTypes pairType, GameObject parentContent) public CachePaired(int index, InteractiveDictionary parentDict, IDictionary refIDict, PairTypes pairType, GameObject parentContent)
{ {
Index = index; Index = index;
ParentDictionary = parentDict; ParentDictionary = parentDict;
RefIDIct = refIDict; RefIDict = refIDict;
this.PairType = pairType; this.PairType = pairType;
this.m_parentContent = parentContent; this.m_parentContent = parentContent;
} }
@ -44,11 +44,6 @@ namespace UnityExplorer.Inspectors.Reflection
IValue.OwnerCacheObject = this; IValue.OwnerCacheObject = this;
} }
public void UpdateSubcontentHeight()
{
ParentDictionary.UpdateSubcontentHeight();
}
#region UI CONSTRUCTION #region UI CONSTRUCTION
internal override void ConstructUI() internal override void ConstructUI()

View File

@ -43,7 +43,7 @@ namespace UnityExplorer.Inspectors.Reflection
} }
else else
{ {
// todo write-only properties // todo write-only properties?
} }
} }

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Inspectors.Reflection
{
public interface INestedValue
{
void UpdateSubcontentHeight();
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Helpers;
using UnityExplorer.UI;
namespace UnityExplorer.Inspectors.Reflection
{
public class InteractiveBool : InteractiveValue
{
public InteractiveBool(object value, Type valueType) : base(value, valueType)
{
}
public override IValueTypes IValueType => IValueTypes.Bool;
public override bool HasSubContent => false;
public override bool SubContentWanted => false;
public override bool WantInspectBtn => false;
internal Toggle m_toggle;
public override void OnValueUpdated()
{
base.OnValueUpdated();
if (!Value.IsNullOrDestroyed())
{
if (OwnerCacheObject.CanWrite)
{
if (!m_toggle.gameObject.activeSelf)
m_toggle.gameObject.SetActive(true);
var val = (bool)Value;
if (m_toggle.isOn != val)
m_toggle.isOn = val;
}
RefreshUIElements();
}
}
internal void RefreshUIElements()
{
if (m_baseLabel)
{
var val = (bool)Value;
var color = val
? "00FF00" // on
: "FF0000"; // off
m_baseLabel.text = $"<color=#{color}>{val}</color> ({m_richValueType})";
}
}
internal void OnToggleValueChanged(bool val)
{
Value = val;
OwnerCacheObject.SetValue();
RefreshUIElements();
}
public override void ConstructUI(GameObject parent, GameObject subGroup)
{
base.ConstructUI(parent, subGroup);
if (OwnerCacheObject.CanWrite)
{
var toggleObj = UIFactory.CreateToggle(m_valueContent, out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f));
toggleObj.SetActive(false);
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
toggleLayout.minWidth = 24;
m_toggle.onValueChanged.AddListener(OnToggleValueChanged);
m_baseLabel.transform.SetAsLastSibling();
}
}
}
}

View File

@ -31,6 +31,7 @@ namespace UnityExplorer.Inspectors.Reflection
public override IValueTypes IValueType => IValueTypes.Dictionary; public override IValueTypes IValueType => IValueTypes.Dictionary;
public override bool HasSubContent => true; public override bool HasSubContent => true;
public override bool SubContentWanted => (RefIDictionary?.Count ?? 1) > 0;
public override bool WantInspectBtn => false; public override bool WantInspectBtn => false;
internal IDictionary RefIDictionary; internal IDictionary RefIDictionary;
@ -44,8 +45,6 @@ namespace UnityExplorer.Inspectors.Reflection
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
= new KeyValuePair<CachePaired, CachePaired>[ModConfig.Instance.Default_Page_Limit]; = 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; internal bool m_recacheWanted = true;
public override void OnDestroy() public override void OnDestroy()
@ -176,7 +175,7 @@ namespace UnityExplorer.Inspectors.Reflection
entry.Value.Enable(); entry.Value.Enable();
} }
UpdateSubcontentHeight(); //UpdateSubcontentHeight();
} }
internal override void OnToggleSubcontent(bool active) internal override void OnToggleSubcontent(bool active)
@ -193,38 +192,6 @@ namespace UnityExplorer.Inspectors.Reflection
RefreshDisplay(); 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 #region UI CONSTRUCTION
internal GameObject m_listContent; internal GameObject m_listContent;

View File

@ -25,6 +25,7 @@ namespace UnityExplorer.Inspectors.Reflection
public override IValueTypes IValueType => IValueTypes.Enumerable; public override IValueTypes IValueType => IValueTypes.Enumerable;
public override bool HasSubContent => true; public override bool HasSubContent => true;
public override bool SubContentWanted => (RefIList?.Count ?? 1) > 0;
public override bool WantInspectBtn => false; public override bool WantInspectBtn => false;
internal IEnumerable RefIEnumerable; internal IEnumerable RefIEnumerable;
@ -137,7 +138,7 @@ namespace UnityExplorer.Inspectors.Reflection
entry.Enable(); entry.Enable();
} }
UpdateSubcontentHeight(); //UpdateSubcontentHeight();
} }
internal override void OnToggleSubcontent(bool active) internal override void OnToggleSubcontent(bool active)
@ -154,36 +155,6 @@ namespace UnityExplorer.Inspectors.Reflection
RefreshDisplay(); 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 #region UI CONSTRUCTION
internal GameObject m_listContent; internal GameObject m_listContent;

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UnityExplorer.Inspectors.Reflection
{
public class InteractiveNumber : InteractiveValue
{
public InteractiveNumber(object value, Type valueType) : base(value, valueType)
{
}
public override IValueTypes IValueType => IValueTypes.Number;
public override bool HasSubContent => false;
public override bool SubContentWanted => false;
public override bool WantInspectBtn => false;
public override void ConstructUI(GameObject parent, GameObject subGroup)
{
base.ConstructUI(parent, subGroup);
}
public override void OnValueUpdated()
{
base.OnValueUpdated();
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UnityExplorer.Inspectors.Reflection
{
public class InteractiveString : InteractiveValue
{
public InteractiveString(object value, Type valueType) : base(value, valueType)
{
}
public override IValueTypes IValueType => IValueTypes.String;
public override bool HasSubContent => false;
public override bool SubContentWanted => false;
public override bool WantInspectBtn => false;
public override void ConstructUI(GameObject parent, GameObject subGroup)
{
base.ConstructUI(parent, subGroup);
}
public override void OnValueUpdated()
{
base.OnValueUpdated();
}
}
}

View File

@ -16,6 +16,13 @@ namespace UnityExplorer.Inspectors.Reflection
Any, Any,
Enumerable, Enumerable,
Dictionary, Dictionary,
Bool,
String,
Number,
Enum,
Flags,
UnityStruct,
Color, // maybe
} }
public class InteractiveValue public class InteractiveValue
@ -28,15 +35,22 @@ namespace UnityExplorer.Inspectors.Reflection
{ IValueTypes.Any, typeof(InteractiveValue) }, { IValueTypes.Any, typeof(InteractiveValue) },
{ IValueTypes.Dictionary, typeof(InteractiveDictionary) }, { IValueTypes.Dictionary, typeof(InteractiveDictionary) },
{ IValueTypes.Enumerable, typeof(InteractiveEnumerable) }, { IValueTypes.Enumerable, typeof(InteractiveEnumerable) },
{ IValueTypes.Bool, typeof(InteractiveBool) },
{ IValueTypes.String, typeof(InteractiveString) },
{ IValueTypes.Number, typeof(InteractiveNumber) },
}; };
// WIP // WIP
public static IValueTypes GetIValueForType(Type type) public static IValueTypes GetIValueForType(Type type)
{ {
if (type.IsPrimitive || type == typeof(string)) if (type == typeof(bool))
return IValueTypes.Any; // TODO Primitive return IValueTypes.Bool;
else if (type == typeof(string))
return IValueTypes.String;
else if (type.IsPrimitive)
return IValueTypes.Number;
else if (typeof(Transform).IsAssignableFrom(type)) else if (typeof(Transform).IsAssignableFrom(type))
return IValueTypes.Any; // TODO Transform return IValueTypes.Any;
else if (ReflectionHelpers.IsDictionary(type)) else if (ReflectionHelpers.IsDictionary(type))
return IValueTypes.Dictionary; return IValueTypes.Dictionary;
else if (ReflectionHelpers.IsEnumerable(type)) else if (ReflectionHelpers.IsEnumerable(type))
@ -69,6 +83,7 @@ namespace UnityExplorer.Inspectors.Reflection
public virtual IValueTypes IValueType => IValueTypes.Any; public virtual IValueTypes IValueType => IValueTypes.Any;
public virtual bool HasSubContent => false; public virtual bool HasSubContent => false;
public virtual bool SubContentWanted => false;
public virtual bool WantInspectBtn => true; public virtual bool WantInspectBtn => true;
public string RichTextValue => m_richValue ?? GetLabelForValue(); public string RichTextValue => m_richValue ?? GetLabelForValue();
@ -87,16 +102,6 @@ namespace UnityExplorer.Inspectors.Reflection
m_valueContent.transform.SetParent(null, false); m_valueContent.transform.SetParent(null, false);
m_valueContent.SetActive(false); m_valueContent.SetActive(false);
GameObject.Destroy(this.m_valueContent.gameObject); 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);
// }
//}
} }
} }
@ -115,18 +120,28 @@ namespace UnityExplorer.Inspectors.Reflection
GetLabelForValue(); GetLabelForValue();
m_baseLabel.text = RichTextValue; m_baseLabel.text = RichTextValue;
} }
}
bool shouldShowBtns = !Value.IsNullOrDestroyed(); public void RefreshElementsAfterUpdate()
{
if (WantInspectBtn)
{
bool shouldShowInspect = !Value.IsNullOrDestroyed();
if (WantInspectBtn && m_inspectButton.activeSelf != shouldShowBtns) if (m_inspectButton.activeSelf != shouldShowInspect)
m_inspectButton.SetActive(shouldShowBtns); m_inspectButton.SetActive(shouldShowInspect);
}
bool subContentWanted = SubContentWanted;
if (OwnerCacheObject is CacheMember cm && !cm.HasEvaluated)
subContentWanted = false;
if (HasSubContent) if (HasSubContent)
{ {
if (m_subExpandBtn.gameObject.activeSelf != shouldShowBtns) if (m_subExpandBtn.gameObject.activeSelf != subContentWanted)
m_subExpandBtn.gameObject.SetActive(shouldShowBtns); m_subExpandBtn.gameObject.SetActive(subContentWanted);
if (!shouldShowBtns && m_subContentParent.activeSelf) if (!subContentWanted && m_subContentParent.activeSelf)
ToggleSubcontent(); ToggleSubcontent();
} }
} }
@ -151,6 +166,8 @@ namespace UnityExplorer.Inspectors.Reflection
} }
OnToggleSubcontent(m_subContentParent.activeSelf); OnToggleSubcontent(m_subContentParent.activeSelf);
RefreshElementsAfterUpdate();
} }
internal virtual void OnToggleSubcontent(bool toggle) internal virtual void OnToggleSubcontent(bool toggle)

View File

@ -347,7 +347,17 @@ namespace UnityExplorer.Inspectors
try try
{ {
var cached = CacheFactory.GetCacheObject(member, target, m_scrollContent); CacheMember cached;
if (mi != null && CacheMember.CanProcessArgs(mi.GetParameters()))
cached = new CacheMethod(mi, target);
else if (pi != null && CacheMember.CanProcessArgs(pi.GetIndexParameters()))
cached = new CacheProperty(pi, target);
else if (member is FieldInfo fi)
cached = new CacheField(fi, target);
else
continue;
cached.m_parentContent = m_scrollContent;
if (cached != null) if (cached != null)
{ {

View File

@ -39,11 +39,12 @@ namespace UnityExplorer.Inspectors
private GameObject m_mainInspectBtn; private GameObject m_mainInspectBtn;
private GameObject m_backButtonObj; private GameObject m_backButtonObj;
public PageHandler m_sceneListPageHandler; public PageHandler m_pageHandler;
private GameObject m_sceneListContent; private GameObject m_pageContent;
private GameObject[] m_allSceneListObjects = new GameObject[0]; private GameObject[] m_allObjects = new GameObject[0];
private readonly List<GameObject> m_sceneShortList = new List<GameObject>(); private readonly List<GameObject> m_shortList = new List<GameObject>();
private readonly List<Text> m_sceneListTexts = new List<Text>(); private readonly List<Text> m_shortListTexts = new List<Text>();
private readonly List<Toggle> m_shortListToggles = new List<Toggle>();
public static int DontDestroyHandle => DontDestroyObject.scene.handle; public static int DontDestroyHandle => DontDestroyObject.scene.handle;
@ -200,18 +201,22 @@ namespace UnityExplorer.Inspectors
private void SetSceneObjectList(GameObject[] objects) private void SetSceneObjectList(GameObject[] objects)
{ {
m_allSceneListObjects = objects; m_allObjects = objects;
RefreshSceneObjectList(); RefreshSceneObjectList();
} }
private void SceneListObjectClicked(int index) private void SceneListObjectClicked(int index)
{ {
if (index >= m_sceneShortList.Count || !m_sceneShortList[index]) if (index >= m_shortList.Count || !m_shortList[index])
{ {
return; return;
} }
SetTargetObject(m_sceneShortList[index]); var obj = m_shortList[index];
if (obj.transform.childCount > 0)
SetTargetObject(obj);
else
InspectorManager.Instance.Inspect(obj);
} }
private void OnSceneListPageTurn() private void OnSceneListPageTurn()
@ -219,30 +224,39 @@ namespace UnityExplorer.Inspectors
RefreshSceneObjectList(); RefreshSceneObjectList();
} }
private void OnToggleClicked(int index, bool val)
{
if (index >= m_shortList.Count || !m_shortList[index])
return;
var obj = m_shortList[index];
obj.SetActive(val);
}
private void RefreshSceneObjectList() private void RefreshSceneObjectList()
{ {
m_timeOfLastSceneUpdate = Time.realtimeSinceStartup; m_timeOfLastSceneUpdate = Time.realtimeSinceStartup;
var objects = m_allSceneListObjects; var objects = m_allObjects;
m_sceneListPageHandler.ListCount = objects.Length; m_pageHandler.ListCount = objects.Length;
//int startIndex = m_sceneListPageHandler.StartIndex; //int startIndex = m_sceneListPageHandler.StartIndex;
int newCount = 0; int newCount = 0;
foreach (var itemIndex in m_sceneListPageHandler) foreach (var itemIndex in m_pageHandler)
{ {
newCount++; newCount++;
// normalized index starting from 0 // normalized index starting from 0
var i = itemIndex - m_sceneListPageHandler.StartIndex; var i = itemIndex - m_pageHandler.StartIndex;
if (itemIndex >= objects.Length) if (itemIndex >= objects.Length)
{ {
if (i > m_lastCount || i >= m_sceneListTexts.Count) if (i > m_lastCount || i >= m_shortListTexts.Count)
break; break;
GameObject label = m_sceneListTexts[i].transform.parent.parent.gameObject; GameObject label = m_shortListTexts[i].transform.parent.parent.gameObject;
if (label.activeSelf) if (label.activeSelf)
label.SetActive(false); label.SetActive(false);
} }
@ -253,17 +267,17 @@ namespace UnityExplorer.Inspectors
if (!obj) if (!obj)
continue; continue;
if (i >= m_sceneShortList.Count) if (i >= m_shortList.Count)
{ {
m_sceneShortList.Add(obj); m_shortList.Add(obj);
AddObjectListButton(); AddObjectListButton();
} }
else else
{ {
m_sceneShortList[i] = obj; m_shortList[i] = obj;
} }
var text = m_sceneListTexts[i]; var text = m_shortListTexts[i];
var name = obj.name; var name = obj.name;
@ -273,6 +287,9 @@ namespace UnityExplorer.Inspectors
text.text = name; text.text = name;
text.color = obj.activeSelf ? Color.green : Color.red; text.color = obj.activeSelf ? Color.green : Color.red;
var tog = m_shortListToggles[i];
tog.isOn = obj.activeSelf;
var label = text.transform.parent.parent.gameObject; var label = text.transform.parent.parent.gameObject;
if (!label.activeSelf) if (!label.activeSelf)
{ {
@ -397,14 +414,17 @@ namespace UnityExplorer.Inspectors
inspectButtonLayout.minWidth = 65; inspectButtonLayout.minWidth = 65;
inspectButtonLayout.flexibleWidth = 0; inspectButtonLayout.flexibleWidth = 0;
Button inspectButton = m_mainInspectBtn.GetComponent<Button>(); Button inspectButton = m_mainInspectBtn.GetComponent<Button>();
colors = inspectButton.colors;
colors.normalColor = new Color(0.12f, 0.12f, 0.12f);
inspectButton.colors = colors;
inspectButton.onClick.AddListener(() => { InspectorManager.Instance.Inspect(m_selectedSceneObject); }); inspectButton.onClick.AddListener(() => { InspectorManager.Instance.Inspect(m_selectedSceneObject); });
GameObject scrollObj = UIFactory.CreateScrollView(leftPane, out m_sceneListContent, out SliderScrollbar scroller, new Color(0.1f, 0.1f, 0.1f)); GameObject scrollObj = UIFactory.CreateScrollView(leftPane, out m_pageContent, out SliderScrollbar scroller, new Color(0.1f, 0.1f, 0.1f));
m_sceneListPageHandler = new PageHandler(scroller); m_pageHandler = new PageHandler(scroller);
m_sceneListPageHandler.ConstructUI(leftPane); m_pageHandler.ConstructUI(leftPane);
m_sceneListPageHandler.OnPageChanged += OnSceneListPageTurn; m_pageHandler.OnPageChanged += OnSceneListPageTurn;
// hide button // hide button
@ -434,7 +454,7 @@ namespace UnityExplorer.Inspectors
sceneDropdownObj.SetActive(false); sceneDropdownObj.SetActive(false);
scenePathGroupObj.SetActive(false); scenePathGroupObj.SetActive(false);
scrollObj.SetActive(false); scrollObj.SetActive(false);
m_sceneListPageHandler.Hide(); m_pageHandler.Hide();
leftLayout.minWidth = 15; leftLayout.minWidth = 15;
} }
@ -459,9 +479,9 @@ namespace UnityExplorer.Inspectors
private void AddObjectListButton() private void AddObjectListButton()
{ {
int thisIndex = m_sceneListTexts.Count(); int thisIndex = m_shortListTexts.Count();
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_sceneListContent, new Color(0.1f, 0.1f, 0.1f)); GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_pageContent, new Color(0.1f, 0.1f, 0.1f));
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>(); HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>();
btnGroup.childForceExpandWidth = true; btnGroup.childForceExpandWidth = true;
btnGroup.childControlWidth = true; btnGroup.childControlWidth = true;
@ -473,6 +493,15 @@ namespace UnityExplorer.Inspectors
btnLayout.flexibleHeight = 0; btnLayout.flexibleHeight = 0;
btnGroupObj.AddComponent<Mask>(); btnGroupObj.AddComponent<Mask>();
var toggleObj = UIFactory.CreateToggle(btnGroupObj, out Toggle toggle, out Text toggleText, new Color(0.1f, 0.1f, 0.1f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 25;
toggleText.text = "";
toggle.isOn = false;
m_shortListToggles.Add(toggle);
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj); GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj);
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>(); LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
mainBtnLayout.minHeight = 25; mainBtnLayout.minHeight = 25;
@ -490,7 +519,7 @@ namespace UnityExplorer.Inspectors
Text mainText = mainButtonObj.GetComponentInChildren<Text>(); Text mainText = mainButtonObj.GetComponentInChildren<Text>();
mainText.alignment = TextAnchor.MiddleLeft; mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow; mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
m_sceneListTexts.Add(mainText); m_shortListTexts.Add(mainText);
GameObject inspectBtnObj = UIFactory.CreateButton(btnGroupObj); GameObject inspectBtnObj = UIFactory.CreateButton(btnGroupObj);
LayoutElement inspectBtnLayout = inspectBtnObj.AddComponent<LayoutElement>(); LayoutElement inspectBtnLayout = inspectBtnObj.AddComponent<LayoutElement>();
@ -508,9 +537,9 @@ namespace UnityExplorer.Inspectors
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 0.5f); mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 0.5f);
inspectBtn.colors = inspectColors; inspectBtn.colors = inspectColors;
inspectBtn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(m_sceneShortList[thisIndex]); }); inspectBtn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(m_shortList[thisIndex]); });
} }
#endregion #endregion
} }
} }

View File

@ -339,7 +339,7 @@ namespace UnityExplorer.UI
GameObject labelObj = CreateUIObject("Label", toggleObj); GameObject labelObj = CreateUIObject("Label", toggleObj);
toggle = toggleObj.AddComponent<Toggle>(); toggle = toggleObj.AddComponent<Toggle>();
//toggle.isOn = true; toggle.isOn = true;
Toggle toggleComp = toggle; Toggle toggleComp = toggle;
toggle.onValueChanged.AddListener(Deselect); toggle.onValueChanged.AddListener(Deselect);

View File

@ -328,7 +328,6 @@
<Compile Include="Helpers\EventHelper.cs" /> <Compile Include="Helpers\EventHelper.cs" />
<Compile Include="Inspectors\MouseInspector.cs" /> <Compile Include="Inspectors\MouseInspector.cs" />
<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\CacheField.cs" /> <Compile Include="Inspectors\Reflection\CacheObject\CacheField.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\CachePaired.cs" /> <Compile Include="Inspectors\Reflection\CacheObject\CachePaired.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\CacheMember.cs" /> <Compile Include="Inspectors\Reflection\CacheObject\CacheMember.cs" />
@ -345,9 +344,11 @@
<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\InteractiveBool.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveDictionary.cs" /> <Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveDictionary.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveEnumerable.cs" /> <Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveEnumerable.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveNumber.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveString.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" />