using System; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace UIWidgets { [RequireComponent(typeof(RectTransform))] public class RangeSliderHandle : Selectable, IDragHandler, IInitializePotentialDragHandler, ISubmitHandler, IEventSystemHandler { public Func IsHorizontal = ReturnTrue; public Action Decrease = DoNothing; public Action Increase = DoNothing; public Func PositionLimits; public Action PositionChanged; public Action OnSubmit = DoNothing; private RectTransform rectTransform; public RectTransform RectTransform { get { if (rectTransform == null) { rectTransform = base.transform as RectTransform; } return rectTransform; } } private bool CanDrag(PointerEventData eventData) { return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left; } private static bool ReturnTrue() { return true; } private static void DoNothing() { } void ISubmitHandler.OnSubmit(BaseEventData eventData) { OnSubmit(); } public virtual void OnDrag(PointerEventData eventData) { Vector2 localPoint; if (CanDrag(eventData) && RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position, eventData.pressEventCamera, out localPoint)) { Vector2 vector = PositionLimits(); Vector3 vector2 = RectTransform.anchoredPosition; if (IsHorizontal()) { vector2.x = Mathf.Clamp(vector2.x + localPoint.x, vector.x, vector.y); } else { vector2.y = Mathf.Clamp(vector2.y + localPoint.y, vector.x, vector.y); } if (IsNewPosition(vector2)) { RectTransform.anchoredPosition = vector2; PositionChanged((!IsHorizontal()) ? vector2.y : vector2.x); } } } private bool IsNewPosition(Vector3 pos) { if (IsHorizontal()) { return RectTransform.anchoredPosition.x != pos.x; } return RectTransform.anchoredPosition.y != pos.y; } public virtual void OnInitializePotentialDrag(PointerEventData eventData) { eventData.useDragThreshold = false; } public override void OnMove(AxisEventData eventData) { if (!IsActive() || !IsInteractable()) { base.OnMove(eventData); return; } switch (eventData.moveDir) { case MoveDirection.Left: if (IsHorizontal() && FindSelectableOnLeft() == null) { Decrease(); } else { base.OnMove(eventData); } break; case MoveDirection.Right: if (IsHorizontal() && FindSelectableOnRight() == null) { Increase(); } else { base.OnMove(eventData); } break; case MoveDirection.Up: if (!IsHorizontal() && FindSelectableOnUp() == null) { Increase(); } else { base.OnMove(eventData); } break; case MoveDirection.Down: if (!IsHorizontal() && FindSelectableOnDown() == null) { Decrease(); } else { base.OnMove(eventData); } break; } } public override Selectable FindSelectableOnLeft() { if (base.navigation.mode == Navigation.Mode.Automatic && IsHorizontal()) { return null; } return base.FindSelectableOnLeft(); } public override Selectable FindSelectableOnRight() { if (base.navigation.mode == Navigation.Mode.Automatic && IsHorizontal()) { return null; } return base.FindSelectableOnRight(); } public override Selectable FindSelectableOnUp() { if (base.navigation.mode == Navigation.Mode.Automatic && !IsHorizontal()) { return null; } return base.FindSelectableOnUp(); } public override Selectable FindSelectableOnDown() { if (base.navigation.mode == Navigation.Mode.Automatic && !IsHorizontal()) { return null; } return base.FindSelectableOnDown(); } } }