A game about forced loneliness, made by TACStudios
1using System; 2using System.Reflection; 3using UnityEngine; 4using UnityEditor.Graphing; 5using System.Globalization; 6using UnityEditor.UIElements; 7using UnityEngine.UIElements; 8 9 10namespace UnityEditor.ShaderGraph.Drawing.Controls 11{ 12 [AttributeUsage(AttributeTargets.Property)] 13 class SliderControlAttribute : Attribute, IControlAttribute 14 { 15 string m_Label; 16 bool m_DisplayMinMax; 17 18 public SliderControlAttribute(string label = null, bool displayMinMax = false) 19 { 20 m_Label = label; 21 m_DisplayMinMax = displayMinMax; 22 } 23 24 public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo) 25 { 26 return new SliderControlView(m_Label, m_DisplayMinMax, node, propertyInfo); 27 } 28 } 29 30 class SliderControlView : VisualElement, AbstractMaterialNodeModificationListener 31 { 32 AbstractMaterialNode m_Node; 33 PropertyInfo m_PropertyInfo; 34 bool m_DisplayMinMax; 35 Vector3 m_Value; 36 37 VisualElement m_SliderPanel; 38 Slider m_Slider; 39 FloatField m_SliderInput; 40 FloatField m_MinField; 41 FloatField m_MaxField; 42 43 public SliderControlView(string label, bool displayMinMax, AbstractMaterialNode node, PropertyInfo propertyInfo) 44 { 45 m_Node = node; 46 m_PropertyInfo = propertyInfo; 47 styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/SliderControlView")); 48 m_DisplayMinMax = displayMinMax; 49 50 if (propertyInfo.PropertyType != typeof(Vector3)) 51 throw new ArgumentException("Property must be of type Vector3.", "propertyInfo"); 52 new GUIContent(label ?? ObjectNames.NicifyVariableName(propertyInfo.Name)); 53 m_Value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); 54 55 m_Slider = new Slider(m_Value.y, m_Value.z) { value = m_Value.x }; 56 m_Slider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue)); 57 58 m_SliderInput = new FloatField { value = m_Value.x }; 59 m_SliderInput.RegisterValueChangedCallback(evt => 60 { 61 var value = (float)evt.newValue; 62 m_Value.x = value; 63 m_PropertyInfo.SetValue(m_Node, m_Value, null); 64 this.MarkDirtyRepaint(); 65 }); 66 m_SliderInput.Q("unity-text-input").RegisterCallback<FocusOutEvent>(evt => 67 { 68 float minValue = Mathf.Min(m_Value.x, m_Value.y); 69 float maxValue = Mathf.Max(m_Value.x, m_Value.z); 70 m_Value = new Vector3(m_Value.x, minValue, maxValue); 71 m_MinField.value = minValue; 72 m_MaxField.value = maxValue; 73 UpdateSlider(); 74 m_PropertyInfo.SetValue(m_Node, m_Value, null); 75 this.MarkDirtyRepaint(); 76 }, TrickleDown.TrickleDown); 77 78 m_SliderPanel = new VisualElement { name = "SliderPanel" }; 79 if (!string.IsNullOrEmpty(label)) 80 m_SliderPanel.Add(new Label(label)); 81 82 m_SliderPanel.Add(m_Slider); 83 m_SliderPanel.Add(m_SliderInput); 84 Add(m_SliderPanel); 85 86 if (m_DisplayMinMax) 87 { 88 var fieldsPanel = new VisualElement { name = "FieldsPanel" }; 89 m_MinField = AddMinMaxField(fieldsPanel, "Min", 1); 90 m_MaxField = AddMinMaxField(fieldsPanel, "Max", 2); 91 Add(fieldsPanel); 92 } 93 } 94 95 public void OnNodeModified(ModificationScope scope) 96 { 97 if (scope == ModificationScope.Graph) 98 { 99 this.MarkDirtyRepaint(); 100 } 101 } 102 103 void OnChangeSlider(float newValue) 104 { 105 m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change"); 106 var value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); 107 value.x = newValue; 108 m_PropertyInfo.SetValue(m_Node, value, null); 109 if (m_SliderInput != null) 110 m_SliderInput.value = newValue; 111 m_PropertyInfo.SetValue(m_Node, m_Value, null); 112 this.MarkDirtyRepaint(); 113 } 114 115 void UpdateSlider() 116 { 117 m_SliderPanel.Remove(m_Slider); 118 m_Slider = new Slider(m_Value.y, m_Value.z) { value = m_Value.x }; 119 m_Slider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue)); 120 m_SliderPanel.Add(m_Slider); 121 m_SliderPanel.Add(m_SliderInput); 122 } 123 124 FloatField AddMinMaxField(VisualElement panel, string label, int index) 125 { 126 var floatField = new FloatField { value = m_Value[index] }; 127 if (label != null) 128 { 129 var labelField = new Label(label); 130 panel.Add(labelField); 131 } 132 133 floatField.RegisterValueChangedCallback(evt => 134 { 135 m_Value[index] = (float)evt.newValue; 136 m_PropertyInfo.SetValue(m_Node, m_Value, null); 137 this.MarkDirtyRepaint(); 138 }); 139 floatField.Q("unity-text-input").RegisterCallback<FocusOutEvent>(evt => 140 { 141 if (index == 1) 142 { 143 m_Value[index] = Mathf.Min(m_Value[index], m_Value.z); 144 m_MinField.value = m_Value[index]; 145 } 146 else 147 { 148 m_Value[index] = Mathf.Max(m_Value[index], m_Value.y); 149 m_MaxField.value = m_Value[index]; 150 } 151 float newValue = Mathf.Max(Mathf.Min(m_Value.x, m_Value.z), m_Value.y); 152 m_Value.x = newValue; 153 m_SliderInput.value = newValue; 154 UpdateSlider(); 155 m_PropertyInfo.SetValue(m_Node, m_Value, null); 156 this.MarkDirtyRepaint(); 157 }, TrickleDown.TrickleDown); 158 159 panel.Add(floatField); 160 return floatField; 161 } 162 163 void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new() 164 { 165 evt.StopPropagation(); 166 this.MarkDirtyRepaint(); 167 } 168 } 169}