2 using UnityEngine.UIElements;
3 using UnityEditor.UIElements;
6 namespace UnityEditor.VFX.UIElements
8 //Copied from mousefield dragger but add notifications needed for delayed fields
9 public class VFXFieldMouseDragger<T>
11 Action m_OnDragFinished;
12 public VFXFieldMouseDragger(IValueField<T> drivenField, Action onDragFinished = null)
14 m_DrivenField = drivenField;
16 m_DragHotZone = new Rect(0, 0, -1, -1);
17 m_OnDragFinished = onDragFinished;
21 IValueField<T> m_DrivenField;
22 VisualElement m_DragElement;
28 public void SetDragZone(VisualElement dragElement)
30 SetDragZone(dragElement, new Rect(0, 0, -1, -1));
33 public void SetDragZone(VisualElement dragElement, Rect hotZone)
35 if (m_DragElement != null)
37 m_DragElement.UnregisterCallback<MouseDownEvent>(UpdateValueOnMouseDown);
38 m_DragElement.UnregisterCallback<MouseMoveEvent>(UpdateValueOnMouseMove);
39 m_DragElement.UnregisterCallback<MouseUpEvent>(UpdateValueOnMouseUp);
40 m_DragElement.UnregisterCallback<KeyDownEvent>(UpdateValueOnKeyDown);
43 m_DragElement = dragElement;
44 m_DragHotZone = hotZone;
46 if (m_DragElement != null)
49 m_DragElement.RegisterCallback<MouseDownEvent>(UpdateValueOnMouseDown);
50 m_DragElement.RegisterCallback<MouseMoveEvent>(UpdateValueOnMouseMove);
51 m_DragElement.RegisterCallback<MouseUpEvent>(UpdateValueOnMouseUp);
52 m_DragElement.RegisterCallback<KeyDownEvent>(UpdateValueOnKeyDown);
56 void UpdateValueOnMouseDown(MouseDownEvent evt)
58 if (evt.button == 0 && (m_DragHotZone.width < 0 || m_DragHotZone.height < 0 || m_DragHotZone.Contains(m_DragElement.WorldToLocal(evt.mousePosition))))
60 m_DragElement.CaptureMouse();
62 // Make sure no other elements can capture the mouse!
63 evt.StopPropagation();
66 startValue = m_DrivenField.value;
68 EditorGUIUtility.SetWantsMouseJumping(1);
72 void UpdateValueOnMouseMove(MouseMoveEvent evt)
76 DeltaSpeed s = evt.shiftKey ? DeltaSpeed.Fast : (evt.altKey ? DeltaSpeed.Slow : DeltaSpeed.Normal);
77 m_DrivenField.ApplyInputDeviceDelta(evt.mouseDelta, s, startValue);
81 void UpdateValueOnMouseUp(MouseUpEvent evt)
86 MouseCaptureController.ReleaseMouse();
87 EditorGUIUtility.SetWantsMouseJumping(0);
88 if (m_OnDragFinished != null)
93 void UpdateValueOnKeyDown(KeyDownEvent evt)
95 if (dragging && evt.keyCode == KeyCode.Escape)
98 m_DrivenField.value = startValue;
99 MouseCaptureController.ReleaseMouse();
100 EditorGUIUtility.SetWantsMouseJumping(0);
104 class VFXLabeledField<T, U> : VisualElement, INotifyValueChanged<U> where T : VisualElement, INotifyValueChanged<U>, new()
106 protected Label m_Label;
107 protected T m_Control;
109 public VisualElement m_IndeterminateLabel;
111 public VFXLabeledField(Label existingLabel)
113 m_Label = existingLabel;
119 bool m_Indeterminate;
121 public bool indeterminate
123 get {return m_Control.parent == null; }
127 if (m_Indeterminate != value)
129 m_Indeterminate = value;
132 m_Control.RemoveFromHierarchy();
133 Add(m_IndeterminateLabel);
137 m_IndeterminateLabel.RemoveFromHierarchy();
144 public VFXLabeledField(string label)
146 if (!string.IsNullOrEmpty(label))
148 m_Label = new Label() { text = label };
149 m_Label.AddToClassList("label");
153 style.flexDirection = FlexDirection.Row;
161 if (typeof(IValueField<U>).IsAssignableFrom(typeof(T)))
163 m_Label.styleSheets.Add(Resources.Load<StyleSheet>("VFXLabeledField"));
164 if (typeof(U) == typeof(float))
166 var dragger = new VFXFieldMouseDragger<float>((IValueField<float>)m_Control, DragValueFinished);
167 dragger.SetDragZone(m_Label);
168 m_Label.AddToClassList("cursor-slide-arrow");
170 else if (typeof(U) == typeof(double))
172 var dragger = new VFXFieldMouseDragger<double>((IValueField<double>)m_Control, DragValueFinished);
173 dragger.SetDragZone(m_Label);
174 m_Label.AddToClassList("cursor-slide-arrow");
176 else if (typeof(U) == typeof(long))
178 var dragger = new VFXFieldMouseDragger<long>((IValueField<long>)m_Control, DragValueFinished);
179 dragger.SetDragZone(m_Label);
180 m_Label.AddToClassList("cursor-slide-arrow");
182 else if (typeof(U) == typeof(int))
184 var dragger = new VFXFieldMouseDragger<int>((IValueField<int>)m_Control, DragValueFinished);
185 dragger.SetDragZone(m_Label);
186 m_Label.AddToClassList("cursor-slide-arrow");
190 m_IndeterminateLabel = new Label()
192 name = "indeterminate",
193 text = VFXControlConstants.indeterminateText
195 m_IndeterminateLabel.SetEnabled(false);
198 void DragValueFinished()
200 if (onValueDragFinished != null)
201 onValueDragFinished(this);
204 public Action<VFXLabeledField<T, U>> onValueDragFinished;
211 m_Control.RegisterValueChangedCallback(OnControlChange);
214 void OnControlChange(ChangeEvent<U> e)
217 using (ChangeEvent<U> evt = ChangeEvent<U>.GetPooled(e.previousValue, e.newValue))
226 get { return m_Control; }
231 get { return m_Label; }
234 public void SetValueAndNotify(U newValue)
236 (m_Control as INotifyValueChanged<U>).value = newValue;
239 public void SetValueWithoutNotify(U newValue)
241 (m_Control as INotifyValueChanged<U>).SetValueWithoutNotify(newValue);
246 get { return m_Control.value; }
247 set { m_Control.value = value; }
251 abstract class ValueControl<T> : VisualElement
253 protected Label m_Label;
255 protected ValueControl(Label existingLabel)
257 m_Label = existingLabel;
260 protected ValueControl(string label)
262 if (!string.IsNullOrEmpty(label))
264 m_Label = new Label() { text = label };
265 m_Label.AddToClassList("label");
269 style.flexDirection = FlexDirection.Row;
277 public void SetValue(T value)
285 get { return GetValue(); }
286 set { SetValue(value); }
289 public void SetMultiplier(T multiplier)
291 m_Multiplier = multiplier;
295 protected T m_Multiplier;
297 public System.Action OnValueChanged;
299 protected abstract void ValueToGUI(bool force);