Files
2026-02-21 16:45:37 +08:00

428 lines
9.0 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
namespace UIWidgets
{
public abstract class RangeSliderBase<T> : MonoBehaviour, IPointerClickHandler, IEventSystemHandler where T : struct
{
[Serializable]
public class OnChangeEvent : UnityEvent<T, T>
{
}
[SerializeField]
protected T valueMin;
[SerializeField]
protected T valueMax;
[SerializeField]
protected T step;
[SerializeField]
protected T limitMin;
[SerializeField]
protected T limitMax;
[SerializeField]
protected RangeSliderHandle handleMin;
protected RectTransform handleMinRect;
[SerializeField]
protected RangeSliderHandle handleMax;
protected RectTransform handleMaxRect;
[SerializeField]
protected RectTransform UsableRangeRect;
[SerializeField]
protected RectTransform FillRect;
protected RectTransform rangeSliderRect;
public OnChangeEvent OnValuesChange = new OnChangeEvent();
public UnityEvent OnChange = new UnityEvent();
public bool WholeNumberOfSteps;
private bool initCalled;
public T ValueMin
{
get
{
return valueMin;
}
set
{
if (!EqualityComparer<T>.Default.Equals(valueMin, InBoundsMin(value)))
{
valueMin = InBoundsMin(value);
UpdateMinHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
}
}
public T ValueMax
{
get
{
return valueMax;
}
set
{
if (!EqualityComparer<T>.Default.Equals(valueMax, InBoundsMax(value)))
{
valueMax = InBoundsMax(value);
UpdateMaxHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
}
}
public T Step
{
get
{
return step;
}
set
{
step = value;
}
}
public T LimitMin
{
get
{
return limitMin;
}
set
{
limitMin = value;
ValueMin = valueMin;
ValueMax = valueMax;
}
}
public T LimitMax
{
get
{
return limitMax;
}
set
{
limitMax = value;
ValueMin = valueMin;
ValueMax = valueMax;
}
}
public RectTransform HandleMinRect
{
get
{
if (handleMin != null && handleMinRect == null)
{
handleMinRect = handleMin.transform as RectTransform;
}
return handleMinRect;
}
}
public RangeSliderHandle HandleMin
{
get
{
return handleMin;
}
set
{
handleMin = value;
handleMinRect = null;
handleMin.IsHorizontal = IsHorizontal;
handleMin.PositionLimits = MinPositionLimits;
handleMin.PositionChanged = UpdateMinValue;
handleMin.OnSubmit = SelectMaxHandle;
handleMin.Increase = IncreaseMin;
handleMin.Decrease = DecreaseMin;
HandleMinRect.anchorMin = new Vector2(0f, 0f);
HandleMinRect.anchorMax = ((!IsHorizontal()) ? new Vector2(1f, 0f) : new Vector2(0f, 1f));
}
}
public RectTransform HandleMaxRect
{
get
{
if (handleMax != null && handleMaxRect == null)
{
handleMaxRect = handleMax.transform as RectTransform;
}
return handleMaxRect;
}
}
public RangeSliderHandle HandleMax
{
get
{
return handleMax;
}
set
{
handleMax = value;
handleMaxRect = null;
handleMax.IsHorizontal = IsHorizontal;
handleMax.PositionLimits = MaxPositionLimits;
handleMax.PositionChanged = UpdateMaxValue;
handleMax.OnSubmit = SelectMinHandle;
handleMax.Increase = IncreaseMax;
handleMax.Decrease = DecreaseMax;
HandleMaxRect.anchorMin = new Vector2(0f, 0f);
HandleMaxRect.anchorMax = ((!IsHorizontal()) ? new Vector2(1f, 0f) : new Vector2(0f, 1f));
}
}
public RectTransform RangeSliderRect
{
get
{
if (rangeSliderRect == null)
{
rangeSliderRect = base.transform as RectTransform;
}
return rangeSliderRect;
}
}
private void Awake()
{
}
private void Init()
{
if (!initCalled)
{
initCalled = true;
HandleMin = handleMin;
HandleMax = handleMax;
UpdateMinHandle();
UpdateMaxHandle();
UpdateFill();
}
}
private void Start()
{
Init();
}
public void SetValue(T min, T max)
{
T x = valueMin;
T x2 = valueMax;
valueMin = min;
valueMax = max;
valueMin = InBoundsMin(valueMin);
valueMax = InBoundsMax(valueMax);
bool flag = EqualityComparer<T>.Default.Equals(x, valueMin);
bool flag2 = EqualityComparer<T>.Default.Equals(x2, valueMax);
if (!flag || !flag2)
{
UpdateMinHandle();
UpdateMaxHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
}
public void SetLimit(T min, T max)
{
T x = valueMin;
T x2 = valueMax;
limitMin = min;
limitMax = max;
valueMin = InBoundsMin(valueMin);
valueMax = InBoundsMax(valueMax);
bool flag = EqualityComparer<T>.Default.Equals(x, valueMin);
bool flag2 = EqualityComparer<T>.Default.Equals(x2, valueMax);
if (!flag || !flag2)
{
UpdateMinHandle();
UpdateMaxHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
}
protected virtual bool IsHorizontal()
{
return true;
}
protected float FillSize()
{
return (!IsHorizontal()) ? UsableRangeRect.rect.height : UsableRangeRect.rect.width;
}
protected float MinHandleSize()
{
if (IsHorizontal())
{
return HandleMinRect.rect.width;
}
return HandleMinRect.rect.height;
}
protected float MaxHandleSize()
{
if (IsHorizontal())
{
return HandleMaxRect.rect.width;
}
return HandleMaxRect.rect.height;
}
protected void UpdateMinValue(float position)
{
valueMin = PositionToValue(position - GetStartPoint());
UpdateMinHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
protected void UpdateMaxValue(float position)
{
valueMax = PositionToValue(position - GetStartPoint());
UpdateMaxHandle();
UpdateFill();
OnValuesChange.Invoke(valueMin, valueMax);
OnChange.Invoke();
}
protected abstract float ValueToPosition(T value);
protected abstract T PositionToValue(float position);
protected float GetStartPoint()
{
return (!IsHorizontal()) ? ((0f - UsableRangeRect.sizeDelta.y) / 2f) : ((0f - UsableRangeRect.sizeDelta.x) / 2f);
}
protected abstract Vector2 MinPositionLimits();
protected abstract Vector2 MaxPositionLimits();
protected abstract T InBounds(T value);
protected abstract T InBoundsMin(T value);
protected abstract T InBoundsMax(T value);
protected abstract void IncreaseMin();
protected abstract void DecreaseMin();
protected abstract void IncreaseMax();
protected abstract void DecreaseMax();
protected void UpdateMinHandle()
{
UpdateHandle(HandleMinRect, valueMin);
}
protected void UpdateMaxHandle()
{
UpdateHandle(HandleMaxRect, valueMax);
}
private void UpdateFill()
{
if (IsHorizontal())
{
FillRect.anchoredPosition = new Vector2(HandleMinRect.anchoredPosition.x, FillRect.anchoredPosition.y);
Vector2 sizeDelta = new Vector2(HandleMaxRect.anchoredPosition.x - HandleMinRect.anchoredPosition.x, FillRect.sizeDelta.y);
FillRect.sizeDelta = sizeDelta;
}
else
{
FillRect.anchoredPosition = new Vector2(FillRect.anchoredPosition.x, HandleMinRect.anchoredPosition.y);
Vector2 sizeDelta2 = new Vector2(FillRect.sizeDelta.x, HandleMaxRect.anchoredPosition.y - HandleMinRect.anchoredPosition.y);
FillRect.sizeDelta = sizeDelta2;
}
}
protected void UpdateHandle(RectTransform handleTransform, T value)
{
Vector2 anchoredPosition = handleTransform.anchoredPosition;
if (IsHorizontal())
{
anchoredPosition.x = ValueToPosition(value) + handleTransform.rect.width * (handleTransform.pivot.x - 0.5f);
}
else
{
anchoredPosition.y = ValueToPosition(value) + handleTransform.rect.height * (handleTransform.pivot.y - 0.5f);
}
handleTransform.anchoredPosition = anchoredPosition;
}
private void SelectMinHandle()
{
if (EventSystem.current != null && !EventSystem.current.alreadySelecting)
{
EventSystem.current.SetSelectedGameObject(handleMin.gameObject);
}
}
private void SelectMaxHandle()
{
if (EventSystem.current != null && !EventSystem.current.alreadySelecting)
{
EventSystem.current.SetSelectedGameObject(handleMax.gameObject);
}
}
public void OnPointerClick(PointerEventData eventData)
{
Vector2 localPoint;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(UsableRangeRect, eventData.position, eventData.pressEventCamera, out localPoint))
{
localPoint -= UsableRangeRect.rect.position;
float num = ((!IsHorizontal()) ? localPoint.y : localPoint.x) + GetStartPoint();
float num2 = num - MaxHandleSize();
float num3 = ((!IsHorizontal()) ? HandleMinRect.anchoredPosition.y : HandleMinRect.anchoredPosition.x);
float num4 = ((!IsHorizontal()) ? HandleMaxRect.anchoredPosition.y : HandleMaxRect.anchoredPosition.x);
float num5 = num - num3;
float num6 = num4 - num2;
if (num5 < num6)
{
UpdateMinValue(num);
}
else
{
UpdateMaxValue(num2);
}
}
}
}
}