ChannelMixerControl.cs 7.7 KB

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