Implemented Interactive List/Dictionary support (todo IL2CPP)

This commit is contained in:
sinaioutlander 2020-11-15 21:11:43 +11:00
parent 02eca61f40
commit 41f0b0ed55
24 changed files with 1093 additions and 203 deletions

View File

@ -105,7 +105,7 @@ The following helper methods are available:
{
if (!m_fixwanted)
{
EventSystem.current.SetSelectedGameObject(CSConsolePage.Instance.m_codeEditor.InputField.gameObject, null);
EventSystem.current.SetSelectedGameObject(InputField.gameObject, null);
m_fixwanted = true;
}
else

View File

@ -18,7 +18,7 @@ namespace UnityExplorer.Helpers
}
}
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = false)
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
{
var unityObj = obj as Object;
if (obj == null)

View File

@ -23,7 +23,7 @@ namespace UnityExplorer.Inspectors
{
Target = target;
if (Target.IsNullOrDestroyed())
if (Target.IsNullOrDestroyed(false))
{
Destroy();
return;
@ -46,7 +46,7 @@ namespace UnityExplorer.Inspectors
public virtual void Update()
{
if (Target.IsNullOrDestroyed())
if (Target.IsNullOrDestroyed(false))
{
Destroy();
return;

View File

@ -45,7 +45,7 @@ namespace UnityExplorer.Inspectors
#endif
UnityEngine.Object unityObj = obj as UnityEngine.Object;
if (obj.IsNullOrDestroyed())
if (obj.IsNullOrDestroyed(false))
{
return;
}

View File

@ -1,26 +1,68 @@
//using System;
//using System.Collections;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using UnityExplorer.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.UI;
using UnityEngine;
using UnityEngine.UI;
//namespace UnityExplorer.Inspectors.Reflection
//{
// public class CacheEnumerated : CacheObjectBase
// {
// public int Index { get; set; }
// public IList RefIList { get; set; }
// public InteractiveEnumerable ParentEnumeration { get; set; }
namespace UnityExplorer.Inspectors.Reflection
{
public class CacheEnumerated : CacheObjectBase, INestedValue
{
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;
public int Index { get; set; }
public IList RefIList { get; set; }
public InteractiveEnumerable ParentEnumeration { get; set; }
// public override void SetValue()
// {
// RefIList[Index] = IValue.Value;
// ParentEnumeration.Value = RefIList;
public CacheEnumerated(int index, InteractiveEnumerable parentEnumeration, IList refIList, GameObject parentContent)
{
this.ParentEnumeration = parentEnumeration;
this.Index = index;
this.RefIList = refIList;
this.m_parentContent = parentContent;
}
// ParentEnumeration.OwnerCacheObject.SetValue();
// }
// }
//}
public override void CreateIValue(object value, Type fallbackType)
{
IValue = InteractiveValue.Create(value, fallbackType);
IValue.OwnerCacheObject = this;
}
public override void SetValue()
{
RefIList[Index] = IValue.Value;
ParentEnumeration.Value = RefIList;
ParentEnumeration.OwnerCacheObject.SetValue();
}
public void UpdateSubcontentHeight()
{
ParentEnumeration.UpdateSubcontentHeight();
}
internal override void ConstructUI()
{
base.ConstructUI();
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.padding.left = 5;
rowGroup.padding.right = 2;
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
indexLayout.minWidth = 20;
indexLayout.flexibleWidth = 30;
indexLayout.minHeight = 25;
var indexText = indexLabelObj.GetComponent<Text>();
indexText.text = this.Index + ":";
IValue.m_mainContentParent = rowObj;
}
}
}

View File

@ -7,23 +7,6 @@ namespace UnityExplorer.Inspectors.Reflection
{
public static class CacheFactory
{
// Don't think I need these with new structure.
// Will possibly need something for CacheEnumerated / InteractiveEnumeration though.
//public static CacheObjectBase GetCacheObject(object obj)
//{
// if (obj == null) return null;
// return GetCacheObject(obj, ReflectionHelpers.GetActualType(obj));
//}
//public static CacheObjectBase GetCacheObject(object obj, Type type)
//{
// var ret = new CacheObjectBase();
// ret.InitValue(obj, type);
// return ret;
//}
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
{
CacheMember ret;

View File

@ -12,11 +12,11 @@ namespace UnityExplorer.Inspectors.Reflection
{
public override bool IsStatic => (MemInfo as FieldInfo).IsStatic;
public override Type FallbackType => (MemInfo as FieldInfo).FieldType;
public CacheField(FieldInfo fieldInfo, object declaringInstance) : base(fieldInfo, declaringInstance)
{
base.InitValue(null, fieldInfo.FieldType);
UpdateValue();
CreateIValue(null, fieldInfo.FieldType);
}
public override void UpdateReflection()

View File

@ -15,35 +15,34 @@ namespace UnityExplorer.Inspectors.Reflection
{
public abstract class CacheMember : CacheObjectBase
{
public override bool IsMember => true;
public override Type FallbackType { get; }
public MemberInfo MemInfo { get; set; }
public Type DeclaringType { get; set; }
public object DeclaringInstance { get; set; }
public virtual bool IsStatic { get; private set; }
public override bool IsMember => true;
public override bool HasParameters => ParamCount > 0;
public virtual int ParamCount => m_arguments.Length;
public override bool HasEvaluated => m_evaluated;
public string RichTextName => m_richTextName ?? GetRichTextName();
private string m_richTextName;
public string NameForFiltering => m_nameForFilter ?? (m_nameForFilter = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}".ToLower());
private string m_nameForFilter;
public string ReflectionException { get; set; }
public override bool CanWrite => m_canWrite ?? GetCanWrite();
private bool? m_canWrite;
public string ReflectionException { get; set; }
public override bool HasParameters => ParamCount > 0;
public virtual int ParamCount => m_arguments.Length;
public override bool HasEvaluated => m_evaluated;
public bool m_evaluated = false;
public bool m_isEvaluating;
public ParameterInfo[] m_arguments = new ParameterInfo[0];
public string[] m_argumentInput = new string[0];
public string NameForFiltering => m_nameForFilter ?? (m_nameForFilter = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}".ToLower());
private string m_nameForFilter;
public string RichTextName => m_richTextName ?? GetRichTextName();
private string m_richTextName;
public CacheMember(MemberInfo memberInfo, object declaringInstance)
{
MemInfo = memberInfo;
@ -51,6 +50,14 @@ namespace UnityExplorer.Inspectors.Reflection
DeclaringInstance = declaringInstance;
}
public override void CreateIValue(object value, Type fallbackType)
{
IValue = InteractiveValue.Create(value, fallbackType);
IValue.OwnerCacheObject = this;
IValue.m_mainContentParent = this.m_rightGroup;
IValue.m_subContentParent = this.m_subContent;
}
public override void UpdateValue()
{
if (!HasParameters || m_isEvaluating)
@ -122,7 +129,7 @@ namespace UnityExplorer.Inspectors.Reflection
}
// No input, see if there is a default value.
if (HasDefaultValue(m_arguments[i]))
if (m_arguments[i].IsOptional)
{
parsedArgs.Add(m_arguments[i].DefaultValue);
continue;
@ -135,8 +142,6 @@ namespace UnityExplorer.Inspectors.Reflection
return parsedArgs.ToArray();
}
public static bool HasDefaultValue(ParameterInfo arg) => arg.DefaultValue != DBNull.Value;
private bool GetCanWrite()
{
if (MemInfo is FieldInfo fi)
@ -159,7 +164,7 @@ namespace UnityExplorer.Inspectors.Reflection
{
try
{
var baseType = this.IValue.ValueType;
var baseType = ReflectionHelpers.GetActualType(IValue.Value) ?? IValue.FallbackType;
var gArgs = baseType.GetGenericArguments();
if (gArgs.Length < 1)
@ -214,13 +219,12 @@ namespace UnityExplorer.Inspectors.Reflection
m_rightLayout.preferredWidth = valueWidth;
}
internal GameObject m_leftGroup;
internal GameObject m_rightGroup;
internal Text m_memLabelText;
internal RectTransform m_topRowRect;
internal Text m_memLabelText;
internal GameObject m_leftGroup;
internal LayoutElement m_leftLayout;
internal GameObject m_rightGroup;
internal LayoutElement m_rightLayout;
internal GameObject m_subContent;
internal override void ConstructUI()
{
@ -292,31 +296,15 @@ namespace UnityExplorer.Inspectors.Reflection
rightGroup.childForceExpandWidth = false;
rightGroup.childControlHeight = true;
rightGroup.childControlWidth = true;
rightGroup.spacing = 4;
rightGroup.padding.top = 2;
rightGroup.spacing = 2;
rightGroup.padding.top = 4;
rightGroup.padding.bottom = 2;
ConstructArgInput(out GameObject argsHolder);
ConstructEvaluateButtons(argsHolder);
// subcontent
m_subContent = UIFactory.CreateHorizontalGroup(m_parentContent, new Color(1, 1, 1, 0));
var subGroup = m_subContent.GetComponent<HorizontalLayoutGroup>();
subGroup.childForceExpandWidth = true;
subGroup.childControlWidth = true;
var subLayout = m_subContent.AddComponent<LayoutElement>();
subLayout.minHeight = 50;
subLayout.flexibleHeight = 500;
subLayout.minWidth = 125;
subLayout.flexibleWidth = 9000;
m_subContent.SetActive(false);
// Construct InteractiveValue's actual UI
IValue.ConstructUI(m_rightGroup, m_subContent);
IValue.m_mainContentParent = m_rightGroup;
}
internal void ConstructArgInput(out GameObject argsHolder)
@ -418,13 +406,13 @@ namespace UnityExplorer.Inspectors.Reflection
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
evalButton.colors = colors;
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.6f, 0.3f, 0.3f));
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.3f, 0.3f, 0.3f));
var cancelLayout = cancelButtonObj.AddComponent<LayoutElement>();
cancelLayout.minWidth = 100;
cancelLayout.minHeight = 22;
cancelLayout.flexibleWidth = 0;
var cancelText = cancelButtonObj.GetComponentInChildren<Text>();
cancelText.text = "Cancel";
cancelText.text = "Close";
cancelButtonObj.SetActive(false);

View File

@ -13,6 +13,8 @@ namespace UnityExplorer.Inspectors.Reflection
{
//private CacheObjectBase m_cachedReturnValue;
public override Type FallbackType => (MemInfo as MethodInfo).ReturnType;
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
public override bool IsStatic => (MemInfo as MethodInfo).IsStatic;
@ -37,12 +39,7 @@ namespace UnityExplorer.Inspectors.Reflection
m_arguments = methodInfo.GetParameters();
m_argumentInput = new string[m_arguments.Length];
base.InitValue(null, methodInfo.ReturnType);
}
public override void UpdateValue()
{
base.UpdateValue();
CreateIValue(null, methodInfo.ReturnType);
}
public override void UpdateReflection()
@ -78,10 +75,8 @@ namespace UnityExplorer.Inspectors.Reflection
ReflectionException = ReflectionHelpers.ExceptionToString(e);
}
// todo do InitValue again for new value, in case type changed fundamentally.
IValue.Value = ret;
IValue.OnValueUpdated();
UpdateValue();
}
private MethodInfo MakeGenericMethodFromInput()

View File

@ -10,7 +10,7 @@ using UnityEngine.UI;
namespace UnityExplorer.Inspectors.Reflection
{
public class CacheObjectBase
public abstract class CacheObjectBase
{
public InteractiveValue IValue;
@ -19,26 +19,9 @@ namespace UnityExplorer.Inspectors.Reflection
public virtual bool IsMember => false;
public virtual bool HasEvaluated => true;
// TODO
public virtual void InitValue(object value, Type valueType)
{
if (valueType == null && value == null)
{
ExplorerCore.LogWarning("CacheObjectBase: Trying to init with no default value or valueType!");
ExplorerCore.Log(Environment.StackTrace);
return;
}
public abstract Type FallbackType { get; }
// temp (havent made rest of InteractiveValue classes yet, just using base class always)
valueType = ReflectionHelpers.GetActualType(value) ?? valueType;
IValue = new InteractiveValue(valueType)
{
OwnerCacheObject = this
};
UpdateValue();
}
public abstract void CreateIValue(object value, Type fallbackType);
public virtual void Enable()
{
@ -54,11 +37,31 @@ namespace UnityExplorer.Inspectors.Reflection
public virtual void Disable()
{
m_mainContent.SetActive(false);
m_mainContent?.SetActive(false);
}
public void Destroy()
{
GameObject.Destroy(this.m_mainContent);
}
public virtual void UpdateValue()
{
var value = IValue.Value;
// see if current value has changed types fundamentally
var type = value == null
? FallbackType
: ReflectionHelpers.GetActualType(value);
var ivalueType = InteractiveValue.GetIValueForType(type);
if (ivalueType != IValue.IValueType)
{
IValue.OnDestroy();
CreateIValue(value, FallbackType);
m_subContent.SetActive(false);
}
IValue.OnValueUpdated();
}
@ -68,7 +71,9 @@ namespace UnityExplorer.Inspectors.Reflection
internal bool m_constructedUI;
internal GameObject m_parentContent;
internal RectTransform m_mainRect;
internal GameObject m_mainContent;
internal GameObject m_subContent;
// Make base UI holder for CacheObject, this doesnt actually display anything.
internal virtual void ConstructUI()
@ -76,16 +81,36 @@ namespace UnityExplorer.Inspectors.Reflection
m_constructedUI = true;
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f));
var rowGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
rowGroup.childForceExpandWidth = true;
rowGroup.childControlWidth = true;
rowGroup.childForceExpandHeight = false;
rowGroup.childControlHeight = true;
var rowLayout = m_mainContent.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleHeight = 500;
rowLayout.minWidth = 200;
rowLayout.flexibleWidth = 5000;
m_mainContent.name = "CacheObjectBase.MainContent";
m_mainRect = m_mainContent.GetComponent<RectTransform>();
m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var mainGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
mainGroup.childForceExpandWidth = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childControlHeight = true;
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
mainLayout.minHeight = 25;
mainLayout.flexibleHeight = 9999;
mainLayout.minWidth = 200;
mainLayout.flexibleWidth = 5000;
// subcontent
m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, new Color(0.085f, 0.085f, 0.085f));
m_subContent.name = "CacheObjectBase.SubContent";
var subGroup = m_subContent.GetComponent<VerticalLayoutGroup>();
subGroup.childForceExpandWidth = true;
subGroup.childForceExpandHeight = false;
var subLayout = m_subContent.AddComponent<LayoutElement>();
subLayout.minHeight = 30;
subLayout.flexibleHeight = 9999;
subLayout.minWidth = 125;
subLayout.flexibleWidth = 9000;
m_subContent.SetActive(false);
IValue.m_subContentParent = m_subContent;
}
#endregion

View File

@ -0,0 +1,76 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.UI;
using UnityEngine;
using UnityEngine.UI;
namespace UnityExplorer.Inspectors.Reflection
{
public enum PairTypes
{
Key,
Value
}
public class CachePaired : CacheObjectBase, INestedValue
{
public override Type FallbackType => PairType == PairTypes.Key
? ParentDictionary.m_typeOfKeys
: ParentDictionary.m_typeofValues;
public override bool CanWrite => false; // todo?
public PairTypes PairType;
public int Index { get; private set; }
public InteractiveDictionary ParentDictionary { get; private set; }
internal IDictionary RefIDIct;
public CachePaired(int index, InteractiveDictionary parentDict, IDictionary refIDict, PairTypes pairType, GameObject parentContent)
{
Index = index;
ParentDictionary = parentDict;
RefIDIct = refIDict;
this.PairType = pairType;
this.m_parentContent = parentContent;
}
public override void CreateIValue(object value, Type fallbackType)
{
IValue = InteractiveValue.Create(value, fallbackType);
IValue.OwnerCacheObject = this;
}
public void UpdateSubcontentHeight()
{
ParentDictionary.UpdateSubcontentHeight();
}
#region UI CONSTRUCTION
internal override void ConstructUI()
{
base.ConstructUI();
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.padding.left = 5;
rowGroup.padding.right = 2;
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
indexLayout.minWidth = 80;
indexLayout.flexibleWidth = 30;
indexLayout.minHeight = 25;
var indexText = indexLabelObj.GetComponent<Text>();
indexText.text = $"{this.PairType} {this.Index}:";
IValue.m_mainContentParent = rowObj;
}
#endregion
}
}

View File

@ -10,6 +10,8 @@ namespace UnityExplorer.Inspectors.Reflection
{
public class CacheProperty : CacheMember
{
public override Type FallbackType => (MemInfo as PropertyInfo).PropertyType;
public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic;
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance) : base(propertyInfo, declaringInstance)
@ -17,9 +19,7 @@ namespace UnityExplorer.Inspectors.Reflection
this.m_arguments = propertyInfo.GetIndexParameters();
this.m_argumentInput = new string[m_arguments.Length];
base.InitValue(null, propertyInfo.PropertyType);
UpdateValue();
CreateIValue(null, propertyInfo.PropertyType);
}
public override void UpdateReflection()

View File

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

View File

@ -0,0 +1,284 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.Helpers;
using UnityExplorer.UI;
using UnityExplorer.UI.Shared;
namespace UnityExplorer.Inspectors.Reflection
{
public class InteractiveDictionary : InteractiveValue
{
public InteractiveDictionary(object value, Type valueType) : base(value, valueType)
{
if (valueType.IsGenericType)
{
var gArgs = valueType.GetGenericArguments();
m_typeOfKeys = gArgs[0];
m_typeofValues = gArgs[1];
}
else
{
m_typeOfKeys = typeof(object);
m_typeofValues = typeof(object);
}
}
public override IValueTypes IValueType => IValueTypes.Dictionary;
public override bool HasSubContent => true;
public override bool WantInspectBtn => false;
internal IDictionary RefIDictionary;
internal Type m_typeOfKeys;
internal Type m_typeofValues;
internal readonly List<KeyValuePair<CachePaired, CachePaired>> m_entries
= new List<KeyValuePair<CachePaired, CachePaired>>();
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
= new KeyValuePair<CachePaired, CachePaired>[ModConfig.Instance.Default_Page_Limit];
//internal readonly List<CacheKeyValuePair> m_entries = new List<CacheKeyValuePair>();
//internal CacheKeyValuePair[] m_displayedEntries = new CacheKeyValuePair[ModConfig.Instance.Default_Page_Limit];
internal bool m_recacheWanted = true;
public override void OnDestroy()
{
base.OnDestroy();
}
public override void OnValueUpdated()
{
base.OnValueUpdated();
if (!Value.IsNullOrDestroyed())
{
RefIDictionary = Value as IDictionary;
UpdateLabel();
}
else
{
m_baseLabel.text = base.GetLabelForValue();
RefIDictionary = null;
}
if (m_subContentParent.activeSelf)
{
GetCacheEntries();
RefreshDisplay();
}
else
m_recacheWanted = true;
}
internal void OnPageTurned()
{
RefreshDisplay();
}
internal void UpdateLabel()
{
string count = "?";
if (m_recacheWanted && RefIDictionary != null)
count = RefIDictionary.Count.ToString();
else if (!m_recacheWanted)
count = m_entries.Count.ToString();
m_baseLabel.text = $"[{count}] {m_richValueType}";
}
public void GetCacheEntries()
{
if (m_entries.Any())
{
// maybe improve this, probably could be more efficient i guess
foreach (var pair in m_entries)
{
pair.Key.Destroy();
pair.Value.Destroy();
}
m_entries.Clear();
}
if (RefIDictionary != null)
{
int index = 0;
foreach (var key in RefIDictionary.Keys)
{
var value = RefIDictionary[key];
//if (index >= m_rowHolders.Count)
//{
// AddRowHolder();
//}
//var holder = m_rowHolders[index];
var cacheKey = new CachePaired(index, this, this.RefIDictionary, PairTypes.Key, m_listContent);
cacheKey.CreateIValue(key, this.m_typeOfKeys);
cacheKey.Disable();
var cacheValue = new CachePaired(index, this, this.RefIDictionary, PairTypes.Value, m_listContent);
cacheValue.CreateIValue(value, this.m_typeofValues);
cacheValue.Disable();
//holder.SetActive(false);
m_entries.Add(new KeyValuePair<CachePaired, CachePaired>(cacheKey, cacheValue));
index++;
}
}
RefreshDisplay();
}
public void RefreshDisplay()
{
var entries = m_entries;
m_pageHandler.ListCount = entries.Count;
for (int i = 0; i < m_displayedEntries.Length; i++)
{
var entry = m_displayedEntries[i];
if (entry.Key != null && entry.Value != null)
{
//m_rowHolders[i].SetActive(false);
entry.Key.Disable();
entry.Value.Disable();
}
else
break;
}
if (entries.Count < 1)
return;
foreach (var itemIndex in m_pageHandler)
{
if (itemIndex >= entries.Count)
break;
var entry = entries[itemIndex];
m_displayedEntries[itemIndex - m_pageHandler.StartIndex] = entry;
//m_rowHolders[itemIndex].SetActive(true);
entry.Key.Enable();
entry.Value.Enable();
}
UpdateSubcontentHeight();
}
internal override void OnToggleSubcontent(bool active)
{
base.OnToggleSubcontent(active);
if (active && m_recacheWanted)
{
m_recacheWanted = false;
GetCacheEntries();
UpdateLabel();
}
RefreshDisplay();
}
public void UpdateSubcontentHeight()
{
Canvas.ForceUpdateCanvases();
float totalHeight = 0f;
if (m_subContentParent.activeSelf)
{
foreach (var itemIndex in m_pageHandler)
{
if (itemIndex >= m_entries.Count)
break;
var entry = m_entries[itemIndex];
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Key.m_mainRect);
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Value.m_mainRect);
totalHeight += Mathf.Max(entry.Key.m_mainRect.rect.height, entry.Value.m_mainRect.rect.height);
}
}
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
//m_mainLayout.minHeight = totalHeight;
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
if (OwnerCacheObject is INestedValue nestedValue)
{
// nested enumerable
nestedValue.UpdateSubcontentHeight();
}
}
#region UI CONSTRUCTION
internal GameObject m_listContent;
internal LayoutElement m_listLayout;
internal PageHandler m_pageHandler;
//internal List<GameObject> m_rowHolders = new List<GameObject>();
public override void ConstructUI(GameObject parent, GameObject subGroup)
{
base.ConstructUI(parent, subGroup);
}
public override void ConstructSubcontent()
{
base.ConstructSubcontent();
m_pageHandler = new PageHandler(null);
m_pageHandler.ConstructUI(m_subContentParent);
m_pageHandler.OnPageChanged += OnPageTurned;
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
m_listContent = scrollObj;
var scrollRect = scrollObj.GetComponent<RectTransform>();
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
m_listLayout = OwnerCacheObject.m_mainContent.GetComponent<LayoutElement>();
m_listLayout.minHeight = 25;
m_listLayout.flexibleHeight = 0;
OwnerCacheObject.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
scrollGroup.childForceExpandHeight = true;
scrollGroup.childControlHeight = true;
scrollGroup.spacing = 2;
scrollGroup.padding.top = 5;
scrollGroup.padding.left = 5;
scrollGroup.padding.right = 5;
scrollGroup.padding.bottom = 5;
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
}
//internal void AddRowHolder()
//{
// var obj = UIFactory.CreateHorizontalGroup(m_listContent, new Color(0.15f, 0.15f, 0.15f));
// m_rowHolders.Add(obj);
//}
#endregion
}
}

View File

@ -0,0 +1,234 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.Helpers;
using UnityExplorer.UI;
using UnityExplorer.UI.Shared;
namespace UnityExplorer.Inspectors.Reflection
{
public class InteractiveEnumerable : InteractiveValue
{
public InteractiveEnumerable(object value, Type valueType) : base(value, valueType)
{
if (valueType.IsGenericType)
m_baseEntryType = valueType.GetGenericArguments()[0];
else
m_baseEntryType = typeof(object);
}
public override IValueTypes IValueType => IValueTypes.Enumerable;
public override bool HasSubContent => true;
public override bool WantInspectBtn => false;
internal IEnumerable RefIEnumerable;
internal IList RefIList;
internal readonly Type m_baseEntryType;
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ModConfig.Instance.Default_Page_Limit];
internal bool m_recacheWanted = true;
public override void OnValueUpdated()
{
base.OnValueUpdated();
if (!Value.IsNullOrDestroyed())
{
RefIEnumerable = Value as IEnumerable; // todo il2cpp
RefIList = Value as IList;
UpdateLabel();
}
else
{
m_baseLabel.text = base.GetLabelForValue();
RefIEnumerable = null;
RefIList = null;
}
if (m_subContentParent.activeSelf)
{
GetCacheEntries();
RefreshDisplay();
}
else
m_recacheWanted = true;
}
private void OnPageTurned()
{
RefreshDisplay();
}
internal void UpdateLabel()
{
string count = "?";
if (m_recacheWanted && RefIList != null)
count = RefIList.Count.ToString();
else if (!m_recacheWanted)
count = m_entries.Count.ToString();
m_baseLabel.text = $"[{count}] {m_richValueType}";
}
public void GetCacheEntries()
{
if (m_entries.Any())
{
// maybe improve this, probably could be more efficient i guess
foreach (var entry in m_entries)
entry.Destroy();
m_entries.Clear();
}
if (RefIEnumerable != null)
{
int index = 0;
foreach (var entry in RefIEnumerable)
{
var cache = new CacheEnumerated(index, this, RefIList, this.m_listContent);
cache.CreateIValue(entry, m_baseEntryType);
m_entries.Add(cache);
cache.Disable();
index++;
}
}
RefreshDisplay();
}
public void RefreshDisplay()
{
var entries = m_entries;
m_pageHandler.ListCount = entries.Count;
for (int i = 0; i < m_displayedEntries.Length; i++)
{
var entry = m_displayedEntries[i];
if (entry != null)
entry.Disable();
else
break;
}
if (entries.Count < 1)
return;
foreach (var itemIndex in m_pageHandler)
{
if (itemIndex >= entries.Count)
break;
CacheEnumerated entry = entries[itemIndex];
m_displayedEntries[itemIndex - m_pageHandler.StartIndex] = entry;
entry.Enable();
}
UpdateSubcontentHeight();
}
internal override void OnToggleSubcontent(bool active)
{
base.OnToggleSubcontent(active);
if (active && m_recacheWanted)
{
m_recacheWanted = false;
GetCacheEntries();
UpdateLabel();
}
RefreshDisplay();
}
public void UpdateSubcontentHeight()
{
Canvas.ForceUpdateCanvases();
float totalHeight = 0f;
if (m_subContentParent.activeSelf)
{
foreach (var itemIndex in m_pageHandler)
{
if (itemIndex >= m_entries.Count)
break;
var entry = m_entries[itemIndex];
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.m_mainRect);
totalHeight += entry.m_mainRect.rect.height;
}
}
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
//m_mainLayout.minHeight = totalHeight;
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
if (OwnerCacheObject is INestedValue nestedValue)
{
// nested enumerable
nestedValue.UpdateSubcontentHeight();
}
}
#region UI CONSTRUCTION
internal GameObject m_listContent;
internal LayoutElement m_listLayout;
internal PageHandler m_pageHandler;
public override void ConstructUI(GameObject parent, GameObject subGroup)
{
base.ConstructUI(parent, subGroup);
}
public override void ConstructSubcontent()
{
base.ConstructSubcontent();
m_pageHandler = new PageHandler(null);
m_pageHandler.ConstructUI(m_subContentParent);
m_pageHandler.OnPageChanged += OnPageTurned;
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
m_listContent = scrollObj;
var scrollRect = scrollObj.GetComponent<RectTransform>();
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
m_listLayout = OwnerCacheObject.m_mainContent.GetComponent<LayoutElement>();
m_listLayout.minHeight = 25;
m_listLayout.flexibleHeight = 0;
OwnerCacheObject.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
scrollGroup.childForceExpandHeight = true;
scrollGroup.childControlHeight = true;
scrollGroup.spacing = 2;
scrollGroup.padding.top = 5;
scrollGroup.padding.left = 5;
scrollGroup.padding.right = 5;
scrollGroup.padding.bottom = 5;
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
}
#endregion
}
}

View File

@ -10,20 +10,66 @@ using UnityExplorer.UI;
namespace UnityExplorer.Inspectors.Reflection
{
// WIP
public enum IValueTypes
{
Any,
Enumerable,
Dictionary,
}
public class InteractiveValue
{
public InteractiveValue(Type valueType)
// ~~~~~~~~~ Static ~~~~~~~~~
// WIP
internal static Dictionary<IValueTypes, Type> s_typeDict = new Dictionary<IValueTypes, Type>
{
this.ValueType = valueType;
{ IValueTypes.Any, typeof(InteractiveValue) },
{ IValueTypes.Dictionary, typeof(InteractiveDictionary) },
{ IValueTypes.Enumerable, typeof(InteractiveEnumerable) },
};
// WIP
public static IValueTypes GetIValueForType(Type type)
{
if (type.IsPrimitive || type == typeof(string))
return IValueTypes.Any; // TODO Primitive
else if (typeof(Transform).IsAssignableFrom(type))
return IValueTypes.Any; // TODO Transform
else if (ReflectionHelpers.IsDictionary(type))
return IValueTypes.Dictionary;
else if (ReflectionHelpers.IsEnumerable(type))
return IValueTypes.Enumerable;
else
return IValueTypes.Any;
}
public static InteractiveValue Create(object value, Type fallbackType)
{
var type = ReflectionHelpers.GetActualType(value) ?? fallbackType;
var iType = GetIValueForType(type);
return (InteractiveValue)Activator.CreateInstance(s_typeDict[iType], new object[] { value, type });
}
// ~~~~~~~~~ Instance ~~~~~~~~~
public InteractiveValue(object value, Type valueType)
{
this.Value = value;
this.FallbackType = valueType;
}
public CacheObjectBase OwnerCacheObject;
public object Value { get; set; }
public readonly Type ValueType;
public readonly Type FallbackType;
public virtual IValueTypes IValueType => IValueTypes.Any;
// might not need
public virtual bool HasSubContent => false;
public virtual bool WantInspectBtn => true;
public string RichTextValue => m_richValue ?? GetLabelForValue();
internal string m_richValue;
@ -32,42 +78,100 @@ namespace UnityExplorer.Inspectors.Reflection
public MethodInfo ToStringMethod => m_toStringMethod ?? GetToStringMethod();
internal MethodInfo m_toStringMethod;
public virtual void Init()
public bool m_UIConstructed;
public virtual void OnDestroy()
{
OnValueUpdated();
if (this.m_valueContent)
{
m_valueContent.transform.SetParent(null, false);
m_valueContent.SetActive(false);
GameObject.Destroy(this.m_valueContent.gameObject);
//if (OwnerCacheObject.m_subContent)
//{
// var subTrans = this.OwnerCacheObject.m_subContent.transform;
// for (int i = subTrans.childCount - 1; i >= 0; i--)
// {
// var child = subTrans.GetChild(i);
// GameObject.Destroy(child.gameObject);
// }
//}
}
}
public virtual void OnValueUpdated()
{
if (!m_text)
return;
if (!m_UIConstructed)
ConstructUI(m_mainContentParent, m_subContentParent);
if (OwnerCacheObject is CacheMember ownerMember && !string.IsNullOrEmpty(ownerMember.ReflectionException))
{
m_text.text = "<color=red>" + ownerMember.ReflectionException + "</color>";
m_baseLabel.text = "<color=red>" + ownerMember.ReflectionException + "</color>";
Value = null;
}
else
{
GetLabelForValue();
m_text.text = RichTextValue;
m_baseLabel.text = RichTextValue;
}
bool shouldShowInspect = !Value.IsNullOrDestroyed(true);
if (m_inspectButton.activeSelf != shouldShowInspect)
m_inspectButton.SetActive(shouldShowInspect);
bool shouldShowBtns = !Value.IsNullOrDestroyed();
if (WantInspectBtn && m_inspectButton.activeSelf != shouldShowBtns)
m_inspectButton.SetActive(shouldShowBtns);
if (HasSubContent)
{
if (m_subExpandBtn.gameObject.activeSelf != shouldShowBtns)
m_subExpandBtn.gameObject.SetActive(shouldShowBtns);
if (!shouldShowBtns && m_subContentParent.activeSelf)
ToggleSubcontent();
}
}
public virtual void ConstructSubcontent()
{
m_subContentConstructed = true;
}
public void ToggleSubcontent()
{
if (!this.m_subContentParent.activeSelf)
{
this.m_subContentParent.SetActive(true);
this.m_subContentParent.transform.SetAsLastSibling();
m_subExpandBtn.GetComponentInChildren<Text>().text = "▼";
}
else
{
this.m_subContentParent.SetActive(false);
m_subExpandBtn.GetComponentInChildren<Text>().text = "▲";
}
OnToggleSubcontent(m_subContentParent.activeSelf);
}
internal virtual void OnToggleSubcontent(bool toggle)
{
if (!m_subContentConstructed)
ConstructSubcontent();
}
public string GetLabelForValue()
{
var valueType = Value?.GetType() ?? this.ValueType;
var valueType = Value?.GetType() ?? this.FallbackType;
m_richValueType = UISyntaxHighlight.ParseFullSyntax(valueType, true);
if (OwnerCacheObject is CacheMember cm && !cm.HasEvaluated)
return $"<i><color=grey>Not yet evaluated</color> ({m_richValueType})</i>";
if (Value == null) return $"<color=grey>null</color> ({m_richValueType})";
if (Value.IsNullOrDestroyed())
{
return $"<color=grey>null</color> ({m_richValueType})";
}
string label;
@ -135,31 +239,58 @@ namespace UnityExplorer.Inspectors.Reflection
#region UI CONSTRUCTION
internal GameObject m_mainContent;
internal GameObject m_inspectButton;
internal Text m_text;
internal GameObject m_mainContentParent;
internal GameObject m_subContentParent;
internal GameObject m_valueContent;
internal GameObject m_inspectButton;
internal Text m_baseLabel;
internal Button m_subExpandBtn;
internal bool m_subContentConstructed;
public virtual void ConstructUI(GameObject parent, GameObject subGroup)
{
m_mainContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var mainGroup = m_mainContent.GetComponent<HorizontalLayoutGroup>();
m_UIConstructed = true;
mainGroup.childForceExpandWidth = true;
m_valueContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
m_valueContent.name = "InteractiveValue.ValueContent";
var mainRect = m_valueContent.GetComponent<RectTransform>();
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var mainGroup = m_valueContent.GetComponent<HorizontalLayoutGroup>();
mainGroup.childForceExpandWidth = false;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = false;
mainGroup.childControlHeight = true;
mainGroup.spacing = 4;
mainGroup.childAlignment = TextAnchor.UpperLeft;
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
var mainLayout = m_valueContent.AddComponent<LayoutElement>();
mainLayout.flexibleWidth = 9000;
mainLayout.minWidth = 175;
mainLayout.minHeight = 25;
mainLayout.flexibleHeight = 0;
// subcontent expand button TODO
if (HasSubContent)
{
var subBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f));
var btnLayout = subBtnObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 25;
btnLayout.minWidth = 25;
btnLayout.flexibleWidth = 0;
btnLayout.flexibleHeight = 0;
var btnText = subBtnObj.GetComponentInChildren<Text>();
btnText.text = "▲";
m_subExpandBtn = subBtnObj.GetComponent<Button>();
m_subExpandBtn.onClick.AddListener(() =>
{
ToggleSubcontent();
});
}
// inspect button
m_inspectButton = UIFactory.CreateButton(m_mainContent, new Color(0.3f, 0.3f, 0.3f, 0.2f));
m_inspectButton = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f, 0.2f));
var inspectLayout = m_inspectButton.AddComponent<LayoutElement>();
inspectLayout.minWidth = 60;
inspectLayout.minHeight = 25;
@ -172,16 +303,16 @@ namespace UnityExplorer.Inspectors.Reflection
inspectBtn.onClick.AddListener(OnInspectClicked);
void OnInspectClicked()
{
if (!Value.IsNullOrDestroyed())
if (!Value.IsNullOrDestroyed(false))
InspectorManager.Instance.Inspect(this.Value);
}
m_inspectButton.SetActive(false);
// value label / tostring
// value label
var labelObj = UIFactory.CreateLabel(m_mainContent, TextAnchor.MiddleLeft);
m_text = labelObj.GetComponent<Text>();
var labelObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft);
m_baseLabel = labelObj.GetComponent<Text>();
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.flexibleWidth = 9000;
labelLayout.minHeight = 25;

View File

@ -13,10 +13,6 @@ using UnityExplorer.Config;
namespace UnityExplorer.Inspectors
{
// TODO:
// - Filters
// - Helper tools for Target object (for UnityEngine.Objects, Components, Textures, and maybe a general ToString helper)
public class ReflectionInspector : InspectorBase
{
#region STATIC
@ -95,8 +91,6 @@ namespace UnityExplorer.Inspectors
internal bool m_widthUpdateWanted;
internal bool m_widthUpdateWaiting;
// Ctor
public ReflectionInspector(object target) : base(target)
{
if (this is StaticInspector)
@ -113,8 +107,6 @@ namespace UnityExplorer.Inspectors
FilterMembers();
}
// Methods
public override void SetActive()
{
base.SetActive();
@ -310,14 +302,14 @@ namespace UnityExplorer.Inspectors
{
try
{
//ExplorerCore.Log($"Trying to cache member {sig}...");
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
// make sure member type is Field, Method or Property (4 / 8 / 16)
int m = (int)member.MemberType;
if (m < 4 || m > 16)
continue;
//ExplorerCore.Log($"Trying to cache member {sig}...");
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
var pi = member as PropertyInfo;
var mi = member as MethodInfo;
@ -338,28 +330,20 @@ namespace UnityExplorer.Inspectors
continue;
if (mi != null)
{
AppendParams(mi.GetParameters());
}
else if (pi != null)
{
AppendParams(pi.GetIndexParameters());
}
void AppendParams(ParameterInfo[] _args)
{
sig += " (";
foreach (var param in _args)
{
sig += $"{param.ParameterType.Name} {param.Name}, ";
}
sig += ")";
}
if (cachedSigs.Contains(sig))
{
continue;
}
try
{
@ -385,10 +369,18 @@ namespace UnityExplorer.Inspectors
}
}
var typeList = types.ToList();
var sorted = new List<CacheMember>();
sorted.AddRange(list.Where(x => x is CacheMethod));
sorted.AddRange(list.Where(x => x is CacheProperty));
sorted.AddRange(list.Where(x => x is CacheField));
sorted.AddRange(list.Where(it => it is CacheMethod)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheProperty)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheField)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
m_allMembers = sorted.ToArray();
@ -623,6 +615,7 @@ namespace UnityExplorer.Inspectors
scrollGroup.spacing = 3;
scrollGroup.padding.left = 0;
scrollGroup.padding.right = 0;
scrollGroup.childForceExpandHeight = true;
m_pageHandler = new PageHandler(m_sliderScroller);
m_pageHandler.ConstructUI(Content);

View File

@ -26,27 +26,71 @@ namespace UnityExplorer.Tests
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
private static TestClass m_instance;
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
public Dictionary<string, List<string>> AComboTest = new Dictionary<string, List<string>>
{
{
"key",
new List<string>
{
"1",
"2"
}
}
};
public object AmbigObject;
public List<List<List<string>>> ANestedNestedList = new List<List<List<string>>>
{
new List<List<string>>
{
new List<string>
{
"one",
"two",
},
new List<string>
{
"three",
"four"
}
},
new List<List<string>>
{
new List<string>
{
"five",
"six"
}
}
};
public static bool SetOnlyProperty
{
set => m_setOnlyProperty = value;
}
private static bool m_setOnlyProperty;
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
public Texture TestTexture;
public static Sprite TestSprite;
public static int StaticProperty => 5;
public static int StaticField = 5;
public int NonStaticField;
#if CPP
public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest;
#endif
public TestClass()
{
int a = 0;
foreach (var list in ANestedNestedList)
{
foreach (var list2 in list)
{
for (int i = 0; i < 33; i++)
list2.Add(a++.ToString());
}
}
#if CPP
TestTexture = UIManager.MakeSolidTexture(Color.white, 200, 200);
TestTexture.name = "TestTexture";

View File

@ -27,7 +27,7 @@ namespace UnityExplorer.UI.Shared
public event Action OnPageChanged;
private SliderScrollbar m_scrollbar;
private readonly SliderScrollbar m_scrollbar;
// For now this is just set when the PageHandler is created, based on config.
// At some point I might make it possible to change this after creation again.
@ -147,7 +147,9 @@ namespace UnityExplorer.UI.Shared
}
if (didTurn)
{
m_scrollbar.m_scrollbar.value = 1;
if (m_scrollbar != null)
m_scrollbar.m_scrollbar.value = 1;
OnPageChanged?.Invoke();
RefreshUI();
}

View File

@ -0,0 +1,71 @@
//using UnityEngine;
//using System.Collections;
//using UnityEngine.UI;
//using System;
//using UnityEngine.EventSystems;
/////////////// kinda works, not really
//public class ScrollRectEx : ScrollRect, IEventSystemHandler
//{
// internal SliderScrollbar sliderScrollbar;
// private bool ShouldRouteToParent(PointerEventData data)
// => !sliderScrollbar.IsActive
// || sliderScrollbar.m_slider.value < 0.001f && data.delta.y > 0
// || sliderScrollbar.m_slider.value == 1f && data.delta.y < 0;
// private void DoForParents<T>(Action<T> action) where T : IEventSystemHandler
// {
// Transform parent = transform.parent;
// while (parent != null)
// {
// foreach (var component in parent.GetComponents<Component>())
// {
// if (component is T)
// action((T)(IEventSystemHandler)component);
// }
// parent = parent.parent;
// }
// }
// public override void OnScroll(PointerEventData data)
// {
// if (ShouldRouteToParent(data))
// DoForParents<IScrollHandler>((parent) => { parent.OnScroll(data); });
// else
// base.OnScroll(data);
// }
// public override void OnInitializePotentialDrag(PointerEventData eventData)
// {
// DoForParents<IInitializePotentialDragHandler>((parent) => { parent.OnInitializePotentialDrag(eventData); });
// base.OnInitializePotentialDrag(eventData);
// }
// public override void OnDrag(PointerEventData data)
// {
// if (ShouldRouteToParent(data))
// DoForParents<IDragHandler>((parent) => { parent.OnDrag(data); });
// else
// base.OnDrag(data);
// }
// public override void OnBeginDrag(UnityEngine.EventSystems.PointerEventData data)
// {
// if (ShouldRouteToParent(data))
// DoForParents<IBeginDragHandler>((parent) => { parent.OnBeginDrag(data); });
// else
// base.OnBeginDrag(data);
// }
// public override void OnEndDrag(UnityEngine.EventSystems.PointerEventData data)
// {
// if (ShouldRouteToParent(data))
// DoForParents<IEndDragHandler>((parent) => { parent.OnEndDrag(data); });
// else
// base.OnEndDrag(data);
// }
//}

View File

@ -13,6 +13,8 @@ public class SliderScrollbar
{
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
public bool IsActive { get; private set; }
internal readonly Scrollbar m_scrollbar;
internal readonly Slider m_slider;
internal readonly RectTransform m_scrollRect;
@ -46,21 +48,25 @@ public class SliderScrollbar
internal void Update()
{
this.RefreshVisibility();
}
}
internal void RefreshVisibility()
{
if (!m_slider.gameObject.activeInHierarchy)
{
IsActive = false;
return;
}
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
var obj = this.m_slider.handleRect.gameObject;
if (obj.activeSelf != shouldShow)
if (IsActive != shouldShow)
{
obj.SetActive(shouldShow);
IsActive = shouldShow;
obj.SetActive(IsActive);
if (shouldShow)
if (IsActive)
this.m_slider.Set(this.m_scrollbar.value, false);
else
m_slider.Set(1f, false);

View File

@ -542,7 +542,7 @@ namespace UnityExplorer.UI
templateImage.type = Image.Type.Sliced;
templateImage.color = new Color(0.15f, 0.15f, 0.15f, 1.0f);
ScrollRect scrollRect = templateObj.AddComponent<ScrollRect>();
var scrollRect = templateObj.AddComponent<ScrollRect>();
scrollRect.scrollSensitivity = 35;
scrollRect.content = contentObj.GetComponent<RectTransform>();
scrollRect.viewport = viewportObj.GetComponent<RectTransform>();
@ -626,7 +626,7 @@ namespace UnityExplorer.UI
var mainLayout = mainObj.AddComponent<LayoutElement>();
mainLayout.minWidth = 100;
mainLayout.minHeight = 100;
mainLayout.minHeight = 30;
mainLayout.flexibleWidth = 5000;
mainLayout.flexibleHeight = 5000;
@ -709,6 +709,8 @@ namespace UnityExplorer.UI
// Create a custom DynamicScrollbar module
scroller = new SliderScrollbar(hiddenScroll, scrollSlider);
//scrollRect.sliderScrollbar = scroller;
return mainObj;
}
}

View File

@ -30,17 +30,14 @@ namespace UnityExplorer.UI
internal static string GetClassColor(Type type)
{
string classColor;
if (type.IsAbstract && type.IsSealed)
classColor = Class_Static;
return Class_Static;
else if (type.IsEnum || type.IsGenericParameter)
classColor = Enum;
return Enum;
else if (type.IsValueType)
classColor = StructGreen;
return StructGreen;
else
classColor = Class_Instance;
return classColor;
return Class_Instance;
}
public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null)

View File

@ -330,6 +330,7 @@
<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\CachePaired.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\CacheMember.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\CacheMethod.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\CacheProperty.cs" />
@ -344,6 +345,9 @@
<Compile Include="Inspectors\GameObjects\ChildList.cs" />
<Compile Include="Inspectors\GameObjects\ComponentList.cs" />
<Compile Include="Inspectors\GameObjects\GameObjectControls.cs" />
<Compile Include="Inspectors\Reflection\CacheObject\INestedValue.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveDictionary.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveEnumerable.cs" />
<Compile Include="UI\ForceUnlockCursor.cs" />
<Compile Include="Input\IHandleInput.cs" />
<Compile Include="Tests\Tests.cs" />
@ -379,6 +383,7 @@
<Compile Include="UI\PanelDragger.cs" />
<Compile Include="Inspectors\Reflection\InteractiveValue\InteractiveValue.cs" />
<Compile Include="UI\Shared\InputFieldScroller.cs" />
<Compile Include="UI\Shared\ScrollRectEx.cs" />
<Compile Include="UI\Shared\SliderScrollbar.cs" />
<Compile Include="UI\Shared\PageHandler.cs" />
<Compile Include="UI\UISyntaxHighlight.cs" />