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}