A game about forced loneliness, made by TACStudios
1using System;
2using System.Globalization;
3using System.Linq;
4using System.Reflection;
5using UnityEngine;
6
7using UnityEngine.UIElements;
8
9namespace UnityEditor.ShaderGraph.Drawing.Controls
10{
11 [AttributeUsage(AttributeTargets.Property)]
12 class MultiFloatControlAttribute : Attribute, IControlAttribute
13 {
14 string m_Label;
15 string m_SubLabel1;
16 string m_SubLabel2;
17 string m_SubLabel3;
18 string m_SubLabel4;
19
20 public MultiFloatControlAttribute(string label = null, string subLabel1 = "X", string subLabel2 = "Y", string subLabel3 = "Z", string subLabel4 = "W")
21 {
22 m_SubLabel1 = subLabel1;
23 m_SubLabel2 = subLabel2;
24 m_SubLabel3 = subLabel3;
25 m_SubLabel4 = subLabel4;
26 m_Label = label;
27 }
28
29 public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
30 {
31 if (!MultiFloatControlView.validTypes.Contains(propertyInfo.PropertyType))
32 return null;
33 return new MultiFloatControlView(m_Label, m_SubLabel1, m_SubLabel2, m_SubLabel3, m_SubLabel4, node, propertyInfo);
34 }
35 }
36
37 class MultiFloatControlView : VisualElement
38 {
39 public static Type[] validTypes = { typeof(float), typeof(Vector2), typeof(Vector3), typeof(Vector4) };
40
41 AbstractMaterialNode m_Node;
42 PropertyInfo m_PropertyInfo;
43 Vector4 m_Value;
44 int m_UndoGroup = -1;
45
46 public MultiFloatControlView(string label, string subLabel1, string subLabel2, string subLabel3, string subLabel4, AbstractMaterialNode node, PropertyInfo propertyInfo)
47 {
48 var components = Array.IndexOf(validTypes, propertyInfo.PropertyType) + 1;
49 if (components == -1)
50 throw new ArgumentException("Property must be of type float, Vector2, Vector3 or Vector4.", "propertyInfo");
51
52 styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/MultiFloatControlView"));
53 m_Node = node;
54 m_PropertyInfo = propertyInfo;
55
56 label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
57 if (!string.IsNullOrEmpty(label))
58 Add(new Label(label));
59
60 m_Value = GetValue();
61 AddField(0, subLabel1);
62 if (components > 1)
63 AddField(1, subLabel2);
64 if (components > 2)
65 AddField(2, subLabel3);
66 if (components > 3)
67 AddField(3, subLabel4);
68 }
69
70 void AddField(int index, string subLabel)
71 {
72 var dummy = new VisualElement { name = "dummy" };
73 var label = new Label(subLabel);
74 dummy.Add(label);
75 Add(dummy);
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 =>
82 {
83 var value = GetValue();
84 value[index] = (float)evt.newValue;
85 SetValue(value);
86 m_UndoGroup = -1;
87 this.MarkDirtyRepaint();
88 });
89 field.Q("unity-text-input").RegisterCallback<InputEvent>(evt =>
90 {
91 if (m_UndoGroup == -1)
92 {
93 m_UndoGroup = Undo.GetCurrentGroup();
94 m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
95 }
96 float newValue;
97 if (!float.TryParse(evt.newData, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out newValue))
98 newValue = 0f;
99 var value = GetValue();
100 value[index] = newValue;
101 SetValue(value);
102 this.MarkDirtyRepaint();
103 }, TrickleDown.TrickleDown);
104 field.Q("unity-text-input").RegisterCallback<KeyDownEvent>(evt =>
105 {
106 if (evt.keyCode == KeyCode.Escape && m_UndoGroup > -1)
107 {
108 Undo.RevertAllDownToGroup(m_UndoGroup);
109 m_UndoGroup = -1;
110 m_Value = GetValue();
111 evt.StopPropagation();
112 }
113 this.MarkDirtyRepaint();
114 }, TrickleDown.TrickleDown);
115 Add(field);
116 }
117
118 object ValueToPropertyType(Vector4 value)
119 {
120 if (m_PropertyInfo.PropertyType == typeof(float))
121 return value.x;
122 if (m_PropertyInfo.PropertyType == typeof(Vector2))
123 return (Vector2)value;
124 if (m_PropertyInfo.PropertyType == typeof(Vector3))
125 return (Vector3)value;
126 return value;
127 }
128
129 Vector4 GetValue()
130 {
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;
139 }
140
141 void SetValue(Vector4 value)
142 {
143 m_PropertyInfo.SetValue(m_Node, ValueToPropertyType(value), null);
144 }
145
146 void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new()
147 {
148 evt.StopPropagation();
149 this.MarkDirtyRepaint();
150 }
151 }
152}