From 9f8d53f55a7b794552a4d43f6241b046de65b383 Mon Sep 17 00:00:00 2001 From: Sinai Date: Mon, 26 Apr 2021 19:56:21 +1000 Subject: [PATCH] Rewriting everything from scratch, developed generic ObjectPool system --- src/ExplorerCore.cs | 3 +- .../CacheObject/CacheConfigEntry.cs | 102 ++++ .../CacheObject/CacheEnumerated.cs | 57 ++ src/Inspectors_OLD/CacheObject/CacheField.cs | 40 ++ src/Inspectors_OLD/CacheObject/CacheMember.cs | 360 +++++++++++++ src/Inspectors_OLD/CacheObject/CacheMethod.cs | 170 ++++++ .../CacheObject/CacheObjectBase.cs | 120 +++++ src/Inspectors_OLD/CacheObject/CachePaired.cs | 72 +++ .../CacheObject/CacheProperty.cs | 70 +++ .../GameObjects/ChildList.cs | 2 +- .../GameObjects/ComponentList.cs | 2 +- .../GameObjects/GameObjectControls.cs | 2 +- .../GameObjects/GameObjectInspector.cs | 2 +- .../InspectUnderMouse.cs | 2 +- src/Inspectors_OLD/InspectorBase.cs | 122 +++++ src/Inspectors_OLD/InspectorManager.cs | 151 ++++++ .../InteractiveValues/InteractiveBool.cs | 110 ++++ .../InteractiveValues/InteractiveColor.cs | 167 ++++++ .../InteractiveDictionary.cs | 246 +++++++++ .../InteractiveValues/InteractiveEnum.cs | 163 ++++++ .../InteractiveEnumerable.cs | 245 +++++++++ .../InteractiveValues/InteractiveFlags.cs | 125 +++++ .../InteractiveFloatStruct.cs | 203 ++++++++ .../InteractiveValues/InteractiveNumber.cs | 115 +++++ .../InteractiveValues/InteractiveString.cs | 186 +++++++ .../InteractiveValues/InteractiveValue.cs | 355 +++++++++++++ .../Reflection/CacheMemberList.cs | 61 +++ .../Reflection/InstanceInspector.cs | 254 +++++++++ src/UI/Inspectors/GameObjectInspector.cs | 173 +++++++ src/UI/Inspectors/InspectorBase.cs | 130 ++--- src/UI/Inspectors/InspectorManager.cs | 160 ++---- src/UI/Inspectors/InspectorTab.cs | 46 ++ .../Inspectors/Reflection/CacheMemberList.cs | 61 --- .../Reflection/InstanceInspector.cs | 254 --------- .../Reflection/ReflectionInspector.cs | 487 ------------------ .../Inspectors/Reflection/StaticInspector.cs | 14 - src/UI/Inspectors/ReflectionInspector.cs | 32 ++ src/UI/Models/UIPanel.cs | 12 +- src/UI/ObjectPool/IPooledObject.cs | 19 + src/UI/ObjectPool/Pool.cs | 106 ++++ src/UI/Panels/ObjectExplorer.cs | 9 +- src/UI/UIFactory.cs | 32 +- src/UI/UIManager.cs | 25 +- src/UI/Utility/SignatureHighlighter.cs | 2 +- src/UI/Widgets/AutoComplete/AutoCompleter.cs | 14 +- src/UI/Widgets/ButtonList/ButtonCell.cs | 73 ++- src/UI/Widgets/ButtonList/ButtonListSource.cs | 41 +- src/UI/Widgets/ButtonRef.cs | 26 + .../Widgets/CacheObject/CacheConfigEntry.cs | 102 ---- src/UI/Widgets/CacheObject/CacheEnumerated.cs | 57 -- src/UI/Widgets/CacheObject/CacheField.cs | 40 -- src/UI/Widgets/CacheObject/CacheMember.cs | 360 ------------- src/UI/Widgets/CacheObject/CacheMethod.cs | 170 ------ src/UI/Widgets/CacheObject/CacheObjectBase.cs | 120 ----- src/UI/Widgets/CacheObject/CachePaired.cs | 72 --- src/UI/Widgets/CacheObject/CacheProperty.cs | 70 --- .../InteractiveValues/InteractiveBool.cs | 110 ---- .../InteractiveValues/InteractiveColor.cs | 167 ------ .../InteractiveDictionary.cs | 246 --------- .../InteractiveValues/InteractiveEnum.cs | 163 ------ .../InteractiveEnumerable.cs | 245 --------- .../InteractiveValues/InteractiveFlags.cs | 125 ----- .../InteractiveFloatStruct.cs | 203 -------- .../InteractiveValues/InteractiveNumber.cs | 115 ----- .../InteractiveValues/InteractiveString.cs | 186 ------- .../InteractiveValues/InteractiveValue.cs | 355 ------------- src/UI/Widgets/ObjectExplorer/ObjectSearch.cs | 20 +- .../Widgets/ObjectExplorer/SceneExplorer.cs | 51 +- src/UI/Widgets/ScrollPool/CellViewHolder.cs | 132 ++--- src/UI/Widgets/ScrollPool/DataHeightCache.cs | 18 +- src/UI/Widgets/ScrollPool/ICell.cs | 3 +- src/UI/Widgets/ScrollPool/IPoolDataSource.cs | 12 +- src/UI/Widgets/ScrollPool/ScrollPool.cs | 93 ++-- .../Widgets/TransformTree/CachedTransform.cs | 8 +- src/UI/Widgets/TransformTree/TransformCell.cs | 104 ++-- src/UI/Widgets/TransformTree/TransformTree.cs | 81 ++- src/UnityExplorer.csproj | 64 ++- 77 files changed, 4399 insertions(+), 4316 deletions(-) create mode 100644 src/Inspectors_OLD/CacheObject/CacheConfigEntry.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheEnumerated.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheField.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheMember.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheMethod.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheObjectBase.cs create mode 100644 src/Inspectors_OLD/CacheObject/CachePaired.cs create mode 100644 src/Inspectors_OLD/CacheObject/CacheProperty.cs rename src/{UI/Inspectors => Inspectors_OLD}/GameObjects/ChildList.cs (99%) rename src/{UI/Inspectors => Inspectors_OLD}/GameObjects/ComponentList.cs (99%) rename src/{UI/Inspectors => Inspectors_OLD}/GameObjects/GameObjectControls.cs (99%) rename src/{UI/Inspectors => Inspectors_OLD}/GameObjects/GameObjectInspector.cs (99%) rename src/{UI/Inspectors => Inspectors_OLD}/InspectUnderMouse.cs (99%) create mode 100644 src/Inspectors_OLD/InspectorBase.cs create mode 100644 src/Inspectors_OLD/InspectorManager.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveBool.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveColor.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveDictionary.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveEnum.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveEnumerable.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveFlags.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveFloatStruct.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveNumber.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveString.cs create mode 100644 src/Inspectors_OLD/InteractiveValues/InteractiveValue.cs create mode 100644 src/Inspectors_OLD/Reflection/CacheMemberList.cs create mode 100644 src/Inspectors_OLD/Reflection/InstanceInspector.cs create mode 100644 src/UI/Inspectors/GameObjectInspector.cs create mode 100644 src/UI/Inspectors/InspectorTab.cs delete mode 100644 src/UI/Inspectors/Reflection/CacheMemberList.cs delete mode 100644 src/UI/Inspectors/Reflection/InstanceInspector.cs delete mode 100644 src/UI/Inspectors/Reflection/ReflectionInspector.cs delete mode 100644 src/UI/Inspectors/Reflection/StaticInspector.cs create mode 100644 src/UI/Inspectors/ReflectionInspector.cs create mode 100644 src/UI/ObjectPool/IPooledObject.cs create mode 100644 src/UI/ObjectPool/Pool.cs create mode 100644 src/UI/Widgets/ButtonRef.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheConfigEntry.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheEnumerated.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheField.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheMember.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheMethod.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheObjectBase.cs delete mode 100644 src/UI/Widgets/CacheObject/CachePaired.cs delete mode 100644 src/UI/Widgets/CacheObject/CacheProperty.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveBool.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveColor.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveDictionary.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveEnum.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveEnumerable.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveFlags.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveFloatStruct.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveNumber.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveString.cs delete mode 100644 src/UI/Widgets/InteractiveValues/InteractiveValue.cs diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index ff69a01..0ca8ffc 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -6,6 +6,7 @@ using UnityExplorer.Core; using UnityExplorer.Core.Config; using UnityExplorer.Core.Input; using UnityExplorer.Core.Runtime; +using UnityExplorer.Tests; using UnityExplorer.UI; using UnityExplorer.UI.Panels; @@ -68,7 +69,7 @@ namespace UnityExplorer UIManager.InitUI(); - //InspectorManager.Instance.Inspect(typeof(TestClass)); + //InspectorManager.Inspect(typeof(TestClass)); } /// diff --git a/src/Inspectors_OLD/CacheObject/CacheConfigEntry.cs b/src/Inspectors_OLD/CacheObject/CacheConfigEntry.cs new file mode 100644 index 0000000..e996a8c --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheConfigEntry.cs @@ -0,0 +1,102 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.Core.Config; +//using UnityExplorer.UI.InteractiveValues; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public class CacheConfigEntry : CacheObjectBase +// { +// public IConfigElement RefConfig { get; } + +// public override Type FallbackType => RefConfig.ElementType; + +// public override bool HasEvaluated => true; +// public override bool HasParameters => false; +// public override bool IsMember => false; +// public override bool CanWrite => true; + +// public CacheConfigEntry(IConfigElement config, GameObject parent) +// { +// RefConfig = config; + +// m_parentContent = parent; + +// config.OnValueChangedNotify += () => { UpdateValue(); }; + +// CreateIValue(config.BoxedValue, config.ElementType); +// } + +// public override void CreateIValue(object value, Type fallbackType) +// { +// IValue = InteractiveValue.Create(value, fallbackType); +// IValue.Owner = this; +// IValue.m_mainContentParent = m_mainGroup; +// IValue.m_subContentParent = this.SubContentGroup; +// } + +// public override void UpdateValue() +// { +// IValue.Value = RefConfig.BoxedValue; + +// base.UpdateValue(); +// } + +// public override void SetValue() +// { +// RefConfig.BoxedValue = IValue.Value; +// } + +// internal GameObject m_mainGroup; + +// internal override void ConstructUI() +// { +// base.ConstructUI(); + +// m_mainGroup = UIFactory.CreateVerticalGroup(UIRoot, "ConfigHolder", true, false, true, true, 5, new Vector4(2, 2, 2, 2)); + +// var horiGroup = UIFactory.CreateHorizontalGroup(m_mainGroup, "ConfigEntryHolder", false, false, true, true, childAlignment: TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(horiGroup, minHeight: 30, flexibleHeight: 0); + +// // config entry label + +// var configLabel = UIFactory.CreateLabel(horiGroup, "ConfigLabel", this.RefConfig.Name, TextAnchor.MiddleLeft); +// var leftRect = configLabel.GetComponent(); +// leftRect.anchorMin = Vector2.zero; +// leftRect.anchorMax = Vector2.one; +// leftRect.offsetMin = Vector2.zero; +// leftRect.offsetMax = Vector2.zero; +// leftRect.sizeDelta = Vector2.zero; +// UIFactory.SetLayoutElement(configLabel.gameObject, minWidth: 250, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0); + +// // Default button + +// var defaultButton = UIFactory.CreateButton(horiGroup, +// "RevertDefaultButton", +// "Default", +// () => { RefConfig.RevertToDefaultValue(); }, +// new Color(0.3f, 0.3f, 0.3f)); +// UIFactory.SetLayoutElement(defaultButton.gameObject, minWidth: 80, minHeight: 22, flexibleWidth: 0); + +// // Description label + +// var desc = UIFactory.CreateLabel(m_mainGroup, "Description", $"{RefConfig.Description}", TextAnchor.MiddleLeft, Color.grey); +// UIFactory.SetLayoutElement(desc.gameObject, minWidth: 250, minHeight: 20, flexibleWidth: 9999, flexibleHeight: 0); + +// // IValue + +// if (IValue != null) +// { +// IValue.m_mainContentParent = m_mainGroup; +// IValue.m_subContentParent = this.SubContentGroup; +// } + +// // makes the subcontent look nicer +// SubContentGroup.transform.SetParent(m_mainGroup.transform, false); +// } +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheEnumerated.cs b/src/Inspectors_OLD/CacheObject/CacheEnumerated.cs new file mode 100644 index 0000000..5af6500 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheEnumerated.cs @@ -0,0 +1,57 @@ +//using System; +//using System.Collections; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityExplorer.UI; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI.InteractiveValues; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public class CacheEnumerated : CacheObjectBase +// { +// public override Type FallbackType => ParentEnumeration.m_baseEntryType; +// public override bool CanWrite => RefIList != null && ParentEnumeration.Owner.CanWrite; + +// public int Index { get; set; } +// public IList RefIList { get; set; } +// public InteractiveEnumerable ParentEnumeration { get; set; } + +// public CacheEnumerated(int index, InteractiveEnumerable parentEnumeration, IList refIList, GameObject parentContent) +// { +// this.ParentEnumeration = parentEnumeration; +// this.Index = index; +// this.RefIList = refIList; +// this.m_parentContent = parentContent; +// } + +// public override void CreateIValue(object value, Type fallbackType) +// { +// IValue = InteractiveValue.Create(value, fallbackType); +// IValue.Owner = this; +// } + +// public override void SetValue() +// { +// RefIList[Index] = IValue.Value; +// ParentEnumeration.Value = RefIList; + +// ParentEnumeration.Owner.SetValue(); +// } + +// internal override void ConstructUI() +// { +// base.ConstructUI(); + +// var rowObj = UIFactory.CreateHorizontalGroup(UIRoot, "CacheEnumeratedGroup", false, true, true, true, 0, new Vector4(0,0,5,2), +// new Color(1, 1, 1, 0)); + +// var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", $"{this.Index}:", TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 20, flexibleWidth: 30, minHeight: 25); + +// IValue.m_mainContentParent = rowObj; +// } +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheField.cs b/src/Inspectors_OLD/CacheObject/CacheField.cs new file mode 100644 index 0000000..40c42d5 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheField.cs @@ -0,0 +1,40 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Reflection; +//using UnityExplorer.UI; +//using UnityEngine; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public class CacheField : CacheMember +// { +// public override bool IsStatic => (MemInfo as FieldInfo).IsStatic; + +// public override Type FallbackType => (MemInfo as FieldInfo).FieldType; + +// public CacheField(FieldInfo fieldInfo, object declaringInstance, GameObject parent) : base(fieldInfo, declaringInstance, parent) +// { +// CreateIValue(null, fieldInfo.FieldType); +// } + +// public override void UpdateReflection() +// { +// var fi = MemInfo as FieldInfo; +// IValue.Value = fi.GetValue(fi.IsStatic ? null : DeclaringInstance); + +// m_evaluated = true; +// ReflectionException = null; +// } + +// public override void SetValue() +// { +// var fi = MemInfo as FieldInfo; +// fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value); + +// if (this.ParentInspector?.ParentMember != null) +// this.ParentInspector.ParentMember.SetValue(); +// } +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheMember.cs b/src/Inspectors_OLD/CacheObject/CacheMember.cs new file mode 100644 index 0000000..6d75048 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheMember.cs @@ -0,0 +1,360 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Reflection; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; +//using UnityExplorer.Core.Runtime; +//using UnityExplorer.Core; +//using UnityExplorer.UI.Utility; +//using UnityExplorer.UI.InteractiveValues; +//using UnityExplorer.Inspectors.Reflection; +//using UnityExplorer.UI.Panels; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public abstract class CacheMember : CacheObjectBase +// { +// public override bool IsMember => true; + +// public override Type FallbackType { get; } + +// public ReflectionInspector ParentInspector { get; set; } +// public MemberInfo MemInfo { get; set; } +// public Type DeclaringType { get; set; } +// public object DeclaringInstance { get; set; } +// public virtual bool IsStatic { get; private set; } + +// public string ReflectionException { get; set; } + +// public override bool CanWrite => m_canWrite ?? GetCanWrite(); +// private bool? m_canWrite; + +// 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, GameObject parentContent) +// { +// MemInfo = memberInfo; +// DeclaringType = memberInfo.DeclaringType; +// DeclaringInstance = declaringInstance; +// this.m_parentContent = parentContent; + +// DeclaringInstance = ReflectionProvider.Instance.Cast(declaringInstance, DeclaringType); +// } + +// public override void Enable() +// { +// base.Enable(); + +// ParentInspector.displayedMembers.Add(this); + +// memberLabelElement.minWidth = 0.4f * InspectorPanel.CurrentPanelWidth; +// } + +// public override void Disable() +// { +// base.Disable(); + +// ParentInspector.displayedMembers.Remove(this); +// } + +// 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) +// { +// IValue = InteractiveValue.Create(value, fallbackType); +// IValue.Owner = this; +// IValue.m_mainContentParent = this.ContentGroup; +// IValue.m_subContentParent = this.SubContentGroup; +// } + +// public override void UpdateValue() +// { +// if (!HasParameters || m_isEvaluating) +// { +// try +// { +// Type baseType = ReflectionUtility.GetActualType(IValue.Value) ?? FallbackType; + +// if (!ReflectionProvider.Instance.IsReflectionSupported(baseType)) +// throw new Exception("Type not supported with reflection"); + +// UpdateReflection(); + +// if (IValue.Value != null) +// IValue.Value = IValue.Value.TryCast(ReflectionUtility.GetActualType(IValue.Value)); +// } +// catch (Exception e) +// { +// ReflectionException = e.ReflectionExToString(true); +// } +// } + +// base.UpdateValue(); +// } + +// public abstract void UpdateReflection(); + +// public override void SetValue() +// { +// // no implementation for base class +// } + +// public object[] ParseArguments() +// { +// if (m_arguments.Length < 1) +// return new object[0]; + +// var parsedArgs = new List(); +// for (int i = 0; i < m_arguments.Length; i++) +// { +// var input = m_argumentInput[i]; +// var type = m_arguments[i].ParameterType; + +// if (type.IsByRef) +// type = type.GetElementType(); + +// if (!string.IsNullOrEmpty(input)) +// { +// if (type == typeof(string)) +// { +// parsedArgs.Add(input); +// continue; +// } +// else +// { +// try +// { +// var arg = type.GetMethod("Parse", new Type[] { typeof(string) }) +// .Invoke(null, new object[] { input }); + +// parsedArgs.Add(arg); +// continue; +// } +// catch +// { +// ExplorerCore.Log($"Could not parse input '{input}' for argument #{i} '{m_arguments[i].Name}' ({type.FullName})"); +// } +// } +// } + +// // No input, see if there is a default value. +// if (m_arguments[i].IsOptional) +// { +// parsedArgs.Add(m_arguments[i].DefaultValue); +// continue; +// } + +// // Try add a null arg I guess +// parsedArgs.Add(null); +// } + +// return parsedArgs.ToArray(); +// } + +// private bool GetCanWrite() +// { +// if (MemInfo is FieldInfo fi) +// m_canWrite = !(fi.IsLiteral && !fi.IsInitOnly); +// else if (MemInfo is PropertyInfo pi) +// m_canWrite = pi.CanWrite; +// else +// m_canWrite = false; + +// return (bool)m_canWrite; +// } + +// private string GetRichTextName() +// { +// return m_richTextName = SignatureHighlighter.ParseFullSyntax(MemInfo.DeclaringType, false, MemInfo); +// } + +// #region UI + +// internal Text memberLabelText; +// internal GameObject ContentGroup; + +// internal LayoutElement memberLabelElement; + +// internal override void ConstructUI() +// { +// base.ConstructUI(); + +// var horiGroup = UIFactory.CreateUIObject("HoriGroup", UIRoot); +// var groupRect = horiGroup.GetComponent(); +// groupRect.pivot = new Vector2(0, 1); +// groupRect.anchorMin = Vector2.zero; +// groupRect.anchorMax = Vector2.one; +// UIFactory.SetLayoutElement(horiGroup, minHeight: 30, flexibleHeight: 9999); +// UIFactory.SetLayoutGroup(horiGroup, true, true, true, true, 2, 2, 2, 2, 2, childAlignment: TextAnchor.UpperLeft); + +// memberLabelText = UIFactory.CreateLabel(horiGroup, "MemLabelText", RichTextName, TextAnchor.UpperLeft); +// memberLabelText.horizontalOverflow = HorizontalWrapMode.Wrap; +// UIFactory.SetLayoutElement(memberLabelText.gameObject, minHeight: 25, flexibleHeight: 9999, minWidth: 150, flexibleWidth: 0); + +// memberLabelElement = memberLabelText.GetComponent(); + +// ContentGroup = UIFactory.CreateUIObject("ContentGroup", horiGroup, default); +// UIFactory.SetLayoutElement(ContentGroup, minHeight: 30, flexibleWidth: 9999); +// var contentRect = ContentGroup.GetComponent(); +// contentRect.pivot = new Vector2(0, 1); +// contentRect.anchorMin = new Vector2(0, 0); +// contentRect.anchorMax = new Vector2(1, 1); +// UIFactory.SetLayoutGroup(ContentGroup, false, false, true, true, childAlignment: TextAnchor.MiddleLeft); + +// ConstructArgInput(out GameObject argsHolder); + +// ConstructEvaluateButtons(argsHolder); + +// IValue.m_mainContentParent = this.ContentGroup; + +// //RightContentGroup.SetActive(false); + +// // ParentInspector.CacheObjectContents.Add(this.m_mainContent); +// } + +// internal void ConstructArgInput(out GameObject argsHolder) +// { +// argsHolder = null; + +// if (HasParameters) +// { +// argsHolder = UIFactory.CreateVerticalGroup(ContentGroup, "ArgsHolder", true, false, true, true, 4, new Color(1, 1, 1, 0)); + +// if (this is CacheMethod cm && cm.GenericArgs.Length > 0) +// cm.ConstructGenericArgInput(argsHolder); + +// if (m_arguments.Length > 0) +// { +// UIFactory.CreateLabel(argsHolder, "ArgumentsLabel", "Arguments:", TextAnchor.MiddleLeft); + +// for (int i = 0; i < m_arguments.Length; i++) +// AddArgRow(i, argsHolder); +// } + +// argsHolder.SetActive(false); +// } +// } + +// internal void AddArgRow(int i, GameObject parent) +// { +// var arg = m_arguments[i]; + +// var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRow", true, false, true, true, 4, default, new Color(1, 1, 1, 0)); +// UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000); + +// var argTypeTxt = SignatureHighlighter.ParseFullSyntax(arg.ParameterType, false); +// var argLabel = UIFactory.CreateLabel(rowObj, "ArgLabel", $"{argTypeTxt} {arg.Name}", +// TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(argLabel.gameObject, minHeight: 25); + +// var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", out InputField argInput, 14, (int)TextAnchor.MiddleLeft, 1); +// UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200, preferredWidth: 150, minWidth: 20, minHeight: 25, flexibleHeight: 0); + +// argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; }); + +// if (arg.IsOptional) +// { +// var phInput = argInput.placeholder.GetComponent(); +// phInput.text = " = " + arg.DefaultValue?.ToString() ?? "null"; +// } +// } + +// internal void ConstructEvaluateButtons(GameObject argsHolder) +// { +// if (HasParameters) +// { +// var evalGroupObj = UIFactory.CreateHorizontalGroup(ContentGroup, "EvalGroup", false, false, true, true, 5, +// default, new Color(1, 1, 1, 0)); +// UIFactory.SetLayoutElement(evalGroupObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000); + +// var evalButton = UIFactory.CreateButton(evalGroupObj, +// "EvalButton", +// $"Evaluate ({ParamCount})", +// null); + +// RuntimeProvider.Instance.SetColorBlock(evalButton, new Color(0.4f, 0.4f, 0.4f), +// new Color(0.4f, 0.7f, 0.4f), new Color(0.3f, 0.3f, 0.3f)); + +// UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0); + +// var evalText = evalButton.GetComponentInChildren(); + +// var cancelButton = UIFactory.CreateButton(evalGroupObj, "CancelButton", "Close", null, new Color(0.3f, 0.3f, 0.3f)); +// UIFactory.SetLayoutElement(cancelButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0); + +// cancelButton.gameObject.SetActive(false); + +// evalButton.onClick.AddListener(() => +// { +// if (!m_isEvaluating) +// { +// argsHolder.SetActive(true); +// m_isEvaluating = true; +// evalText.text = "Evaluate"; +// RuntimeProvider.Instance.SetColorBlock(evalButton, new Color(0.3f, 0.6f, 0.3f)); + +// cancelButton.gameObject.SetActive(true); +// } +// else +// { +// if (this is CacheMethod cm) +// cm.Evaluate(); +// else +// UpdateValue(); +// } +// }); + +// cancelButton.onClick.AddListener(() => +// { +// cancelButton.gameObject.SetActive(false); +// argsHolder.SetActive(false); +// m_isEvaluating = false; + +// evalText.text = $"Evaluate ({ParamCount})"; +// RuntimeProvider.Instance.SetColorBlock(evalButton, new Color(0.4f, 0.4f, 0.4f)); +// }); +// } +// else if (this is CacheMethod) +// { +// // simple method evaluate button + +// var evalButton = UIFactory.CreateButton(ContentGroup, "EvalButton", "Evaluate", () => { (this as CacheMethod).Evaluate(); }); +// RuntimeProvider.Instance.SetColorBlock(evalButton, new Color(0.4f, 0.4f, 0.4f), +// new Color(0.4f, 0.7f, 0.4f), new Color(0.3f, 0.3f, 0.3f)); + +// UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0); +// } +// } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheMethod.cs b/src/Inspectors_OLD/CacheObject/CacheMethod.cs new file mode 100644 index 0000000..9ad1186 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheMethod.cs @@ -0,0 +1,170 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Reflection; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; +//using UnityExplorer.Core; +//using UnityExplorer.UI.Utility; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public class CacheMethod : CacheMember +// { +// //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; + +// public override int ParamCount => base.ParamCount + m_genericArgInput.Length; + +// public Type[] GenericArgs { get; private set; } +// public Type[][] GenericConstraints { get; private set; } + +// public string[] m_genericArgInput = new string[0]; + +// public CacheMethod(MethodInfo methodInfo, object declaringInstance, GameObject parent) : base(methodInfo, declaringInstance, parent) +// { +// GenericArgs = methodInfo.GetGenericArguments(); + +// GenericConstraints = GenericArgs.Select(x => x.GetGenericParameterConstraints()) +// .Where(x => x != null) +// .ToArray(); + +// m_genericArgInput = new string[GenericArgs.Length]; + +// m_arguments = methodInfo.GetParameters(); +// m_argumentInput = new string[m_arguments.Length]; + +// CreateIValue(null, methodInfo.ReturnType); +// } + +// public override void UpdateReflection() +// { +// // CacheMethod cannot UpdateValue directly. Need to Evaluate. +// } + +// public void Evaluate() +// { +// MethodInfo mi; +// if (GenericArgs.Length > 0) +// { +// mi = MakeGenericMethodFromInput(); +// if (mi == null) return; +// } +// else +// { +// mi = MemInfo as MethodInfo; +// } + +// object ret = null; + +// try +// { +// ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments()); +// m_evaluated = true; +// m_isEvaluating = false; +// ReflectionException = null; +// } +// catch (Exception e) +// { +// while (e.InnerException != null) +// e = e.InnerException; + +// ExplorerCore.LogWarning($"Exception evaluating: {e.GetType()}, {e.Message}"); +// ReflectionException = ReflectionUtility.ReflectionExToString(e); +// } + +// IValue.Value = ret; +// UpdateValue(); +// } + +// private MethodInfo MakeGenericMethodFromInput() +// { +// var mi = MemInfo as MethodInfo; + +// var list = new List(); +// for (int i = 0; i < GenericArgs.Length; i++) +// { +// var input = m_genericArgInput[i]; +// if (ReflectionUtility.GetTypeByName(input) is Type t) +// { +// if (GenericConstraints[i].Length == 0) +// { +// list.Add(t); +// } +// else +// { +// foreach (var constraint in GenericConstraints[i].Where(x => x != null)) +// { +// if (!constraint.IsAssignableFrom(t)) +// { +// ExplorerCore.LogWarning($"Generic argument #{i}, '{input}' is not assignable from the constraint '{constraint}'!"); +// return null; +// } +// } + +// list.Add(t); +// } +// } +// else +// { +// ExplorerCore.LogWarning($"Generic argument #{i}, could not get any type by the name of '{input}'!" + +// $" Make sure you use the full name including the namespace."); +// return null; +// } +// } + +// // make into a generic with type list +// mi = mi.MakeGenericMethod(list.ToArray()); + +// return mi; +// } + +// #region UI CONSTRUCTION + +// internal void ConstructGenericArgInput(GameObject parent) +// { +// UIFactory.CreateLabel(parent, "GenericArgLabel", "Generic Arguments:", TextAnchor.MiddleLeft); + +// for (int i = 0; i < GenericArgs.Length; i++) +// AddGenericArgRow(i, parent); +// } + +// internal void AddGenericArgRow(int i, GameObject parent) +// { +// var arg = GenericArgs[i]; + +// string constrainTxt = ""; +// if (this.GenericConstraints[i].Length > 0) +// { +// foreach (var constraint in this.GenericConstraints[i]) +// { +// if (constrainTxt != "") +// constrainTxt += ", "; + +// constrainTxt += $"{SignatureHighlighter.ParseFullSyntax(constraint, false)}"; +// } +// } +// else +// constrainTxt = $"Any"; + +// var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRowObj", false, true, true, true, 4, default, new Color(1, 1, 1, 0)); +// UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000); + +// var argLabelObj = UIFactory.CreateLabel(rowObj, "ArgLabelObj", $"{constrainTxt} {arg.Name}", +// TextAnchor.MiddleLeft); + +// var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", out InputField argInput, 14, (int)TextAnchor.MiddleLeft, 1); +// UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200); +// argInput.onValueChanged.AddListener((string val) => { m_genericArgInput[i] = val; }); + +// } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheObjectBase.cs b/src/Inspectors_OLD/CacheObject/CacheObjectBase.cs new file mode 100644 index 0000000..4f08bfc --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheObjectBase.cs @@ -0,0 +1,120 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Reflection; +//using UnityEngine; +//using UnityExplorer.UI; +//using UnityEngine.UI; +//using UnityExplorer.Core; +//using UnityExplorer.UI.InteractiveValues; +//using UnityExplorer.UI.Widgets; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public abstract class CacheObjectBase +// { +// public InteractiveValue IValue; + +// public virtual bool CanWrite => false; +// public virtual bool HasParameters => false; +// public virtual bool IsMember => false; +// public virtual bool HasEvaluated => true; + +// public abstract Type FallbackType { get; } + +// public abstract void CreateIValue(object value, Type fallbackType); + +// public virtual void Enable() +// { +// if (!m_constructedUI) +// { +// ConstructUI(); +// UpdateValue(); +// } +// } + +// public virtual void Disable() +// { +// if (UIRoot) +// UIRoot.SetActive(false); +// } + +// public void Destroy() +// { +// if (this.UIRoot) +// GameObject.Destroy(this.UIRoot); +// } + +// public virtual void UpdateValue() +// { +// var value = IValue.Value; + +// // if the type has changed fundamentally, make a new interactivevalue for it +// var type = value == null +// ? FallbackType +// : ReflectionUtility.GetActualType(value); + +// var ivalueType = InteractiveValue.GetIValueForType(type); + +// if (ivalueType != IValue.GetType()) +// { +// IValue.OnDestroy(); +// CreateIValue(value, FallbackType); +// SubContentGroup.SetActive(false); +// } + +// IValue.OnValueUpdated(); + +// IValue.RefreshElementsAfterUpdate(); +// } + +// public virtual void SetValue() => throw new NotImplementedException(); + +// #region UI CONSTRUCTION + +// internal bool m_constructedUI; +// internal GameObject m_parentContent; +// internal RectTransform m_mainRect; +// internal GameObject UIRoot; + +// internal GameObject SubContentGroup; +// internal bool constructedSubcontent; + +// // Make base UI holder for CacheObject, this doesnt actually display anything. +// internal virtual void ConstructUI() +// { +// m_constructedUI = true; + +// //UIRoot = UIFactory.CreateVerticalGroup(m_parentContent, $"{this.GetType().Name}.MainContent", true, true, true, true, 2, +// // new Vector4(0, 5, 0, 0), new Color(0.1f, 0.1f, 0.1f), TextAnchor.UpperLeft); + +// UIRoot = UIFactory.CreateUIObject($"{this.GetType().Name}.MainContent", m_parentContent); +// UIFactory.SetLayoutGroup(UIRoot, true, true, true, true, 2, 0, 5, 0, 0, TextAnchor.UpperLeft); +// m_mainRect = UIRoot.GetComponent(); +// m_mainRect.pivot = new Vector2(0, 1); +// m_mainRect.anchorMin = Vector2.zero; +// m_mainRect.anchorMax = Vector2.one; +// UIFactory.SetLayoutElement(UIRoot, minHeight: 30, flexibleHeight: 9999, minWidth: 200, flexibleWidth: 5000); + +// SubContentGroup = new GameObject("SubContent"); +// SubContentGroup.transform.parent = UIRoot.transform; +// UIFactory.SetLayoutElement(SubContentGroup, minHeight: 30, flexibleHeight: 9999, minWidth: 125, flexibleWidth: 9000); +// UIFactory.SetLayoutGroup(SubContentGroup, true, false, true, true); +// SubContentGroup.SetActive(false); + +// IValue.m_subContentParent = SubContentGroup; +// } + +// public virtual void CheckSubcontentCreation() +// { +// if (!constructedSubcontent) +// { +// SubContentGroup.AddComponent().color = new Color(0.08f, 0.08f, 0.08f); +// constructedSubcontent = true; +// } +// } + +// #endregion + +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CachePaired.cs b/src/Inspectors_OLD/CacheObject/CachePaired.cs new file mode 100644 index 0000000..48ed204 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CachePaired.cs @@ -0,0 +1,72 @@ +//using System; +//using System.Collections; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityExplorer.UI; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI.InteractiveValues; + +//namespace UnityExplorer.UI.CacheObject +//{ +// public enum PairTypes +// { +// Key, +// Value +// } + +// public class CachePaired : CacheObjectBase +// { +// 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.Owner = this; +// } + +// #region UI CONSTRUCTION + +// internal override void ConstructUI() +// { +// base.ConstructUI(); + +// Color bgColor = this.PairType == PairTypes.Key +// ? new Color(0.07f, 0.07f, 0.07f) +// : new Color(0.1f, 0.1f, 0.1f); + +// var rowObj = UIFactory.CreateHorizontalGroup(UIRoot, "PairedGroup", false, false, true, true, 0, new Vector4(0,0,5,2), +// bgColor); + +// string lbl = $"{this.PairType}"; +// if (this.PairType == PairTypes.Key) +// lbl = $"[{Index}] {lbl}"; + +// var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", lbl, TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 80, flexibleWidth: 30, minHeight: 25); + +// IValue.m_mainContentParent = rowObj; +// } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/CacheObject/CacheProperty.cs b/src/Inspectors_OLD/CacheObject/CacheProperty.cs new file mode 100644 index 0000000..01c8914 --- /dev/null +++ b/src/Inspectors_OLD/CacheObject/CacheProperty.cs @@ -0,0 +1,70 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Reflection; +//using UnityExplorer.UI; +//using UnityEngine; + +//namespace UnityExplorer.UI.CacheObject +//{ +// 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, GameObject parent) : base(propertyInfo, declaringInstance, parent) +// { +// this.m_arguments = propertyInfo.GetIndexParameters(); +// this.m_argumentInput = new string[m_arguments.Length]; + +// CreateIValue(null, propertyInfo.PropertyType); +// } + +// public override void UpdateReflection() +// { +// if (HasParameters && !m_isEvaluating) +// { +// // Need to enter parameters first. +// return; +// } + +// var pi = MemInfo as PropertyInfo; + +// if (pi.CanRead) +// { +// var target = pi.GetAccessors(true)[0].IsStatic ? null : DeclaringInstance; + +// IValue.Value = pi.GetValue(target, ParseArguments()); + +// m_evaluated = true; +// ReflectionException = null; +// } +// else +// { +// if (FallbackType == typeof(string)) +// { +// IValue.Value = ""; +// } +// else if (FallbackType.IsPrimitive) +// { +// IValue.Value = Activator.CreateInstance(FallbackType); +// } +// m_evaluated = true; +// ReflectionException = null; +// } +// } + +// public override void SetValue() +// { +// var pi = MemInfo as PropertyInfo; +// var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance; + +// pi.SetValue(target, IValue.Value, ParseArguments()); + +// if (this.ParentInspector?.ParentMember != null) +// this.ParentInspector.ParentMember.SetValue(); +// } +// } +//} diff --git a/src/UI/Inspectors/GameObjects/ChildList.cs b/src/Inspectors_OLD/GameObjects/ChildList.cs similarity index 99% rename from src/UI/Inspectors/GameObjects/ChildList.cs rename to src/Inspectors_OLD/GameObjects/ChildList.cs index 606ea67..deff7ab 100644 --- a/src/UI/Inspectors/GameObjects/ChildList.cs +++ b/src/Inspectors_OLD/GameObjects/ChildList.cs @@ -7,7 +7,7 @@ //using UnityExplorer.Core.Runtime; //using UnityExplorer.UI.Utility; -//namespace UnityExplorer.UI.Inspectors.GameObjects +//namespace UnityExplorer.Inspectors.GameObjects //{ // public class ChildList // { diff --git a/src/UI/Inspectors/GameObjects/ComponentList.cs b/src/Inspectors_OLD/GameObjects/ComponentList.cs similarity index 99% rename from src/UI/Inspectors/GameObjects/ComponentList.cs rename to src/Inspectors_OLD/GameObjects/ComponentList.cs index d7bb9ad..f35818f 100644 --- a/src/UI/Inspectors/GameObjects/ComponentList.cs +++ b/src/Inspectors_OLD/GameObjects/ComponentList.cs @@ -8,7 +8,7 @@ //using UnityExplorer.Core.Runtime; //using UnityExplorer.UI.Utility; -//namespace UnityExplorer.UI.Inspectors.GameObjects +//namespace UnityExplorer.Inspectors.GameObjects //{ // public class ComponentList // { diff --git a/src/UI/Inspectors/GameObjects/GameObjectControls.cs b/src/Inspectors_OLD/GameObjects/GameObjectControls.cs similarity index 99% rename from src/UI/Inspectors/GameObjects/GameObjectControls.cs rename to src/Inspectors_OLD/GameObjects/GameObjectControls.cs index b8d1342..f7d65ef 100644 --- a/src/UI/Inspectors/GameObjects/GameObjectControls.cs +++ b/src/Inspectors_OLD/GameObjects/GameObjectControls.cs @@ -7,7 +7,7 @@ //using UnityExplorer.Core.Input; //using UnityExplorer.Core.Runtime; -//namespace UnityExplorer.UI.Inspectors.GameObjects +//namespace UnityExplorer.Inspectors.GameObjects //{ // public class GameObjectControls // { diff --git a/src/UI/Inspectors/GameObjects/GameObjectInspector.cs b/src/Inspectors_OLD/GameObjects/GameObjectInspector.cs similarity index 99% rename from src/UI/Inspectors/GameObjects/GameObjectInspector.cs rename to src/Inspectors_OLD/GameObjects/GameObjectInspector.cs index 95c0cd0..776d842 100644 --- a/src/UI/Inspectors/GameObjects/GameObjectInspector.cs +++ b/src/Inspectors_OLD/GameObjects/GameObjectInspector.cs @@ -6,7 +6,7 @@ //using UnityEngine.UI; //using UnityExplorer.Core.Runtime; -//namespace UnityExplorer.UI.Inspectors.GameObjects +//namespace UnityExplorer.Inspectors.GameObjects //{ // public class GameObjectInspector : InspectorBase // { diff --git a/src/UI/Inspectors/InspectUnderMouse.cs b/src/Inspectors_OLD/InspectUnderMouse.cs similarity index 99% rename from src/UI/Inspectors/InspectUnderMouse.cs rename to src/Inspectors_OLD/InspectUnderMouse.cs index fb62bb1..188618c 100644 --- a/src/UI/Inspectors/InspectUnderMouse.cs +++ b/src/Inspectors_OLD/InspectUnderMouse.cs @@ -10,7 +10,7 @@ //using UnityExplorer.Core.Runtime; //using UnityExplorer.UI; //using UnityExplorer.UI.Main; -//using UnityExplorer.UI.Inspectors; +//using UnityExplorer.Inspectors; //namespace UnityExplorer.UI.Main.Home //{ diff --git a/src/Inspectors_OLD/InspectorBase.cs b/src/Inspectors_OLD/InspectorBase.cs new file mode 100644 index 0000000..04d3479 --- /dev/null +++ b/src/Inspectors_OLD/InspectorBase.cs @@ -0,0 +1,122 @@ +//using System; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI.Panels; + +//namespace UnityExplorer.Inspectors +//{ +// public abstract class InspectorBase +// { +// public object Target; +// public bool IsActive { get; private set; } + +// public abstract string TabLabel { get; } + +// internal bool m_pendingDestroy; + +// public InspectorBase(object target) +// { +// Target = target; + +// if (Target.IsNullOrDestroyed(false)) +// { +// Destroy(); +// return; +// } + +// AddInspectorTab(this); +// } + +// public virtual void SetActive() +// { +// this.IsActive = true; +// Content?.SetActive(true); +// } + +// public virtual void SetInactive() +// { +// this.IsActive = false; +// Content?.SetActive(false); +// } + +// public virtual void Update() +// { +// if (Target.IsNullOrDestroyed(false)) +// { +// Destroy(); +// return; +// } + +// m_tabText.text = TabLabel; +// } + +// public virtual void Destroy() +// { +// m_pendingDestroy = true; + +// GameObject tabGroup = m_tabButton?.transform.parent.gameObject; + +// if (tabGroup) +// GameObject.Destroy(tabGroup); + +// int thisIndex = -1; +// if (InspectorManager.ActiveInspectors.Contains(this)) +// { +// thisIndex = InspectorManager.ActiveInspectors.IndexOf(this); +// InspectorManager.ActiveInspectors.Remove(this); +// } + +// if (ReferenceEquals(InspectorManager.m_activeInspector, this)) +// { +// InspectorManager.UnsetInspectorTab(); + +// if (InspectorManager.ActiveInspectors.Count > 0) +// { +// var prevTab = InspectorManager.ActiveInspectors[thisIndex > 0 ? thisIndex - 1 : 0]; +// InspectorManager.SetInspectorTab(prevTab); +// } +// } +// } + +// #region UI + +// public abstract GameObject Content { get; set; } +// public Button m_tabButton; +// public Text m_tabText; + +// public void AddInspectorTab(InspectorBase parent) +// { +// var tabContent = InspectorPanel.Instance.NavbarHolder; + +// var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent, "TabObject", true, true, true, true); +// UIFactory.SetLayoutElement(tabGroupObj, minWidth: 185, flexibleWidth: 0); +// tabGroupObj.AddComponent(); + +// m_tabButton = UIFactory.CreateButton(tabGroupObj, +// "TabButton", +// "", +// () => { InspectorManager.SetInspectorTab(parent); }); + +// UIFactory.SetLayoutElement(m_tabButton.gameObject, minWidth: 165, flexibleWidth: 0); + +// m_tabText = m_tabButton.GetComponentInChildren(); +// m_tabText.horizontalOverflow = HorizontalWrapMode.Overflow; +// m_tabText.alignment = TextAnchor.MiddleLeft; + +// var closeBtn = UIFactory.CreateButton(tabGroupObj, +// "CloseButton", +// "X", +// () => { InspectorManager.DestroyInspector(parent); }, +// new Color(0.2f, 0.2f, 0.2f, 1)); + +// UIFactory.SetLayoutElement(closeBtn.gameObject, minWidth: 20, flexibleWidth: 0); + +// var closeBtnText = closeBtn.GetComponentInChildren(); +// closeBtnText.color = new Color(1, 0, 0, 1); +// } + +// public virtual void OnPanelResized() { } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/InspectorManager.cs b/src/Inspectors_OLD/InspectorManager.cs new file mode 100644 index 0000000..0a841f7 --- /dev/null +++ b/src/Inspectors_OLD/InspectorManager.cs @@ -0,0 +1,151 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using UnityExplorer.UI; +//using UnityEngine; +//using UnityEngine.SceneManagement; +//using UnityEngine.UI; +//using UnityExplorer.Core.Runtime; +//using UnityExplorer.UI.CacheObject; +//using UnityExplorer.Inspectors.Reflection; +//using UnityExplorer.UI.Panels; + +//namespace UnityExplorer.Inspectors +//{ +// public static class InspectorManager +// { +// public static InspectorBase m_activeInspector; +// public static readonly List ActiveInspectors = new List(); + +// public static void Update() +// { +// try +// { +// for (int i = 0; i < ActiveInspectors.Count; i++) +// ActiveInspectors[i].Update(); +// } +// catch (Exception ex) +// { +// ExplorerCore.LogWarning(ex); +// } +// } + +// public static void DestroyInspector(InspectorBase inspector) +// { +// if (inspector is ReflectionInspector ri) +// ri.Destroy(); +// else +// inspector.Destroy(); +// } + +// public static void Inspect(object obj, CacheObjectBase parentMember = null) +// { +// var type = ReflectionProvider.Instance.GetActualType(obj); + +// // only need to set parent member for structs +// if (!type.IsValueType) +// parentMember = null; + +// obj = ReflectionProvider.Instance.Cast(obj, type); + +// if (obj.IsNullOrDestroyed(false)) +// return; + +// // check if currently inspecting this object +// foreach (InspectorBase tab in ActiveInspectors) +// { +// if (obj.ReferenceEqual(tab.Target)) +// { +// SetInspectorTab(tab); +// return; +// } +// } + +// InspectorBase inspector; +// if (obj is GameObject go) +// { +// ExplorerCore.Log("TODO"); +// return; +// // inspector = new GameObjectInspector(go); +// } +// else +// inspector = new InstanceInspector(obj); + +// if (inspector is ReflectionInspector ri) +// ri.ParentMember = parentMember; + +// ActiveInspectors.Add(inspector); +// SetInspectorTab(inspector); +// } + +// public static void Inspect(Type type) +// { +// if (type == null) +// { +// ExplorerCore.LogWarning("The provided type was null!"); +// return; +// } + +// foreach (var tab in ActiveInspectors.Where(x => x is StaticInspector)) +// { +// if (ReferenceEquals(tab.Target as Type, type)) +// { +// SetInspectorTab(tab); +// return; +// } +// } + +// var inspector = new StaticInspector(type); + +// ActiveInspectors.Add(inspector); +// SetInspectorTab(inspector); +// } + +// public static void SetInspectorTab(InspectorBase inspector) +// { +// UIManager.SetPanelActive(UIManager.Panels.Inspector, true); + +// if (m_activeInspector == inspector) +// return; + +// UnsetInspectorTab(); + +// m_activeInspector = inspector; +// inspector.SetActive(); + +// OnSetInspectorTab(inspector); +// } + +// public static void UnsetInspectorTab() +// { +// if (m_activeInspector == null) +// return; + +// m_activeInspector.SetInactive(); + +// OnUnsetInspectorTab(); + +// m_activeInspector = null; +// } + +// public static void OnSetInspectorTab(InspectorBase inspector) +// { +// Color activeColor = new Color(0, 0.25f, 0, 1); +// RuntimeProvider.Instance.SetColorBlock(inspector.m_tabButton, activeColor, activeColor); +// } + +// public static void OnUnsetInspectorTab() +// { +// RuntimeProvider.Instance.SetColorBlock(m_activeInspector.m_tabButton, +// new Color(0.2f, 0.2f, 0.2f, 1), new Color(0.1f, 0.3f, 0.1f, 1)); +// } + +// internal static void OnPanelResized() +// { +// foreach (var instance in ActiveInspectors) +// { +// instance.OnPanelResized(); +// } +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveBool.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveBool.cs new file mode 100644 index 0000000..b908b51 --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveBool.cs @@ -0,0 +1,110 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; +//using UnityExplorer.UI.CacheObject; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveBool : InteractiveValue +// { +// public InteractiveBool(object value, Type valueType) : base(value, valueType) { } + +// public override bool HasSubContent => false; +// public override bool SubContentWanted => false; +// public override bool WantInspectBtn => false; + +// internal Toggle m_toggle; +// internal Button m_applyBtn; + +// public override void OnValueUpdated() +// { +// base.OnValueUpdated(); +// } + +// public override void RefreshUIForValue() +// { +// GetDefaultLabel(); + +// if (Owner.HasEvaluated) +// { +// var val = (bool)Value; + +// if (!m_toggle.gameObject.activeSelf) +// m_toggle.gameObject.SetActive(true); + +// if (val != m_toggle.isOn) +// m_toggle.isOn = val; + +// if (Owner.CanWrite) +// { +// if (!m_applyBtn.gameObject.activeSelf) +// m_applyBtn.gameObject.SetActive(true); +// } + +// var color = val +// ? "6bc981" // on +// : "c96b6b"; // off + +// m_baseLabel.text = $"{val}"; +// } +// else +// { +// m_baseLabel.text = DefaultLabel; +// } +// } + +// public override void OnException(CacheMember member) +// { +// base.OnException(member); + +// if (Owner.CanWrite) +// { +// if (m_toggle.gameObject.activeSelf) +// m_toggle.gameObject.SetActive(false); + +// if (m_applyBtn.gameObject.activeSelf) +// m_applyBtn.gameObject.SetActive(false); +// } +// } + +// internal void OnToggleValueChanged(bool val) +// { +// Value = val; +// RefreshUIForValue(); +// } + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); + +// var baseLayout = m_baseLabel.gameObject.GetComponent(); +// baseLayout.flexibleWidth = 0; +// baseLayout.minWidth = 50; + +// var toggleObj = UIFactory.CreateToggle(m_mainContent, "InteractiveBoolToggle", out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f)); +// UIFactory.SetLayoutElement(toggleObj, minWidth: 24); +// m_toggle.onValueChanged.AddListener(OnToggleValueChanged); + +// m_baseLabel.transform.SetAsLastSibling(); + +// m_applyBtn = UIFactory.CreateButton(m_mainContent, +// "ApplyButton", +// "Apply", +// () => { Owner.SetValue(); }, +// new Color(0.2f, 0.2f, 0.2f)); + +// UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0); + +// toggleObj.SetActive(false); + +// if (!Owner.CanWrite) +// m_toggle.interactable = false; + +// m_applyBtn.gameObject.SetActive(false); +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveColor.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveColor.cs new file mode 100644 index 0000000..afd942e --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveColor.cs @@ -0,0 +1,167 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveColor : InteractiveValue +// { +// //~~~~~~~~~ Instance ~~~~~~~~~~ + +// public InteractiveColor(object value, Type valueType) : base(value, valueType) { } + +// public override bool HasSubContent => true; +// public override bool SubContentWanted => true; +// public override bool WantInspectBtn => true; + +// public override void RefreshUIForValue() +// { +// base.RefreshUIForValue(); + +// if (m_subContentConstructed) +// RefreshUI(); +// } + +// private void RefreshUI() +// { +// var color = (Color)this.Value; + +// m_inputs[0].text = color.r.ToString(); +// m_inputs[1].text = color.g.ToString(); +// m_inputs[2].text = color.b.ToString(); +// m_inputs[3].text = color.a.ToString(); + +// if (m_colorImage) +// m_colorImage.color = color; +// } + +// internal override void OnToggleSubcontent(bool toggle) +// { +// base.OnToggleSubcontent(toggle); + +// RefreshUI(); +// } + +// #region UI CONSTRUCTION + +// private Image m_colorImage; + +// private readonly InputField[] m_inputs = new InputField[4]; +// private readonly Slider[] m_sliders = new Slider[4]; + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); + +// //// Limit the label width for colors, they're always about the same so make use of that space. +// //UIFactory.SetLayoutElement(this.m_baseLabel.gameObject, flexibleWidth: 0, minWidth: 250); +// } + +// public override void ConstructSubcontent() +// { +// base.ConstructSubcontent(); + +// var horiGroup = UIFactory.CreateHorizontalGroup(m_subContentParent, "ColorEditor", false, false, true, true, 5, +// default, default, TextAnchor.MiddleLeft); + +// var editorContainer = UIFactory.CreateVerticalGroup(horiGroup, "EditorContent", false, true, true, true, 2, new Vector4(4, 4, 4, 4), +// new Color(0.08f, 0.08f, 0.08f)); +// UIFactory.SetLayoutElement(editorContainer, minWidth: 300, flexibleWidth: 0); + +// for (int i = 0; i < 4; i++) +// AddEditorRow(i, editorContainer); + +// if (Owner.CanWrite) +// { +// var applyBtn = UIFactory.CreateButton(editorContainer, "ApplyButton", "Apply", OnSetValue, new Color(0.2f, 0.2f, 0.2f)); +// UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 175, minHeight: 25, flexibleWidth: 0); + +// void OnSetValue() +// { +// Owner.SetValue(); +// RefreshUIForValue(); +// } +// } + +// var imgHolder = UIFactory.CreateVerticalGroup(horiGroup, "ImgHolder", true, true, true, true, 0, new Vector4(1, 1, 1, 1), +// new Color(0.08f, 0.08f, 0.08f)); +// UIFactory.SetLayoutElement(imgHolder, minWidth: 128, minHeight: 128, flexibleWidth: 0, flexibleHeight: 0); + +// var imgObj = UIFactory.CreateUIObject("ColorImageHelper", imgHolder, new Vector2(100, 25)); +// m_colorImage = imgObj.AddComponent(); +// m_colorImage.color = (Color)this.Value; +// } + +// private static readonly string[] s_fieldNames = new[] { "R", "G", "B", "A" }; + +// internal void AddEditorRow(int index, GameObject groupObj) +// { +// var row = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow_" + s_fieldNames[index], +// false, true, true, true, 5, default, new Color(1, 1, 1, 0)); + +// var label = UIFactory.CreateLabel(row, "RowLabel", $"{s_fieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan); +// UIFactory.SetLayoutElement(label.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 25); + +// var inputFieldObj = UIFactory.CreateInputField(row, "InputField", "...", out InputField inputField, 14, 3, 1); +// UIFactory.SetLayoutElement(inputFieldObj, minWidth: 120, minHeight: 25, flexibleWidth: 0); + +// m_inputs[index] = inputField; +// inputField.characterValidation = InputField.CharacterValidation.Decimal; + +// inputField.onValueChanged.AddListener((string value) => +// { +// float val = float.Parse(value); +// SetValueToColor(val); +// m_sliders[index].value = val; +// }); + +// var sliderObj = UIFactory.CreateSlider(row, "Slider", out Slider slider); +// m_sliders[index] = slider; +// UIFactory.SetLayoutElement(sliderObj, minWidth: 200, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0); +// slider.minValue = 0; +// slider.maxValue = 1; +// slider.value = GetValueFromColor(); + +// slider.onValueChanged.AddListener((float value) => +// { +// inputField.text = value.ToString(); +// SetValueToColor(value); +// m_inputs[index].text = value.ToString(); +// }); + +// // methods for writing to the color for this field + +// void SetValueToColor(float floatValue) +// { +// Color _color = (Color)Value; +// switch (index) +// { +// case 0: _color.r = floatValue; break; +// case 1: _color.g = floatValue; break; +// case 2: _color.b = floatValue; break; +// case 3: _color.a = floatValue; break; +// } +// Value = _color; +// m_colorImage.color = _color; +// } + +// float GetValueFromColor() +// { +// Color _color = (Color)Value; +// switch (index) +// { +// case 0: return _color.r; +// case 1: return _color.g; +// case 2: return _color.b; +// case 3: return _color.a; +// default: throw new NotImplementedException(); +// } +// } +// } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveDictionary.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveDictionary.cs new file mode 100644 index 0000000..d09c961 --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveDictionary.cs @@ -0,0 +1,246 @@ +//using System; +//using System.Collections; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.Core.Config; +//using UnityExplorer.UI; +//using System.Reflection; +//using UnityExplorer.UI.CacheObject; +//using UnityExplorer.Core; +//using UnityExplorer.UI.Utility; +//#if CPP +//using AltIDictionary = Il2CppSystem.Collections.IDictionary; +//#else +//using AltIDictionary = System.Collections.IDictionary; +//#endif + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// 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 bool WantInspectBtn => false; +// public override bool HasSubContent => true; +// public override bool SubContentWanted +// { +// get +// { +// if (m_recacheWanted && Value != null) +// return true; +// else return m_entries.Count > 0; +// } +// } + +// internal IDictionary RefIDictionary; +// internal AltIDictionary RefAltIDictionary; +// internal Type m_typeOfKeys; +// internal Type m_typeofValues; + +// internal readonly List> m_entries +// = new List>(); + +// internal readonly KeyValuePair[] m_displayedEntries +// = new KeyValuePair[ConfigManager.Default_Page_Limit.Value]; + +// internal bool m_recacheWanted = true; + +// public override void OnDestroy() +// { +// base.OnDestroy(); +// } + +// public override void OnValueUpdated() +// { +// RefIDictionary = Value as IDictionary; + +// if (RefIDictionary == null) +// { +// try { RefAltIDictionary = Value.TryCast(); } +// catch { } +// } + +// if (m_subContentParent.activeSelf) +// { +// GetCacheEntries(); +// RefreshDisplay(); +// } +// else +// m_recacheWanted = true; + +// base.OnValueUpdated(); +// } + +// internal void OnPageTurned() +// { +// RefreshDisplay(); +// } + +// public override void RefreshUIForValue() +// { +// GetDefaultLabel(); + +// if (Value != null) +// { +// 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}"; +// } +// else +// { +// m_baseLabel.text = DefaultLabel; +// } +// } + +// 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 && Value != null) +// RefIDictionary = RuntimeProvider.Instance.Reflection.EnumerateDictionary(Value, m_typeOfKeys, m_typeofValues); + +// if (RefIDictionary != null) +// { +// int index = 0; + +// foreach (var key in RefIDictionary.Keys) +// { +// var value = RefIDictionary[key]; + +// 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(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(); +// RefreshUIForValue(); +// } + +// RefreshDisplay(); +// } + +// 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; + +// m_listContent = UIFactory.CreateVerticalGroup(m_subContentParent, "DictionaryContent", true, true, true, true, 2, new Vector4(5,5,5,5), +// new Color(0.08f, 0.08f, 0.08f)); + +// var scrollRect = m_listContent.GetComponent(); +// scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0); + +// m_listLayout = Owner.UIRoot.GetComponent(); +// m_listLayout.minHeight = 25; +// m_listLayout.flexibleHeight = 0; + +// Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); + +// var contentFitter = m_listContent.AddComponent(); +// contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; +// contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveEnum.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveEnum.cs new file mode 100644 index 0000000..18e682f --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveEnum.cs @@ -0,0 +1,163 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveEnum : InteractiveValue +// { +// internal static Dictionary[]> s_enumNamesCache = new Dictionary[]>(); + +// public InteractiveEnum(object value, Type valueType) : base(value, valueType) +// { +// GetNames(); +// } + +// public override bool HasSubContent => true; +// public override bool SubContentWanted => Owner.CanWrite; +// public override bool WantInspectBtn => false; + +// internal KeyValuePair[] m_values = new KeyValuePair[0]; + +// internal Type m_lastEnumType; + +// internal void GetNames() +// { +// var type = Value?.GetType() ?? FallbackType; + +// if (m_lastEnumType == type) +// return; + +// m_lastEnumType = type; + +// if (m_subContentConstructed) +// { +// DestroySubContent(); +// } + +// if (!s_enumNamesCache.ContainsKey(type)) +// { +// // using GetValues not GetNames, to catch instances of weird enums (eg CameraClearFlags) +// var values = Enum.GetValues(type); + +// var list = new List>(); +// var set = new HashSet(); + +// foreach (var value in values) +// { +// var name = value.ToString(); + +// if (set.Contains(name)) +// continue; + +// set.Add(name); + +// var backingType = Enum.GetUnderlyingType(type); +// int intValue; +// try +// { +// // this approach is necessary, a simple '(int)value' is not sufficient. + +// var unbox = Convert.ChangeType(value, backingType); + +// intValue = (int)Convert.ChangeType(unbox, typeof(int)); +// } +// catch (Exception ex) +// { +// ExplorerCore.LogWarning("[InteractiveEnum] Could not Unbox underlying type " + backingType.Name + " from " + type.FullName); +// ExplorerCore.Log(ex.ToString()); +// continue; +// } + +// list.Add(new KeyValuePair(intValue, name)); +// } + +// s_enumNamesCache.Add(type, list.ToArray()); +// } + +// m_values = s_enumNamesCache[type]; +// } + +// public override void OnValueUpdated() +// { +// GetNames(); + +// base.OnValueUpdated(); +// } + +// public override void RefreshUIForValue() +// { +// base.RefreshUIForValue(); + +// if (m_subContentConstructed && !(this is InteractiveFlags)) +// { +// m_dropdownText.text = Value?.ToString() ?? ""; +// } +// } + +// internal override void OnToggleSubcontent(bool toggle) +// { +// base.OnToggleSubcontent(toggle); + +// RefreshUIForValue(); +// } + +// private void SetValueFromDropdown() +// { +// var type = Value?.GetType() ?? FallbackType; +// var index = m_dropdown.value; + +// var value = Enum.Parse(type, s_enumNamesCache[type][index].Value); + +// if (value != null) +// { +// Value = value; +// Owner.SetValue(); +// RefreshUIForValue(); +// } +// } + +// internal Dropdown m_dropdown; +// internal Text m_dropdownText; + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); +// } + +// public override void ConstructSubcontent() +// { +// base.ConstructSubcontent(); + +// if (Owner.CanWrite) +// { +// var groupObj = UIFactory.CreateHorizontalGroup(m_subContentParent, "InteractiveEnumGroup", false, true, true, true, 5, +// new Vector4(3,3,3,3),new Color(1, 1, 1, 0)); + +// // apply button + +// var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromDropdown, new Color(0.3f, 0.3f, 0.3f)); +// UIFactory.SetLayoutElement(apply.gameObject, minHeight: 25, minWidth: 50); + +// // dropdown + +// var dropdownObj = UIFactory.CreateDropdown(groupObj, out m_dropdown, "", 14, null); +// UIFactory.SetLayoutElement(dropdownObj, minWidth: 150, minHeight: 25, flexibleWidth: 120); + +// foreach (var kvp in m_values) +// { +// m_dropdown.options.Add(new Dropdown.OptionData +// { +// text = $"{kvp.Key}: {kvp.Value}" +// }); +// } + +// m_dropdownText = m_dropdown.transform.Find("Label").GetComponent(); +// } +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveEnumerable.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveEnumerable.cs new file mode 100644 index 0000000..7d2711f --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveEnumerable.cs @@ -0,0 +1,245 @@ +//using System; +//using System.Collections; +//using System.Collections.Generic; +//using System.Linq; +//using System.Reflection; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.Core; +//using UnityExplorer.Core.Config; +//using UnityExplorer.UI; +//using UnityExplorer.UI.CacheObject; +//using UnityExplorer.UI.Utility; +//using UnityExplorer.UI.Widgets; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveEnumerable : InteractiveValue, IPoolDataSource +// { +// // IPoolDataSource + +// public ScrollPool ScrollPool; +// public GameObject InactiveHolder; +// internal LayoutElement listLayout; + +// public int ItemCount => m_entries?.Count ?? 0; + +// public void SetCell(ICell icell, int index) +// { +// var cell = icell as CellViewHolder; + +// if (index < 0 || index >= ItemCount) +// { +// var existing = cell.DisableContent(); +// if (existing) +// existing.transform.SetParent(InactiveHolder.transform, false); +// return; +// } + +// var cache = m_entries[index]; +// cache.Enable(); + +// var prev = cell.SetContent(cache.UIRoot); +// if (prev) +// prev.transform.SetParent(InactiveHolder.transform, false); +// } + +// public void DisableCell(ICell cell, int index) +// { +// var content = (cell as CellViewHolder).DisableContent(); +// if (content) +// content.transform.SetParent(InactiveHolder.transform, false); +// } + +// //public void SetCell(ICell cell, int index) +// //{ +// // var root = (cell as CellViewHolder).UIRoot; + +// // if (index < 0 || index >= ItemCount) +// // { +// // DisableContent(root); +// // cell.Disable(); +// // return; +// // } + +// // var cache = m_entries[index]; +// // cache.Enable(); + +// // var content = cache.UIRoot; + +// // if (content.transform.parent.ReferenceEqual(root.transform)) +// // return; + +// // DisableContent(root); + +// // content.transform.SetParent(root.transform, false); +// //} + +// //public void DisableCell(ICell cell, int index) +// //{ +// // var root = (cell as CellViewHolder).UIRoot; +// // DisableContent(root); +// // cell.Disable(); +// //} + +// //private void DisableContent(GameObject cellRoot) +// //{ +// // if (cellRoot.transform.childCount > 0 && cellRoot.transform.GetChild(0) is Transform existing) +// // existing.transform.SetParent(InactiveHolder.transform, false); +// //} + +// public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject); + +// public int GetRealIndexOfTempIndex(int tempIndex) => throw new NotImplementedException("Filtering not supported"); + +// // InteractiveEnumerable + +// public InteractiveEnumerable(object value, Type valueType) : base(value, valueType) +// { +// if (valueType.IsGenericType) +// m_baseEntryType = valueType.GetGenericArguments()[0]; +// else +// m_baseEntryType = typeof(object); +// } + +// public override bool WantInspectBtn => false; +// public override bool HasSubContent => true; +// public override bool SubContentWanted +// { +// get +// { +// if (m_recacheWanted && Value != null) +// return true; +// else return m_entries.Count > 0; +// } +// } + + +// internal IEnumerable RefIEnumerable; +// internal IList RefIList; + +// internal readonly Type m_baseEntryType; + +// internal readonly List m_entries = new List(); +// internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ConfigManager.Default_Page_Limit.Value]; +// internal bool m_recacheWanted = true; + +// public override void OnValueUpdated() +// { +// RefIEnumerable = Value as IEnumerable; +// RefIList = Value as IList; + +// if (m_subContentParent && m_subContentParent.activeSelf) +// { +// ToggleSubcontent(); +// //GetCacheEntries(); +// //RefreshDisplay(); +// } + +// m_recacheWanted = true; + +// base.OnValueUpdated(); +// } + +// public override void OnException(CacheMember member) +// { +// base.OnException(member); +// } + +// public override void RefreshUIForValue() +// { +// GetDefaultLabel(); + +// if (Value != null) +// { +// 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}"; +// } +// else +// { +// m_baseLabel.text = DefaultLabel; +// } +// } + +// public void GetCacheEntries() +// { +// if (m_entries.Any()) +// { +// foreach (var entry in m_entries) +// entry.Destroy(); + +// m_entries.Clear(); +// } + +// if (RefIEnumerable == null && Value != null) +// RefIEnumerable = RuntimeProvider.Instance.Reflection.EnumerateEnumerable(Value); + +// if (RefIEnumerable != null) +// { +// int index = 0; +// foreach (var entry in RefIEnumerable) +// { +// var cache = new CacheEnumerated(index, this, RefIList, this.InactiveHolder); +// cache.CreateIValue(entry, m_baseEntryType); +// m_entries.Add(cache); + +// cache.Disable(); + +// index++; +// } +// } + +// RefreshDisplay(); +// } + +// public void RefreshDisplay() +// { +// ScrollPool.RefreshCells(true); + +// listLayout.minHeight = Math.Min(500f, m_entries.Count * 32f); +// } + +// internal override void OnToggleSubcontent(bool active) +// { +// base.OnToggleSubcontent(active); + +// if (active && m_recacheWanted) +// { +// m_recacheWanted = false; +// GetCacheEntries(); +// RefreshUIForValue(); +// } + +// RefreshDisplay(); +// } + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); + +// InactiveHolder = new GameObject("InactiveHolder"); +// InactiveHolder.transform.SetParent(parent.transform, false); +// InactiveHolder.SetActive(false); +// } + +// public override void ConstructSubcontent() +// { +// base.ConstructSubcontent(); + +// ScrollPool = UIFactory.CreateScrollPool(m_subContentParent, "ListEntries", out GameObject scrollRoot, out GameObject scrollContent, +// new Color(0.05f, 0.05f, 0.05f)); + +// listLayout = scrollRoot.AddComponent(); + +// var proto = CellViewHolder.CreatePrototypeCell(scrollRoot); +// proto.sizeDelta = new Vector2(100, 30); +// ScrollPool.Initialize(this, proto); +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveFlags.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveFlags.cs new file mode 100644 index 0000000..2629ffd --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveFlags.cs @@ -0,0 +1,125 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveFlags : InteractiveEnum +// { +// public InteractiveFlags(object value, Type valueType) : base(value, valueType) +// { +// m_toggles = new Toggle[m_values.Length]; +// m_enabledFlags = new bool[m_values.Length]; +// } + +// public override bool HasSubContent => true; +// public override bool SubContentWanted => Owner.CanWrite; +// public override bool WantInspectBtn => false; + +// internal bool[] m_enabledFlags; +// internal Toggle[] m_toggles; + +// public override void OnValueUpdated() +// { +// if (Owner.CanWrite) +// { +// var enabledNames = new List(); + +// var enabled = Value?.ToString().Split(',').Select(it => it.Trim()); +// if (enabled != null) +// enabledNames.AddRange(enabled); + +// for (int i = 0; i < m_values.Length; i++) +// m_enabledFlags[i] = enabledNames.Contains(m_values[i].Value); +// } + +// base.OnValueUpdated(); +// } + +// public override void RefreshUIForValue() +// { +// GetDefaultLabel(); +// m_baseLabel.text = DefaultLabel; + +// base.RefreshUIForValue(); + +// if (m_subContentConstructed) +// { +// for (int i = 0; i < m_values.Length; i++) +// { +// var toggle = m_toggles[i]; +// if (toggle.isOn != m_enabledFlags[i]) +// toggle.isOn = m_enabledFlags[i]; +// } +// } +// } + +// private void SetValueFromToggles() +// { +// string val = ""; +// for (int i = 0; i < m_values.Length; i++) +// { +// if (m_enabledFlags[i]) +// { +// if (val != "") val += ", "; +// val += m_values[i].Value; +// } +// } +// var type = Value?.GetType() ?? FallbackType; +// Value = Enum.Parse(type, val); +// RefreshUIForValue(); +// Owner.SetValue(); +// } + +// internal override void OnToggleSubcontent(bool toggle) +// { +// base.OnToggleSubcontent(toggle); + +// RefreshUIForValue(); +// } + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); +// } + +// public override void ConstructSubcontent() +// { +// m_subContentConstructed = true; + +// if (Owner.CanWrite) +// { +// var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "InteractiveFlagsContent", false, true, true, true, 5, +// new Vector4(3,3,3,3), new Color(1, 1, 1, 0)); + +// // apply button + +// var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromToggles, new Color(0.3f, 0.3f, 0.3f)); +// UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25); + +// // toggles + +// for (int i = 0; i < m_values.Length; i++) +// AddToggle(i, groupObj); +// } +// } + +// internal void AddToggle(int index, GameObject groupObj) +// { +// var value = m_values[index]; + +// var toggleObj = UIFactory.CreateToggle(groupObj, "FlagToggle", out Toggle toggle, out Text text, new Color(0.1f, 0.1f, 0.1f)); +// UIFactory.SetLayoutElement(toggleObj, minWidth: 100, flexibleWidth: 2000, minHeight: 25); + +// m_toggles[index] = toggle; + +// toggle.onValueChanged.AddListener((bool val) => { m_enabledFlags[index] = val; }); + +// text.text = $"{value.Key}: {value.Value}"; +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveFloatStruct.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveFloatStruct.cs new file mode 100644 index 0000000..6f5d96c --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveFloatStruct.cs @@ -0,0 +1,203 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using System.Reflection; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// // Class for supporting any "float struct" (ie Vector, Rect, etc). +// // Supports any struct where all the public instance fields are floats (or types assignable to float) + +// public class StructInfo +// { +// public string[] FieldNames { get; } +// private readonly FieldInfo[] m_fields; + +// public StructInfo(Type type) +// { +// m_fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) +// .Where(it => !it.IsLiteral) +// .ToArray(); + +// FieldNames = m_fields.Select(it => it.Name) +// .ToArray(); +// } + +// public object SetValue(ref object instance, int fieldIndex, float val) +// { +// m_fields[fieldIndex].SetValue(instance, val); +// return instance; +// } + +// public float GetValue(object instance, int fieldIndex) +// => (float)m_fields[fieldIndex].GetValue(instance); + +// public void RefreshUI(InputField[] inputs, object instance) +// { +// try +// { +// for (int i = 0; i < m_fields.Length; i++) +// { +// var field = m_fields[i]; +// float val = (float)field.GetValue(instance); +// inputs[i].text = val.ToString(); +// } +// } +// catch (Exception ex) +// { +// ExplorerCore.Log(ex); +// } +// } +// } + +// public class InteractiveFloatStruct : InteractiveValue +// { +// private static readonly Dictionary _typeSupportCache = new Dictionary(); +// public static bool IsTypeSupported(Type type) +// { +// if (!type.IsValueType) +// return false; + +// if (string.IsNullOrEmpty(type.AssemblyQualifiedName)) +// return false; + +// if (_typeSupportCache.TryGetValue(type.AssemblyQualifiedName, out bool ret)) +// return ret; + +// if (type.FullName == "System.Void") +// return false; + +// ret = true; +// var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); +// foreach (var field in fields) +// { +// if (field.IsLiteral) +// continue; + +// if (!typeof(float).IsAssignableFrom(field.FieldType)) +// { +// ret = false; +// break; +// } +// } +// _typeSupportCache.Add(type.AssemblyQualifiedName, ret); +// return ret; +// } + +// //~~~~~~~~~ Instance ~~~~~~~~~~ + +// public InteractiveFloatStruct(object value, Type valueType) : base(value, valueType) { } + +// public override bool HasSubContent => true; +// public override bool SubContentWanted => true; + +// public StructInfo StructInfo; + +// public override void RefreshUIForValue() +// { +// InitializeStructInfo(); + +// base.RefreshUIForValue(); + +// if (m_subContentConstructed) +// StructInfo.RefreshUI(m_inputs, this.Value); +// } + +// internal override void OnToggleSubcontent(bool toggle) +// { +// InitializeStructInfo(); + +// base.OnToggleSubcontent(toggle); + +// StructInfo.RefreshUI(m_inputs, this.Value); +// } + +// internal Type m_lastStructType; + +// internal void InitializeStructInfo() +// { +// var type = Value?.GetType() ?? FallbackType; + +// if (StructInfo != null && type == m_lastStructType) +// return; + +// if (StructInfo != null && m_subContentConstructed) +// DestroySubContent(); + +// m_lastStructType = type; + +// StructInfo = new StructInfo(type); + +// if (m_subContentParent.activeSelf) +// ConstructSubcontent(); +// } + +// #region UI CONSTRUCTION + +// internal InputField[] m_inputs; + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); +// } + +// public override void ConstructSubcontent() +// { +// base.ConstructSubcontent(); + +// if (StructInfo == null) +// { +// ExplorerCore.LogWarning("Setting up subcontent but structinfo is null"); +// return; +// } + +// var editorContainer = UIFactory.CreateVerticalGroup(m_subContentParent, "EditorContent", false, true, true, true, 2, new Vector4(4, 4, 4, 4), +// new Color(0.08f, 0.08f, 0.08f)); + +// m_inputs = new InputField[StructInfo.FieldNames.Length]; + +// for (int i = 0; i < StructInfo.FieldNames.Length; i++) +// AddEditorRow(i, editorContainer); + +// RefreshUIForValue(); +// } + +// internal void AddEditorRow(int index, GameObject groupObj) +// { +// try +// { +// var row = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow", false, true, true, true, 5, default, new Color(1, 1, 1, 0)); + +// string name = StructInfo.FieldNames[index]; + +// var label = UIFactory.CreateLabel(row, "RowLabel", $"{name}:", TextAnchor.MiddleRight, Color.cyan); +// UIFactory.SetLayoutElement(label.gameObject, minWidth: 30, flexibleWidth: 0, minHeight: 25); + +// var inputFieldObj = UIFactory.CreateInputField(row, "InputField", "...", out InputField inputField, 14, 3, 1); +// UIFactory.SetLayoutElement(inputFieldObj, minWidth: 120, minHeight: 25, flexibleWidth: 0); + +// m_inputs[index] = inputField; + +// inputField.onValueChanged.AddListener((string val) => +// { +// try +// { +// float f = float.Parse(val); +// Value = StructInfo.SetValue(ref this.Value, index, f); +// Owner.SetValue(); +// } +// catch { } +// }); +// } +// catch (Exception ex) +// { +// ExplorerCore.Log(ex); +// } +// } + +// #endregion +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveNumber.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveNumber.cs new file mode 100644 index 0000000..c8f9a6d --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveNumber.cs @@ -0,0 +1,115 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Reflection; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; +//using UnityExplorer.Core; +//using UnityExplorer.UI.Utility; +//using UnityExplorer.UI.CacheObject; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveNumber : InteractiveValue +// { +// public InteractiveNumber(object value, Type valueType) : base(value, valueType) { } + +// public override bool HasSubContent => false; +// public override bool SubContentWanted => false; +// public override bool WantInspectBtn => false; + +// public override void OnValueUpdated() +// { +// base.OnValueUpdated(); +// } + +// public override void OnException(CacheMember member) +// { +// base.OnException(member); + +// if (m_valueInput.gameObject.activeSelf) +// m_valueInput.gameObject.SetActive(false); + +// if (Owner.CanWrite) +// { +// if (m_applyBtn.gameObject.activeSelf) +// m_applyBtn.gameObject.SetActive(false); +// } +// } + +// public override void RefreshUIForValue() +// { +// if (!Owner.HasEvaluated) +// { +// GetDefaultLabel(); +// m_baseLabel.text = DefaultLabel; +// return; +// } + +// m_baseLabel.text = SignatureHighlighter.ParseFullSyntax(FallbackType, false); +// m_valueInput.text = Value.ToString(); + +// var type = Value.GetType(); +// if (type == typeof(float) +// || type == typeof(double) +// || type == typeof(decimal)) +// { +// m_valueInput.characterValidation = InputField.CharacterValidation.Decimal; +// } +// else +// { +// m_valueInput.characterValidation = InputField.CharacterValidation.Integer; +// } + +// if (Owner.CanWrite) +// { +// if (!m_applyBtn.gameObject.activeSelf) +// m_applyBtn.gameObject.SetActive(true); +// } + +// if (!m_valueInput.gameObject.activeSelf) +// m_valueInput.gameObject.SetActive(true); +// } + +// public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) })); +// private MethodInfo m_parseMethod; + +// internal void OnApplyClicked() +// { +// try +// { +// Value = ParseMethod.Invoke(null, new object[] { m_valueInput.text }); +// Owner.SetValue(); +// RefreshUIForValue(); +// } +// catch (Exception e) +// { +// ExplorerCore.LogWarning("Could not parse input! " + ReflectionUtility.ReflectionExToString(e, true)); +// } +// } + +// internal InputField m_valueInput; +// internal Button m_applyBtn; + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); + +// var labelLayout = m_baseLabel.gameObject.GetComponent(); +// labelLayout.minWidth = 50; +// labelLayout.flexibleWidth = 0; + +// var inputObj = UIFactory.CreateInputField(m_mainContent, "InteractiveNumberInput", "...", out m_valueInput); +// UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 0); +// m_valueInput.gameObject.SetActive(false); + +// if (Owner.CanWrite) +// { +// m_applyBtn = UIFactory.CreateButton(m_mainContent, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f)); +// UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0); +// } +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveString.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveString.cs new file mode 100644 index 0000000..3c0a89e --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveString.cs @@ -0,0 +1,186 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Reflection; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.UI; +//using UnityExplorer.UI.Utility; +//using UnityExplorer.UI.CacheObject; +//using UnityExplorer.Core.Runtime; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveString : InteractiveValue +// { +// public InteractiveString(object value, Type valueType) : base(value, valueType) { } + +// public override bool HasSubContent => true; +// public override bool SubContentWanted => true; + +// public override bool WantInspectBtn => false; + +// public override void OnValueUpdated() +// { +// if (!(Value is string) && Value != null) +// Value = RuntimeProvider.Instance.Reflection.UnboxString(Value); + +// base.OnValueUpdated(); +// } + +// public override void OnException(CacheMember member) +// { +// base.OnException(member); + +// if (m_subContentConstructed && m_hiddenObj.gameObject.activeSelf) +// m_hiddenObj.gameObject.SetActive(false); + +// m_labelLayout.minWidth = 200; +// m_labelLayout.flexibleWidth = 5000; +// } + +// public override void RefreshUIForValue() +// { +// GetDefaultLabel(false); + +// if (!Owner.HasEvaluated) +// { +// m_baseLabel.text = DefaultLabel; +// return; +// } + +// m_baseLabel.text = m_richValueType; + +// if (m_subContentConstructed) +// { +// if (!m_hiddenObj.gameObject.activeSelf) +// m_hiddenObj.gameObject.SetActive(true); +// } + +// if (!string.IsNullOrEmpty((string)Value)) +// { +// var toString = (string)Value; +// if (toString.Length > 15000) +// toString = toString.Substring(0, 15000); + +// m_readonlyInput.text = toString; + +// if (m_subContentConstructed) +// { +// m_valueInput.text = toString; +// m_placeholderText.text = toString; +// } +// } +// else +// { +// string s = Value == null +// ? "null" +// : "empty"; + +// m_readonlyInput.text = $"{s}"; + +// if (m_subContentConstructed) +// { +// m_valueInput.text = ""; +// m_placeholderText.text = s; +// } +// } + +// m_labelLayout.minWidth = 50; +// m_labelLayout.flexibleWidth = 0; +// } + +// internal void SetValueFromInput() +// { +// Value = m_valueInput.text; + +// if (!typeof(string).IsAssignableFrom(Owner.FallbackType)) +// ReflectionProvider.Instance.BoxStringToType(ref Value, Owner.FallbackType); + +// Owner.SetValue(); + +// // revert back to string now +// OnValueUpdated(); + +// RefreshUIForValue(); +// } + +// // for the default label +// internal LayoutElement m_labelLayout; + +// //internal InputField m_readonlyInput; +// internal Text m_readonlyInput; + +// // for input +// internal InputField m_valueInput; +// internal GameObject m_hiddenObj; +// internal Text m_placeholderText; + +// public override void ConstructUI(GameObject parent, GameObject subGroup) +// { +// base.ConstructUI(parent, subGroup); + +// GetDefaultLabel(false); +// m_richValueType = SignatureHighlighter.ParseFullSyntax(FallbackType, false); + +// m_labelLayout = m_baseLabel.gameObject.GetComponent(); + +// m_readonlyInput = UIFactory.CreateLabel(m_mainContent, "ReadonlyLabel", "", TextAnchor.MiddleLeft); +// m_readonlyInput.horizontalOverflow = HorizontalWrapMode.Overflow; + +// var testFitter = m_readonlyInput.gameObject.AddComponent(); +// testFitter.verticalFit = ContentSizeFitter.FitMode.MinSize; + +// UIFactory.SetLayoutElement(m_readonlyInput.gameObject, minHeight: 25, preferredHeight: 25, flexibleHeight: 0); +// } + +// public override void ConstructSubcontent() +// { +// base.ConstructSubcontent(); + +// var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "SubContent", false, false, true, true, 4, new Vector4(3,3,3,3), +// new Color(1, 1, 1, 0)); + +// m_hiddenObj = UIFactory.CreateLabel(groupObj, "HiddenLabel", "", TextAnchor.MiddleLeft).gameObject; +// m_hiddenObj.SetActive(false); +// var hiddenText = m_hiddenObj.GetComponent(); +// hiddenText.color = Color.clear; +// hiddenText.fontSize = 14; +// hiddenText.raycastTarget = false; +// hiddenText.supportRichText = false; +// var hiddenFitter = m_hiddenObj.AddComponent(); +// hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; +// UIFactory.SetLayoutElement(m_hiddenObj, minHeight: 25, flexibleHeight: 500, minWidth: 250, flexibleWidth: 9000); +// UIFactory.SetLayoutGroup(m_hiddenObj, true, true, true, true); + +// var inputObj = UIFactory.CreateInputField(m_hiddenObj, "StringInputField", "...", out m_valueInput, 14, 3); +// UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 5000, flexibleHeight: 5000); + +// m_valueInput.lineType = InputField.LineType.MultiLineNewline; + +// m_placeholderText = m_valueInput.placeholder.GetComponent(); + +// m_placeholderText.supportRichText = false; +// m_valueInput.textComponent.supportRichText = false; + +// m_valueInput.onValueChanged.AddListener((string val) => +// { +// hiddenText.text = val ?? ""; +// LayoutRebuilder.ForceRebuildLayoutImmediate(Owner.m_mainRect); +// }); + +// if (Owner.CanWrite) +// { +// var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromInput, new Color(0.2f, 0.2f, 0.2f)); +// UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0); +// } +// else +// { +// m_valueInput.readOnly = true; +// } + +// RefreshUIForValue(); +// } +// } +//} diff --git a/src/Inspectors_OLD/InteractiveValues/InteractiveValue.cs b/src/Inspectors_OLD/InteractiveValues/InteractiveValue.cs new file mode 100644 index 0000000..0a8efdd --- /dev/null +++ b/src/Inspectors_OLD/InteractiveValues/InteractiveValue.cs @@ -0,0 +1,355 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Reflection; +//using UnityEngine; +//using UnityEngine.EventSystems; +//using UnityEngine.UI; +//using UnityExplorer.Core; +//using UnityExplorer.Core.Runtime; +//using UnityExplorer.UI; +//using UnityExplorer.UI.Utility; +//using UnityExplorer.UI.CacheObject; +//using UnityExplorer.Inspectors; + +//namespace UnityExplorer.UI.InteractiveValues +//{ +// public class InteractiveValue +// { +// /// +// /// Get the subclass which supports the provided . +// /// +// /// The which you want the Type for. +// /// The best subclass of which supports the provided . +// public static Type GetIValueForType(Type type) +// { +// // rather ugly but I couldn't think of a cleaner way that was worth it. +// // switch-case doesn't really work here. + +// // arbitrarily check some types, fastest methods first. +// if (type == typeof(bool)) +// return typeof(InteractiveBool); +// // if type is primitive then it must be a number if its not a bool. Also check for decimal. +// else if (type.IsPrimitive || type == typeof(decimal)) +// return typeof(InteractiveNumber); +// // check for strings +// else if (type == typeof(string)) +// return typeof(InteractiveString); +// // check for enum/flags +// else if (typeof(Enum).IsAssignableFrom(type)) +// { +// // NET 3.5 doesn't have "GetCustomAttribute", gotta use the multiple version. +// if (type.GetCustomAttributes(typeof(FlagsAttribute), true) is object[] fa && fa.Any()) +// return typeof(InteractiveFlags); +// else +// return typeof(InteractiveEnum); +// } +// // check for unity struct types +// else if (typeof(Color).IsAssignableFrom(type)) +// return typeof(InteractiveColor); +// else if (InteractiveFloatStruct.IsTypeSupported(type)) +// return typeof(InteractiveFloatStruct); +// // check Transform, force InteractiveValue so they dont become InteractiveEnumerables. +// else if (typeof(Transform).IsAssignableFrom(type)) +// return typeof(InteractiveValue); +// // check Dictionaries before Enumerables +// else if (ReflectionUtility.IsDictionary(type)) +// return typeof(InteractiveDictionary); +// // finally check for Enumerables +// else if (ReflectionUtility.IsEnumerable(type)) +// return typeof(InteractiveEnumerable); +// // fallback to default +// else +// return typeof(InteractiveValue); +// } + +// public static InteractiveValue Create(object value, Type fallbackType) +// { +// var type = ReflectionUtility.GetActualType(value) ?? fallbackType; +// var iType = GetIValueForType(type); + +// return (InteractiveValue)Activator.CreateInstance(iType, new object[] { value, type }); +// } + +// // ~~~~~~~~~ Instance ~~~~~~~~~ + +// public InteractiveValue(object value, Type valueType) +// { +// this.Value = value; +// this.FallbackType = valueType; +// } + +// public CacheObjectBase Owner; + +// public object Value; +// public readonly Type FallbackType; + +// public virtual bool HasSubContent => false; +// public virtual bool SubContentWanted => false; +// public virtual bool WantInspectBtn => true; + +// public string DefaultLabel => m_defaultLabel ?? GetDefaultLabel(); +// internal string m_defaultLabel; +// internal string m_richValueType; + +// public bool m_UIConstructed; + +// public virtual void OnDestroy() +// { +// if (this.m_mainContent) +// { +// m_mainContent.transform.SetParent(null, false); +// m_mainContent.SetActive(false); +// GameObject.Destroy(this.m_mainContent.gameObject); +// } + +// DestroySubContent(); +// } + +// public virtual void DestroySubContent() +// { +// if (this.m_subContentParent && HasSubContent) +// { +// for (int i = 0; i < this.m_subContentParent.transform.childCount; i++) +// { +// var child = m_subContentParent.transform.GetChild(i); +// if (child) +// GameObject.Destroy(child.gameObject); +// } +// } + +// m_subContentConstructed = false; +// } + +// public virtual void OnValueUpdated() +// { +// if (!m_UIConstructed) +// ConstructUI(m_mainContentParent, m_subContentParent); + +// if (Owner is CacheMember ownerMember && !string.IsNullOrEmpty(ownerMember.ReflectionException)) +// OnException(ownerMember); +// else +// RefreshUIForValue(); +// } + +// public virtual void OnException(CacheMember member) +// { +// if (m_UIConstructed) +// m_baseLabel.text = "" + member.ReflectionException + ""; + +// Value = null; +// } + +// public virtual void RefreshUIForValue() +// { +// GetDefaultLabel(); +// m_baseLabel.text = DefaultLabel; +// } + +// public void RefreshElementsAfterUpdate() +// { +// if (WantInspectBtn) +// { +// bool shouldShowInspect = !Value.IsNullOrDestroyed(); + +// if (m_inspectButton.activeSelf != shouldShowInspect) +// m_inspectButton.SetActive(shouldShowInspect); +// } + +// bool subContentWanted = SubContentWanted; +// if (Owner is CacheMember cm && (!cm.HasEvaluated || !string.IsNullOrEmpty(cm.ReflectionException))) +// subContentWanted = false; + +// if (HasSubContent) +// { +// if (m_subExpandBtn.gameObject.activeSelf != subContentWanted) +// m_subExpandBtn.gameObject.SetActive(subContentWanted); + +// if (!subContentWanted && m_subContentParent.activeSelf) +// ToggleSubcontent(); +// } +// } + +// public virtual void ConstructSubcontent() +// { +// Owner.CheckSubcontentCreation(); + +// 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 = "▼"; +// } +// else +// { +// this.m_subContentParent.SetActive(false); +// m_subExpandBtn.GetComponentInChildren().text = "▲"; +// } + +// OnToggleSubcontent(m_subContentParent.activeSelf); + +// RefreshElementsAfterUpdate(); +// } + +// internal virtual void OnToggleSubcontent(bool toggle) +// { +// if (!m_subContentConstructed) +// ConstructSubcontent(); +// } + +// internal MethodInfo m_toStringMethod; +// internal MethodInfo m_toStringFormatMethod; +// internal bool m_gotToStringMethods; + +// public string GetDefaultLabel(bool updateType = true) +// { +// var valueType = Value?.GetType() ?? this.FallbackType; +// if (updateType) +// m_richValueType = SignatureHighlighter.ParseFullSyntax(valueType, true); + +// if (!Owner.HasEvaluated) +// return m_defaultLabel = $"Not yet evaluated ({m_richValueType})"; + +// if (Value.IsNullOrDestroyed()) +// return m_defaultLabel = $"null ({m_richValueType})"; + +// string label; + +// // Two dirty fixes for TextAsset and EventSystem, which can have very long ToString results. +// if (Value is TextAsset textAsset) +// { +// label = textAsset.text; + +// if (label.Length > 10) +// label = $"{label.Substring(0, 10)}..."; + +// label = $"\"{label}\" {textAsset.name} ({m_richValueType})"; +// } +// else if (Value is EventSystem) +// { +// label = m_richValueType; +// } +// else // For everything else... +// { +// if (!m_gotToStringMethods) +// { +// m_gotToStringMethods = true; + +// m_toStringMethod = valueType.GetMethod("ToString", new Type[0]); +// m_toStringFormatMethod = valueType.GetMethod("ToString", new Type[] { typeof(string) }); + +// // test format method actually works +// try +// { +// m_toStringFormatMethod.Invoke(Value, new object[] { "F3" }); +// } +// catch +// { +// m_toStringFormatMethod = null; +// } +// } + +// string toString; +// if (m_toStringFormatMethod != null) +// toString = (string)m_toStringFormatMethod.Invoke(Value, new object[] { "F3" }); +// else +// toString = (string)m_toStringMethod.Invoke(Value, new object[0]); + +// toString = toString ?? ""; + +// string typeName = valueType.FullName; +// if (typeName.StartsWith("Il2CppSystem.")) +// typeName = typeName.Substring(6, typeName.Length - 6); + +// toString = ReflectionProvider.Instance.ProcessTypeFullNameInString(valueType, toString, ref typeName); + +// // If the ToString is just the type name, use our syntax highlighted type name instead. +// if (toString == typeName) +// { +// label = m_richValueType; +// } +// else // Otherwise, parse the result and put our highlighted name in. +// { +// if (toString.Length > 200) +// toString = toString.Substring(0, 200) + "..."; + +// label = toString; + +// var unityType = $"({valueType.FullName})"; +// if (Value is UnityEngine.Object && label.Contains(unityType)) +// label = label.Replace(unityType, $"({m_richValueType})"); +// else +// label += $" ({m_richValueType})"; +// } +// } + +// return m_defaultLabel = label; +// } + +// #region UI CONSTRUCTION + +// internal GameObject m_mainContentParent; +// internal GameObject m_subContentParent; + +// internal GameObject m_mainContent; +// 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_UIConstructed = true; + +// //m_mainContent = UIFactory.CreateHorizontalGroup(parent, $"InteractiveValue_{this.GetType().Name}", false, false, true, true, 4, default, +// // new Color(1, 1, 1, 0), TextAnchor.UpperLeft); + +// m_mainContent = UIFactory.CreateUIObject($"InteractiveValue_{this.GetType().Name}", parent); +// UIFactory.SetLayoutGroup(m_mainContent, false, false, true, true, 4, 0, 0, 0, 0, TextAnchor.UpperLeft); + +// var mainRect = m_mainContent.GetComponent(); +// mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); + +// UIFactory.SetLayoutElement(m_mainContent, flexibleWidth: 9000, minWidth: 175, minHeight: 25, flexibleHeight: 0); + +// // subcontent expand button +// if (HasSubContent) +// { +// m_subExpandBtn = UIFactory.CreateButton(m_mainContent, "ExpandSubcontentButton", "▲", ToggleSubcontent, new Color(1,1,1,0)); +// UIFactory.SetLayoutElement(m_subExpandBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0, flexibleHeight: 0); +// } + +// // inspect button + +// var inspectBtn = UIFactory.CreateButton(m_mainContent, +// "InspectButton", +// "Inspect", +// () => +// { +// if (!Value.IsNullOrDestroyed(false)) +// InspectorManager.Inspect(this.Value, this.Owner); +// }, +// new Color(0.3f, 0.3f, 0.3f, 0.2f)); + +// m_inspectButton = inspectBtn.gameObject; +// UIFactory.SetLayoutElement(m_inspectButton, minWidth: 60, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0); + +// m_inspectButton.SetActive(false); + +// // value label + +// m_baseLabel = UIFactory.CreateLabel(m_mainContent, "ValueLabel", "", TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(m_baseLabel.gameObject, flexibleWidth: 9000, minHeight: 25); + +// m_subContentParent = subGroup; +// } + +//#endregion +// } +//} diff --git a/src/Inspectors_OLD/Reflection/CacheMemberList.cs b/src/Inspectors_OLD/Reflection/CacheMemberList.cs new file mode 100644 index 0000000..020e4da --- /dev/null +++ b/src/Inspectors_OLD/Reflection/CacheMemberList.cs @@ -0,0 +1,61 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityExplorer.UI.Widgets; + +//namespace UnityExplorer.Inspectors.Reflection +//{ +// public class CacheMemberList : IPoolDataSource +// { +// public ScrollPool ScrollPool { get; } +// public ReflectionInspector Inspector { get; } + +// public CacheMemberList(ScrollPool scrollPool, ReflectionInspector inspector) +// { +// this.ScrollPool = scrollPool; +// this.Inspector = inspector; +// } + +// public int ItemCount => Inspector.filteredMembers.Count; + +// public int GetRealIndexOfTempIndex(int index) +// { +// if (index < 0 || index >= Inspector.filteredToRealIndices.Count) +// return -1; +// return Inspector.filteredToRealIndices[index]; +// } + +// public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject); + +// public void SetCell(ICell icell, int index) +// { +// var cell = icell as CellViewHolder; + +// if (index < 0 || index >= ItemCount) +// { +// var existing = cell.DisableContent(); +// if (existing) +// existing.transform.SetParent(Inspector.InactiveHolder.transform, false); +// return; +// } + +// index = GetRealIndexOfTempIndex(index); + +// var cache = Inspector.allMembers[index]; +// cache.Enable(); + +// var prev = cell.SetContent(cache.UIRoot); +// if (prev) +// prev.transform.SetParent(Inspector.InactiveHolder.transform, false); +// } + +// public void DisableCell(ICell cell, int index) +// { +// var content = (cell as CellViewHolder).DisableContent(); +// if (content) +// content.transform.SetParent(Inspector.InactiveHolder.transform, false); +// } +// } +//} diff --git a/src/Inspectors_OLD/Reflection/InstanceInspector.cs b/src/Inspectors_OLD/Reflection/InstanceInspector.cs new file mode 100644 index 0000000..49260bd --- /dev/null +++ b/src/Inspectors_OLD/Reflection/InstanceInspector.cs @@ -0,0 +1,254 @@ +//using System; +//using System.Collections.Generic; +//using System.IO; +//using System.Linq; +//using System.Text; +//using UnityEngine; +//using UnityEngine.UI; +//using UnityExplorer.Core; +//using UnityExplorer.Core.Config; +//using UnityExplorer.Core.Runtime; + +//namespace UnityExplorer.Inspectors.Reflection +//{ +// public enum MemberScopes +// { +// All, +// Instance, +// Static +// } + +// public class InstanceInspector : ReflectionInspector +// { +// public override string TabLabel => $" [R] {base.TabLabel}"; + +// internal MemberScopes m_scopeFilter; +// internal Button m_lastActiveScopeButton; + +// public InstanceInspector(object target) : base(target) { } + +// internal void OnScopeFilterClicked(MemberScopes type, Button button) +// { +// if (m_lastActiveScopeButton) +// RuntimeProvider.Instance.SetColorBlock(m_lastActiveScopeButton, new Color(0.2f, 0.2f, 0.2f)); + +// m_scopeFilter = type; +// m_lastActiveScopeButton = button; + +// RuntimeProvider.Instance.SetColorBlock(m_lastActiveScopeButton, new Color(0.2f, 0.6f, 0.2f)); + +// FilterMembers(null, true); + +// ScrollPool.RecreateHeightCache(); +// ScrollPool.RefreshAndJumpToTop(); +// //RefreshDisplay(); +// //m_sliderScroller.m_slider.value = 1f; +// } + +// public void ConstructInstanceScopeFilters(GameObject parent) +// { +// var memberFilterRowObj = UIFactory.CreateHorizontalGroup(parent, "InstanceFilterRow", false, false, true, true, 5, default, +// new Color(1, 1, 1, 0)); +// UIFactory.SetLayoutElement(memberFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000); + +// var memLabel = UIFactory.CreateLabel(memberFilterRowObj, "MemberLabel", "Filter scope:", TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(memLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0); + +// AddFilterButton(memberFilterRowObj, MemberScopes.All, true); +// AddFilterButton(memberFilterRowObj, MemberScopes.Instance); +// AddFilterButton(memberFilterRowObj, MemberScopes.Static); +// } + +// private void AddFilterButton(GameObject parent, MemberScopes type, bool setEnabled = false) +// { +// var btn = UIFactory.CreateButton(parent, +// "ScopeFilterButton_" + type, +// type.ToString(), +// null, +// new Color(0.2f, 0.2f, 0.2f)); + +// UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 70); + +// btn.onClick.AddListener(() => { OnScopeFilterClicked(type, btn); }); + +// RuntimeProvider.Instance.SetColorBlock(btn, highlighted: new Color(0.3f, 0.7f, 0.3f)); + +// if (setEnabled) +// { +// RuntimeProvider.Instance.SetColorBlock(btn, new Color(0.2f, 0.6f, 0.2f)); +// m_scopeFilter = type; +// m_lastActiveScopeButton = btn; +// } +// } + +// public void ConstructUnityInstanceHelpers() +// { +// if (!typeof(UnityEngine.Object).IsAssignableFrom(m_targetType)) +// return; + +// var rowObj = UIFactory.CreateHorizontalGroup(Content, "InstanceHelperRow", true, true, true, true, 5, new Vector4(2, 2, 2, 2), +// new Color(0.1f, 0.1f, 0.1f)); +// UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000); + +// if (typeof(Component).IsAssignableFrom(m_targetType)) +// ConstructCompHelper(rowObj); + +// ConstructUnityObjHelper(rowObj); + +// if (m_targetType == typeof(Texture2D)) +// ConstructTextureHelper(); +// } + +// internal void ConstructCompHelper(GameObject rowObj) +// { +// //var gameObjectLabel = UIFactory.CreateLabel(rowObj, "GameObjectLabel", "GameObject:", TextAnchor.MiddleLeft); +// //UIFactory.SetLayoutElement(gameObjectLabel.gameObject, minWidth: 90, minHeight: 25, flexibleWidth: 0); + +// var comp = Target.TryCast(typeof(Component)) as Component; + +// var btn = UIFactory.CreateButton(rowObj, +// "GameObjectButton", +// "View GameObject", +// () => { InspectorManager.Inspect(comp.gameObject); }, +// new Color(0.2f, 0.5f, 0.2f)); +// UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0); +// } + +// internal void ConstructUnityObjHelper(GameObject rowObj) +// { +// var label = UIFactory.CreateLabel(rowObj, "NameLabel", "Name:", TextAnchor.MiddleLeft); +// UIFactory.SetLayoutElement(label.gameObject, minWidth: 60, minHeight: 25, flexibleWidth: 0); + +// var uObj = Target.TryCast(typeof(UnityEngine.Object)) as UnityEngine.Object; + +// var inputObj = UIFactory.CreateInputField(rowObj, "NameInput", "...", out InputField inputField, 14, 3, 1); +// UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleWidth: 2000); +// inputField.readOnly = true; +// inputField.text = uObj.name; +// } + +// internal bool showingTextureHelper; +// internal bool constructedTextureViewer; + +// internal GameObject m_textureViewerObj; + +// internal void ConstructTextureHelper() +// { +// var rowObj = UIFactory.CreateHorizontalGroup(Content, "TextureHelper", false, false, true, true, 5, new Vector4(3, 3, 3, 3), +// new Color(0.1f, 0.1f, 0.1f)); +// UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0); + +// var showBtn = UIFactory.CreateButton(rowObj, "ShowButton", "Show", null, new Color(0.2f, 0.3f, 0.2f)); +// UIFactory.SetLayoutElement(showBtn.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 20); + +// UIFactory.CreateLabel(rowObj, "TextureViewerLabel", "Texture Viewer", TextAnchor.MiddleLeft); + +// m_textureViewerObj = UIFactory.CreateScrollView(Content, "TextureViewerContent", out GameObject scrollContent, out _, +// new Color(0.1f, 0.1f, 0.1f)); +// UIFactory.SetLayoutGroup(scrollContent, false, false, true, true); +// UIFactory.SetLayoutElement(m_textureViewerObj, minHeight: 100, flexibleHeight: 9999, flexibleWidth: 9999); + +// m_textureViewerObj.SetActive(false); + +// var showText = showBtn.GetComponentInChildren(); +// showBtn.onClick.AddListener(() => +// { +// showingTextureHelper = !showingTextureHelper; + +// if (showingTextureHelper) +// { +// if (!constructedTextureViewer) +// ConstructTextureViewerArea(scrollContent); + +// showText.text = "Hide"; +// ToggleTextureViewer(true); +// } +// else +// { +// showText.text = "Show"; +// ToggleTextureViewer(false); +// } +// }); +// } + +// internal void ConstructTextureViewerArea(GameObject parent) +// { +// constructedTextureViewer = true; + +// var tex = Target.TryCast(typeof(Texture2D)) as Texture2D; + +// if (!tex) +// { +// ExplorerCore.LogWarning("Could not cast the target instance to Texture2D! Maybe its null or destroyed?"); +// return; +// } + +// // Save helper + +// var saveRowObj = UIFactory.CreateHorizontalGroup(parent, "SaveRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2), +// new Color(0.1f, 0.1f, 0.1f)); + +// var saveBtn = UIFactory.CreateButton(saveRowObj, "SaveButton", "Save .PNG", null, new Color(0.2f, 0.2f, 0.2f)); +// UIFactory.SetLayoutElement(saveBtn.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0); + +// var inputObj = UIFactory.CreateInputField(saveRowObj, "SaveInput", "...", out InputField inputField); +// UIFactory.SetLayoutElement(inputObj, minHeight: 25, minWidth: 100, flexibleWidth: 9999); + +// var name = tex.name; +// if (string.IsNullOrEmpty(name)) +// name = "untitled"; + +// inputField.text = Path.Combine(ConfigManager.Default_Output_Path.Value, $"{name}.png"); + +// saveBtn.onClick.AddListener(() => +// { +// if (tex && !string.IsNullOrEmpty(inputField.text)) +// { +// var path = inputField.text; +// if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) +// { +// ExplorerCore.LogWarning("Desired save path must end with '.png'!"); +// return; +// } + +// var dir = Path.GetDirectoryName(path); +// if (!Directory.Exists(dir)) +// Directory.CreateDirectory(dir); + +// if (File.Exists(path)) +// File.Delete(path); + +// if (!TextureUtilProvider.IsReadable(tex)) +// tex = TextureUtilProvider.ForceReadTexture(tex); + +// byte[] data = TextureUtilProvider.Instance.EncodeToPNG(tex); + +// File.WriteAllBytes(path, data); +// } +// }); + +// // Actual texture viewer + +// var imageObj = UIFactory.CreateUIObject("TextureViewerImage", parent); +// var image = imageObj.AddComponent(); +// var sprite = TextureUtilProvider.Instance.CreateSprite(tex); +// image.sprite = sprite; + +// var fitter = imageObj.AddComponent(); +// fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; + +// var imageLayout = imageObj.AddComponent(); +// imageLayout.preferredHeight = sprite.rect.height; +// imageLayout.preferredWidth = sprite.rect.width; +// } + +// internal void ToggleTextureViewer(bool enabled) +// { +// m_textureViewerObj.SetActive(enabled); + +// m_filterAreaObj.SetActive(!enabled); +// this.ScrollPool.UIRoot.SetActive(!enabled); +// m_updateRowObj.SetActive(!enabled); +// } +// } +//} diff --git a/src/UI/Inspectors/GameObjectInspector.cs b/src/UI/Inspectors/GameObjectInspector.cs new file mode 100644 index 0000000..416d8e5 --- /dev/null +++ b/src/UI/Inspectors/GameObjectInspector.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.UI; +using UnityExplorer.UI.ObjectPool; +using UnityExplorer.UI.Utility; +using UnityExplorer.UI.Widgets; + +namespace UnityExplorer.UI.Inspectors +{ + public class GameObjectInspector : InspectorBase + { + public GameObject Target; + + public override GameObject UIRoot => uiRoot; + private GameObject uiRoot; + + private Text NameText; + + public TransformTree TransformTree; + private ScrollPool transformScroll; + + public ButtonListSource ComponentList; + private ScrollPool componentScroll; + + public override GameObject CreateContent(GameObject parent) + { + uiRoot = UIFactory.CreateVerticalGroup(Pool.Instance.InactiveHolder, + "GameObjectInspector", 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: 30, flexibleHeight: 0); + + var listHolder = UIFactory.CreateHorizontalGroup(uiRoot, "ListHolder", true, true, true, true, 5, new Vector4(2, 2, 2, 2)); + UIFactory.SetLayoutElement(listHolder, flexibleWidth: 9999, flexibleHeight: 9999); + + transformScroll = UIFactory.CreateScrollPool(listHolder, "TransformTree", out GameObject transformObj, + out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f)); + UIFactory.SetLayoutElement(transformObj, flexibleHeight: 9999); + UIFactory.SetLayoutElement(transformContent, flexibleHeight: 9999); + + componentScroll = UIFactory.CreateScrollPool(listHolder, "ComponentList", out GameObject compObj, + out GameObject compContent, new Color(0.11f, 0.11f, 0.11f)); + UIFactory.SetLayoutElement(compObj, flexibleHeight: 9999); + UIFactory.SetLayoutElement(compContent, flexibleHeight: 9999); + + TransformTree = new TransformTree(transformScroll) { GetRootEntriesMethod = GetTransformEntries }; + TransformTree.Init(); + + ComponentList = new ButtonListSource(componentScroll, GetComponentEntries, SetComponentCell, ShouldDisplay, OnComponentClicked); + componentScroll.Initialize(ComponentList); + + return uiRoot; + } + + private readonly List _rootEntries = new List(); + + private IEnumerable GetTransformEntries() + { + _rootEntries.Clear(); + for (int i = 0; i < Target.transform.childCount; i++) + _rootEntries.Add(Target.transform.GetChild(i).gameObject); + return _rootEntries; + } + + private readonly List _componentEntries = new List(); + + private List GetComponentEntries() + { + return _componentEntries; + } + + private static readonly Dictionary compToStringCache = new Dictionary(); + + 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, + $"{type.Namespace}.{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()) + _componentEntries.Add(comp); + + ComponentList.RefreshData(); + ComponentList.ScrollPool.RefreshCells(true); + } + + protected override void OnCloseClicked() + { + InspectorManager.ReleaseInspector(this); + } + } +} diff --git a/src/UI/Inspectors/InspectorBase.cs b/src/UI/Inspectors/InspectorBase.cs index 5f4b033..389bd22 100644 --- a/src/UI/Inspectors/InspectorBase.cs +++ b/src/UI/Inspectors/InspectorBase.cs @@ -1,122 +1,64 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using UnityEngine; -using UnityEngine.UI; +using UnityExplorer.UI.ObjectPool; using UnityExplorer.UI.Panels; namespace UnityExplorer.UI.Inspectors { - public abstract class InspectorBase + public abstract class InspectorBase : IPooledObject { - public object Target; - public bool IsActive { get; private set; } + public InspectorTab Tab { get; internal set; } + public bool IsActive { get; internal set; } - public abstract string TabLabel { get; } + public abstract GameObject UIRoot { get; } - internal bool m_pendingDestroy; + 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); - public InspectorBase(object target) + public float DefaultHeight => -1f; + public abstract GameObject CreateContent(GameObject content); + + public abstract void Update(); + + public virtual void OnBorrowedFromPool(object target) { - Target = target; + Tab = Pool.Borrow(); + Tab.UIRoot.transform.SetParent(InspectorPanel.Instance.NavbarHolder.transform, false); - if (Target.IsNullOrDestroyed(false)) - { - Destroy(); - return; - } - - AddInspectorTab(this); + Tab.TabButton.OnClick += OnTabButtonClicked; + Tab.CloseButton.OnClick += OnCloseClicked; } - public virtual void SetActive() + public virtual void OnReturnToPool() { - this.IsActive = true; - Content?.SetActive(true); + Pool.Return(Tab); + + Tab.TabButton.OnClick -= OnTabButtonClicked; + Tab.CloseButton.OnClick -= OnCloseClicked; } - public virtual void SetInactive() + public virtual void OnSetActive() { - this.IsActive = false; - Content?.SetActive(false); + RuntimeProvider.Instance.SetColorBlock(Tab.TabButton.Button, _enabledTabColor, _enabledTabColor * 1.2f); + UIRoot.SetActive(true); + IsActive = true; } - public virtual void Update() + public virtual void OnSetInactive() { - if (Target.IsNullOrDestroyed(false)) - { - Destroy(); - return; - } - - m_tabText.text = TabLabel; + RuntimeProvider.Instance.SetColorBlock(Tab.TabButton.Button, _disabledTabColor, _disabledTabColor * 1.2f); + UIRoot.SetActive(false); + IsActive = false; } - public virtual void Destroy() + private void OnTabButtonClicked() { - m_pendingDestroy = true; - - GameObject tabGroup = m_tabButton?.transform.parent.gameObject; - - if (tabGroup) - GameObject.Destroy(tabGroup); - - int thisIndex = -1; - if (InspectorManager.ActiveInspectors.Contains(this)) - { - thisIndex = InspectorManager.ActiveInspectors.IndexOf(this); - InspectorManager.ActiveInspectors.Remove(this); - } - - if (ReferenceEquals(InspectorManager.m_activeInspector, this)) - { - InspectorManager.UnsetInspectorTab(); - - if (InspectorManager.ActiveInspectors.Count > 0) - { - var prevTab = InspectorManager.ActiveInspectors[thisIndex > 0 ? thisIndex - 1 : 0]; - InspectorManager.SetInspectorTab(prevTab); - } - } + InspectorManager.SetInspectorActive(this); } - #region UI - - public abstract GameObject Content { get; set; } - public Button m_tabButton; - public Text m_tabText; - - public void AddInspectorTab(InspectorBase parent) - { - var tabContent = InspectorPanel.Instance.NavbarHolder; - - var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent, "TabObject", true, true, true, true); - UIFactory.SetLayoutElement(tabGroupObj, minWidth: 185, flexibleWidth: 0); - tabGroupObj.AddComponent(); - - m_tabButton = UIFactory.CreateButton(tabGroupObj, - "TabButton", - "", - () => { InspectorManager.SetInspectorTab(parent); }); - - UIFactory.SetLayoutElement(m_tabButton.gameObject, minWidth: 165, flexibleWidth: 0); - - m_tabText = m_tabButton.GetComponentInChildren(); - m_tabText.horizontalOverflow = HorizontalWrapMode.Overflow; - m_tabText.alignment = TextAnchor.MiddleLeft; - - var closeBtn = UIFactory.CreateButton(tabGroupObj, - "CloseButton", - "X", - () => { InspectorManager.DestroyInspector(parent); }, - new Color(0.2f, 0.2f, 0.2f, 1)); - - UIFactory.SetLayoutElement(closeBtn.gameObject, minWidth: 20, flexibleWidth: 0); - - var closeBtnText = closeBtn.GetComponentInChildren(); - closeBtnText.color = new Color(1, 0, 0, 1); - } - - public virtual void OnPanelResized() { } - - #endregion + protected abstract void OnCloseClicked(); } } diff --git a/src/UI/Inspectors/InspectorManager.cs b/src/UI/Inspectors/InspectorManager.cs index cb604a9..0a94c38 100644 --- a/src/UI/Inspectors/InspectorManager.cs +++ b/src/UI/Inspectors/InspectorManager.cs @@ -1,151 +1,79 @@ using System; using System.Collections.Generic; using System.Linq; -using UnityExplorer.UI; +using System.Text; using UnityEngine; -using UnityEngine.SceneManagement; -using UnityEngine.UI; -using UnityExplorer.Core.Runtime; -using UnityExplorer.UI.CacheObject; -using UnityExplorer.UI.Inspectors.Reflection; +using UnityExplorer.UI.ObjectPool; using UnityExplorer.UI.Panels; namespace UnityExplorer.UI.Inspectors { public static class InspectorManager { - public static InspectorBase m_activeInspector; - public static readonly List ActiveInspectors = new List(); + public static readonly List Inspectors = new List(); - public static void Update() + public static InspectorBase ActiveInspector { get; private set; } + + public static void Inspect(object obj) { - try - { - for (int i = 0; i < ActiveInspectors.Count; i++) - ActiveInspectors[i].Update(); - } - catch (Exception ex) - { - ExplorerCore.LogWarning(ex); - } - } - - public static void DestroyInspector(InspectorBase inspector) - { - if (inspector is ReflectionInspector ri) - ri.Destroy(); + obj = obj.TryCast(); + if (obj is GameObject) + CreateInspector(obj); else - inspector.Destroy(); - } - - public static void Inspect(object obj, CacheObjectBase parentMember = null) - { - var type = ReflectionProvider.Instance.GetActualType(obj); - - // only need to set parent member for structs - if (!type.IsValueType) - parentMember = null; - - obj = ReflectionProvider.Instance.Cast(obj, type); - - if (obj.IsNullOrDestroyed(false)) - return; - - // check if currently inspecting this object - foreach (InspectorBase tab in ActiveInspectors) - { - if (obj.ReferenceEqual(tab.Target)) - { - SetInspectorTab(tab); - return; - } - } - - InspectorBase inspector; - if (obj is GameObject go) - { - ExplorerCore.Log("TODO"); - return; - // inspector = new GameObjectInspector(go); - } - else - inspector = new InstanceInspector(obj); - - if (inspector is ReflectionInspector ri) - ri.ParentMember = parentMember; - - ActiveInspectors.Add(inspector); - SetInspectorTab(inspector); + CreateInspector(obj); } public static void Inspect(Type type) { - if (type == null) - { - ExplorerCore.LogWarning("The provided type was null!"); - return; - } - - foreach (var tab in ActiveInspectors.Where(x => x is StaticInspector)) - { - if (ReferenceEquals(tab.Target as Type, type)) - { - SetInspectorTab(tab); - return; - } - } - - var inspector = new StaticInspector(type); - - ActiveInspectors.Add(inspector); - SetInspectorTab(inspector); + CreateInspector(type); } - public static void SetInspectorTab(InspectorBase inspector) + public static void SetInspectorActive(InspectorBase inspector) { + UnsetActiveInspector(); + + ActiveInspector = inspector; + inspector.OnSetActive(); + } + + public static void UnsetActiveInspector() + { + if (ActiveInspector != null) + ActiveInspector.OnSetInactive(); + } + + private static void CreateInspector(object target) where T : InspectorBase + { + var inspector = Pool.Borrow(); + Inspectors.Add(inspector); + + inspector.UIRoot.transform.SetParent(InspectorPanel.Instance.ContentHolder.transform, false); + + inspector.OnBorrowedFromPool(target); + SetInspectorActive(inspector); + UIManager.SetPanelActive(UIManager.Panels.Inspector, true); - - if (m_activeInspector == inspector) - return; - - UnsetInspectorTab(); - - m_activeInspector = inspector; - inspector.SetActive(); - - OnSetInspectorTab(inspector); } - public static void UnsetInspectorTab() + internal static void ReleaseInspector(T inspector) where T : InspectorBase { - if (m_activeInspector == null) - return; + inspector.OnReturnToPool(); + Pool.Return(inspector); - m_activeInspector.SetInactive(); - - OnUnsetInspectorTab(); - - m_activeInspector = null; + Inspectors.Remove(inspector); } - public static void OnSetInspectorTab(InspectorBase inspector) + internal static void Update() { - Color activeColor = new Color(0, 0.25f, 0, 1); - RuntimeProvider.Instance.SetColorBlock(inspector.m_tabButton, activeColor, activeColor); - } - - public static void OnUnsetInspectorTab() - { - RuntimeProvider.Instance.SetColorBlock(m_activeInspector.m_tabButton, - new Color(0.2f, 0.2f, 0.2f, 1), new Color(0.1f, 0.3f, 0.1f, 1)); + foreach (var inspector in Inspectors) + { + inspector.Update(); + } } internal static void OnPanelResized() { - foreach (var instance in ActiveInspectors) - { - instance.OnPanelResized(); - } + } } } diff --git a/src/UI/Inspectors/InspectorTab.cs b/src/UI/Inspectors/InspectorTab.cs new file mode 100644 index 0000000..0f1cec5 --- /dev/null +++ b/src/UI/Inspectors/InspectorTab.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.UI; +using UnityExplorer.UI.ObjectPool; +using UnityExplorer.UI.Widgets; + +namespace UnityExplorer.UI.Inspectors +{ + public class InspectorTab : IPooledObject + { + public GameObject UIRoot => uiRoot; + private GameObject uiRoot; + + public float DefaultHeight => 25f; + + public ButtonRef TabButton; + public Text TabText; + + public ButtonRef CloseButton; + + public GameObject CreateContent(GameObject parent) + { + uiRoot = UIFactory.CreateHorizontalGroup(parent, "TabObject", true, true, true, true, 0, new Vector4(0, 0, 3, 0)); + UIFactory.SetLayoutElement(uiRoot, minWidth: 185, flexibleWidth: 0); + uiRoot.AddComponent(); + + TabButton = UIFactory.CreateButton(uiRoot, "TabButton", ""); + + UIFactory.SetLayoutElement(TabButton.Button.gameObject, minWidth: 165, flexibleWidth: 0); + + TabText = TabButton.Button.GetComponentInChildren(); + TabText.horizontalOverflow = HorizontalWrapMode.Overflow; + TabText.alignment = TextAnchor.MiddleLeft; + + CloseButton = UIFactory.CreateButton(uiRoot, "CloseButton", "X", new Color(0.2f, 0.2f, 0.2f, 1)); + UIFactory.SetLayoutElement(CloseButton.Button.gameObject, minWidth: 20, flexibleWidth: 0); + var closeBtnText = CloseButton.Button.GetComponentInChildren(); + closeBtnText.color = Color.red; + + return uiRoot; + } + } +} diff --git a/src/UI/Inspectors/Reflection/CacheMemberList.cs b/src/UI/Inspectors/Reflection/CacheMemberList.cs deleted file mode 100644 index 27903c6..0000000 --- a/src/UI/Inspectors/Reflection/CacheMemberList.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; -using UnityExplorer.UI.Widgets; - -namespace UnityExplorer.UI.Inspectors.Reflection -{ - public class CacheMemberList : IPoolDataSource - { - public ScrollPool ScrollPool { get; } - public ReflectionInspector Inspector { get; } - - public CacheMemberList(ScrollPool scrollPool, ReflectionInspector inspector) - { - this.ScrollPool = scrollPool; - this.Inspector = inspector; - } - - public int ItemCount => Inspector.filteredMembers.Count; - - public int GetRealIndexOfTempIndex(int index) - { - if (index < 0 || index >= Inspector.filteredToRealIndices.Count) - return -1; - return Inspector.filteredToRealIndices[index]; - } - - public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject); - - public void SetCell(ICell icell, int index) - { - var cell = icell as CellViewHolder; - - if (index < 0 || index >= ItemCount) - { - var existing = cell.DisableContent(); - if (existing) - existing.transform.SetParent(Inspector.InactiveHolder.transform, false); - return; - } - - index = GetRealIndexOfTempIndex(index); - - var cache = Inspector.allMembers[index]; - cache.Enable(); - - var prev = cell.SetContent(cache.UIRoot); - if (prev) - prev.transform.SetParent(Inspector.InactiveHolder.transform, false); - } - - public void DisableCell(ICell cell, int index) - { - var content = (cell as CellViewHolder).DisableContent(); - if (content) - content.transform.SetParent(Inspector.InactiveHolder.transform, false); - } - } -} diff --git a/src/UI/Inspectors/Reflection/InstanceInspector.cs b/src/UI/Inspectors/Reflection/InstanceInspector.cs deleted file mode 100644 index d95f792..0000000 --- a/src/UI/Inspectors/Reflection/InstanceInspector.cs +++ /dev/null @@ -1,254 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using UnityExplorer.Core; -using UnityExplorer.Core.Config; -using UnityExplorer.Core.Runtime; - -namespace UnityExplorer.UI.Inspectors.Reflection -{ - public enum MemberScopes - { - All, - Instance, - Static - } - - public class InstanceInspector : ReflectionInspector - { - public override string TabLabel => $" [R] {base.TabLabel}"; - - internal MemberScopes m_scopeFilter; - internal Button m_lastActiveScopeButton; - - public InstanceInspector(object target) : base(target) { } - - internal void OnScopeFilterClicked(MemberScopes type, Button button) - { - if (m_lastActiveScopeButton) - RuntimeProvider.Instance.SetColorBlock(m_lastActiveScopeButton, new Color(0.2f, 0.2f, 0.2f)); - - m_scopeFilter = type; - m_lastActiveScopeButton = button; - - RuntimeProvider.Instance.SetColorBlock(m_lastActiveScopeButton, new Color(0.2f, 0.6f, 0.2f)); - - FilterMembers(null, true); - - ScrollPool.RecreateHeightCache(); - ScrollPool.RefreshAndJumpToTop(); - //RefreshDisplay(); - //m_sliderScroller.m_slider.value = 1f; - } - - public void ConstructInstanceScopeFilters(GameObject parent) - { - var memberFilterRowObj = UIFactory.CreateHorizontalGroup(parent, "InstanceFilterRow", false, false, true, true, 5, default, - new Color(1, 1, 1, 0)); - UIFactory.SetLayoutElement(memberFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000); - - var memLabel = UIFactory.CreateLabel(memberFilterRowObj, "MemberLabel", "Filter scope:", TextAnchor.MiddleLeft); - UIFactory.SetLayoutElement(memLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0); - - AddFilterButton(memberFilterRowObj, MemberScopes.All, true); - AddFilterButton(memberFilterRowObj, MemberScopes.Instance); - AddFilterButton(memberFilterRowObj, MemberScopes.Static); - } - - private void AddFilterButton(GameObject parent, MemberScopes type, bool setEnabled = false) - { - var btn = UIFactory.CreateButton(parent, - "ScopeFilterButton_" + type, - type.ToString(), - null, - new Color(0.2f, 0.2f, 0.2f)); - - UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 70); - - btn.onClick.AddListener(() => { OnScopeFilterClicked(type, btn); }); - - RuntimeProvider.Instance.SetColorBlock(btn, highlighted: new Color(0.3f, 0.7f, 0.3f)); - - if (setEnabled) - { - RuntimeProvider.Instance.SetColorBlock(btn, new Color(0.2f, 0.6f, 0.2f)); - m_scopeFilter = type; - m_lastActiveScopeButton = btn; - } - } - - public void ConstructUnityInstanceHelpers() - { - if (!typeof(UnityEngine.Object).IsAssignableFrom(m_targetType)) - return; - - var rowObj = UIFactory.CreateHorizontalGroup(Content, "InstanceHelperRow", true, true, true, true, 5, new Vector4(2, 2, 2, 2), - new Color(0.1f, 0.1f, 0.1f)); - UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000); - - if (typeof(Component).IsAssignableFrom(m_targetType)) - ConstructCompHelper(rowObj); - - ConstructUnityObjHelper(rowObj); - - if (m_targetType == typeof(Texture2D)) - ConstructTextureHelper(); - } - - internal void ConstructCompHelper(GameObject rowObj) - { - //var gameObjectLabel = UIFactory.CreateLabel(rowObj, "GameObjectLabel", "GameObject:", TextAnchor.MiddleLeft); - //UIFactory.SetLayoutElement(gameObjectLabel.gameObject, minWidth: 90, minHeight: 25, flexibleWidth: 0); - - var comp = Target.TryCast(typeof(Component)) as Component; - - var btn = UIFactory.CreateButton(rowObj, - "GameObjectButton", - "View GameObject", - () => { InspectorManager.Inspect(comp.gameObject); }, - new Color(0.2f, 0.5f, 0.2f)); - UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0); - } - - internal void ConstructUnityObjHelper(GameObject rowObj) - { - var label = UIFactory.CreateLabel(rowObj, "NameLabel", "Name:", TextAnchor.MiddleLeft); - UIFactory.SetLayoutElement(label.gameObject, minWidth: 60, minHeight: 25, flexibleWidth: 0); - - var uObj = Target.TryCast(typeof(UnityEngine.Object)) as UnityEngine.Object; - - var inputObj = UIFactory.CreateInputField(rowObj, "NameInput", "...", out InputField inputField, 14, 3, 1); - UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleWidth: 2000); - inputField.readOnly = true; - inputField.text = uObj.name; - } - - internal bool showingTextureHelper; - internal bool constructedTextureViewer; - - internal GameObject m_textureViewerObj; - - internal void ConstructTextureHelper() - { - var rowObj = UIFactory.CreateHorizontalGroup(Content, "TextureHelper", false, false, true, true, 5, new Vector4(3, 3, 3, 3), - new Color(0.1f, 0.1f, 0.1f)); - UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0); - - var showBtn = UIFactory.CreateButton(rowObj, "ShowButton", "Show", null, new Color(0.2f, 0.3f, 0.2f)); - UIFactory.SetLayoutElement(showBtn.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 20); - - UIFactory.CreateLabel(rowObj, "TextureViewerLabel", "Texture Viewer", TextAnchor.MiddleLeft); - - m_textureViewerObj = UIFactory.CreateScrollView(Content, "TextureViewerContent", out GameObject scrollContent, out _, - new Color(0.1f, 0.1f, 0.1f)); - UIFactory.SetLayoutGroup(scrollContent, false, false, true, true); - UIFactory.SetLayoutElement(m_textureViewerObj, minHeight: 100, flexibleHeight: 9999, flexibleWidth: 9999); - - m_textureViewerObj.SetActive(false); - - var showText = showBtn.GetComponentInChildren(); - showBtn.onClick.AddListener(() => - { - showingTextureHelper = !showingTextureHelper; - - if (showingTextureHelper) - { - if (!constructedTextureViewer) - ConstructTextureViewerArea(scrollContent); - - showText.text = "Hide"; - ToggleTextureViewer(true); - } - else - { - showText.text = "Show"; - ToggleTextureViewer(false); - } - }); - } - - internal void ConstructTextureViewerArea(GameObject parent) - { - constructedTextureViewer = true; - - var tex = Target.TryCast(typeof(Texture2D)) as Texture2D; - - if (!tex) - { - ExplorerCore.LogWarning("Could not cast the target instance to Texture2D! Maybe its null or destroyed?"); - return; - } - - // Save helper - - var saveRowObj = UIFactory.CreateHorizontalGroup(parent, "SaveRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2), - new Color(0.1f, 0.1f, 0.1f)); - - var saveBtn = UIFactory.CreateButton(saveRowObj, "SaveButton", "Save .PNG", null, new Color(0.2f, 0.2f, 0.2f)); - UIFactory.SetLayoutElement(saveBtn.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0); - - var inputObj = UIFactory.CreateInputField(saveRowObj, "SaveInput", "...", out InputField inputField); - UIFactory.SetLayoutElement(inputObj, minHeight: 25, minWidth: 100, flexibleWidth: 9999); - - var name = tex.name; - if (string.IsNullOrEmpty(name)) - name = "untitled"; - - inputField.text = Path.Combine(ConfigManager.Default_Output_Path.Value, $"{name}.png"); - - saveBtn.onClick.AddListener(() => - { - if (tex && !string.IsNullOrEmpty(inputField.text)) - { - var path = inputField.text; - if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) - { - ExplorerCore.LogWarning("Desired save path must end with '.png'!"); - return; - } - - var dir = Path.GetDirectoryName(path); - if (!Directory.Exists(dir)) - Directory.CreateDirectory(dir); - - if (File.Exists(path)) - File.Delete(path); - - if (!TextureUtilProvider.IsReadable(tex)) - tex = TextureUtilProvider.ForceReadTexture(tex); - - byte[] data = TextureUtilProvider.Instance.EncodeToPNG(tex); - - File.WriteAllBytes(path, data); - } - }); - - // Actual texture viewer - - var imageObj = UIFactory.CreateUIObject("TextureViewerImage", parent); - var image = imageObj.AddComponent(); - var sprite = TextureUtilProvider.Instance.CreateSprite(tex); - image.sprite = sprite; - - var fitter = imageObj.AddComponent(); - fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; - - var imageLayout = imageObj.AddComponent(); - imageLayout.preferredHeight = sprite.rect.height; - imageLayout.preferredWidth = sprite.rect.width; - } - - internal void ToggleTextureViewer(bool enabled) - { - m_textureViewerObj.SetActive(enabled); - - m_filterAreaObj.SetActive(!enabled); - this.ScrollPool.UIRoot.SetActive(!enabled); - m_updateRowObj.SetActive(!enabled); - } - } -} diff --git a/src/UI/Inspectors/Reflection/ReflectionInspector.cs b/src/UI/Inspectors/Reflection/ReflectionInspector.cs deleted file mode 100644 index 6474d8f..0000000 --- a/src/UI/Inspectors/Reflection/ReflectionInspector.cs +++ /dev/null @@ -1,487 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using UnityExplorer.Core; -using UnityExplorer.Core.Config; -using UnityExplorer.Core.Runtime; -using UnityExplorer.UI.CacheObject; -using UnityExplorer.UI.Panels; -using UnityExplorer.UI.Utility; -using UnityExplorer.UI.Widgets; - -namespace UnityExplorer.UI.Inspectors.Reflection -{ - public class ReflectionInspector : InspectorBase - { - #region STATIC - - public static ReflectionInspector ActiveInstance { get; private set; } - - //static ReflectionInspector() - //{ - // PanelDragger.OnFinishResize += (RectTransform _) => OnContainerResized(); - // SceneExplorer.OnToggleShow += OnContainerResized; - //} - - //private static void OnContainerResized(bool _ = false) - //{ - // if (ActiveInstance == null) - // return; - - // ActiveInstance.m_widthUpdateWanted = true; - //} - - // Blacklists - private static readonly HashSet bl_typeAndMember = new HashSet - { -#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 bl_methodNameStartsWith = new HashSet - { - // these are redundant, just adds noise, properties are supported directly - "get_", - "set_", - }; - - #endregion - - #region INSTANCE - - public override string TabLabel => m_targetTypeShortName; - - public CacheObjectBase ParentMember { get; internal set; } - - public ScrollPool ScrollPool { get; private set; } - public CacheMemberList CacheMemberList { get; private set; } - - public GameObject InactiveHolder => m_inactiveHolder; - private GameObject m_inactiveHolder; - - internal readonly Type m_targetType; - internal readonly string m_targetTypeShortName; - - // all cached members of the target - internal CacheMember[] allMembers; - // filtered members based on current filters - internal readonly List filteredMembers = new List(); - // actual shortlist of displayed members - internal readonly List displayedMembers = new List(); - - // index: Index in filter list, Value: Actual real index in allMembers list. - internal readonly List filteredToRealIndices = new List(); - - internal bool autoUpdate; - - public override void OnPanelResized() - { - foreach (var member in displayedMembers) - { - member.memberLabelElement.minWidth = 0.4f * InspectorPanel.CurrentPanelWidth; - } - } - - public ReflectionInspector(object target) : base(target) - { - if (this is StaticInspector) - m_targetType = target as Type; - else - m_targetType = ReflectionUtility.GetActualType(target); - - m_targetTypeShortName = SignatureHighlighter.ParseFullSyntax(m_targetType, false); - - ConstructUI(); - - CacheMembers(m_targetType); - - FilterMembers(); - } - - public override void SetActive() - { - base.SetActive(); - ActiveInstance = this; - } - - public override void SetInactive() - { - base.SetInactive(); - ActiveInstance = null; - } - - public override void Destroy() - { - base.Destroy(); - - if (this.Content) - { - GameObject.Destroy(this.InactiveHolder); - GameObject.Destroy(this.Content); - } - } - - 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 string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}"; - internal string AppendArgsToSig(ParameterInfo[] args) - { - string ret = " ("; - foreach (var param in args) - ret += $"{param.ParameterType.Name} {param.Name}, "; - ret += ")"; - return ret; - } - - public void CacheMembers(Type type) - { - var list = new List(); - var cachedSigs = new HashSet(); - - var types = ReflectionUtility.GetAllBaseTypes(type); - - var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static; - if (this is InstanceInspector) - flags |= BindingFlags.Instance; - - foreach (var declaringType in types) - { - var target = Target; - target = target.TryCast(declaringType); - - IEnumerable infos = declaringType.GetMethods(flags); - infos = infos.Concat(declaringType.GetProperties(flags)); - infos = infos.Concat(declaringType.GetFields(flags)); - - foreach (var member in infos) - { - try - { - var sig = GetSig(member); - - //ExplorerCore.Log($"Trying to cache member {sig}..."); - //ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name); - - var mi = member as MethodInfo; - var pi = member as PropertyInfo; - var fi = member as FieldInfo; - - if (IsBlacklisted(sig) || (mi != null && IsBlacklisted(mi))) - continue; - - var args = mi?.GetParameters() ?? pi?.GetIndexParameters(); - if (args != null) - { - if (!CacheMember.CanProcessArgs(args)) - continue; - - sig += AppendArgsToSig(args); - } - - if (cachedSigs.Contains(sig)) - continue; - - cachedSigs.Add(sig); - - if (mi != null) - list.Add(new CacheMethod(mi, target, InactiveHolder)); - else if (pi != null) - list.Add(new CacheProperty(pi, target, InactiveHolder)); - else - list.Add(new CacheField(fi, target, InactiveHolder)); - - var cached = list[list.Count - 1]; - cached.ParentInspector = this; - } - catch (Exception e) - { - ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!"); - ExplorerCore.Log(e.ToString()); - } - } - } - - var typeList = types.ToList(); - - var sorted = new List(); - 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)); - - allMembers = sorted.ToArray(); - } - - public override void Update() - { - base.Update(); - - if (autoUpdate) - { - foreach (var member in displayedMembers) - { - if (member == null) break; - member.UpdateValue(); - } - } - - //if (m_widthUpdateWanted) - //{ - // if (!m_widthUpdateWaiting) - // m_widthUpdateWaiting = true; - // else - // { - // UpdateWidths(); - // m_widthUpdateWaiting = false; - // m_widthUpdateWanted = false; - // } - //} - } - - internal void OnMemberFilterClicked(MemberTypes type, Button button) - { - if (m_lastActiveMemButton) - RuntimeProvider.Instance.SetColorBlock(m_lastActiveMemButton, new Color(0.2f, 0.2f, 0.2f)); - - m_memberFilter = type; - m_lastActiveMemButton = button; - - RuntimeProvider.Instance.SetColorBlock(m_lastActiveMemButton, new Color(0.2f, 0.6f, 0.2f)); - - FilterMembers(null, true); - ScrollPool.RecreateHeightCache(); - ScrollPool.Rebuild(); - } - - public void FilterMembers(string nameFilter = null, bool force = false) - { - int lastCount = filteredMembers.Count; - filteredMembers.Clear(); - - nameFilter = nameFilter?.ToLower() ?? m_nameFilterText.text.ToLower(); - - filteredToRealIndices.Clear(); - - for (int i = 0; i < allMembers.Length; i++) - { - var mem = allMembers[i]; - - // membertype filter - if (m_memberFilter != MemberTypes.All && mem.MemInfo.MemberType != m_memberFilter) - continue; - - if (this is InstanceInspector ii && ii.m_scopeFilter != MemberScopes.All) - { - if (mem.IsStatic && ii.m_scopeFilter != MemberScopes.Static) - continue; - else if (!mem.IsStatic && ii.m_scopeFilter != MemberScopes.Instance) - continue; - } - - // name filter - if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter)) - continue; - - filteredMembers.Add(mem); - filteredToRealIndices.Add(i); - } - - //if (force || lastCount != filteredMembers.Count) - //{ - // ScrollPool.EnableTempCache(); - // ScrollPool.Rebuild(); - //} - } - - #endregion - - #region UI - - private GameObject m_content; - public override GameObject Content - { - get => m_content; - set => m_content = value; - } - - internal Text m_nameFilterText; - internal MemberTypes m_memberFilter; - internal Button m_lastActiveMemButton; - - internal GameObject m_filterAreaObj; - internal GameObject m_updateRowObj; - - internal void ConstructUI() - { - var parent = InspectorPanel.Instance.ContentHolder; - - this.Content = UIFactory.CreateVerticalGroup(parent, "ReflectionInspector", true, false, true, true, 5, new Vector4(4, 4, 4, 4), - new Color(0.15f, 0.15f, 0.15f)); - - this.m_inactiveHolder = new GameObject("InactiveContentHolder"); - m_inactiveHolder.transform.SetParent(Content.transform, false); - m_inactiveHolder.SetActive(false); - - ConstructTopArea(); - - ConstructMemberList(); - } - - internal void ConstructTopArea() - { - var nameRowObj = UIFactory.CreateHorizontalGroup(Content, "NameRowObj", true, true, true, true, 2, default, new Color(1, 1, 1, 0)); - UIFactory.SetLayoutElement(nameRowObj, minHeight: 25, flexibleHeight: 0, minWidth: 200, flexibleWidth: 5000); - - var typeLabelText = UIFactory.CreateLabel(nameRowObj, "TypeLabel", "Type:", TextAnchor.MiddleLeft); - typeLabelText.horizontalOverflow = HorizontalWrapMode.Overflow; - UIFactory.SetLayoutElement(typeLabelText.gameObject, minWidth: 40, flexibleWidth: 0, minHeight: 25); - - var typeDisplay = UIFactory.CreateLabel(nameRowObj, "TypeDisplayText", SignatureHighlighter.ParseFullSyntax(m_targetType, true), - TextAnchor.MiddleLeft); - - UIFactory.SetLayoutElement(typeDisplay.gameObject, minHeight: 25, flexibleWidth: 5000); - - // instance helper tools - - if (this is InstanceInspector instanceInspector) - { - instanceInspector.ConstructUnityInstanceHelpers(); - } - - ConstructFilterArea(); - - ConstructUpdateRow(); - } - - internal void ConstructFilterArea() - { - // Filters - - m_filterAreaObj = UIFactory.CreateVerticalGroup(Content, "FilterGroup", true, true, true, true, 4, new Vector4(4, 4, 4, 4), - new Color(0.1f, 0.1f, 0.1f)); - UIFactory.SetLayoutElement(m_filterAreaObj, minHeight: 60); - - // name filter - - var nameFilterRowObj = UIFactory.CreateHorizontalGroup(m_filterAreaObj, "NameFilterRow", false, false, true, true, 5, default, - new Color(1, 1, 1, 0)); - UIFactory.SetLayoutElement(nameFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000); - - var nameLabel = UIFactory.CreateLabel(nameFilterRowObj, "NameLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey); - UIFactory.SetLayoutElement(nameLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0); - - var nameInputObj = UIFactory.CreateInputField(nameFilterRowObj, "NameInput", "...", out InputField nameInput, 14, (int)TextAnchor.MiddleLeft, - (int)HorizontalWrapMode.Overflow); - UIFactory.SetLayoutElement(nameInputObj, flexibleWidth: 5000, minWidth: 100, minHeight: 25); - nameInput.onValueChanged.AddListener((string val) => - { - FilterMembers(val, true); - ScrollPool.RecreateHeightCache(); - ScrollPool.Rebuild(); - }); - m_nameFilterText = nameInput.textComponent; - - // membertype filter - - var memberFilterRowObj = UIFactory.CreateHorizontalGroup(m_filterAreaObj, "MemberFilter", false, false, true, true, 5, default, - new Color(1, 1, 1, 0)); - UIFactory.SetLayoutElement(memberFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000); - - var memLabel = UIFactory.CreateLabel(memberFilterRowObj, "MemberFilterLabel", "Filter members:", TextAnchor.MiddleLeft, Color.grey); - UIFactory.SetLayoutElement(memLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0); - - AddFilterButton(memberFilterRowObj, MemberTypes.All, true); - AddFilterButton(memberFilterRowObj, MemberTypes.Method); - AddFilterButton(memberFilterRowObj, MemberTypes.Property); - AddFilterButton(memberFilterRowObj, MemberTypes.Field); - - // Instance filters - - if (this is InstanceInspector instanceInspector) - { - instanceInspector.ConstructInstanceScopeFilters(m_filterAreaObj); - } - } - - private void AddFilterButton(GameObject parent, MemberTypes type, bool setEnabled = false) - { - var btn = UIFactory.CreateButton(parent, - "FilterButton_" + type, - type.ToString(), - null, - new Color(0.2f, 0.2f, 0.2f)); - UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 70); - btn.onClick.AddListener(() => { OnMemberFilterClicked(type, btn); }); - - RuntimeProvider.Instance.SetColorBlock(btn, highlighted: new Color(0.3f, 0.7f, 0.3f)); - - if (setEnabled) - { - RuntimeProvider.Instance.SetColorBlock(btn, new Color(0.2f, 0.6f, 0.2f)); - m_memberFilter = type; - m_lastActiveMemButton = btn; - } - } - - internal void ConstructUpdateRow() - { - m_updateRowObj = UIFactory.CreateHorizontalGroup(Content, "UpdateRow", false, true, true, true, 10, default, new Color(1, 1, 1, 0)); - UIFactory.SetLayoutElement(m_updateRowObj, minHeight: 25); - - // update button - - var updateBtn = UIFactory.CreateButton(m_updateRowObj, "UpdateButton", "Update Values", null, new Color(0.2f, 0.2f, 0.2f)); - UIFactory.SetLayoutElement(updateBtn.gameObject, minWidth: 110, flexibleWidth: 0); - updateBtn.onClick.AddListener(() => - { - bool orig = autoUpdate; - autoUpdate = true; - Update(); - if (!orig) - autoUpdate = orig; - }); - - // auto update - - var autoUpdateObj = UIFactory.CreateToggle(m_updateRowObj, "UpdateToggle", out Toggle autoUpdateToggle, out Text autoUpdateText); - var autoUpdateLayout = autoUpdateObj.AddComponent(); - autoUpdateLayout.minWidth = 150; - autoUpdateLayout.minHeight = 25; - autoUpdateText.text = "Auto-update?"; - autoUpdateToggle.isOn = false; - autoUpdateToggle.onValueChanged.AddListener((bool val) => { autoUpdate = val; }); - } - - internal void ConstructMemberList() - { - ScrollPool = UIFactory.CreateScrollPool(Content, "MemberList", out GameObject scrollRoot, out GameObject scrollContent, - new Color(0.05f, 0.05f, 0.05f)); - UIFactory.SetLayoutElement(scrollRoot, flexibleHeight: 9999); - UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999); - - CacheMemberList = new CacheMemberList(ScrollPool, this); - - ScrollPool.Initialize(CacheMemberList, CellViewHolder.CreatePrototypeCell(scrollRoot)); - - // ScrollPool.Viewport.GetComponent().enabled = false; - } - } - - #endregion -} \ No newline at end of file diff --git a/src/UI/Inspectors/Reflection/StaticInspector.cs b/src/UI/Inspectors/Reflection/StaticInspector.cs deleted file mode 100644 index eeeb537..0000000 --- a/src/UI/Inspectors/Reflection/StaticInspector.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace UnityExplorer.UI.Inspectors.Reflection -{ - public class StaticInspector : ReflectionInspector - { - public override string TabLabel => $" [S] {base.TabLabel}"; - - public StaticInspector(Type type) : base(type) { } - } -} diff --git a/src/UI/Inspectors/ReflectionInspector.cs b/src/UI/Inspectors/ReflectionInspector.cs new file mode 100644 index 0000000..363d7e1 --- /dev/null +++ b/src/UI/Inspectors/ReflectionInspector.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace UnityExplorer.UI.Inspectors +{ + public class InstanceInspector : ReflectionInspector { } + + public class StaticInspector : ReflectionInspector { } + + public class ReflectionInspector : InspectorBase + { + public override GameObject UIRoot => throw new NotImplementedException(); + + public override GameObject CreateContent(GameObject content) + { + throw new NotImplementedException(); + } + + public override void Update() + { + throw new NotImplementedException(); + } + + protected override void OnCloseClicked() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/UI/Models/UIPanel.cs b/src/UI/Models/UIPanel.cs index 7b6fa77..fc66e9c 100644 --- a/src/UI/Models/UIPanel.cs +++ b/src/UI/Models/UIPanel.cs @@ -127,13 +127,15 @@ namespace UnityExplorer.UI.Models // close button - var closeBtn = UIFactory.CreateButton(titleGroup, "CloseButton", "X", () => + var closeBtn = UIFactory.CreateButton(titleGroup, "CloseButton", "X"); + UIFactory.SetLayoutElement(closeBtn.Button.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0); + RuntimeProvider.Instance.SetColorBlock(closeBtn.Button, new Color(0.63f, 0.32f, 0.31f), + new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f)); + + closeBtn.OnClick += () => { UIManager.SetPanelActive(this.PanelType, false); - }); - UIFactory.SetLayoutElement(closeBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0); - RuntimeProvider.Instance.SetColorBlock(closeBtn, new Color(0.63f, 0.32f, 0.31f), - new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f)); + }; if (!CanDrag) titleGroup.SetActive(false); diff --git a/src/UI/ObjectPool/IPooledObject.cs b/src/UI/ObjectPool/IPooledObject.cs new file mode 100644 index 0000000..194a983 --- /dev/null +++ b/src/UI/ObjectPool/IPooledObject.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace UnityExplorer.UI.ObjectPool +{ + public interface IPooledObject + { + GameObject UIRoot { get; } + + GameObject CreateContent(GameObject parent); + + float DefaultHeight { get; } + + //GameObject CreatePrototype(); + } +} \ No newline at end of file diff --git a/src/UI/ObjectPool/Pool.cs b/src/UI/ObjectPool/Pool.cs new file mode 100644 index 0000000..d8c7a8e --- /dev/null +++ b/src/UI/ObjectPool/Pool.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace UnityExplorer.UI.ObjectPool +{ + public interface IObjectPool { } + + public class Pool : IObjectPool where T : IPooledObject + { + // internal pool management + + private static readonly Dictionary pools = new Dictionary(); + + public static Pool GetPool() + { + var type = typeof(T); + if (!pools.ContainsKey(type)) + CreatePool(); + return (Pool)pools[type]; + } + + private static Pool CreatePool() + { + var pool = new Pool(); + pools.Add(typeof(T), pool); + return pool; + } + + public static T Borrow() + { + return GetPool().BorrowObject(); + } + + public static void Return(T obj) + { + GetPool().ReturnObject(obj); + } + + // Instance + + public static Pool Instance + { + get => s_instance ?? CreatePool(); + } + private static Pool s_instance; + + public Pool() + { + s_instance = this; + + ExplorerCore.LogWarning("Creating Pool<" + typeof(T).Name + ">"); + + InactiveHolder = new GameObject($"InactiveHolder_{typeof(T).Name}"); + InactiveHolder.transform.parent = UIManager.PoolHolder.transform; + InactiveHolder.hideFlags |= HideFlags.HideAndDontSave; + InactiveHolder.SetActive(false); + + // 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)); + DefaultHeight = obj.DefaultHeight; + } + + public GameObject InactiveHolder { get; } + public float DefaultHeight { get; } + + private readonly HashSet available = new HashSet(); + private readonly HashSet borrowed = new HashSet(); + + public int AvailableObjects => available.Count; + + private void IncrementPool() + { + var obj = (T)Activator.CreateInstance(typeof(T)); + obj.CreateContent(InactiveHolder); + available.Add(obj); + } + + public T BorrowObject() + { + if (available.Count <= 0) + IncrementPool(); + + var obj = available.First(); + available.Remove(obj); + borrowed.Add(obj); + + return obj; + } + + public void ReturnObject(T obj) + { + if (!borrowed.Contains(obj)) + ExplorerCore.LogWarning($"Returning an item to object pool ({typeof(T).Name}) but the item didn't exist in the borrowed list?"); + else + borrowed.Remove(obj); + + available.Add(obj); + obj.UIRoot.transform.SetParent(InactiveHolder.transform, false); + } + } +} diff --git a/src/UI/Panels/ObjectExplorer.cs b/src/UI/Panels/ObjectExplorer.cs index b8bd87c..5740e5c 100644 --- a/src/UI/Panels/ObjectExplorer.cs +++ b/src/UI/Panels/ObjectExplorer.cs @@ -26,7 +26,7 @@ namespace UnityExplorer.UI.Panels public int SelectedTab = -1; private readonly List tabPages = new List(); - private readonly List