Files
2026-09-21 12:15:57 +03:00

113 lines
3.8 KiB
C#

using System;
using Alchemy.Inspector;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Assertions;
using UnityEngine.UIElements;
namespace Alchemy.Editor.Elements
{
/// <summary>
/// Visual Element that draws the ObjectField of the InlineEditor attribute
/// </summary>
public sealed class InlineEditorObjectField : BindableElement
{
public InlineEditorObjectField(SerializedProperty property, Type type)
{
Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference);
style.minHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
foldout = new Foldout()
{
text = ObjectNames.NicifyVariableName(property.displayName)
};
var toggle = foldout.Q<Toggle>();
var clickable = InternalAPIHelper.GetClickable(toggle);
InternalAPIHelper.SetAcceptClicksIfDisabled(clickable, true);
foldout.BindProperty(property);
inspectorContainer = new VisualElement();
field = new ObjectField()
{
label = ObjectNames.NicifyVariableName(property.displayName),
objectType = type,
allowSceneObjects = !property.GetFieldInfo().HasCustomAttribute<AssetsOnlyAttribute>(),
value = property.objectReferenceValue
};
field.style.position = Position.Absolute;
field.style.width = Length.Percent(100f);
GUIHelper.ScheduleAdjustLabelWidth(field);
OnPropertyChanged(property);
field.RegisterValueChangedCallback(x =>
{
property.objectReferenceValue = x.newValue;
property.serializedObject.ApplyModifiedProperties();
OnPropertyChanged(property);
});
Add(foldout);
Add(field);
}
readonly Foldout foldout;
readonly VisualElement inspectorContainer;
readonly ObjectField field;
bool isNull;
public bool IsObjectNull => isNull;
public string Label
{
get
{
if (isNull) return field.Q<Label>().text;
else return foldout.text;
}
set
{
if (isNull) field.Q<Label>().text = value;
else foldout.text = value;
}
}
void OnPropertyChanged(SerializedProperty property)
{
isNull = property.objectReferenceValue == null;
field.Q<Label>().text = isNull ? ObjectNames.NicifyVariableName(property.displayName) : string.Empty;
field.pickingMode = PickingMode.Ignore;
var objectField = field.Q<ObjectField>();
objectField.pickingMode = PickingMode.Ignore;
var label = objectField.Q<Label>();
label.pickingMode = PickingMode.Ignore;
Build(property);
}
void Build(SerializedProperty property)
{
inspectorContainer.Unbind();
inspectorContainer.Clear();
foldout.Clear();
var toggle = foldout.Q<Toggle>();
isNull = property.objectReferenceValue == null;
toggle.style.display = isNull ? DisplayStyle.None : DisplayStyle.Flex;
if (!isNull)
{
foldout.Add(new VisualElement() { style = { height = EditorGUIUtility.standardVerticalSpacing } });
var so = new SerializedObject(property.objectReferenceValue);
InspectorHelper.BuildElements(so, inspectorContainer, so.targetObject, name => so.FindProperty(name));
inspectorContainer.Bind(so);
foldout.Add(inspectorContainer);
}
}
}
}