No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VectorControl.cs 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Reflection;
  5. using UnityEngine;
  6. using UnityEngine.UIElements;
  7. namespace UnityEditor.ShaderGraph.Drawing.Controls
  8. {
  9. [AttributeUsage(AttributeTargets.Property)]
  10. class MultiFloatControlAttribute : Attribute, IControlAttribute
  11. {
  12. string m_Label;
  13. string m_SubLabel1;
  14. string m_SubLabel2;
  15. string m_SubLabel3;
  16. string m_SubLabel4;
  17. public MultiFloatControlAttribute(string label = null, string subLabel1 = "X", string subLabel2 = "Y", string subLabel3 = "Z", string subLabel4 = "W")
  18. {
  19. m_SubLabel1 = subLabel1;
  20. m_SubLabel2 = subLabel2;
  21. m_SubLabel3 = subLabel3;
  22. m_SubLabel4 = subLabel4;
  23. m_Label = label;
  24. }
  25. public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
  26. {
  27. if (!MultiFloatControlView.validTypes.Contains(propertyInfo.PropertyType))
  28. return null;
  29. return new MultiFloatControlView(m_Label, m_SubLabel1, m_SubLabel2, m_SubLabel3, m_SubLabel4, node, propertyInfo);
  30. }
  31. }
  32. class MultiFloatControlView : VisualElement
  33. {
  34. public static Type[] validTypes = { typeof(float), typeof(Vector2), typeof(Vector3), typeof(Vector4) };
  35. AbstractMaterialNode m_Node;
  36. PropertyInfo m_PropertyInfo;
  37. Vector4 m_Value;
  38. int m_UndoGroup = -1;
  39. public MultiFloatControlView(string label, string subLabel1, string subLabel2, string subLabel3, string subLabel4, AbstractMaterialNode node, PropertyInfo propertyInfo)
  40. {
  41. var components = Array.IndexOf(validTypes, propertyInfo.PropertyType) + 1;
  42. if (components == -1)
  43. throw new ArgumentException("Property must be of type float, Vector2, Vector3 or Vector4.", "propertyInfo");
  44. styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/MultiFloatControlView"));
  45. m_Node = node;
  46. m_PropertyInfo = propertyInfo;
  47. label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
  48. if (!string.IsNullOrEmpty(label))
  49. Add(new Label(label));
  50. m_Value = GetValue();
  51. AddField(0, subLabel1);
  52. if (components > 1)
  53. AddField(1, subLabel2);
  54. if (components > 2)
  55. AddField(2, subLabel3);
  56. if (components > 3)
  57. AddField(3, subLabel4);
  58. }
  59. void AddField(int index, string subLabel)
  60. {
  61. var dummy = new VisualElement { name = "dummy" };
  62. var label = new Label(subLabel);
  63. dummy.Add(label);
  64. Add(dummy);
  65. var field = new FloatField { userData = index, value = m_Value[index] };
  66. var dragger = new FieldMouseDragger<double>(field);
  67. dragger.SetDragZone(label);
  68. field.RegisterCallback<MouseDownEvent>(Repaint);
  69. field.RegisterCallback<MouseMoveEvent>(Repaint);
  70. field.RegisterValueChangedCallback(evt =>
  71. {
  72. var value = GetValue();
  73. value[index] = (float)evt.newValue;
  74. SetValue(value);
  75. m_UndoGroup = -1;
  76. this.MarkDirtyRepaint();
  77. });
  78. field.Q("unity-text-input").RegisterCallback<InputEvent>(evt =>
  79. {
  80. if (m_UndoGroup == -1)
  81. {
  82. m_UndoGroup = Undo.GetCurrentGroup();
  83. m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
  84. }
  85. float newValue;
  86. if (!float.TryParse(evt.newData, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out newValue))
  87. newValue = 0f;
  88. var value = GetValue();
  89. value[index] = newValue;
  90. SetValue(value);
  91. this.MarkDirtyRepaint();
  92. }, TrickleDown.TrickleDown);
  93. field.Q("unity-text-input").RegisterCallback<KeyDownEvent>(evt =>
  94. {
  95. if (evt.keyCode == KeyCode.Escape && m_UndoGroup > -1)
  96. {
  97. Undo.RevertAllDownToGroup(m_UndoGroup);
  98. m_UndoGroup = -1;
  99. m_Value = GetValue();
  100. evt.StopPropagation();
  101. }
  102. this.MarkDirtyRepaint();
  103. }, TrickleDown.TrickleDown);
  104. Add(field);
  105. }
  106. object ValueToPropertyType(Vector4 value)
  107. {
  108. if (m_PropertyInfo.PropertyType == typeof(float))
  109. return value.x;
  110. if (m_PropertyInfo.PropertyType == typeof(Vector2))
  111. return (Vector2)value;
  112. if (m_PropertyInfo.PropertyType == typeof(Vector3))
  113. return (Vector3)value;
  114. return value;
  115. }
  116. Vector4 GetValue()
  117. {
  118. var value = m_PropertyInfo.GetValue(m_Node, null);
  119. if (m_PropertyInfo.PropertyType == typeof(float))
  120. return new Vector4((float)value, 0f, 0f, 0f);
  121. if (m_PropertyInfo.PropertyType == typeof(Vector2))
  122. return (Vector2)value;
  123. if (m_PropertyInfo.PropertyType == typeof(Vector3))
  124. return (Vector3)value;
  125. return (Vector4)value;
  126. }
  127. void SetValue(Vector4 value)
  128. {
  129. m_PropertyInfo.SetValue(m_Node, ValueToPropertyType(value), null);
  130. }
  131. void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new()
  132. {
  133. evt.StopPropagation();
  134. this.MarkDirtyRepaint();
  135. }
  136. }
  137. }