using System; using KitsuneCafe.System.Attributes; using Unity.Properties; using UnityEditor; using UnityEditor.UIElements; using UnityEngine.UIElements; [CustomPropertyDrawer(typeof(ConditionalDisplayAttribute), true)] public class ConditionalDisplayPropertyDrawer : PropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { var attribute = this.attribute as ConditionalDisplayAttribute; var serializedObject = property.serializedObject; var names = attribute.Properties; var length = names.Length; var properties = new SerializedProperty[length]; for (int i = 0; i < length; i++) { properties[i] = serializedObject.FindProperty(names[i]); } return new BoolConditionPropertyField(properties, attribute, property); } public abstract class ConditionalPropertyField : PropertyField { protected readonly SerializedProperty[] properties; protected readonly ConditionalDisplayAttribute attribute; public ConditionalPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property) : base(property) { this.properties = properties; this.attribute = attribute; TrackProperties(properties); } public ConditionalPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property, string label) : base(property, label) { this.properties = properties; this.attribute = attribute; TrackProperties(properties); } private void TrackProperties(SerializedProperty[] properties) { var len = properties.Length; for (int i = 0; i < len; i++) { var property = properties[i]; OnTrackedValueChanged(property); this.TrackPropertyValue(property, OnTrackedValueChanged); } } protected abstract void OnTrackedValueChanged(SerializedProperty property); } public class BoolConditionPropertyField : ConditionalPropertyField { public BoolConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property) : base(properties, attribute, property) { } public BoolConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property, string label) : base(properties, attribute, property, label) { } protected override void OnTrackedValueChanged(SerializedProperty property) { var value = (attribute.LogicalOperator, attribute.ComparisonOperator) switch { (LogicalOperator.Or, ComparisonOperator.Equal) => true, (LogicalOperator.And, ComparisonOperator.NotEqual) => true, _ => false }; for (int i = 0; i < properties.Length; i++) { if (properties[i].boolValue == value) { DisplayElement(value); return; } } DisplayElement(!value); } private void DisplayElement(bool displayed) { style.display = displayed ? DisplayStyle.Flex : DisplayStyle.None; } } }