A game about forced loneliness, made by TACStudios
1using System;
2using System.Globalization;
3using System.Reflection;
4using UnityEngine;
5
6
7using UnityEngine.UIElements;
8
9namespace UnityEditor.ShaderGraph.Drawing.Controls
10{
11 [AttributeUsage(AttributeTargets.Property)]
12 class DielectricSpecularControlAttribute : Attribute, IControlAttribute
13 {
14 public DielectricSpecularControlAttribute()
15 {
16 }
17
18 public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
19 {
20 return new DielectricSpecularControlView(node, propertyInfo);
21 }
22 }
23
24 class DielectricSpecularControlView : VisualElement
25 {
26 AbstractMaterialNode m_Node;
27 PropertyInfo m_PropertyInfo;
28 DielectricSpecularNode.DielectricMaterial m_DielectricMaterial;
29
30 VisualElement m_RangePanel;
31 Slider m_RangeSlider;
32 FloatField m_RangeField;
33 VisualElement m_IORPanel;
34 Slider m_IORSlider;
35 FloatField m_IORField;
36
37 public DielectricSpecularControlView(AbstractMaterialNode node, PropertyInfo propertyInfo)
38 {
39 m_Node = node;
40 m_PropertyInfo = propertyInfo;
41
42 styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/DielectricSpecularControlView"));
43 m_DielectricMaterial = (DielectricSpecularNode.DielectricMaterial)m_PropertyInfo.GetValue(m_Node, null);
44
45 if (propertyInfo.PropertyType != typeof(DielectricSpecularNode.DielectricMaterial))
46 throw new ArgumentException("Property must be of type DielectricMaterial.", "propertyInfo");
47
48 var enumPanel = new VisualElement { name = "enumPanel" };
49 enumPanel.Add(new Label("Material"));
50 var enumField = new EnumField(m_DielectricMaterial.type);
51 enumField.RegisterValueChangedCallback(OnEnumChanged);
52 enumPanel.Add(enumField);
53 Add(enumPanel);
54
55 m_RangePanel = new VisualElement { name = "sliderPanel" };
56 m_RangePanel.Add(new Label("Range"));
57 m_RangeSlider = new Slider(0.01f, 1) { value = m_DielectricMaterial.range };
58 m_RangeSlider.RegisterValueChangedCallback((evt) => OnChangeRangeSlider(evt.newValue));
59
60 m_RangePanel.Add(m_RangeSlider);
61 m_RangeField = AddField(m_RangePanel, m_RangeSlider, 0, m_DielectricMaterial);
62 m_RangePanel.SetEnabled(m_DielectricMaterial.type == DielectricMaterialType.Common);
63 Add(m_RangePanel);
64
65 m_IORPanel = new VisualElement { name = "sliderPanel" };
66 m_IORPanel.Add(new Label("IOR"));
67 m_IORSlider = new Slider(1, 2.5f) { value = m_DielectricMaterial.indexOfRefraction };
68 m_IORSlider.RegisterValueChangedCallback((evt) => OnChangeIORSlider(evt.newValue));
69
70 m_IORPanel.Add(m_IORSlider);
71 m_IORField = AddField(m_IORPanel, m_IORSlider, 1, m_DielectricMaterial);
72 m_IORPanel.SetEnabled(m_DielectricMaterial.type == DielectricMaterialType.Custom);
73 Add(m_IORPanel);
74 }
75
76 void OnEnumChanged(ChangeEvent<Enum> evt)
77 {
78 if (!evt.newValue.Equals(m_DielectricMaterial.type))
79 {
80 m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
81 m_DielectricMaterial.type = (DielectricMaterialType)evt.newValue;
82 m_PropertyInfo.SetValue(m_Node, m_DielectricMaterial, null);
83
84 switch (m_DielectricMaterial.type)
85 {
86 case DielectricMaterialType.Common:
87 m_RangePanel.SetEnabled(true);
88 m_IORPanel.SetEnabled(false);
89 break;
90 case DielectricMaterialType.Custom:
91 m_RangePanel.SetEnabled(false);
92 m_IORPanel.SetEnabled(true);
93 break;
94 default:
95 m_RangePanel.SetEnabled(false);
96 m_IORPanel.SetEnabled(false);
97 break;
98 }
99 }
100 }
101
102 void OnChangeRangeSlider(float newValue)
103 {
104 m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change");
105 m_DielectricMaterial.range = newValue;
106 m_PropertyInfo.SetValue(m_Node, m_DielectricMaterial, null);
107 if (m_RangeField != null)
108 m_RangeField.value = newValue;
109 this.MarkDirtyRepaint();
110 }
111
112 void OnChangeIORSlider(float newValue)
113 {
114 m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change");
115 m_DielectricMaterial.indexOfRefraction = newValue;
116 m_PropertyInfo.SetValue(m_Node, m_DielectricMaterial, null);
117 if (m_IORField != null)
118 m_IORField.value = newValue;
119 this.MarkDirtyRepaint();
120 }
121
122 FloatField AddField(VisualElement panel, Slider slider, int index, DielectricSpecularNode.DielectricMaterial initMaterial)
123 {
124 float initValue;
125 if (index == 1)
126 initValue = initMaterial.indexOfRefraction;
127 else
128 initValue = initMaterial.range;
129
130 var field = new FloatField { userData = index, value = initValue };
131
132 field.RegisterCallback<MouseDownEvent>(Repaint);
133 field.RegisterCallback<MouseMoveEvent>(Repaint);
134 field.RegisterValueChangedCallback(evt =>
135 {
136 var fieldValue = (float)evt.newValue;
137 if (index == 1)
138 m_DielectricMaterial.indexOfRefraction = fieldValue;
139 else
140 m_DielectricMaterial.range = fieldValue;
141
142 m_PropertyInfo.SetValue(m_Node, m_DielectricMaterial, null);
143 this.MarkDirtyRepaint();
144 });
145 field.Q("unity-text-input").RegisterCallback<FocusOutEvent>(evt =>
146 {
147 if (index == 1)
148 RedrawIORControls(m_DielectricMaterial.indexOfRefraction);
149 else
150 RedrawRangeControls(m_DielectricMaterial.range);
151
152 this.MarkDirtyRepaint();
153 }, TrickleDown.TrickleDown);
154 panel.Add(field);
155 return field;
156 }
157
158 void RedrawRangeControls(float value)
159 {
160 value = Mathf.Max(Mathf.Min(value, 1), 0.01f);
161 m_RangePanel.Remove(m_RangeSlider);
162 m_RangeSlider = new Slider(0.01f, 1) { value = value };
163 m_RangeSlider.RegisterValueChangedCallback((evt) => OnChangeRangeSlider(evt.newValue));
164 m_RangePanel.Add(m_RangeSlider);
165 m_RangePanel.Remove(m_RangeField);
166 m_RangeField.value = value;
167 m_RangePanel.Add(m_RangeField);
168 }
169
170 void RedrawIORControls(float value)
171 {
172 value = Mathf.Max(Mathf.Min(value, 5), 1);
173 m_IORPanel.Remove(m_IORSlider);
174 m_IORSlider = new Slider(1, 2.5f) { value = value };
175 m_IORSlider.RegisterValueChangedCallback((evt) => OnChangeIORSlider(evt.newValue));
176
177 m_IORPanel.Add(m_IORSlider);
178 m_IORPanel.Remove(m_IORField);
179 m_IORField.value = value;
180 m_IORPanel.Add(m_IORField);
181 }
182
183 void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new()
184 {
185 evt.StopPropagation();
186 this.MarkDirtyRepaint();
187 }
188 }
189}