using UnityEngine; using UnityEngine.VFX; using UnityEngine.UIElements; using System; namespace UnityEditor.VFX.UI { class SpaceablePropertyRM : PropertyRM { static readonly bool s_UseDropDownMenu = true; static readonly bool s_UseHovering = true; void OnMouseHover(EventBase evt) { if (m_Button == null || !m_Button.enabledSelf) return; if (evt.eventTypeId == MouseEnterEvent.TypeId()) m_Button.AddToClassList("hovered"); else m_Button.RemoveFromClassList("hovered"); } public SpaceablePropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { if (!string.IsNullOrEmpty(controller.name)) { var label = new Label(ObjectNames.NicifyVariableName(controller.name)); label.AddToClassList("label"); Add(label); } m_Button = new VisualElement { name = "spacebutton" }; m_Button.AddManipulator(new Clickable(OnButtonClick)); Add(m_Button); AddToClassList("spaceablepropertyrm"); if (s_UseHovering) { RegisterCallback(OnMouseHover); RegisterCallback(OnMouseHover); } } public override float GetPreferredControlWidth() => 40; private VFXSpace space { get => m_Provider.space; set => m_Provider.space = value; } void ChangeSpace(object val) { space = (VFXSpace)val; } void OnButtonClick() { var values = (VFXSpace[])Enum.GetValues(space.GetType()); if (s_UseDropDownMenu) { var menu = new GenericMenu(); foreach (var spaceOption in values) { menu.AddItem( new GUIContent(ObjectNames.NicifyVariableName(spaceOption.ToString())), spaceOption == space, ChangeSpace, spaceOption); } menu.DropDown(m_Button.worldBound); } else { var spaceCount = values.Length; var index = Array.IndexOf(values, space); var nextIndex = (index + 1) % spaceCount; space = values[nextIndex]; } } public override void UpdateGUI(bool force) { foreach (string name in Enum.GetNames(typeof(VFXSpace))) { if (space.ToString() != name) m_Button.RemoveFromClassList("space" + name); } m_Button.AddToClassList("space" + space.ToString()); } VisualElement m_Button; protected override void UpdateEnabled() { m_Button.SetEnabled(!m_Provider.IsSpaceInherited()); } protected override void UpdateIndeterminate() { } public override bool showsEverything => false; } abstract class Vector3SpaceablePropertyRM : SpaceablePropertyRM { public Vector3SpaceablePropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { m_VectorField = new VFXVector3Field(); m_VectorField.RegisterCallback>(OnValueChanged); m_VectorField.AddToClassList("fieldContainer"); m_VectorField.onValueDragFinished += ValueDragFinished; m_VectorField.onValueDragStarted += ValueDragStarted; Add(m_VectorField); } public override float GetPreferredControlWidth() { return 200; } public abstract void OnValueChanged(ChangeEvent e); protected VFXVector3Field m_VectorField; protected override void UpdateEnabled() { base.UpdateEnabled(); m_VectorField.SetEnabled(propertyEnabled); } protected override void UpdateIndeterminate() { base.UpdateEnabled(); m_VectorField.indeterminate = indeterminate; } public override bool showsEverything { get { return true; } } } class VectorPropertyRM : Vector3SpaceablePropertyRM { public VectorPropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { } public override void OnValueChanged(ChangeEvent e) { Vector3 newValue = m_VectorField.value; if (newValue != m_Value.vector) { m_Value.vector = newValue; NotifyValueChanged(); } } public override void UpdateGUI(bool force) { base.UpdateGUI(force); m_VectorField.SetValueWithoutNotify(m_Value.vector); } } class PositionPropertyRM : Vector3SpaceablePropertyRM { public PositionPropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { } public override void OnValueChanged(ChangeEvent e) { Vector3 newValue = m_VectorField.value; if (newValue != m_Value.position) { m_Value.position = newValue; NotifyValueChanged(); } } public override void UpdateGUI(bool force) { base.UpdateGUI(force); m_VectorField.SetValueWithoutNotify(m_Value.position); } } class DirectionPropertyRM : Vector3SpaceablePropertyRM { public DirectionPropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { } public override void OnValueChanged(ChangeEvent e) { Vector3 newValue = m_VectorField.value; if (newValue != m_Value.direction) { m_Value.direction = newValue; NotifyValueChanged(); } } public override void UpdateGUI(bool force) { base.UpdateGUI(force); m_VectorField.SetValueWithoutNotify(m_Value.direction); } } }