Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/UIWidgets/SlideBlock.cs
2026-02-21 16:45:37 +08:00

370 lines
9.4 KiB
C#

using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
namespace UIWidgets
{
public class SlideBlock : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler, IEventSystemHandler
{
[SerializeField]
[Tooltip("Requirements: start value should be less than end value; Recommended start value = 0; end value = 1;")]
public AnimationCurve Curve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
public SlideBlockAxis Direction;
[SerializeField]
private bool isOpen;
[SerializeField]
private bool scrollRectSupport;
[SerializeField]
private GameObject optionalHandle;
public UnityEvent OnOpen = new UnityEvent();
public UnityEvent OnClose = new UnityEvent();
private RectTransform rectTransform;
private Vector2 closePosition;
private IEnumerator currentAnimation;
private float size;
public bool IsOpen
{
get
{
return isOpen;
}
set
{
isOpen = value;
ResetPosition();
}
}
public bool ScrollRectSupport
{
get
{
return scrollRectSupport;
}
set
{
if (scrollRectSupport)
{
GetComponentsInChildren<ScrollRect>().ForEach(RemoveHandleEvents);
}
scrollRectSupport = value;
if (scrollRectSupport)
{
GetComponentsInChildren<ScrollRect>().ForEach(AddHandleEvents);
}
}
}
public GameObject OptionalHandle
{
get
{
return optionalHandle;
}
set
{
if (optionalHandle != null)
{
RemoveHandleEvents(optionalHandle);
}
optionalHandle = value;
if (optionalHandle != null)
{
AddHandleEvents(optionalHandle);
}
}
}
protected RectTransform RectTransform
{
get
{
if (rectTransform == null)
{
rectTransform = base.transform as RectTransform;
}
return rectTransform;
}
}
private string GetWarning()
{
Keyframe[] keys = Curve.keys;
if (keys[0].value >= keys[keys.Length - 1].value)
{
return string.Format("Curve requirements: start value (current: {0}) should be less than end value (current: {1}).", keys[0].value, keys[keys.Length - 1].value);
}
return string.Empty;
}
private void Start()
{
string warning = GetWarning();
if (warning != string.Empty)
{
Debug.LogWarning(warning, this);
}
closePosition = RectTransform.anchoredPosition;
size = ((!IsHorizontal()) ? RectTransform.rect.height : RectTransform.rect.width);
if (IsOpen)
{
if (Direction == SlideBlockAxis.LeftToRight)
{
closePosition = new Vector2(closePosition.x - size, closePosition.y);
}
if (Direction == SlideBlockAxis.RightToLeft)
{
closePosition = new Vector2(closePosition.x + size, closePosition.y);
}
else if (Direction == SlideBlockAxis.TopToBottom)
{
closePosition = new Vector2(closePosition.x, closePosition.y - size);
}
else if (Direction == SlideBlockAxis.BottomToTop)
{
closePosition = new Vector2(closePosition.x, closePosition.y + size);
}
}
OptionalHandle = optionalHandle;
ScrollRectSupport = scrollRectSupport;
}
private void AddScrollRectHandle()
{
GetComponentsInChildren<ScrollRect>().ForEach(AddHandleEvents);
}
private void RemoveScrollRectHandle()
{
GetComponentsInChildren<ScrollRect>().ForEach(RemoveHandleEvents);
}
private void AddHandleEvents(Component handleComponent)
{
AddHandleEvents(handleComponent.gameObject);
}
private void AddHandleEvents(GameObject handleObject)
{
SlideBlockHandle slideBlockHandle = handleObject.GetComponent<SlideBlockHandle>() ?? handleObject.AddComponent<SlideBlockHandle>();
slideBlockHandle.BeginDragEvent.AddListener(OnBeginDrag);
slideBlockHandle.DragEvent.AddListener(OnDrag);
slideBlockHandle.EndDragEvent.AddListener(OnEndDrag);
}
private void RemoveHandleEvents(Component handleComponent)
{
RemoveHandleEvents(handleComponent.gameObject);
}
private void RemoveHandleEvents(GameObject handleObject)
{
SlideBlockHandle component = handleObject.GetComponent<SlideBlockHandle>();
if (component != null)
{
component.BeginDragEvent.RemoveListener(OnBeginDrag);
component.DragEvent.RemoveListener(OnDrag);
component.EndDragEvent.RemoveListener(OnEndDrag);
}
}
private void ResetPosition()
{
if (isOpen)
{
size = ((!IsHorizontal()) ? RectTransform.rect.height : RectTransform.rect.width);
if (Direction == SlideBlockAxis.LeftToRight)
{
RectTransform.anchoredPosition = new Vector2(closePosition.x + size, RectTransform.anchoredPosition.y);
}
else if (Direction == SlideBlockAxis.RightToLeft)
{
RectTransform.anchoredPosition = new Vector2(closePosition.x - size, RectTransform.anchoredPosition.y);
}
else if (Direction == SlideBlockAxis.TopToBottom)
{
RectTransform.anchoredPosition = new Vector2(RectTransform.anchoredPosition.x, closePosition.y - size);
}
else if (Direction == SlideBlockAxis.BottomToTop)
{
RectTransform.anchoredPosition = new Vector2(RectTransform.anchoredPosition.x, closePosition.y + size);
}
}
else
{
RectTransform.anchoredPosition = closePosition;
}
}
public void Toggle()
{
if (IsOpen)
{
Close();
}
else
{
Open();
}
}
public void OnBeginDrag(PointerEventData eventData)
{
size = ((!IsHorizontal()) ? RectTransform.rect.height : RectTransform.rect.width);
}
public void OnEndDrag(PointerEventData eventData)
{
float num = ((!IsHorizontal()) ? (RectTransform.anchoredPosition.y - closePosition.y) : (RectTransform.anchoredPosition.x - closePosition.x));
if (num == 0f)
{
isOpen = false;
OnClose.Invoke();
return;
}
int num2 = ((!IsReverse()) ? 1 : (-1));
if (num == size * (float)num2)
{
isOpen = true;
OnOpen.Invoke();
return;
}
float num3 = num / (size * (float)num2);
if (num3 >= 0.5f)
{
isOpen = false;
Open();
}
else
{
isOpen = true;
Close();
}
}
public void OnDrag(PointerEventData eventData)
{
if (currentAnimation != null)
{
StopCoroutine(currentAnimation);
}
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position, eventData.pressEventCamera, out localPoint);
Vector2 localPoint2;
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position - eventData.delta, eventData.pressEventCamera, out localPoint2);
Vector2 vector = localPoint - localPoint2;
if (Direction == SlideBlockAxis.LeftToRight)
{
float x = Mathf.Clamp(RectTransform.anchoredPosition.x + vector.x, closePosition.x, closePosition.x + size);
RectTransform.anchoredPosition = new Vector2(x, RectTransform.anchoredPosition.y);
}
else if (Direction == SlideBlockAxis.RightToLeft)
{
float x2 = Mathf.Clamp(RectTransform.anchoredPosition.x + vector.x, closePosition.x - size, closePosition.x);
RectTransform.anchoredPosition = new Vector2(x2, RectTransform.anchoredPosition.y);
}
else if (Direction == SlideBlockAxis.TopToBottom)
{
float y = Mathf.Clamp(RectTransform.anchoredPosition.y + vector.y, closePosition.y - size, closePosition.y);
RectTransform.anchoredPosition = new Vector2(RectTransform.anchoredPosition.x, y);
}
else if (Direction == SlideBlockAxis.BottomToTop)
{
float y2 = Mathf.Clamp(RectTransform.anchoredPosition.y + vector.y, closePosition.y, closePosition.y + size);
RectTransform.anchoredPosition = new Vector2(RectTransform.anchoredPosition.x, y2);
}
}
public void Open()
{
if (!IsOpen)
{
Animate();
}
}
public void Close()
{
if (IsOpen)
{
Animate();
}
}
private bool IsHorizontal()
{
return Direction == SlideBlockAxis.LeftToRight || SlideBlockAxis.RightToLeft == Direction;
}
private bool IsReverse()
{
return Direction == SlideBlockAxis.RightToLeft || SlideBlockAxis.TopToBottom == Direction;
}
private void Animate()
{
if (currentAnimation != null)
{
StopCoroutine(currentAnimation);
}
float time = Curve.keys[Curve.keys.Length - 1].time;
size = ((!IsHorizontal()) ? RectTransform.rect.height : RectTransform.rect.width);
float num = ((!IsHorizontal()) ? RectTransform.anchoredPosition.y : RectTransform.anchoredPosition.x);
float num2 = num - ((!IsHorizontal()) ? closePosition.y : closePosition.x);
int num3 = ((!IsReverse()) ? 1 : (-1));
float num4 = ((!isOpen) ? (size * (float)num3 - num2) : (size * (float)num3));
float num5 = ((num4 != 0f) ? (size / num4) : 1f);
if (IsReverse())
{
num5 *= -1f;
}
currentAnimation = RunAnimation(Time.time, time, num, num4, num5);
StartCoroutine(currentAnimation);
}
private IEnumerator RunAnimation(float startTime, float animationLength, float startPosition, float movement, float acceleration)
{
int direction = ((!isOpen) ? 1 : (-1));
float delta;
do
{
delta = (Time.time - startTime) * acceleration;
float value = Curve.Evaluate(delta);
if (IsHorizontal())
{
RectTransform.anchoredPosition = new Vector2(startPosition + value * movement * (float)direction, RectTransform.anchoredPosition.y);
}
else
{
RectTransform.anchoredPosition = new Vector2(RectTransform.anchoredPosition.x, startPosition + value * movement * (float)direction);
}
yield return null;
}
while (delta < animationLength);
isOpen = !isOpen;
ResetPosition();
if (IsOpen)
{
OnOpen.Invoke();
}
else
{
OnClose.Invoke();
}
}
}
}