10 [RequireComponent(typeof(RectTransform))]
11 [AddComponentMenu(
"UI/Extensions/BoxSlider")]
12 public class BoxSlider : Selectable, IDragHandler, IInitializePotentialDragHandler, ICanvasElement
26 private RectTransform m_HandleRect;
27 public RectTransform
HandleRect {
get {
return m_HandleRect; }
set {
if (SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } }
32 private float m_MinValue = 0;
33 public float MinValue {
get {
return m_MinValue; }
set {
if (SetStruct(ref m_MinValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
36 private float m_MaxValue = 1;
37 public float MaxValue {
get {
return m_MaxValue; }
set {
if (SetStruct(ref m_MaxValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
40 private bool m_WholeNumbers =
false;
41 public bool WholeNumbers {
get {
return m_WholeNumbers; }
set {
if (SetStruct(ref m_WholeNumbers, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
44 private float m_ValueX = 1f;
50 return Mathf.Round(m_ValueX);
74 private float m_ValueY = 1f;
80 return Mathf.Round(m_ValueY);
107 private BoxSliderEvent m_OnValueChanged =
new BoxSliderEvent();
112 private Transform m_HandleTransform;
113 private RectTransform m_HandleContainerRect;
116 private Vector2 m_Offset = Vector2.zero;
118 private DrivenRectTransformTracker m_Tracker;
127 protected override void OnValidate()
133 m_MinValue = Mathf.Round(m_MinValue);
134 m_MaxValue = Mathf.Round(m_MaxValue);
136 UpdateCachedReferences();
137 SetX(m_ValueX,
false);
138 SetY(m_ValueY,
false);
140 if(!Application.isPlaying) UpdateVisuals();
142#if UNITY_2018_3_OR_NEWER
143 if (!Application.isPlaying)
145 var prefabType =
UnityEditor.PrefabUtility.GetPrefabType(
this);
146 if (prefabType !=
UnityEditor.PrefabType.Prefab && !Application.isPlaying)
149 CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(
this);
155 public virtual void Rebuild(CanvasUpdate executing)
158 if (executing == CanvasUpdate.Prelayout)
173 public static bool SetClass<T>(ref T currentValue, T newValue) where T :
class
175 if ((currentValue ==
null && newValue ==
null) || (currentValue !=
null && currentValue.Equals(newValue)))
178 currentValue = newValue;
182 public static bool SetStruct<T>(ref T currentValue, T newValue) where T :
struct
184 if (currentValue.Equals(newValue))
187 currentValue = newValue;
194 UpdateCachedReferences();
195 SetX(m_ValueX,
false);
196 SetY(m_ValueY,
false);
207 void UpdateCachedReferences()
212 m_HandleTransform = m_HandleRect.transform;
213 if (m_HandleTransform.parent !=
null)
214 m_HandleContainerRect = m_HandleTransform.parent.GetComponent<RectTransform>();
218 m_HandleContainerRect =
null;
223 void SetX(
float input)
228 void SetX(
float input,
bool sendCallback)
233 newValue = Mathf.Round(newValue);
236 if (m_ValueX == newValue)
242 m_OnValueChanged.Invoke(newValue,
ValueY);
245 void SetY(
float input)
250 void SetY(
float input,
bool sendCallback)
255 newValue = Mathf.Round(newValue);
258 if (m_ValueY == newValue)
264 m_OnValueChanged.Invoke(
ValueX, newValue);
270 base.OnRectTransformDimensionsChange();
282 private void UpdateVisuals()
285 if (!Application.isPlaying)
286 UpdateCachedReferences();
293 if (m_HandleContainerRect !=
null)
295 m_Tracker.Add(
this, m_HandleRect, DrivenTransformProperties.Anchors);
296 Vector2 anchorMin = Vector2.zero;
297 Vector2 anchorMax = Vector2.one;
301 if (Application.isPlaying)
303 m_HandleRect.anchorMin = anchorMin;
304 m_HandleRect.anchorMax = anchorMax;
311 void UpdateDrag(PointerEventData eventData, Camera cam)
313 RectTransform clickRect = m_HandleContainerRect;
314 if (clickRect !=
null && clickRect.rect.size[0] > 0)
317 if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, eventData.position, cam, out localCursor))
319 localCursor -= clickRect.rect.position;
321 float val = Mathf.Clamp01((localCursor - m_Offset)[0] / clickRect.rect.size[0]);
324 float valY = Mathf.Clamp01((localCursor - m_Offset)[1] / clickRect.rect.size[1]);
330 private bool CanDrag(PointerEventData eventData)
332 return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left;
337 if (!CanDrag(eventData))
340 base.OnPointerDown(eventData);
342 m_Offset = Vector2.zero;
343 if (m_HandleContainerRect !=
null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera))
345 Vector2 localMousePos;
346 if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos))
347 m_Offset = localMousePos;
348 m_Offset.y = -m_Offset.y;
353 UpdateDrag(eventData, eventData.pressEventCamera);
357 public virtual void OnDrag(PointerEventData eventData)
359 if (!CanDrag(eventData))
362 UpdateDrag(eventData, eventData.pressEventCamera);
367 eventData.useDragThreshold =
false;
virtual void OnInitializePotentialDrag(PointerEventData eventData)
void GraphicUpdateComplete()
override void OnPointerDown(PointerEventData eventData)
static bool SetClass< T >(ref T currentValue, T newValue)
virtual void OnDrag(PointerEventData eventData)
override void OnDisable()
virtual void Rebuild(CanvasUpdate executing)
BoxSliderEvent OnValueChanged
static bool SetStruct< T >(ref T currentValue, T newValue)
override void OnRectTransformDimensionsChange()
Credit Erdener Gonenc - @PixelEnvision.