mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-16 00:07:52 +08:00
More progress
This commit is contained in:
@ -12,9 +12,9 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
|
||||
public override bool ShouldAutoEvaluate => true;
|
||||
|
||||
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.Initialize(inspector, declaringType, member, returnType);
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
||||
// not constant
|
||||
CanWrite = !(FieldInfo.IsLiteral && !FieldInfo.IsInitOnly);
|
||||
|
@ -15,98 +15,26 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
public abstract class CacheMember : CacheObjectBase
|
||||
{
|
||||
public ReflectionInspector ParentInspector { get; internal set; }
|
||||
public CacheMemberCell CurrentView { get; internal set; }
|
||||
public bool AutoUpdateWanted { get; internal set; }
|
||||
|
||||
public Type DeclaringType { get; protected set; }
|
||||
public string NameForFiltering { get; protected set; }
|
||||
|
||||
public Type DeclaringType { get; private set; }
|
||||
public string NameForFiltering { get; private set; }
|
||||
|
||||
public object Value { get; protected set; }
|
||||
public Type FallbackType { get; private set; }
|
||||
|
||||
public abstract bool ShouldAutoEvaluate { get; }
|
||||
public bool HasArguments => Arguments?.Length > 0;
|
||||
public override bool HasArguments => Arguments?.Length > 0;
|
||||
public ParameterInfo[] Arguments { get; protected set; }
|
||||
public bool Evaluating { get; protected set; }
|
||||
public bool CanWrite { get; protected set; }
|
||||
public bool HadException { get; protected set; }
|
||||
public Exception LastException { get; protected set; }
|
||||
|
||||
public string MemberLabelText { get; private set; }
|
||||
public string TypeLabelText { get; protected set; }
|
||||
public string ValueLabelText { get; protected set; }
|
||||
|
||||
private static readonly Dictionary<string, MethodInfo> numberParseMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
public enum ValueState
|
||||
|
||||
public virtual void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
NotEvaluated, Exception, NullValue,
|
||||
Boolean, Number, String, Enum,
|
||||
Collection, ValueStruct, Unsupported
|
||||
}
|
||||
|
||||
protected ValueState State = ValueState.NotEvaluated;
|
||||
|
||||
private const string NOT_YET_EVAL = "<color=grey>Not yet evaluated</color>";
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the CacheMember when an Inspector is opened and caches the member
|
||||
/// </summary>
|
||||
public virtual void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||
{
|
||||
this.DeclaringType = declaringType;
|
||||
this.ParentInspector = inspector;
|
||||
this.FallbackType = returnType;
|
||||
this.MemberLabelText = SignatureHighlighter.ParseFullSyntax(declaringType, false, member);
|
||||
this.NameForFiltering = $"{declaringType.Name}.{member.Name}";
|
||||
this.TypeLabelText = SignatureHighlighter.ParseFullType(FallbackType, false);
|
||||
this.ValueLabelText = GetValueLabel();
|
||||
}
|
||||
|
||||
public virtual void OnDestroyed()
|
||||
{
|
||||
// TODO release IValue / Evaluate back to pool, etc
|
||||
this.NameLabelText = SignatureHighlighter.ParseFullSyntax(member.DeclaringType, false, member);
|
||||
this.NameForFiltering = $"{member.DeclaringType.Name}.{member.Name}";
|
||||
}
|
||||
|
||||
protected abstract void TryEvaluate();
|
||||
|
||||
public void SetValue(object value)
|
||||
{
|
||||
// TODO unbox string, cast, etc
|
||||
|
||||
TrySetValue(value);
|
||||
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
protected abstract void TrySetValue(object value);
|
||||
|
||||
public void OnCellApplyClicked()
|
||||
{
|
||||
if (CurrentView == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Trying to apply CacheMember but current cell reference is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == ValueState.Boolean)
|
||||
SetValue(this.CurrentView.Toggle.isOn);
|
||||
else
|
||||
{
|
||||
if (!numberParseMethods.ContainsKey(FallbackType.AssemblyQualifiedName))
|
||||
{
|
||||
var method = FallbackType.GetMethod("Parse", new Type[] { typeof(string) });
|
||||
numberParseMethods.Add(FallbackType.AssemblyQualifiedName, method);
|
||||
}
|
||||
|
||||
var val = numberParseMethods[FallbackType.AssemblyQualifiedName]
|
||||
.Invoke(null, new object[] { CurrentView.InputField.text });
|
||||
SetValue(val);
|
||||
}
|
||||
|
||||
SetCell(this.CurrentView);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluate when first shown (if ShouldAutoEvaluate), or else when Evaluate button is clicked.
|
||||
/// </summary>
|
||||
@ -120,79 +48,27 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
ProcessOnEvaluate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the CacheMember state when the value has been evaluated (or re-evaluated)
|
||||
/// </summary>
|
||||
protected virtual void ProcessOnEvaluate()
|
||||
public override void SetUserValue(object value)
|
||||
{
|
||||
var prevState = State;
|
||||
// TODO unbox string, cast, etc
|
||||
|
||||
if (HadException)
|
||||
State = ValueState.Exception;
|
||||
else if (Value.IsNullOrDestroyed())
|
||||
State = ValueState.NullValue;
|
||||
else
|
||||
{
|
||||
var type = Value.GetActualType();
|
||||
TrySetValue(value);
|
||||
|
||||
if (type == typeof(bool))
|
||||
State = ValueState.Boolean;
|
||||
else if (type.IsPrimitive || type == typeof(decimal))
|
||||
State = ValueState.Number;
|
||||
else if (type == typeof(string))
|
||||
State = ValueState.String;
|
||||
else if (type.IsEnum)
|
||||
State = ValueState.Enum;
|
||||
else if (type.IsEnumerable() || type.IsDictionary())
|
||||
State = ValueState.Collection;
|
||||
// todo Color and ValueStruct
|
||||
else
|
||||
State = ValueState.Unsupported;
|
||||
}
|
||||
|
||||
// Set label text
|
||||
ValueLabelText = GetValueLabel();
|
||||
|
||||
if (State != prevState)
|
||||
{
|
||||
// TODO handle if subcontent / evaluate shown, check type change, etc
|
||||
}
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
private string GetValueLabel()
|
||||
protected override void SetValueState(CacheObjectCell cell, bool valueActive, bool valueRichText, Color valueColor,
|
||||
bool typeLabelActive, bool toggleActive, bool inputActive, bool applyActive, bool inspectActive, bool subContentActive)
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case ValueState.NotEvaluated:
|
||||
return $"<i>{NOT_YET_EVAL} ({SignatureHighlighter.ParseFullType(FallbackType, true)})</i>";
|
||||
case ValueState.Exception:
|
||||
return $"<i><color=red>{ReflectionUtility.ReflectionExToString(LastException)}</color></i>";
|
||||
case ValueState.Boolean:
|
||||
case ValueState.Number:
|
||||
return null;
|
||||
case ValueState.String:
|
||||
string s = Value as string;
|
||||
if (s.Length > 200)
|
||||
s = $"{s.Substring(0, 200)}...";
|
||||
return $"\"{s}\"";
|
||||
case ValueState.NullValue:
|
||||
return $"<i>{ToStringUtility.ToStringWithType(Value, FallbackType, true)}</i>";
|
||||
case ValueState.Enum:
|
||||
case ValueState.Collection:
|
||||
case ValueState.ValueStruct:
|
||||
case ValueState.Unsupported:
|
||||
default:
|
||||
return ToStringUtility.ToStringWithType(Value, FallbackType, true);
|
||||
}
|
||||
base.SetValueState(cell, valueActive, valueRichText, valueColor, typeLabelActive, toggleActive, inputActive, applyActive,
|
||||
inspectActive, subContentActive);
|
||||
|
||||
(cell as CacheMemberCell).UpdateToggle.gameObject.SetActive(ShouldAutoEvaluate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the cell view for an enabled cell based on this CacheMember model.
|
||||
/// </summary>
|
||||
public void SetCell(CacheMemberCell cell)
|
||||
protected override bool SetCellEvaluateState(CacheObjectCell objectcell)
|
||||
{
|
||||
cell.MemberLabel.text = MemberLabelText;
|
||||
cell.ValueLabel.gameObject.SetActive(true);
|
||||
var cell = objectcell as CacheMemberCell;
|
||||
|
||||
cell.EvaluateHolder.SetActive(!ShouldAutoEvaluate);
|
||||
if (!ShouldAutoEvaluate)
|
||||
@ -205,7 +81,7 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
cell.EvaluateButton.ButtonText.text = "Evaluate";
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
cell.UpdateToggle.gameObject.SetActive(true);
|
||||
cell.UpdateToggle.isOn = AutoUpdateWanted;
|
||||
}
|
||||
@ -215,79 +91,15 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
// todo evaluate buttons etc
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, false, false);
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == ValueState.NotEvaluated)
|
||||
Evaluate();
|
||||
|
||||
switch (State)
|
||||
{
|
||||
case ValueState.Exception:
|
||||
case ValueState.NullValue:
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, false, false);
|
||||
break;
|
||||
case ValueState.Boolean:
|
||||
SetValueState(cell, false, false, default, true, toggleActive: true, false, CanWrite, false, false);
|
||||
break;
|
||||
case ValueState.Number:
|
||||
SetValueState(cell, false, true, Color.white, true, false, inputActive: true, CanWrite, false, false);
|
||||
break;
|
||||
case ValueState.String:
|
||||
SetValueState(cell, true, false, SignatureHighlighter.StringOrange, false, false, false, false, false, true);
|
||||
break;
|
||||
case ValueState.Enum:
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, false, true);
|
||||
break;
|
||||
case ValueState.Collection:
|
||||
case ValueState.ValueStruct:
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, true, true);
|
||||
break;
|
||||
case ValueState.Unsupported:
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, true, false);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetValueState(CacheMemberCell cell, bool valueActive, bool valueRichText, Color valueColor,
|
||||
bool typeLabelActive, bool toggleActive, bool inputActive, bool applyActive, bool inspectActive, bool subContentActive)
|
||||
{
|
||||
//cell.ValueLabel.gameObject.SetActive(valueActive);
|
||||
if (valueActive)
|
||||
{
|
||||
cell.ValueLabel.text = ValueLabelText;
|
||||
cell.ValueLabel.supportRichText = valueRichText;
|
||||
cell.ValueLabel.color = valueColor;
|
||||
}
|
||||
else
|
||||
cell.ValueLabel.text = "";
|
||||
|
||||
cell.TypeLabel.gameObject.SetActive(typeLabelActive);
|
||||
if (typeLabelActive)
|
||||
cell.TypeLabel.text = TypeLabelText;
|
||||
|
||||
cell.Toggle.gameObject.SetActive(toggleActive);
|
||||
if (toggleActive)
|
||||
{
|
||||
cell.Toggle.isOn = (bool)Value;
|
||||
cell.ToggleText.text = Value.ToString();
|
||||
}
|
||||
|
||||
cell.InputField.gameObject.SetActive(inputActive);
|
||||
if (inputActive)
|
||||
{
|
||||
cell.InputField.text = Value.ToString();
|
||||
cell.InputField.readOnly = !CanWrite;
|
||||
}
|
||||
|
||||
cell.ApplyButton.Button.gameObject.SetActive(applyActive);
|
||||
cell.InspectButton.Button.gameObject.SetActive(inspectActive);
|
||||
cell.SubContentButton.Button.gameObject.SetActive(subContentActive);
|
||||
|
||||
cell.UpdateToggle.gameObject.SetActive(ShouldAutoEvaluate);
|
||||
}
|
||||
|
||||
|
||||
#region Cache Member Util
|
||||
|
||||
public static bool CanProcessArgs(ParameterInfo[] parameters)
|
||||
@ -430,7 +242,9 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
|
||||
cachedSigs.Add(sig);
|
||||
|
||||
cached.Initialize(_inspector, declaringType, member, returnType);
|
||||
//cached.Initialize(_inspector, declaringType, member, returnType);
|
||||
cached.Initialize(returnType);
|
||||
cached.SetInspectorOwner(_inspector, member);
|
||||
|
||||
list.Add(cached);
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
|
||||
public override bool ShouldAutoEvaluate => false;
|
||||
|
||||
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.Initialize(inspector, declaringType, member, returnType);
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
||||
Arguments = MethodInfo.GetParameters();
|
||||
}
|
||||
|
@ -1,12 +1,307 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.UI.Inspectors.CacheObject.Views;
|
||||
using UnityExplorer.UI.Inspectors.IValues;
|
||||
using UnityExplorer.UI.ObjectPool;
|
||||
using UnityExplorer.UI.Utility;
|
||||
|
||||
namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
{
|
||||
public abstract class CacheObjectBase
|
||||
{
|
||||
public CacheObjectCell CellView { get; internal set; }
|
||||
|
||||
public InteractiveValue IValue { get; private set; }
|
||||
public Type CurrentIValueType { get; private set; }
|
||||
public bool SubContentState { get; private set; }
|
||||
|
||||
public object Value { get; protected set; }
|
||||
public Type FallbackType { get; protected set; }
|
||||
|
||||
public string NameLabelText { get; protected set; }
|
||||
public string TypeLabelText { get; protected set; }
|
||||
public string ValueLabelText { get; protected set; }
|
||||
|
||||
public abstract bool ShouldAutoEvaluate { get; }
|
||||
public abstract bool HasArguments { get; }
|
||||
public bool CanWrite { get; protected set; }
|
||||
public bool HadException { get; protected set; }
|
||||
public Exception LastException { get; protected set; }
|
||||
|
||||
public virtual void Initialize(Type fallbackType)
|
||||
{
|
||||
this.FallbackType = fallbackType;
|
||||
this.TypeLabelText = SignatureHighlighter.ParseFullType(FallbackType, false);
|
||||
this.ValueLabelText = GetValueLabel();
|
||||
}
|
||||
|
||||
// internals
|
||||
|
||||
private static readonly Dictionary<string, MethodInfo> numberParseMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
public enum ValueState
|
||||
{
|
||||
NotEvaluated, Exception, NullValue,
|
||||
Boolean, Number, String, Enum,
|
||||
Collection, ValueStruct, Unsupported
|
||||
}
|
||||
|
||||
public ValueState State = ValueState.NotEvaluated;
|
||||
|
||||
protected const string NOT_YET_EVAL = "<color=grey>Not yet evaluated</color>";
|
||||
|
||||
internal static GameObject InactiveIValueHolder
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!inactiveIValueHolder)
|
||||
{
|
||||
inactiveIValueHolder = new GameObject("InactiveIValueHolder");
|
||||
GameObject.DontDestroyOnLoad(inactiveIValueHolder);
|
||||
inactiveIValueHolder.transform.parent = UIManager.PoolHolder.transform;
|
||||
inactiveIValueHolder.SetActive(false);
|
||||
}
|
||||
return inactiveIValueHolder;
|
||||
}
|
||||
}
|
||||
private static GameObject inactiveIValueHolder;
|
||||
|
||||
// On parent destroying this
|
||||
|
||||
public virtual void OnDestroyed()
|
||||
{
|
||||
// TODO release IValue / Evaluate back to pool, etc
|
||||
ReleaseIValue();
|
||||
}
|
||||
|
||||
// Updating and applying values
|
||||
|
||||
public abstract void SetUserValue(object value);
|
||||
|
||||
/// <summary>
|
||||
/// Process the CacheMember state when the value has been evaluated (or re-evaluated)
|
||||
/// </summary>
|
||||
protected virtual void ProcessOnEvaluate()
|
||||
{
|
||||
var prevState = State;
|
||||
|
||||
if (HadException)
|
||||
State = ValueState.Exception;
|
||||
else if (Value.IsNullOrDestroyed())
|
||||
State = ValueState.NullValue;
|
||||
else
|
||||
{
|
||||
var type = Value.GetActualType();
|
||||
|
||||
if (type == typeof(bool))
|
||||
State = ValueState.Boolean;
|
||||
else if (type.IsPrimitive || type == typeof(decimal))
|
||||
State = ValueState.Number;
|
||||
else if (type == typeof(string))
|
||||
State = ValueState.String;
|
||||
else if (type.IsEnum)
|
||||
State = ValueState.Enum;
|
||||
else if (type.IsEnumerable() || type.IsDictionary())
|
||||
State = ValueState.Collection;
|
||||
// todo Color and ValueStruct
|
||||
else
|
||||
State = ValueState.Unsupported;
|
||||
}
|
||||
|
||||
// Set label text
|
||||
ValueLabelText = GetValueLabel();
|
||||
|
||||
if (State != prevState)
|
||||
{
|
||||
// TODO handle if subcontent / evaluate shown, check type change, etc
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetValueLabel()
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case ValueState.NotEvaluated:
|
||||
return $"<i>{NOT_YET_EVAL} ({SignatureHighlighter.ParseFullType(FallbackType, true)})</i>";
|
||||
case ValueState.Exception:
|
||||
return $"<i><color=red>{ReflectionUtility.ReflectionExToString(LastException)}</color></i>";
|
||||
case ValueState.Boolean:
|
||||
case ValueState.Number:
|
||||
return null;
|
||||
case ValueState.String:
|
||||
string s = Value as string;
|
||||
if (s.Length > 200)
|
||||
s = $"{s.Substring(0, 200)}...";
|
||||
return $"\"{s}\"";
|
||||
case ValueState.NullValue:
|
||||
return $"<i>{ToStringUtility.ToStringWithType(Value, FallbackType, true)}</i>";
|
||||
case ValueState.Enum:
|
||||
case ValueState.Collection:
|
||||
case ValueState.ValueStruct:
|
||||
case ValueState.Unsupported:
|
||||
default:
|
||||
return ToStringUtility.ToStringWithType(Value, FallbackType, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract bool SetCellEvaluateState(CacheObjectCell cell);
|
||||
|
||||
public virtual void SetCell(CacheObjectCell cell)
|
||||
{
|
||||
cell.NameLabel.text = NameLabelText;
|
||||
cell.ValueLabel.gameObject.SetActive(true);
|
||||
|
||||
cell.SubContentHolder.gameObject.SetActive(SubContentState);
|
||||
if (IValue != null)
|
||||
IValue.UIRoot.transform.SetParent(cell.SubContentHolder.transform, false);
|
||||
|
||||
if (SetCellEvaluateState(cell))
|
||||
return;
|
||||
|
||||
switch (State)
|
||||
{
|
||||
case ValueState.Exception:
|
||||
case ValueState.NullValue:
|
||||
ReleaseIValue();
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, false, false);
|
||||
break;
|
||||
case ValueState.Boolean:
|
||||
SetValueState(cell, false, false, default, false, toggleActive: true, false, CanWrite, false, false);
|
||||
break;
|
||||
case ValueState.Number:
|
||||
SetValueState(cell, false, true, Color.white, true, false, inputActive: true, CanWrite, false, false);
|
||||
break;
|
||||
case ValueState.String:
|
||||
UpdateIValueOnValueUpdate();
|
||||
SetValueState(cell, true, false, SignatureHighlighter.StringOrange, false, false, false, false, false, true);
|
||||
break;
|
||||
case ValueState.Enum:
|
||||
UpdateIValueOnValueUpdate();
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, false, true);
|
||||
break;
|
||||
case ValueState.Collection:
|
||||
case ValueState.ValueStruct:
|
||||
UpdateIValueOnValueUpdate();
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, true, true);
|
||||
break;
|
||||
case ValueState.Unsupported:
|
||||
SetValueState(cell, true, true, Color.white, false, false, false, false, true, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetValueState(CacheObjectCell cell, bool valueActive, bool valueRichText, Color valueColor,
|
||||
bool typeLabelActive, bool toggleActive, bool inputActive, bool applyActive, bool inspectActive, bool subContentActive)
|
||||
{
|
||||
//cell.ValueLabel.gameObject.SetActive(valueActive);
|
||||
if (valueActive)
|
||||
{
|
||||
cell.ValueLabel.text = ValueLabelText;
|
||||
cell.ValueLabel.supportRichText = valueRichText;
|
||||
cell.ValueLabel.color = valueColor;
|
||||
}
|
||||
else
|
||||
cell.ValueLabel.text = "";
|
||||
|
||||
cell.TypeLabel.gameObject.SetActive(typeLabelActive);
|
||||
if (typeLabelActive)
|
||||
cell.TypeLabel.text = TypeLabelText;
|
||||
|
||||
cell.Toggle.gameObject.SetActive(toggleActive);
|
||||
if (toggleActive)
|
||||
{
|
||||
cell.Toggle.isOn = (bool)Value;
|
||||
cell.ToggleText.text = Value.ToString();
|
||||
}
|
||||
|
||||
cell.InputField.gameObject.SetActive(inputActive);
|
||||
if (inputActive)
|
||||
{
|
||||
cell.InputField.text = Value.ToString();
|
||||
cell.InputField.readOnly = !CanWrite;
|
||||
}
|
||||
|
||||
cell.ApplyButton.Button.gameObject.SetActive(applyActive);
|
||||
cell.InspectButton.Button.gameObject.SetActive(inspectActive);
|
||||
cell.SubContentButton.Button.gameObject.SetActive(subContentActive);
|
||||
}
|
||||
|
||||
// IValues
|
||||
|
||||
public virtual void OnCellSubContentToggle()
|
||||
{
|
||||
if (this.IValue == null)
|
||||
{
|
||||
IValue = (InteractiveValue)Pool.Borrow(typeof(InteractiveValue));
|
||||
IValue.SetOwner(this);
|
||||
IValue.UIRoot.transform.SetParent(CellView.SubContentHolder.transform, false);
|
||||
CellView.SubContentHolder.SetActive(true);
|
||||
SubContentState = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubContentState = !SubContentState;
|
||||
CellView.SubContentHolder.SetActive(SubContentState);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ReleaseIValue()
|
||||
{
|
||||
if (IValue == null)
|
||||
return;
|
||||
|
||||
IValue.OnOwnerReleased();
|
||||
Pool.Return(CurrentIValueType, IValue);
|
||||
|
||||
IValue = null;
|
||||
}
|
||||
|
||||
internal void HideIValue()
|
||||
{
|
||||
if (this.IValue == null)
|
||||
return;
|
||||
|
||||
this.IValue.UIRoot.transform.SetParent(InactiveIValueHolder.transform, false);
|
||||
}
|
||||
|
||||
public void UpdateIValueOnValueUpdate()
|
||||
{
|
||||
if (this.IValue == null)
|
||||
return;
|
||||
|
||||
IValue.SetValue(Value);
|
||||
}
|
||||
|
||||
// CacheObjectCell Apply
|
||||
|
||||
public virtual void OnCellApplyClicked()
|
||||
{
|
||||
if (CellView == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Trying to apply CacheMember but current cell reference is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == ValueState.Boolean)
|
||||
SetUserValue(this.CellView.Toggle.isOn);
|
||||
else
|
||||
{
|
||||
if (!numberParseMethods.ContainsKey(FallbackType.AssemblyQualifiedName))
|
||||
{
|
||||
var method = FallbackType.GetMethod("Parse", new Type[] { typeof(string) });
|
||||
numberParseMethods.Add(FallbackType.AssemblyQualifiedName, method);
|
||||
}
|
||||
|
||||
var val = numberParseMethods[FallbackType.AssemblyQualifiedName]
|
||||
.Invoke(null, new object[] { CellView.InputField.text });
|
||||
SetUserValue(val);
|
||||
}
|
||||
|
||||
SetCell(this.CellView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ namespace UnityExplorer.UI.Inspectors.CacheObject
|
||||
|
||||
public override bool ShouldAutoEvaluate => !HasArguments;
|
||||
|
||||
public override void Initialize(ReflectionInspector inspector, Type declaringType, MemberInfo member, Type returnType)
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.Initialize(inspector, declaringType, member, returnType);
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
||||
this.CanWrite = PropertyInfo.CanWrite;
|
||||
Arguments = PropertyInfo.GetIndexParameters();
|
||||
|
@ -4,207 +4,57 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.UI.Utility;
|
||||
using UnityExplorer.UI.Widgets;
|
||||
|
||||
namespace UnityExplorer.UI.Inspectors.CacheObject.Views
|
||||
{
|
||||
public class CacheMemberCell : ICell
|
||||
public class CacheMemberCell : CacheObjectCell
|
||||
{
|
||||
#region ICell
|
||||
|
||||
public float DefaultHeight => 30f;
|
||||
|
||||
public GameObject UIRoot => uiRoot;
|
||||
public GameObject uiRoot;
|
||||
|
||||
public bool Enabled => m_enabled;
|
||||
private bool m_enabled;
|
||||
|
||||
public RectTransform Rect => m_rect;
|
||||
private RectTransform m_rect;
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
m_enabled = false;
|
||||
uiRoot.SetActive(false);
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
m_enabled = true;
|
||||
uiRoot.SetActive(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public ReflectionInspector CurrentOwner { get; set; }
|
||||
public CacheMember CurrentOccupant { get; set; }
|
||||
|
||||
public LayoutElement MemberLayout;
|
||||
public LayoutElement RightGroupLayout;
|
||||
|
||||
public Text MemberLabel;
|
||||
public Text TypeLabel;
|
||||
public Text ValueLabel;
|
||||
public Toggle Toggle;
|
||||
public Text ToggleText;
|
||||
public InputField InputField;
|
||||
public CacheMember MemberOccupant => Occupant as CacheMember;
|
||||
|
||||
public GameObject EvaluateHolder;
|
||||
public ButtonRef EvaluateButton;
|
||||
|
||||
public ButtonRef InspectButton;
|
||||
public ButtonRef SubContentButton;
|
||||
public ButtonRef ApplyButton;
|
||||
|
||||
public Toggle UpdateToggle;
|
||||
|
||||
public GameObject SubContentHolder;
|
||||
|
||||
public void OnReturnToPool()
|
||||
protected virtual void EvaluateClicked()
|
||||
{
|
||||
if (CurrentOccupant != null)
|
||||
{
|
||||
// TODO
|
||||
// TODO
|
||||
}
|
||||
|
||||
CurrentOccupant = null;
|
||||
}
|
||||
public override void OnReturnToPool()
|
||||
{
|
||||
base.OnReturnToPool();
|
||||
|
||||
// TODO ?
|
||||
|
||||
CurrentOwner = null;
|
||||
}
|
||||
|
||||
private void ApplyClicked()
|
||||
protected override void ConstructEvaluateHolder(GameObject parent)
|
||||
{
|
||||
CurrentOccupant.OnCellApplyClicked();
|
||||
}
|
||||
|
||||
private void InspectClicked()
|
||||
{
|
||||
InspectorManager.Inspect(CurrentOccupant.Value);
|
||||
}
|
||||
|
||||
private void EvaluateClicked()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
private void SubContentClicked()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
private void ToggleClicked(bool value)
|
||||
{
|
||||
ToggleText.text = value.ToString();
|
||||
}
|
||||
|
||||
// Todo could create these as needed maybe, just need to make sure the transform order is correct.
|
||||
|
||||
public GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
// Main layout
|
||||
|
||||
uiRoot = UIFactory.CreateUIObject("CacheMemberCell", parent, new Vector2(100, 30));
|
||||
m_rect = uiRoot.GetComponent<RectTransform>();
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(uiRoot, true, false, true, true, 2, 0);
|
||||
UIFactory.SetLayoutElement(uiRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 600);
|
||||
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
var separator = UIFactory.CreateUIObject("TopSeperator", uiRoot);
|
||||
UIFactory.SetLayoutElement(separator, minHeight: 1, flexibleHeight: 0, flexibleWidth: 9999);
|
||||
separator.AddComponent<Image>().color = Color.black;
|
||||
|
||||
var horiRow = UIFactory.CreateUIObject("HoriGroup", uiRoot);
|
||||
UIFactory.SetLayoutElement(horiRow, minHeight: 29, flexibleHeight: 150, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horiRow, false, false, true, true, 5, 2, childAlignment: TextAnchor.UpperLeft);
|
||||
horiRow.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// Left member label
|
||||
|
||||
MemberLabel = UIFactory.CreateLabel(horiRow, "MemberLabel", "<notset>", TextAnchor.MiddleLeft);
|
||||
MemberLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(MemberLabel.gameObject, minHeight: 25, minWidth: 20, flexibleHeight: 300, flexibleWidth: 0);
|
||||
MemberLayout = MemberLabel.GetComponent<LayoutElement>();
|
||||
|
||||
// Right vertical group
|
||||
|
||||
var rightGroupHolder = UIFactory.CreateUIObject("RightGroup", horiRow);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(rightGroupHolder, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
|
||||
UIFactory.SetLayoutElement(rightGroupHolder, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
RightGroupLayout = rightGroupHolder.GetComponent<LayoutElement>();
|
||||
|
||||
// Evaluate vert group
|
||||
|
||||
EvaluateHolder = UIFactory.CreateUIObject("EvalGroup", rightGroupHolder);
|
||||
EvaluateHolder = UIFactory.CreateUIObject("EvalGroup", parent);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(EvaluateHolder, false, false, true, true, 3);
|
||||
UIFactory.SetLayoutElement(EvaluateHolder, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 775);
|
||||
|
||||
EvaluateButton = UIFactory.CreateButton(EvaluateHolder, "EvaluateButton", "Evaluate", new Color(0.15f, 0.15f, 0.15f));
|
||||
UIFactory.SetLayoutElement(EvaluateButton.Button.gameObject, minWidth: 100, minHeight: 25);
|
||||
EvaluateButton.OnClick += EvaluateClicked;
|
||||
}
|
||||
|
||||
// Right horizontal group
|
||||
|
||||
var rightHoriGroup = UIFactory.CreateUIObject("RightHoriGroup", rightGroupHolder);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rightHoriGroup, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
|
||||
UIFactory.SetLayoutElement(rightHoriGroup, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
|
||||
SubContentButton = UIFactory.CreateButton(rightHoriGroup, "SubContentButton", "▲");
|
||||
UIFactory.SetLayoutElement(SubContentButton.Button.gameObject, minWidth: 25, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
SubContentButton.OnClick += SubContentClicked;
|
||||
|
||||
TypeLabel = UIFactory.CreateLabel(rightHoriGroup, "ReturnLabel", "<notset>", TextAnchor.MiddleLeft);
|
||||
TypeLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(TypeLabel.gameObject, minHeight: 25, flexibleHeight: 150, minWidth: 70, flexibleWidth: 0);
|
||||
|
||||
// Bool and number value interaction
|
||||
|
||||
var toggleObj = UIFactory.CreateToggle(rightHoriGroup, "Toggle", out Toggle, out ToggleText);
|
||||
UIFactory.SetLayoutElement(toggleObj, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
ToggleText.color = SignatureHighlighter.KeywordBlue;
|
||||
Toggle.onValueChanged.AddListener(ToggleClicked);
|
||||
|
||||
var inputObj = UIFactory.CreateInputField(rightHoriGroup, "InputField", "...", out InputField);
|
||||
UIFactory.SetLayoutElement(inputObj, minWidth: 150, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// Inspect and apply buttons
|
||||
|
||||
InspectButton = UIFactory.CreateButton(rightHoriGroup, "InspectButton", "Inspect", new Color(0.15f, 0.15f, 0.15f));
|
||||
UIFactory.SetLayoutElement(InspectButton.Button.gameObject, minWidth: 60, flexibleWidth: 0, minHeight: 25);
|
||||
InspectButton.OnClick += InspectClicked;
|
||||
|
||||
ApplyButton = UIFactory.CreateButton(rightHoriGroup, "ApplyButton", "Apply", new Color(0.15f, 0.15f, 0.15f));
|
||||
UIFactory.SetLayoutElement(ApplyButton.Button.gameObject, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
ApplyButton.OnClick += ApplyClicked;
|
||||
|
||||
// Main value label
|
||||
|
||||
ValueLabel = UIFactory.CreateLabel(rightHoriGroup, "ValueLabel", "Value goes here", TextAnchor.MiddleLeft);
|
||||
ValueLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(ValueLabel.gameObject, minHeight: 25, flexibleHeight: 150, flexibleWidth: 9999);
|
||||
|
||||
protected override void ConstructUpdateToggle(GameObject parent)
|
||||
{
|
||||
// Auto-update toggle
|
||||
|
||||
var updateToggle = UIFactory.CreateToggle(rightHoriGroup, "AutoUpdate", out UpdateToggle, out Text autoText);
|
||||
var updateToggle = UIFactory.CreateToggle(parent, "AutoUpdate", out UpdateToggle, out Text autoText);
|
||||
UIFactory.SetLayoutElement(updateToggle, minHeight: 25, minWidth: 30, flexibleWidth: 0, flexibleHeight: 0);
|
||||
GameObject.Destroy(autoText);
|
||||
UpdateToggle.isOn = false;
|
||||
UpdateToggle.onValueChanged.AddListener((bool val) => { CurrentOccupant.AutoUpdateWanted = val; });
|
||||
|
||||
//UpdateButton = UIFactory.CreateButton(rightHoriGroup, "UpdateButton", "Update", new Color(0.15f, 0.2f, 0.15f));
|
||||
//UIFactory.SetLayoutElement(UpdateButton.Button.gameObject, minWidth: 65, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||
//UpdateButton.OnClick += UpdateClicked;
|
||||
|
||||
// Subcontent (todo?)
|
||||
|
||||
SubContentHolder = UIFactory.CreateUIObject("SubContent", uiRoot);
|
||||
UIFactory.SetLayoutElement(SubContentHolder.gameObject, minHeight: 30, flexibleHeight: 500, minWidth: 100, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(SubContentHolder, true, false, true, true, 2, childAlignment: TextAnchor.UpperLeft);
|
||||
|
||||
SubContentHolder.SetActive(false);
|
||||
|
||||
return uiRoot;
|
||||
UpdateToggle.onValueChanged.AddListener((bool val) => { MemberOccupant.AutoUpdateWanted = val; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,189 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.UI.Inspectors.IValues;
|
||||
using UnityExplorer.UI.ObjectPool;
|
||||
using UnityExplorer.UI.Utility;
|
||||
using UnityExplorer.UI.Widgets;
|
||||
|
||||
namespace UnityExplorer.UI.Inspectors.CacheObject.Views
|
||||
{
|
||||
class CacheObjectCell
|
||||
public abstract class CacheObjectCell : ICell
|
||||
{
|
||||
#region ICell
|
||||
|
||||
public float DefaultHeight => 30f;
|
||||
|
||||
public GameObject UIRoot => uiRoot;
|
||||
public GameObject uiRoot;
|
||||
|
||||
public bool Enabled => m_enabled;
|
||||
private bool m_enabled;
|
||||
|
||||
public RectTransform Rect => m_rect;
|
||||
private RectTransform m_rect;
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
m_enabled = false;
|
||||
uiRoot.SetActive(false);
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
m_enabled = true;
|
||||
uiRoot.SetActive(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public CacheObjectBase Occupant { get; set; }
|
||||
public bool SubContentActive => SubContentHolder.activeSelf;
|
||||
|
||||
public LayoutElement MemberLayout;
|
||||
public LayoutElement RightGroupLayout;
|
||||
|
||||
public Text NameLabel;
|
||||
public Text TypeLabel;
|
||||
public Text ValueLabel;
|
||||
public Toggle Toggle;
|
||||
public Text ToggleText;
|
||||
public InputField InputField;
|
||||
|
||||
public ButtonRef InspectButton;
|
||||
public ButtonRef SubContentButton;
|
||||
public ButtonRef ApplyButton;
|
||||
|
||||
public GameObject SubContentHolder;
|
||||
|
||||
public virtual void OnReturnToPool()
|
||||
{
|
||||
if (Occupant != null)
|
||||
{
|
||||
// TODO ?
|
||||
|
||||
SubContentHolder.SetActive(false);
|
||||
|
||||
Occupant = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ApplyClicked()
|
||||
{
|
||||
Occupant.OnCellApplyClicked();
|
||||
}
|
||||
|
||||
protected virtual void InspectClicked()
|
||||
{
|
||||
InspectorManager.Inspect(Occupant.Value);
|
||||
}
|
||||
|
||||
protected virtual void ToggleClicked(bool value)
|
||||
{
|
||||
ToggleText.text = value.ToString();
|
||||
}
|
||||
|
||||
protected virtual void SubContentClicked()
|
||||
{
|
||||
this.Occupant.OnCellSubContentToggle();
|
||||
}
|
||||
|
||||
protected abstract void ConstructEvaluateHolder(GameObject parent);
|
||||
|
||||
protected abstract void ConstructUpdateToggle(GameObject parent);
|
||||
|
||||
// Todo could create these as needed maybe, just need to make sure the transform order is correct.
|
||||
|
||||
public GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
// Main layout
|
||||
|
||||
uiRoot = UIFactory.CreateUIObject("CacheMemberCell", parent, new Vector2(100, 30));
|
||||
m_rect = uiRoot.GetComponent<RectTransform>();
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(uiRoot, true, false, true, true, 2, 0);
|
||||
UIFactory.SetLayoutElement(uiRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 600);
|
||||
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
var separator = UIFactory.CreateUIObject("TopSeperator", uiRoot);
|
||||
UIFactory.SetLayoutElement(separator, minHeight: 1, flexibleHeight: 0, flexibleWidth: 9999);
|
||||
separator.AddComponent<Image>().color = Color.black;
|
||||
|
||||
var horiRow = UIFactory.CreateUIObject("HoriGroup", uiRoot);
|
||||
UIFactory.SetLayoutElement(horiRow, minHeight: 29, flexibleHeight: 150, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horiRow, false, false, true, true, 5, 2, childAlignment: TextAnchor.UpperLeft);
|
||||
horiRow.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// Left member label
|
||||
|
||||
NameLabel = UIFactory.CreateLabel(horiRow, "MemberLabel", "<notset>", TextAnchor.MiddleLeft);
|
||||
NameLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(NameLabel.gameObject, minHeight: 25, minWidth: 20, flexibleHeight: 300, flexibleWidth: 0);
|
||||
MemberLayout = NameLabel.GetComponent<LayoutElement>();
|
||||
|
||||
// Right vertical group
|
||||
|
||||
var rightGroupHolder = UIFactory.CreateUIObject("RightGroup", horiRow);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(rightGroupHolder, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
|
||||
UIFactory.SetLayoutElement(rightGroupHolder, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
RightGroupLayout = rightGroupHolder.GetComponent<LayoutElement>();
|
||||
|
||||
ConstructEvaluateHolder(rightGroupHolder);
|
||||
|
||||
// Right horizontal group
|
||||
|
||||
var rightHoriGroup = UIFactory.CreateUIObject("RightHoriGroup", rightGroupHolder);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rightHoriGroup, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
|
||||
UIFactory.SetLayoutElement(rightHoriGroup, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
|
||||
SubContentButton = UIFactory.CreateButton(rightHoriGroup, "SubContentButton", "▲");
|
||||
UIFactory.SetLayoutElement(SubContentButton.Button.gameObject, minWidth: 25, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
SubContentButton.OnClick += SubContentClicked;
|
||||
|
||||
// Type label
|
||||
|
||||
TypeLabel = UIFactory.CreateLabel(rightHoriGroup, "ReturnLabel", "<notset>", TextAnchor.MiddleLeft);
|
||||
TypeLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(TypeLabel.gameObject, minHeight: 25, flexibleHeight: 150, minWidth: 60, flexibleWidth: 0);
|
||||
|
||||
// Bool and number value interaction
|
||||
|
||||
var toggleObj = UIFactory.CreateToggle(rightHoriGroup, "Toggle", out Toggle, out ToggleText);
|
||||
UIFactory.SetLayoutElement(toggleObj, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
ToggleText.color = SignatureHighlighter.KeywordBlue;
|
||||
Toggle.onValueChanged.AddListener(ToggleClicked);
|
||||
|
||||
var inputObj = UIFactory.CreateInputField(rightHoriGroup, "InputField", "...", out InputField);
|
||||
UIFactory.SetLayoutElement(inputObj, minWidth: 150, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// Inspect and apply buttons
|
||||
|
||||
InspectButton = UIFactory.CreateButton(rightHoriGroup, "InspectButton", "Inspect", new Color(0.15f, 0.15f, 0.15f));
|
||||
UIFactory.SetLayoutElement(InspectButton.Button.gameObject, minWidth: 60, flexibleWidth: 0, minHeight: 25);
|
||||
InspectButton.OnClick += InspectClicked;
|
||||
|
||||
ApplyButton = UIFactory.CreateButton(rightHoriGroup, "ApplyButton", "Apply", new Color(0.15f, 0.15f, 0.15f));
|
||||
UIFactory.SetLayoutElement(ApplyButton.Button.gameObject, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
ApplyButton.OnClick += ApplyClicked;
|
||||
|
||||
// Main value label
|
||||
|
||||
ValueLabel = UIFactory.CreateLabel(rightHoriGroup, "ValueLabel", "Value goes here", TextAnchor.MiddleLeft);
|
||||
ValueLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
UIFactory.SetLayoutElement(ValueLabel.gameObject, minHeight: 25, flexibleHeight: 150, flexibleWidth: 9999);
|
||||
|
||||
ConstructUpdateToggle(rightHoriGroup);
|
||||
|
||||
// Subcontent (todo?)
|
||||
|
||||
SubContentHolder = UIFactory.CreateUIObject("SubContent", uiRoot);
|
||||
UIFactory.SetLayoutElement(SubContentHolder.gameObject, minHeight: 30, flexibleHeight: 500, minWidth: 100, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(SubContentHolder, true, false, true, true, 2, childAlignment: TextAnchor.UpperLeft);
|
||||
|
||||
SubContentHolder.SetActive(false);
|
||||
|
||||
return uiRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.UI.ObjectPool;
|
||||
|
||||
namespace UnityExplorer.UI.Inspectors.IValues
|
||||
{
|
||||
public class IValueTest : IPooledObject
|
||||
{
|
||||
public GameObject UIRoot => uiRoot;
|
||||
private GameObject uiRoot;
|
||||
|
||||
public float DefaultHeight => -1f;
|
||||
|
||||
public GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
uiRoot = UIFactory.CreateUIObject(this.GetType().Name, parent);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(uiRoot, true, true, true, true, 3, childAlignment: TextAnchor.MiddleLeft);
|
||||
|
||||
|
||||
|
||||
return uiRoot;
|
||||
}
|
||||
}
|
||||
}
|
60
src/UI/Inspectors/IValues/InteractiveValue.cs
Normal file
60
src/UI/Inspectors/IValues/InteractiveValue.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.UI.Inspectors.CacheObject;
|
||||
using UnityExplorer.UI.ObjectPool;
|
||||
|
||||
namespace UnityExplorer.UI.Inspectors.IValues
|
||||
{
|
||||
public class InteractiveValue : IPooledObject
|
||||
{
|
||||
public GameObject UIRoot => uiRoot;
|
||||
private GameObject uiRoot;
|
||||
|
||||
public float DefaultHeight => -1f;
|
||||
|
||||
public CacheObjectBase CurrentOwner { get; }
|
||||
private CacheObjectBase m_owner;
|
||||
|
||||
public object EditedValue { get; private set; }
|
||||
|
||||
public virtual void SetOwner(CacheObjectBase owner)
|
||||
{
|
||||
if (this.m_owner != null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Setting an IValue's owner but there is already one set. Maybe it wasn't cleaned up?");
|
||||
OnOwnerReleased();
|
||||
}
|
||||
|
||||
this.m_owner = owner;
|
||||
// ...
|
||||
}
|
||||
|
||||
public virtual void SetValue(object value)
|
||||
{
|
||||
this.EditedValue = value;
|
||||
}
|
||||
|
||||
public virtual void OnOwnerReleased()
|
||||
{
|
||||
if (this.m_owner == null)
|
||||
return;
|
||||
|
||||
// ...
|
||||
this.m_owner = null;
|
||||
}
|
||||
|
||||
public GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
uiRoot = UIFactory.CreateUIObject(this.GetType().Name, parent);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(uiRoot, true, true, true, true, 3, childAlignment: TextAnchor.MiddleLeft);
|
||||
|
||||
UIFactory.CreateLabel(uiRoot, "Label", "this is an ivalue", TextAnchor.MiddleLeft);
|
||||
|
||||
return uiRoot;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ namespace UnityExplorer.UI.Inspectors
|
||||
public class ReflectionInspector : InspectorBase, IPoolDataSource<CacheMemberCell>
|
||||
{
|
||||
public bool StaticOnly { get; internal set; }
|
||||
//public bool AutoUpdate { get; internal set; }
|
||||
|
||||
public object Target { get; private set; }
|
||||
public Type TargetType { get; private set; }
|
||||
@ -38,6 +37,8 @@ namespace UnityExplorer.UI.Inspectors
|
||||
|
||||
private LayoutElement memberTitleLayout;
|
||||
|
||||
private Toggle autoUpdateToggle;
|
||||
|
||||
public override void OnBorrowedFromPool(object target)
|
||||
{
|
||||
base.OnBorrowedFromPool(target);
|
||||
@ -45,6 +46,7 @@ namespace UnityExplorer.UI.Inspectors
|
||||
SetTitleLayouts();
|
||||
SetTarget(target);
|
||||
|
||||
MemberScrollPool.Initialize(this);
|
||||
RuntimeProvider.Instance.StartCoroutine(InitCoroutine());
|
||||
}
|
||||
|
||||
@ -53,9 +55,6 @@ namespace UnityExplorer.UI.Inspectors
|
||||
yield return null;
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(InspectorPanel.Instance.ContentRect);
|
||||
|
||||
MemberScrollPool.RecreateHeightCache();
|
||||
MemberScrollPool.Rebuild();
|
||||
}
|
||||
|
||||
public override void OnReturnToPool()
|
||||
@ -71,6 +70,8 @@ namespace UnityExplorer.UI.Inspectors
|
||||
filteredMembers.Clear();
|
||||
displayedMembers.Clear();
|
||||
|
||||
autoUpdateToggle.isOn = false;
|
||||
|
||||
base.OnReturnToPool();
|
||||
}
|
||||
|
||||
@ -113,6 +114,8 @@ namespace UnityExplorer.UI.Inspectors
|
||||
var member = members[i];
|
||||
filteredMembers.Add(member);
|
||||
}
|
||||
|
||||
//MemberScrollPool.RecreateHeightCache();
|
||||
}
|
||||
|
||||
public override void OnSetActive()
|
||||
@ -161,11 +164,11 @@ namespace UnityExplorer.UI.Inspectors
|
||||
bool shouldRefresh = false;
|
||||
foreach (var member in displayedMembers)
|
||||
{
|
||||
if (!onlyAutoUpdate || member.AutoUpdateWanted)
|
||||
if (member.ShouldAutoEvaluate && (!onlyAutoUpdate || member.AutoUpdateWanted))
|
||||
{
|
||||
shouldRefresh = true;
|
||||
member.Evaluate();
|
||||
member.SetCell(member.CurrentView);
|
||||
member.SetCell(member.CellView);
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,12 +194,12 @@ namespace UnityExplorer.UI.Inspectors
|
||||
{
|
||||
if (index < 0 || index >= filteredMembers.Count)
|
||||
{
|
||||
if (cell.CurrentOccupant != null)
|
||||
if (cell.Occupant != null)
|
||||
{
|
||||
if (displayedMembers.Contains(cell.CurrentOccupant))
|
||||
displayedMembers.Remove(cell.CurrentOccupant);
|
||||
if (displayedMembers.Contains(cell.MemberOccupant))
|
||||
displayedMembers.Remove(cell.MemberOccupant);
|
||||
|
||||
cell.CurrentOccupant.CurrentView = null;
|
||||
cell.Occupant.CellView = null;
|
||||
}
|
||||
|
||||
cell.Disable();
|
||||
@ -205,19 +208,17 @@ namespace UnityExplorer.UI.Inspectors
|
||||
|
||||
var member = filteredMembers[index];
|
||||
|
||||
if (member != cell.CurrentOccupant)
|
||||
if (member != cell.Occupant)
|
||||
{
|
||||
if (cell.CurrentOccupant != null)
|
||||
if (cell.Occupant != null)
|
||||
{
|
||||
// TODO
|
||||
// changing occupant, put subcontent/evaluator on temp holder, etc
|
||||
|
||||
displayedMembers.Remove(cell.CurrentOccupant);
|
||||
cell.CurrentOccupant.CurrentView = null;
|
||||
cell.Occupant.HideIValue();
|
||||
displayedMembers.Remove(cell.MemberOccupant);
|
||||
cell.Occupant.CellView = null;
|
||||
}
|
||||
|
||||
cell.CurrentOccupant = member;
|
||||
member.CurrentView = cell;
|
||||
cell.Occupant = member;
|
||||
member.CellView = cell;
|
||||
displayedMembers.Add(member);
|
||||
}
|
||||
|
||||
@ -226,6 +227,18 @@ namespace UnityExplorer.UI.Inspectors
|
||||
SetCellLayout(cell);
|
||||
}
|
||||
|
||||
private void ToggleAllAutoUpdateStates(bool state)
|
||||
{
|
||||
if (members == null || !members.Any())
|
||||
return;
|
||||
|
||||
foreach (var member in members)
|
||||
member.AutoUpdateWanted = state;
|
||||
|
||||
foreach (var cell in MemberScrollPool.CellPool)
|
||||
cell.UpdateToggle.isOn = state;
|
||||
}
|
||||
|
||||
// Cell layout (fake table alignment)
|
||||
|
||||
private static float MemLabelWidth { get; set; }
|
||||
@ -240,7 +253,7 @@ namespace UnityExplorer.UI.Inspectors
|
||||
memberTitleLayout.minWidth = MemLabelWidth;
|
||||
}
|
||||
|
||||
private void SetCellLayout(CacheMemberCell cell)
|
||||
private void SetCellLayout(CacheObjectCell cell)
|
||||
{
|
||||
cell.MemberLayout.minWidth = MemLabelWidth;
|
||||
cell.RightGroupLayout.minWidth = RightGroupWidth;
|
||||
@ -279,7 +292,7 @@ namespace UnityExplorer.UI.Inspectors
|
||||
memberTitleLayout = memberTitle.gameObject.AddComponent<LayoutElement>();
|
||||
|
||||
var valueTitle = UIFactory.CreateLabel(listTitles, "ValueTitle", "Value", TextAnchor.LowerLeft, Color.grey, fontSize: 15);
|
||||
UIFactory.SetLayoutElement(valueTitle.gameObject, minWidth: 150, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutElement(valueTitle.gameObject, minWidth: 50, flexibleWidth: 9999);
|
||||
|
||||
var updateButton = UIFactory.CreateButton(listTitles, "UpdateButton", "Update values", new Color(0.22f, 0.28f, 0.22f));
|
||||
UIFactory.SetLayoutElement(updateButton.Button.gameObject, minHeight: 25, minWidth: 130, flexibleWidth: 0);
|
||||
@ -288,17 +301,24 @@ namespace UnityExplorer.UI.Inspectors
|
||||
var updateText = UIFactory.CreateLabel(listTitles, "AutoUpdateLabel", "Auto-update", TextAnchor.MiddleRight, Color.grey);
|
||||
UIFactory.SetLayoutElement(updateText.gameObject, minHeight: 25, minWidth: 80, flexibleWidth: 0);
|
||||
|
||||
var toggleObj = UIFactory.CreateToggle(listTitles, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
|
||||
GameObject.DestroyImmediate(toggleText);
|
||||
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: 25);
|
||||
autoUpdateToggle.isOn = false;
|
||||
autoUpdateToggle.onValueChanged.AddListener((bool val) => { ToggleAllAutoUpdateStates(val); });
|
||||
|
||||
var spacer = UIFactory.CreateUIObject("spacer", listTitles);
|
||||
UIFactory.SetLayoutElement(spacer, minWidth: 25, flexibleWidth: 0);
|
||||
|
||||
// Member scroll pool
|
||||
|
||||
MemberScrollPool = UIFactory.CreateScrollPool<CacheMemberCell>(uiRoot, "MemberList", out GameObject scrollObj,
|
||||
out GameObject _, new Color(0.09f, 0.09f, 0.09f));
|
||||
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||
|
||||
MemberScrollPool.Initialize(this);
|
||||
|
||||
InspectorPanel.Instance.UIRoot.GetComponent<Mask>().enabled = false;
|
||||
MemberScrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||
MemberScrollPool.Viewport.GetComponent<Image>().color = new Color(0.12f, 0.12f, 0.12f);
|
||||
//InspectorPanel.Instance.UIRoot.GetComponent<Mask>().enabled = false;
|
||||
//MemberScrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||
//MemberScrollPool.Viewport.GetComponent<Image>().color = new Color(0.12f, 0.12f, 0.12f);
|
||||
|
||||
return uiRoot;
|
||||
}
|
||||
|
Reference in New Issue
Block a user