A game about forced loneliness, made by TACStudios
1using System;
2using System.Reflection;
3using UnityEngine;
4
5using UnityEngine.UIElements;
6
7namespace UnityEditor.ShaderGraph.Drawing.Controls
8{
9 [AttributeUsage(AttributeTargets.Property)]
10 class ChannelMixerControlAttribute : Attribute, IControlAttribute
11 {
12 string m_Label;
13 float m_Minimum;
14 float m_Maximum;
15
16 public ChannelMixerControlAttribute(string label = null, float minimum = -2f, float maximum = 2f)
17 {
18 m_Label = label;
19 m_Minimum = minimum;
20 m_Maximum = maximum;
21 }
22
23 public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
24 {
25 return new ChannelMixerControlView(m_Label, m_Minimum, m_Maximum, node, propertyInfo);
26 }
27 }
28
29 class ChannelMixerControlView : VisualElement
30 {
31 AbstractMaterialNode m_Node;
32 PropertyInfo m_PropertyInfo;
33 ChannelMixerNode.ChannelMixer m_ChannelMixer;
34 int m_OutChannel;
35
36 Slider m_RedSlider;
37 Slider m_GreenSlider;
38 Slider m_BlueSlider;
39
40 FloatField m_RedInputField;
41 FloatField m_GreenInputField;
42 FloatField m_BlueInputField;
43
44 float m_Minimum;
45 float m_Maximum;
46 bool m_Initialized;
47
48 public ChannelMixerControlView(string label, float minimum, float maximum, AbstractMaterialNode node, PropertyInfo propertyInfo)
49 {
50 m_Node = node;
51 m_PropertyInfo = propertyInfo;
52 styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/ChannelMixerControlView"));
53 m_ChannelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
54 m_OutChannel = 0;
55
56 m_Minimum = minimum;
57 m_Maximum = maximum;
58
59 if (propertyInfo.PropertyType != typeof(ChannelMixerNode.ChannelMixer))
60 throw new ArgumentException("Property must be of type ChannelMixer.", "propertyInfo");
61 label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
62
63 if (!string.IsNullOrEmpty(label))
64 Add(new Label(label));
65
66 var buttonPanel = new VisualElement { name = "buttonPanel" };
67
68 Action changedOutputRed = () => OnClickButton(0);
69 var outputButtonRed = new Button(changedOutputRed);
70 outputButtonRed.Add(new Label("R"));
71 buttonPanel.Add(outputButtonRed);
72
73 Action changedOutputGreen = () => OnClickButton(1);
74 var outputButtonGreen = new Button(changedOutputGreen);
75 outputButtonGreen.Add(new Label("G"));
76 buttonPanel.Add(outputButtonGreen);
77
78 Action changedOutputBlue = () => OnClickButton(2);
79 var outputButtonBlue = new Button(changedOutputBlue);
80 outputButtonBlue.Add(new Label("B"));
81 buttonPanel.Add(outputButtonBlue);
82
83 Add(buttonPanel);
84
85 var redSliderPanel = new VisualElement { name = "sliderPanel" };
86 redSliderPanel.Add(new Label("R"));
87 Action<float> changedRedIn = (s) => { OnChangeSlider(s, 0); };
88 m_RedSlider = new Slider(m_Minimum, m_Maximum);
89 m_RedSlider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue, 0));
90
91 redSliderPanel.Add(m_RedSlider);
92 m_RedInputField = new FloatField { value = m_ChannelMixer.outRed.x };
93 m_RedInputField.RegisterCallback<ChangeEvent<double>, int>(OnChangeInputField, 0);
94 redSliderPanel.Add(m_RedInputField);
95 Add(redSliderPanel);
96
97 var greenSliderPanel = new VisualElement { name = "sliderPanel" };
98 greenSliderPanel.Add(new Label("G"));
99 m_GreenSlider = new Slider(m_Minimum, m_Maximum);
100 m_GreenSlider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue, 1));
101 greenSliderPanel.Add(m_GreenSlider);
102 m_GreenInputField = new FloatField { value = m_ChannelMixer.outRed.y };
103 m_GreenInputField.RegisterCallback<ChangeEvent<double>, int>(OnChangeInputField, 1);
104 greenSliderPanel.Add(m_GreenInputField);
105 Add(greenSliderPanel);
106
107 var blueSliderPanel = new VisualElement { name = "sliderPanel" };
108 blueSliderPanel.Add(new Label("B"));
109 m_BlueSlider = new Slider(m_Minimum, m_Maximum);
110 m_BlueSlider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue, 2));
111 blueSliderPanel.Add(m_BlueSlider);
112 m_BlueInputField = new FloatField { value = m_ChannelMixer.outRed.z };
113 m_BlueInputField.RegisterCallback<ChangeEvent<double>, int>(OnChangeInputField, 2);
114 blueSliderPanel.Add(m_BlueInputField);
115 Add(blueSliderPanel);
116
117 m_Initialized = true;
118 ResetSliders();
119 }
120
121 void ResetSliders()
122 {
123 Vector3 outputChannel = GetOutputChannel();
124 m_RedSlider.value = outputChannel[0];
125 m_GreenSlider.value = outputChannel[1];
126 m_BlueSlider.value = outputChannel[2];
127 }
128
129 void OnChangeSlider(float value, int inChannel)
130 {
131 if (!m_Initialized)
132 return;
133 m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change");
134 switch (m_OutChannel)
135 {
136 case 1:
137 m_ChannelMixer.outGreen[inChannel] = value;
138 break;
139 case 2:
140 m_ChannelMixer.outBlue[inChannel] = value;
141 break;
142 default:
143 m_ChannelMixer.outRed[inChannel] = value;
144 break;
145 }
146 switch (inChannel)
147 {
148 case 1:
149 m_GreenInputField.value = value;
150 break;
151 case 2:
152 m_BlueInputField.value = value;
153 break;
154 default:
155 m_RedInputField.value = value;
156 break;
157 }
158 m_PropertyInfo.SetValue(m_Node, m_ChannelMixer, null);
159 }
160
161 void OnChangeInputField(ChangeEvent<double> evt, int inChannel)
162 {
163 if (!m_Initialized)
164 return;
165 var value = Mathf.Max(Mathf.Min((float)evt.newValue, m_Maximum), m_Minimum);
166 m_Node.owner.owner.RegisterCompleteObjectUndo("Input Field Change");
167 switch (m_OutChannel)
168 {
169 case 1:
170 m_ChannelMixer.outGreen[inChannel] = value;
171 break;
172 case 2:
173 m_ChannelMixer.outBlue[inChannel] = value;
174 break;
175 default:
176 m_ChannelMixer.outRed[inChannel] = value;
177 break;
178 }
179 switch (inChannel)
180 {
181 case 1:
182 m_GreenSlider.value = value;
183 break;
184 case 2:
185 m_BlueSlider.value = value;
186 break;
187 default:
188 m_RedSlider.value = value;
189 break;
190 }
191 m_PropertyInfo.SetValue(m_Node, m_ChannelMixer, null);
192 this.MarkDirtyRepaint();
193 }
194
195 void OnClickButton(int outChannel)
196 {
197 m_OutChannel = outChannel;
198 ResetSliders();
199 }
200
201 Vector3 GetOutputChannel()
202 {
203 switch (m_OutChannel)
204 {
205 case 1:
206 return m_ChannelMixer.outGreen;
207 case 2:
208 return m_ChannelMixer.outBlue;
209 default:
210 return m_ChannelMixer.outRed;
211 }
212 }
213 }
214}