mirror of
https://github.com/AnnulusGames/Alchemy.git
synced 2025-01-22 08:18:51 -05:00
Remove: depth limit
This commit is contained in:
parent
ea19961861
commit
cd3c0f2a00
@ -92,7 +92,7 @@ namespace Alchemy.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add elements
|
// Add elements
|
||||||
InspectorHelper.BuildElements(serializedObject, root, target, name => serializedObject.FindProperty(name), 0);
|
InspectorHelper.BuildElements(serializedObject, root, target, name => serializedObject.FindProperty(name));
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace Alchemy.Editor
|
|||||||
var serializedObject = new SerializedObject(this);
|
var serializedObject = new SerializedObject(this);
|
||||||
|
|
||||||
// Build visual elements and bind serialized object
|
// Build visual elements and bind serialized object
|
||||||
InspectorHelper.BuildElements(serializedObject, windowElement, this, name => serializedObject.FindProperty(name), 0);
|
InspectorHelper.BuildElements(serializedObject, windowElement, this, name => serializedObject.FindProperty(name));
|
||||||
windowElement.Bind(serializedObject);
|
windowElement.Bind(serializedObject);
|
||||||
|
|
||||||
// Remove "Serialized Data Model Controller" field
|
// Remove "Serialized Data Model Controller" field
|
||||||
|
@ -11,9 +11,8 @@ namespace Alchemy.Editor.Elements
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class AlchemyPropertyField : BindableElement
|
public sealed class AlchemyPropertyField : BindableElement
|
||||||
{
|
{
|
||||||
public AlchemyPropertyField(SerializedProperty property, Type type, int depth, bool isArrayElement = false)
|
public AlchemyPropertyField(SerializedProperty property, Type type, bool isArrayElement = false)
|
||||||
{
|
{
|
||||||
if (depth > 20) return;
|
|
||||||
var labelText = ObjectNames.NicifyVariableName(property.displayName);
|
var labelText = ObjectNames.NicifyVariableName(property.displayName);
|
||||||
|
|
||||||
switch (property.propertyType)
|
switch (property.propertyType)
|
||||||
@ -24,7 +23,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
case SerializedPropertyType.ObjectReference:
|
case SerializedPropertyType.ObjectReference:
|
||||||
if (property.GetAttribute<InlineEditorAttribute>() != null)
|
if (property.GetAttribute<InlineEditorAttribute>() != null)
|
||||||
{
|
{
|
||||||
element = new InlineEditorObjectField(property, type, depth);
|
element = new InlineEditorObjectField(property, type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -40,14 +39,14 @@ namespace Alchemy.Editor.Elements
|
|||||||
}
|
}
|
||||||
else if (property.isArray)
|
else if (property.isArray)
|
||||||
{
|
{
|
||||||
element = new PropertyListView(property, depth);
|
element = new PropertyListView(property);
|
||||||
}
|
}
|
||||||
else if (targetType.TryGetCustomAttribute<PropertyGroupAttribute>(out var groupAttribute)) // custom group
|
else if (targetType.TryGetCustomAttribute<PropertyGroupAttribute>(out var groupAttribute)) // custom group
|
||||||
{
|
{
|
||||||
var drawer = AlchemyEditorUtility.CreateGroupDrawer(groupAttribute, targetType);
|
var drawer = AlchemyEditorUtility.CreateGroupDrawer(groupAttribute, targetType);
|
||||||
|
|
||||||
var root = drawer.CreateRootElement(labelText);
|
var root = drawer.CreateRootElement(labelText);
|
||||||
InspectorHelper.BuildElements(property.serializedObject, root, property.GetValue<object>(), name => property.FindPropertyRelative(name), depth + 1);
|
InspectorHelper.BuildElements(property.serializedObject, root, property.GetValue<object>(), name => property.FindPropertyRelative(name));
|
||||||
if (root is BindableElement bindableElement) bindableElement.BindProperty(property);
|
if (root is BindableElement bindableElement) bindableElement.BindProperty(property);
|
||||||
element = root;
|
element = root;
|
||||||
}
|
}
|
||||||
@ -57,13 +56,13 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
var clickable = InternalAPIHelper.GetClickable(foldout.Q<Toggle>());
|
var clickable = InternalAPIHelper.GetClickable(foldout.Q<Toggle>());
|
||||||
InternalAPIHelper.SetAcceptClicksIfDisabled(clickable, true);
|
InternalAPIHelper.SetAcceptClicksIfDisabled(clickable, true);
|
||||||
InspectorHelper.BuildElements(property.serializedObject, foldout, property.GetValue<object>(), name => property.FindPropertyRelative(name), depth + 1);
|
InspectorHelper.BuildElements(property.serializedObject, foldout, property.GetValue<object>(), name => property.FindPropertyRelative(name));
|
||||||
foldout.BindProperty(property);
|
foldout.BindProperty(property);
|
||||||
element = foldout;
|
element = foldout;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SerializedPropertyType.ManagedReference:
|
case SerializedPropertyType.ManagedReference:
|
||||||
element = new SerializeReferenceField(property, depth);
|
element = new SerializeReferenceField(property);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Add(element);
|
Add(element);
|
||||||
|
@ -7,11 +7,9 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
public sealed class ClassField : VisualElement
|
public sealed class ClassField : VisualElement
|
||||||
{
|
{
|
||||||
public ClassField(Type type, string label, int depth) : this(TypeHelper.CreateDefaultInstance(type), type, label, depth) { }
|
public ClassField(Type type, string label) : this(TypeHelper.CreateDefaultInstance(type), type, label) { }
|
||||||
public ClassField(object obj, Type type, string label, int depth)
|
public ClassField(object obj, Type type, string label)
|
||||||
{
|
{
|
||||||
if (depth > InspectorHelper.MaxDepth) return;
|
|
||||||
|
|
||||||
var foldout = new Foldout
|
var foldout = new Foldout
|
||||||
{
|
{
|
||||||
text = label,
|
text = label,
|
||||||
@ -46,7 +44,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
// Add member elements
|
// Add member elements
|
||||||
foreach (var member in node.Members.OrderByAttributeThenByMemberType())
|
foreach (var member in node.Members.OrderByAttributeThenByMemberType())
|
||||||
{
|
{
|
||||||
var element = new ReflectionField(obj, member, depth + 1);
|
var element = new ReflectionField(obj, member);
|
||||||
element.style.width = Length.Percent(100f);
|
element.style.width = Length.Percent(100f);
|
||||||
element.OnValueChanged += x => OnValueChanged?.Invoke(obj);
|
element.OnValueChanged += x => OnValueChanged?.Invoke(obj);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
public sealed class DictionaryField : HashMapFieldBase
|
public sealed class DictionaryField : HashMapFieldBase
|
||||||
{
|
{
|
||||||
public DictionaryField(object collection, string label, int depth) : base(collection, label, depth)
|
public DictionaryField(object collection, string label) : base(collection, label)
|
||||||
{
|
{
|
||||||
if (collection != null)
|
if (collection != null)
|
||||||
{
|
{
|
||||||
@ -60,14 +60,14 @@ namespace Alchemy.Editor.Elements
|
|||||||
ReflectionHelper.Invoke(Collection, "Clear");
|
ReflectionHelper.Invoke(Collection, "Clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth)
|
public override HashMapItemBase CreateItem(object collection, object elementObj, string label)
|
||||||
{
|
{
|
||||||
return new Item(collection, elementObj, depth + 1);
|
return new Item(collection, elementObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class Item : HashMapItemBase
|
public sealed class Item : HashMapItemBase
|
||||||
{
|
{
|
||||||
public Item(object collection, object keyValuePair, int depth)
|
public Item(object collection, object keyValuePair)
|
||||||
{
|
{
|
||||||
var box = new Box()
|
var box = new Box()
|
||||||
{
|
{
|
||||||
@ -97,14 +97,14 @@ namespace Alchemy.Editor.Elements
|
|||||||
};
|
};
|
||||||
box.Add(keyValueElement);
|
box.Add(keyValueElement);
|
||||||
|
|
||||||
keyField = new GenericField(key, keyType, KeyName, depth)
|
keyField = new GenericField(key, keyType, KeyName)
|
||||||
{
|
{
|
||||||
style = { flexGrow = 1f }
|
style = { flexGrow = 1f }
|
||||||
};
|
};
|
||||||
keyField.OnValueChanged += SetKey;
|
keyField.OnValueChanged += SetKey;
|
||||||
keyValueElement.Add(keyField);
|
keyValueElement.Add(keyField);
|
||||||
|
|
||||||
valueField = new GenericField(value, valueType, ValueName, depth)
|
valueField = new GenericField(value, valueType, ValueName)
|
||||||
{
|
{
|
||||||
style = { flexGrow = 1f }
|
style = { flexGrow = 1f }
|
||||||
};
|
};
|
||||||
|
@ -15,15 +15,14 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
const string CreateButtonText = "Create...";
|
const string CreateButtonText = "Create...";
|
||||||
|
|
||||||
public GenericField(object obj, Type type, string label, int depth, bool isDelayed = false)
|
public GenericField(object obj, Type type, string label,bool isDelayed = false)
|
||||||
{
|
{
|
||||||
Build(obj, type, label, depth, isDelayed);
|
Build(obj, type, label, isDelayed);
|
||||||
GUIHelper.ScheduleAdjustLabelWidth(this);
|
GUIHelper.ScheduleAdjustLabelWidth(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Build(object obj, Type type, string label, int depth, bool isDelayed)
|
void Build(object obj, Type type, string label, bool isDelayed)
|
||||||
{
|
{
|
||||||
if (depth > InspectorHelper.MaxDepth) return;
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// Add [Create...] button
|
// Add [Create...] button
|
||||||
@ -53,7 +52,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
nullLabelElement.Add(new Button(() =>
|
nullLabelElement.Add(new Button(() =>
|
||||||
{
|
{
|
||||||
var instance = "";
|
var instance = "";
|
||||||
Build(instance, type, label, depth, isDelayed);
|
Build(instance, type, label, isDelayed);
|
||||||
OnValueChanged?.Invoke(instance);
|
OnValueChanged?.Invoke(instance);
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
@ -65,7 +64,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
nullLabelElement.Add(new Button(() =>
|
nullLabelElement.Add(new Button(() =>
|
||||||
{
|
{
|
||||||
var instance = Activator.CreateInstance(type, Activator.CreateInstance(type.GenericTypeArguments[0]));
|
var instance = Activator.CreateInstance(type, Activator.CreateInstance(type.GenericTypeArguments[0]));
|
||||||
Build(instance, type, label, depth, isDelayed);
|
Build(instance, type, label, isDelayed);
|
||||||
OnValueChanged?.Invoke(instance);
|
OnValueChanged?.Invoke(instance);
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
@ -77,7 +76,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
nullLabelElement.Add(new Button(() =>
|
nullLabelElement.Add(new Button(() =>
|
||||||
{
|
{
|
||||||
var instance = TypeHelper.CreateDefaultInstance(type);
|
var instance = TypeHelper.CreateDefaultInstance(type);
|
||||||
Build(instance, type, label, depth, isDelayed);
|
Build(instance, type, label, isDelayed);
|
||||||
OnValueChanged?.Invoke(instance);
|
OnValueChanged?.Invoke(instance);
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
@ -228,26 +227,26 @@ namespace Alchemy.Editor.Elements
|
|||||||
}
|
}
|
||||||
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>))
|
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>))
|
||||||
{
|
{
|
||||||
var field = new HashSetField(obj, label, depth + 1);
|
var field = new HashSetField(obj, label);
|
||||||
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
||||||
|
|
||||||
Add(field);
|
Add(field);
|
||||||
}
|
}
|
||||||
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
||||||
{
|
{
|
||||||
var field = new DictionaryField(obj, label, depth + 1);
|
var field = new DictionaryField(obj, label);
|
||||||
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
||||||
Add(field);
|
Add(field);
|
||||||
}
|
}
|
||||||
else if (typeof(IList).IsAssignableFrom(type))
|
else if (typeof(IList).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
var field = new ListField((IList)obj, label, depth + 1);
|
var field = new ListField((IList)obj, label);
|
||||||
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
||||||
Add(field);
|
Add(field);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var field = new ClassField(obj, type, label, depth + 1);
|
var field = new ClassField(obj, type, label);
|
||||||
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
field.OnValueChanged += x => OnValueChanged?.Invoke(x);
|
||||||
Add(field);
|
Add(field);
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,8 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
public abstract class HashMapFieldBase : VisualElement
|
public abstract class HashMapFieldBase : VisualElement
|
||||||
{
|
{
|
||||||
public HashMapFieldBase(object collection, string label, int depth)
|
public HashMapFieldBase(object collection, string label)
|
||||||
{
|
{
|
||||||
this.depth = depth;
|
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
|
|
||||||
var foldout = new Foldout()
|
var foldout = new Foldout()
|
||||||
@ -51,7 +50,6 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
public object Collection => collection;
|
public object Collection => collection;
|
||||||
readonly object collection;
|
readonly object collection;
|
||||||
readonly int depth;
|
|
||||||
|
|
||||||
bool isInputting;
|
bool isInputting;
|
||||||
|
|
||||||
@ -75,7 +73,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
isInputting = true;
|
isInputting = true;
|
||||||
|
|
||||||
var initValue = CreateElement();
|
var initValue = CreateElement();
|
||||||
var form = CreateItem(collection, initValue, "New Value", depth);
|
var form = CreateItem(collection, initValue, "New Value");
|
||||||
inputForm.Clear();
|
inputForm.Clear();
|
||||||
inputForm.Add(form);
|
inputForm.Add(form);
|
||||||
form.OnValueChanged += ValidateValue;
|
form.OnValueChanged += ValidateValue;
|
||||||
@ -119,7 +117,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var item in (IEnumerable)collection)
|
foreach (var item in (IEnumerable)collection)
|
||||||
{
|
{
|
||||||
var element = CreateItem(collection, item, "Element " + i, depth);
|
var element = CreateItem(collection, item, "Element " + i);
|
||||||
element.OnClose += () =>
|
element.OnClose += () =>
|
||||||
{
|
{
|
||||||
if (isInputting) return;
|
if (isInputting) return;
|
||||||
@ -151,7 +149,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth);
|
public abstract HashMapItemBase CreateItem(object collection, object elementObj, string label);
|
||||||
public abstract bool CheckElement(object element);
|
public abstract bool CheckElement(object element);
|
||||||
public abstract object CreateElement();
|
public abstract object CreateElement();
|
||||||
public abstract void AddElement(object element);
|
public abstract void AddElement(object element);
|
||||||
|
@ -6,7 +6,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
public sealed class HashSetField : HashMapFieldBase
|
public sealed class HashSetField : HashMapFieldBase
|
||||||
{
|
{
|
||||||
public HashSetField(object collection, string label, int depth) : base(collection, label, depth) { }
|
public HashSetField(object collection, string label) : base(collection, label) { }
|
||||||
|
|
||||||
public override string CollectionTypeName => "HashSet";
|
public override string CollectionTypeName => "HashSet";
|
||||||
|
|
||||||
@ -35,14 +35,14 @@ namespace Alchemy.Editor.Elements
|
|||||||
ReflectionHelper.Invoke(Collection, "Clear");
|
ReflectionHelper.Invoke(Collection, "Clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth)
|
public override HashMapItemBase CreateItem(object collection, object elementObj, string label)
|
||||||
{
|
{
|
||||||
return new Item(collection, elementObj, label, depth);
|
return new Item(collection, elementObj, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class Item : HashMapItemBase
|
public sealed class Item : HashMapItemBase
|
||||||
{
|
{
|
||||||
public Item(object collection, object elementObj, string label, int depth)
|
public Item(object collection, object elementObj, string label)
|
||||||
{
|
{
|
||||||
var box = new Box()
|
var box = new Box()
|
||||||
{
|
{
|
||||||
@ -55,7 +55,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
var valueType = elementObj == null ? collection.GetType().GenericTypeArguments[0] : elementObj.GetType();
|
var valueType = elementObj == null ? collection.GetType().GenericTypeArguments[0] : elementObj.GetType();
|
||||||
|
|
||||||
inputField = new GenericField(elementObj, valueType, label, depth);
|
inputField = new GenericField(elementObj, valueType, label);
|
||||||
inputField.style.flexGrow = 1f;
|
inputField.style.flexGrow = 1f;
|
||||||
inputField.OnValueChanged += x =>
|
inputField.OnValueChanged += x =>
|
||||||
{
|
{
|
||||||
|
@ -12,12 +12,10 @@ namespace Alchemy.Editor.Elements
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class InlineEditorObjectField : BindableElement
|
public sealed class InlineEditorObjectField : BindableElement
|
||||||
{
|
{
|
||||||
public InlineEditorObjectField(SerializedProperty property, Type type, int depth)
|
public InlineEditorObjectField(SerializedProperty property, Type type)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference);
|
Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference);
|
||||||
|
|
||||||
this.depth = depth;
|
|
||||||
|
|
||||||
style.minHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
style.minHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||||
|
|
||||||
foldout = new Foldout()
|
foldout = new Foldout()
|
||||||
@ -55,7 +53,6 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
readonly Foldout foldout;
|
readonly Foldout foldout;
|
||||||
readonly ObjectField field;
|
readonly ObjectField field;
|
||||||
readonly int depth;
|
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
|
||||||
public bool IsObjectNull => isNull;
|
public bool IsObjectNull => isNull;
|
||||||
@ -101,7 +98,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
foldout.Add(new VisualElement() { style = { height = EditorGUIUtility.standardVerticalSpacing } });
|
foldout.Add(new VisualElement() { style = { height = EditorGUIUtility.standardVerticalSpacing } });
|
||||||
var so = new SerializedObject(property.objectReferenceValue);
|
var so = new SerializedObject(property.objectReferenceValue);
|
||||||
InspectorHelper.BuildElements(so, foldout, so.targetObject, name => so.FindProperty(name), depth);
|
InspectorHelper.BuildElements(so, foldout, so.targetObject, name => so.FindProperty(name));
|
||||||
this.Bind(so);
|
this.Bind(so);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -18,7 +18,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
const string ItemClassName = "unity-list-view__item";
|
const string ItemClassName = "unity-list-view__item";
|
||||||
|
|
||||||
public ListField(IList target, string label, int depth)
|
public ListField(IList target, string label)
|
||||||
{
|
{
|
||||||
Assert.IsNotNull(target);
|
Assert.IsNotNull(target);
|
||||||
list = target;
|
list = target;
|
||||||
@ -32,7 +32,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
var value = list[index];
|
var value = list[index];
|
||||||
var listType = list.GetType();
|
var listType = list.GetType();
|
||||||
var valueType = value != null ? value.GetType() : listType.IsGenericType ? listType.GenericTypeArguments[0] : typeof(object);
|
var valueType = value != null ? value.GetType() : listType.IsGenericType ? listType.GenericTypeArguments[0] : typeof(object);
|
||||||
var fieldElement = new GenericField(value, valueType, label, depth);
|
var fieldElement = new GenericField(value, valueType, label);
|
||||||
element.Add(fieldElement);
|
element.Add(fieldElement);
|
||||||
var labelElement = fieldElement.Q<Label>();
|
var labelElement = fieldElement.Q<Label>();
|
||||||
if (labelElement != null) labelElement.text = "Element " + index;
|
if (labelElement != null) labelElement.text = "Element " + index;
|
||||||
|
@ -60,7 +60,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
var index = i;
|
var index = i;
|
||||||
var parameter = parameters[index];
|
var parameter = parameters[index];
|
||||||
parameterObjects[index] = TypeHelper.CreateDefaultInstance(parameter.ParameterType);
|
parameterObjects[index] = TypeHelper.CreateDefaultInstance(parameter.ParameterType);
|
||||||
var element = new GenericField(parameterObjects[index], parameter.ParameterType, ObjectNames.NicifyVariableName(parameter.Name), 0);
|
var element = new GenericField(parameterObjects[index], parameter.ParameterType, ObjectNames.NicifyVariableName(parameter.Name));
|
||||||
element.OnValueChanged += x => parameterObjects[index] = x;
|
element.OnValueChanged += x => parameterObjects[index] = x;
|
||||||
element.style.paddingRight = 4f;
|
element.style.paddingRight = 4f;
|
||||||
foldout.Add(element);
|
foldout.Add(element);
|
||||||
|
@ -12,7 +12,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class PropertyListView : BindableElement
|
public sealed class PropertyListView : BindableElement
|
||||||
{
|
{
|
||||||
public PropertyListView(SerializedProperty property, int depth)
|
public PropertyListView(SerializedProperty property)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(property.isArray);
|
Assert.IsTrue(property.isArray);
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
listView.bindItem = (element, index) =>
|
listView.bindItem = (element, index) =>
|
||||||
{
|
{
|
||||||
var arrayElement = property.GetArrayElementAtIndex(index);
|
var arrayElement = property.GetArrayElementAtIndex(index);
|
||||||
var e = new AlchemyPropertyField(arrayElement, property.GetPropertyType(true), depth + 1, true);
|
var e = new AlchemyPropertyField(arrayElement, property.GetPropertyType(true), true);
|
||||||
element.Add(e);
|
element.Add(e);
|
||||||
element.Bind(arrayElement.serializedObject);
|
element.Bind(arrayElement.serializedObject);
|
||||||
if (events != null)
|
if (events != null)
|
||||||
|
@ -9,12 +9,12 @@ namespace Alchemy.Editor.Elements
|
|||||||
{
|
{
|
||||||
public sealed class ReflectionField : VisualElement
|
public sealed class ReflectionField : VisualElement
|
||||||
{
|
{
|
||||||
public ReflectionField(object target, MemberInfo memberInfo, int depth)
|
public ReflectionField(object target, MemberInfo memberInfo)
|
||||||
{
|
{
|
||||||
Rebuild(target, memberInfo, depth);
|
Rebuild(target, memberInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Rebuild(object target, MemberInfo memberInfo, int depth)
|
public void Rebuild(object target, MemberInfo memberInfo)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
case FieldInfo fieldInfo:
|
case FieldInfo fieldInfo:
|
||||||
value = fieldInfo.IsStatic ? fieldInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(fieldInfo.FieldType) : fieldInfo.GetValue(target);
|
value = fieldInfo.IsStatic ? fieldInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(fieldInfo.FieldType) : fieldInfo.GetValue(target);
|
||||||
var fieldType = target == null ? fieldInfo.FieldType : fieldInfo.GetValue(target)?.GetType() ?? fieldInfo.FieldType;
|
var fieldType = target == null ? fieldInfo.FieldType : fieldInfo.GetValue(target)?.GetType() ?? fieldInfo.FieldType;
|
||||||
element = new GenericField(value, fieldType, ObjectNames.NicifyVariableName(memberInfo.Name), depth, true);
|
element = new GenericField(value, fieldType, ObjectNames.NicifyVariableName(memberInfo.Name), true);
|
||||||
element.OnValueChanged += x =>
|
element.OnValueChanged += x =>
|
||||||
{
|
{
|
||||||
OnBeforeValueChange?.Invoke(target);
|
OnBeforeValueChange?.Invoke(target);
|
||||||
@ -57,7 +57,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
|
|
||||||
value = propertyInfo.GetMethod.IsStatic ? propertyInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(propertyInfo.PropertyType) : propertyInfo.GetValue(target);
|
value = propertyInfo.GetMethod.IsStatic ? propertyInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(propertyInfo.PropertyType) : propertyInfo.GetValue(target);
|
||||||
var propertyType = target == null ? propertyInfo.PropertyType : propertyInfo.GetValue(target)?.GetType() ?? propertyInfo.PropertyType;
|
var propertyType = target == null ? propertyInfo.PropertyType : propertyInfo.GetValue(target)?.GetType() ?? propertyInfo.PropertyType;
|
||||||
element = new GenericField(value, propertyType, ObjectNames.NicifyVariableName(memberInfo.Name), depth, true);
|
element = new GenericField(value, propertyType, ObjectNames.NicifyVariableName(memberInfo.Name), true);
|
||||||
element.OnValueChanged += x =>
|
element.OnValueChanged += x =>
|
||||||
{
|
{
|
||||||
OnBeforeValueChange?.Invoke(target);
|
OnBeforeValueChange?.Invoke(target);
|
||||||
|
@ -14,7 +14,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class SerializeReferenceField : VisualElement
|
public sealed class SerializeReferenceField : VisualElement
|
||||||
{
|
{
|
||||||
public SerializeReferenceField(SerializedProperty property, int depth)
|
public SerializeReferenceField(SerializedProperty property)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(property.propertyType == SerializedPropertyType.ManagedReference);
|
Assert.IsTrue(property.propertyType == SerializedPropertyType.ManagedReference);
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
property.serializedObject.ApplyModifiedProperties();
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
property.serializedObject.Update();
|
property.serializedObject.Update();
|
||||||
|
|
||||||
Rebuild(property, depth);
|
Rebuild(property);
|
||||||
};
|
};
|
||||||
|
|
||||||
dropdown.Show(position);
|
dropdown.Show(position);
|
||||||
@ -100,7 +100,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
buttonContainer.style.right = 0f;
|
buttonContainer.style.right = 0f;
|
||||||
Add(buttonContainer);
|
Add(buttonContainer);
|
||||||
|
|
||||||
Rebuild(property, depth);
|
Rebuild(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly Foldout foldout;
|
public readonly Foldout foldout;
|
||||||
@ -109,7 +109,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rebuild child elements
|
/// Rebuild child elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Rebuild(SerializedProperty property, int depth)
|
void Rebuild(SerializedProperty property)
|
||||||
{
|
{
|
||||||
foldout.Clear();
|
foldout.Clear();
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ namespace Alchemy.Editor.Elements
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InspectorHelper.BuildElements(property.serializedObject, foldout, property.managedReferenceValue, x => property.FindPropertyRelative(x), depth + 1);
|
InspectorHelper.BuildElements(property.serializedObject, foldout, property.managedReferenceValue, x => property.FindPropertyRelative(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Bind(property.serializedObject);
|
this.Bind(property.serializedObject);
|
||||||
|
@ -16,8 +16,6 @@ namespace Alchemy.Editor
|
|||||||
{
|
{
|
||||||
internal static class InspectorHelper
|
internal static class InspectorHelper
|
||||||
{
|
{
|
||||||
public const int MaxDepth = 15;
|
|
||||||
|
|
||||||
public sealed class GroupNode
|
public sealed class GroupNode
|
||||||
{
|
{
|
||||||
public GroupNode(string name, AlchemyGroupDrawer drawer)
|
public GroupNode(string name, AlchemyGroupDrawer drawer)
|
||||||
@ -74,9 +72,8 @@ namespace Alchemy.Editor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BuildElements(SerializedObject serializedObject, VisualElement rootElement, object target, Func<string, SerializedProperty> findPropertyFunc, int depth)
|
public static void BuildElements(SerializedObject serializedObject, VisualElement rootElement, object target, Func<string, SerializedProperty> findPropertyFunc)
|
||||||
{
|
{
|
||||||
if (depth >= MaxDepth) return;
|
|
||||||
if (target == null) return;
|
if (target == null) return;
|
||||||
|
|
||||||
// Build node
|
// Build node
|
||||||
@ -133,7 +130,7 @@ namespace Alchemy.Editor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
element = CreateMemberElement(serializedObject, target, member, findPropertyFunc, depth + 1);
|
element = CreateMemberElement(serializedObject, target, member, findPropertyFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element == null) continue;
|
if (element == null) continue;
|
||||||
@ -197,10 +194,8 @@ namespace Alchemy.Editor
|
|||||||
return rootNode;
|
return rootNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VisualElement CreateMemberElement(SerializedObject serializedObject, object target, MemberInfo memberInfo, Func<string, SerializedProperty> findPropertyFunc, int depth)
|
public static VisualElement CreateMemberElement(SerializedObject serializedObject, object target, MemberInfo memberInfo, Func<string, SerializedProperty> findPropertyFunc)
|
||||||
{
|
{
|
||||||
if (depth > MaxDepth) return null;
|
|
||||||
|
|
||||||
switch (memberInfo)
|
switch (memberInfo)
|
||||||
{
|
{
|
||||||
case MethodInfo methodInfo:
|
case MethodInfo methodInfo:
|
||||||
@ -224,11 +219,11 @@ namespace Alchemy.Editor
|
|||||||
{
|
{
|
||||||
if (memberInfo is FieldInfo fieldInfo)
|
if (memberInfo is FieldInfo fieldInfo)
|
||||||
{
|
{
|
||||||
return new AlchemyPropertyField(property, fieldInfo.FieldType, depth);
|
return new AlchemyPropertyField(property, fieldInfo.FieldType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new AlchemyPropertyField(property, ((PropertyInfo)memberInfo).PropertyType, depth);
|
return new AlchemyPropertyField(property, ((PropertyInfo)memberInfo).PropertyType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,12 +241,12 @@ namespace Alchemy.Editor
|
|||||||
var p = GetProperty();
|
var p = GetProperty();
|
||||||
if (p != null)
|
if (p != null)
|
||||||
{
|
{
|
||||||
var field = new ReflectionField(target, fieldInfo, depth);
|
var field = new ReflectionField(target, fieldInfo);
|
||||||
var foldout = field.Q<Foldout>();
|
var foldout = field.Q<Foldout>();
|
||||||
foldout?.BindProperty(p);
|
foldout?.BindProperty(p);
|
||||||
field.TrackPropertyValue(p, p =>
|
field.TrackPropertyValue(p, p =>
|
||||||
{
|
{
|
||||||
field.Rebuild(target, memberInfo, depth);
|
field.Rebuild(target, memberInfo);
|
||||||
var foldout = field.Q<Foldout>();
|
var foldout = field.Q<Foldout>();
|
||||||
foldout?.BindProperty(p);
|
foldout?.BindProperty(p);
|
||||||
});
|
});
|
||||||
@ -279,7 +274,7 @@ namespace Alchemy.Editor
|
|||||||
// Create element if member has ShowInInspector attribute
|
// Create element if member has ShowInInspector attribute
|
||||||
if (memberInfo.HasCustomAttribute<ShowInInspectorAttribute>())
|
if (memberInfo.HasCustomAttribute<ShowInInspectorAttribute>())
|
||||||
{
|
{
|
||||||
return new ReflectionField(target, memberInfo, depth);
|
return new ReflectionField(target, memberInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
24
Alchemy/Assets/Tests/DepthTest.cs
Normal file
24
Alchemy/Assets/Tests/DepthTest.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using Alchemy.Inspector;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class DepthTest : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[BoxGroup]
|
||||||
|
public class NodeA
|
||||||
|
{
|
||||||
|
[SerializeField] float foo;
|
||||||
|
[SerializeField] NodeB node;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[BoxGroup]
|
||||||
|
public class NodeB
|
||||||
|
{
|
||||||
|
[SerializeField] float bar;
|
||||||
|
[SerializeField] NodeA node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeA node;
|
||||||
|
}
|
11
Alchemy/Assets/Tests/DepthTest.cs.meta
Normal file
11
Alchemy/Assets/Tests/DepthTest.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6eba956dee63540d8b7030e2e337edfc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user