|
|
|
|
|
|
public class SliderControlAttribute : Attribute, IControlAttribute |
|
|
|
{ |
|
|
|
string m_Label; |
|
|
|
bool m_DisplayMinMax; |
|
|
|
public SliderControlAttribute(string label = null) |
|
|
|
public SliderControlAttribute(string label = null, bool displayMinMax = false) |
|
|
|
m_DisplayMinMax = displayMinMax; |
|
|
|
return new SliderControlView(m_Label, node, propertyInfo); |
|
|
|
return new SliderControlView(m_Label, m_DisplayMinMax, node, propertyInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
AbstractMaterialNode m_Node; |
|
|
|
PropertyInfo m_PropertyInfo; |
|
|
|
IMGUIContainer m_Container; |
|
|
|
bool m_DisplayMinMax; |
|
|
|
int m_UndoGroup = -1; |
|
|
|
Vector3 m_Value; |
|
|
|
public SliderControlView(string label, AbstractMaterialNode node, PropertyInfo propertyInfo) |
|
|
|
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_DisplayMinMax = displayMinMax; |
|
|
|
|
|
|
|
m_Container = new IMGUIContainer(OnGUIHandler); |
|
|
|
Add(m_Container); |
|
|
|
m_Value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
|
|
|
|
|
|
m_SliderPanel = new VisualElement { name = "SliderPanel" }; |
|
|
|
if (!string.IsNullOrEmpty(label)) |
|
|
|
m_SliderPanel.Add(new Label(label)); |
|
|
|
Action<float> changedSlider = (s) => { OnChangeSlider(s); }; |
|
|
|
m_Slider = new Slider(m_Value.y, m_Value.z, changedSlider); |
|
|
|
m_Slider.value = m_Value.x; |
|
|
|
m_SliderPanel.Add(m_Slider); |
|
|
|
m_SliderInput = AddField(m_SliderPanel, "", 0, m_Value); |
|
|
|
Add(m_SliderPanel); |
|
|
|
|
|
|
|
if(m_DisplayMinMax) |
|
|
|
{ |
|
|
|
var fieldsPanel = new VisualElement { name = "FieldsPanel" }; |
|
|
|
m_MinField = AddField(fieldsPanel, "Min", 1, m_Value); |
|
|
|
m_MaxField = AddField(fieldsPanel, "Max", 2, m_Value); |
|
|
|
Add(fieldsPanel); |
|
|
|
} |
|
|
|
m_Container.Dirty(ChangeType.Repaint); |
|
|
|
{ |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
} |
|
|
|
void OnGUIHandler() |
|
|
|
void OnChangeSlider(float newValue) |
|
|
|
m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change"); |
|
|
|
value.x = newValue; |
|
|
|
m_PropertyInfo.SetValue(m_Node, value, null); |
|
|
|
if(m_SliderInput != null) |
|
|
|
m_SliderInput.value = newValue; |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
} |
|
|
|
|
|
|
|
FloatField AddField(VisualElement panel, string label, int index, Vector3 initValiue) |
|
|
|
{ |
|
|
|
var field = new FloatField { userData = index, value = initValiue[index] }; |
|
|
|
|
|
|
|
if(label != "") |
|
|
|
{ |
|
|
|
var l = new Label(label); |
|
|
|
panel.Add(l); |
|
|
|
var dragger = new FieldMouseDragger<double>(field); |
|
|
|
dragger.SetDragZone(l); |
|
|
|
} |
|
|
|
|
|
|
|
field.RegisterCallback<MouseDownEvent>(Repaint); |
|
|
|
field.RegisterCallback<MouseMoveEvent>(Repaint); |
|
|
|
field.OnValueChanged(evt => |
|
|
|
{ |
|
|
|
var value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
|
|
value[index] = (float)evt.newValue; |
|
|
|
m_PropertyInfo.SetValue(m_Node, value, null); |
|
|
|
m_UndoGroup = -1; |
|
|
|
UpdateSlider(m_SliderPanel, index, value); |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
}); |
|
|
|
field.RegisterCallback<InputEvent>(evt => |
|
|
|
{ |
|
|
|
if (m_UndoGroup == -1) |
|
|
|
{ |
|
|
|
m_UndoGroup = Undo.GetCurrentGroup(); |
|
|
|
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name); |
|
|
|
} |
|
|
|
float newValue; |
|
|
|
if (!float.TryParse(evt.newData, out newValue)) |
|
|
|
newValue = 0f; |
|
|
|
var value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
|
|
value[index] = newValue; |
|
|
|
m_PropertyInfo.SetValue(m_Node, value, null); |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
}); |
|
|
|
field.RegisterCallback<KeyDownEvent>(evt => |
|
|
|
{ |
|
|
|
if (evt.keyCode == KeyCode.Escape && m_UndoGroup > -1) |
|
|
|
{ |
|
|
|
Undo.RevertAllDownToGroup(m_UndoGroup); |
|
|
|
m_UndoGroup = -1; |
|
|
|
m_Value = (Vector3)m_PropertyInfo.GetValue(m_Node, null); |
|
|
|
UpdateSlider(m_SliderPanel, index, m_Value); |
|
|
|
evt.StopPropagation(); |
|
|
|
} |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
}); |
|
|
|
panel.Add(field); |
|
|
|
return field; |
|
|
|
} |
|
|
|
using (var changeCheckScope = new EditorGUI.ChangeCheckScope()) |
|
|
|
{ |
|
|
|
var slider = EditorGUILayout.Slider(value.x, value.y, value.z); |
|
|
|
GUILayout.BeginHorizontal(); |
|
|
|
EditorGUIUtility.labelWidth = 32f; |
|
|
|
var minField = EditorGUILayout.FloatField("Min", value.y); |
|
|
|
var maxField = EditorGUILayout.FloatField("Max", value.z); |
|
|
|
GUILayout.EndHorizontal(); |
|
|
|
void UpdateSlider(VisualElement panel, int index, Vector3 value) |
|
|
|
{ |
|
|
|
value.x = Mathf.Max(Mathf.Min(value.x, value.z), value.y); |
|
|
|
panel.Remove(m_Slider); |
|
|
|
Action<float> changedSlider = (s) => { OnChangeSlider(s); }; |
|
|
|
m_Slider = new Slider(value.y, value.z, changedSlider); |
|
|
|
m_Slider.lowValue = value.y; |
|
|
|
m_Slider.highValue = value.z; |
|
|
|
m_Slider.value = value.x; |
|
|
|
panel.Add(m_Slider); |
|
|
|
|
|
|
|
panel.Remove(m_SliderInput); |
|
|
|
if(index != 0) |
|
|
|
m_SliderInput = AddField(panel, "", 0, value); |
|
|
|
m_SliderInput.value = value.x; |
|
|
|
panel.Add(m_SliderInput); |
|
|
|
} |
|
|
|
if (changeCheckScope.changed) |
|
|
|
{ |
|
|
|
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name); |
|
|
|
m_PropertyInfo.SetValue(m_Node, new Vector3(slider, minField, maxField), null); |
|
|
|
} |
|
|
|
} |
|
|
|
void Repaint<T>(MouseEventBase<T> evt) where T : MouseEventBase<T>, new() |
|
|
|
{ |
|
|
|
evt.StopPropagation(); |
|
|
|
Dirty(ChangeType.Repaint); |
|
|
|
} |
|
|
|
} |
|
|
|
} |