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.
169 lines
6.0 KiB
169 lines
6.0 KiB
using System; |
|
using System.Reflection; |
|
using UnityEngine; |
|
using UnityEditor.Graphing; |
|
using System.Globalization; |
|
using UnityEditor.UIElements; |
|
using UnityEngine.UIElements; |
|
|
|
|
|
namespace UnityEditor.ShaderGraph.Drawing.Controls |
|
{ |
|
[AttributeUsage(AttributeTargets.Property)] |
|
class SliderControlAttribute : Attribute, IControlAttribute |
|
{ |
|
string m_Label; |
|
bool m_DisplayMinMax; |
|
|
|
public SliderControlAttribute(string label = null, bool displayMinMax = false) |
|
{ |
|
m_Label = label; |
|
m_DisplayMinMax = displayMinMax; |
|
} |
|
|
|
public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo) |
|
{ |
|
return new SliderControlView(m_Label, m_DisplayMinMax, node, propertyInfo); |
|
} |
|
} |
|
|
|
class SliderControlView : VisualElement, AbstractMaterialNodeModificationListener |
|
{ |
|
AbstractMaterialNode m_Node; |
|
PropertyInfo m_PropertyInfo; |
|
bool m_DisplayMinMax; |
|
Vector3 m_Value; |
|
|
|
VisualElement m_SliderPanel; |
|
Slider m_Slider; |
|
FloatField m_SliderInput; |
|
FloatField m_MinField; |
|
FloatField m_MaxField; |
|
|
|
public SliderControlView(string label, bool displayMinMax, AbstractMaterialNode node, PropertyInfo propertyInfo) |
|
{ |
|
m_Node = node; |
|
m_PropertyInfo = propertyInfo; |
|
styleSheets.Add(Resources.Load<StyleSheet>("Styles/Controls/SliderControlView")); |
|
m_DisplayMinMax = displayMinMax; |
|
|
|
if (propertyInfo.PropertyType != typeof(Vector3)) |
|
throw new ArgumentException("Property must be of type Vector3.", "propertyInfo"); |
|
new GUIContent(label ?? ObjectNames.NicifyVariableName(propertyInfo.Name)); |
|
m_Value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
|
|
m_Slider = new Slider(m_Value.y, m_Value.z) { value = m_Value.x }; |
|
m_Slider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue)); |
|
|
|
m_SliderInput = new FloatField { value = m_Value.x }; |
|
m_SliderInput.RegisterValueChangedCallback(evt => |
|
{ |
|
var value = (float)evt.newValue; |
|
m_Value.x = value; |
|
m_PropertyInfo.SetValue(m_Node, m_Value, null); |
|
this.MarkDirtyRepaint(); |
|
}); |
|
m_SliderInput.Q("unity-text-input").RegisterCallback<FocusOutEvent>(evt => |
|
{ |
|
float minValue = Mathf.Min(m_Value.x, m_Value.y); |
|
float maxValue = Mathf.Max(m_Value.x, m_Value.z); |
|
m_Value = new Vector3(m_Value.x, minValue, maxValue); |
|
m_MinField.value = minValue; |
|
m_MaxField.value = maxValue; |
|
UpdateSlider(); |
|
m_PropertyInfo.SetValue(m_Node, m_Value, null); |
|
this.MarkDirtyRepaint(); |
|
}); |
|
|
|
m_SliderPanel = new VisualElement { name = "SliderPanel" }; |
|
if (!string.IsNullOrEmpty(label)) |
|
m_SliderPanel.Add(new Label(label)); |
|
|
|
m_SliderPanel.Add(m_Slider); |
|
m_SliderPanel.Add(m_SliderInput); |
|
Add(m_SliderPanel); |
|
|
|
if (m_DisplayMinMax) |
|
{ |
|
var fieldsPanel = new VisualElement { name = "FieldsPanel" }; |
|
m_MinField = AddMinMaxField(fieldsPanel, "Min", 1); |
|
m_MaxField = AddMinMaxField(fieldsPanel, "Max", 2); |
|
Add(fieldsPanel); |
|
} |
|
} |
|
|
|
public void OnNodeModified(ModificationScope scope) |
|
{ |
|
if (scope == ModificationScope.Graph) |
|
{ |
|
this.MarkDirtyRepaint(); |
|
} |
|
} |
|
|
|
void OnChangeSlider(float newValue) |
|
{ |
|
m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change"); |
|
var value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
value.x = newValue; |
|
m_PropertyInfo.SetValue(m_Node, value, null); |
|
if (m_SliderInput != null) |
|
m_SliderInput.value = newValue; |
|
m_PropertyInfo.SetValue(m_Node, m_Value, null); |
|
this.MarkDirtyRepaint(); |
|
} |
|
|
|
void UpdateSlider() |
|
{ |
|
m_SliderPanel.Remove(m_Slider); |
|
m_Slider = new Slider(m_Value.y, m_Value.z) { value = m_Value.x }; |
|
m_Slider.RegisterValueChangedCallback((evt) => OnChangeSlider(evt.newValue)); |
|
m_SliderPanel.Add(m_Slider); |
|
m_SliderPanel.Add(m_SliderInput); |
|
} |
|
|
|
FloatField AddMinMaxField(VisualElement panel, string label, int index) |
|
{ |
|
var floatField = new FloatField { value = m_Value[index] }; |
|
if (label != null) |
|
{ |
|
var labelField = new Label(label); |
|
panel.Add(labelField); |
|
} |
|
|
|
floatField.RegisterValueChangedCallback(evt => |
|
{ |
|
m_Value[index] = (float)evt.newValue; |
|
m_PropertyInfo.SetValue(m_Node, m_Value, null); |
|
this.MarkDirtyRepaint(); |
|
}); |
|
floatField.Q("unity-text-input").RegisterCallback<FocusOutEvent>(evt => |
|
{ |
|
if (index == 1) |
|
{ |
|
m_Value[index] = Mathf.Min(m_Value[index], m_Value.z); |
|
m_MinField.value = m_Value[index]; |
|
} |
|
else |
|
{ |
|
m_Value[index] = Mathf.Max(m_Value[index], m_Value.y); |
|
m_MaxField.value = m_Value[index]; |
|
} |
|
float newValue = Mathf.Max(Mathf.Min(m_Value.x, m_Value.z), m_Value.y); |
|
m_Value.x = newValue; |
|
m_SliderInput.value = newValue; |
|
UpdateSlider(); |
|
m_PropertyInfo.SetValue(m_Node, m_Value, null); |
|
this.MarkDirtyRepaint(); |
|
}); |
|
|
|
panel.Add(floatField); |
|
return floatField; |
|
} |
|
|
|
void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new() |
|
{ |
|
evt.StopPropagation(); |
|
this.MarkDirtyRepaint(); |
|
} |
|
} |
|
}
|
|
|