2 using System.Globalization;
4 using System.Reflection;
6 using UnityEditor.UIElements;
7 using UnityEngine.UIElements;
9 namespace UnityEditor.ShaderGraph.Drawing.Controls
11 [AttributeUsage(AttributeTargets.Property)]
12 class MultiFloatControlAttribute : Attribute, IControlAttribute
20 public MultiFloatControlAttribute(string label = null, string subLabel1 = "X", string subLabel2 = "Y", string subLabel3 = "Z", string subLabel4 = "W")
22 m_SubLabel1 = subLabel1;
23 m_SubLabel2 = subLabel2;
24 m_SubLabel3 = subLabel3;
25 m_SubLabel4 = subLabel4;
29 public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
31 if (!MultiFloatControlView.validTypes.Contains(propertyInfo.PropertyType))
33 return new MultiFloatControlView(m_Label, m_SubLabel1, m_SubLabel2, m_SubLabel3, m_SubLabel4, node, propertyInfo);
37 class MultiFloatControlView : VisualElement
39 public static Type[] validTypes = { typeof(float), typeof(Vector2), typeof(Vector3), typeof(Vector4) };
41 AbstractMaterialNode m_Node;
42 PropertyInfo m_PropertyInfo;
46 public MultiFloatControlView(string label, string subLabel1, string subLabel2, string subLabel3, string subLabel4, AbstractMaterialNode node, PropertyInfo propertyInfo)
48 var components = Array.IndexOf(validTypes, propertyInfo.PropertyType) + 1;
50 throw new ArgumentException("Property must be of type float, Vector2, Vector3 or Vector4.", "propertyInfo");
52 styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/MultiFloatControlView"));
54 m_PropertyInfo = propertyInfo;
56 label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
57 if (!string.IsNullOrEmpty(label))
58 Add(new Label(label));
61 AddField(0, subLabel1);
63 AddField(1, subLabel2);
65 AddField(2, subLabel3);
67 AddField(3, subLabel4);
70 void AddField(int index, string subLabel)
72 var dummy = new VisualElement { name = "dummy" };
73 var label = new Label(subLabel);
76 var field = new FloatField { userData = index, value = m_Value[index] };
77 var dragger = new FieldMouseDragger<double>(field);
78 dragger.SetDragZone(label);
79 field.RegisterCallback<MouseDownEvent>(Repaint);
80 field.RegisterCallback<MouseMoveEvent>(Repaint);
81 field.RegisterValueChangedCallback(evt =>
83 var value = GetValue();
84 value[index] = (float)evt.newValue;
87 this.MarkDirtyRepaint();
89 field.Q("unity-text-input").RegisterCallback<InputEvent>(evt =>
91 if (m_UndoGroup == -1)
93 m_UndoGroup = Undo.GetCurrentGroup();
94 m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
97 if (!float.TryParse(evt.newData, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out newValue))
99 var value = GetValue();
100 value[index] = newValue;
102 this.MarkDirtyRepaint();
104 field.Q("unity-text-input").RegisterCallback<KeyDownEvent>(evt =>
106 if (evt.keyCode == KeyCode.Escape && m_UndoGroup > -1)
108 Undo.RevertAllDownToGroup(m_UndoGroup);
110 m_Value = GetValue();
111 evt.StopPropagation();
113 this.MarkDirtyRepaint();
118 object ValueToPropertyType(Vector4 value)
120 if (m_PropertyInfo.PropertyType == typeof(float))
122 if (m_PropertyInfo.PropertyType == typeof(Vector2))
123 return (Vector2)value;
124 if (m_PropertyInfo.PropertyType == typeof(Vector3))
125 return (Vector3)value;
131 var value = m_PropertyInfo.GetValue(m_Node, null);
132 if (m_PropertyInfo.PropertyType == typeof(float))
133 return new Vector4((float)value, 0f, 0f, 0f);
134 if (m_PropertyInfo.PropertyType == typeof(Vector2))
135 return (Vector2)value;
136 if (m_PropertyInfo.PropertyType == typeof(Vector3))
137 return (Vector3)value;
138 return (Vector4)value;
141 void SetValue(Vector4 value)
143 m_PropertyInfo.SetValue(m_Node, ValueToPropertyType(value), null);
146 void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new()
148 evt.StopPropagation();
149 this.MarkDirtyRepaint();