NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIButtonEx.cs

199 lines
5.0 KiB
C#

using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Button))]
public class UIButtonEx: Button
{
private Button m_button;
private enum DragState
{
None,
Dragging,
End
}
private bool _isPressed;
private float _pressedTime;
private bool _isCalled = false;
private bool _isLongPressing;
private bool _upDragCalled;
private DragState _curDragState;
private Vector2 _mousePos;
private Vector2 _lastFrameMousePos;
private Vector2 _startDragPos;
private const float MAX_PRESSED_TIME = 0.65f;
private const float MIN_PRESSED_TIME = 0.2f;
private const float MIN_DRAG_DISTANCE = 1f;
private const float MIN_UP_DRAG_DIS = 40f;
public delegate void OnLongPressCall();
public delegate void OnPointUpCall();
public delegate void OnStartDrag();
public delegate void OnDrag();
public delegate void OnEndDrag();
public delegate void OnUpDrag(); //向上拖动
public delegate void OnClick();
private OnLongPressCall _OnLongPress;
private OnPointUpCall _OnPointUp; //长按后抬起
private OnStartDrag _OnStartDrag;
private OnDrag _OnDrag;
private OnEndDrag _OnEndDrag;
private OnUpDrag _OnUpDrag;
private OnClick _OnClick;
//测试代码
private int _count = 0;
private void Awake()
{
m_button = GetComponent<Button>();
}
void Update()
{
if (_isPressed)
{
_mousePos = InputManager.Instance.GetTouchPosition();
_pressedTime += Time.deltaTime;
//判断是否进入拖拽
var distance = Vector2.Distance(_startDragPos, _mousePos);
if (!_isLongPressing && distance > MIN_DRAG_DISTANCE && _curDragState == DragState.None)
{
_EnterDrag();
}
if (_IsDragging() && _lastFrameMousePos != _mousePos)
{
_OnDrag?.Invoke();
if (!_upDragCalled && Math.Abs(_startDragPos.y - _mousePos.y) > MIN_UP_DRAG_DIS)
{
_OnUpDrag?.Invoke();
_upDragCalled = true;
}
}
if (_pressedTime > MAX_PRESSED_TIME && !_isCalled && !_IsDragging())
{
_isCalled = true;
_isLongPressing = true;
_OnLongPress?.Invoke();
}
_lastFrameMousePos = _mousePos;
}
}
private bool _IsDragging()
{
return _curDragState == DragState.Dragging && !_isLongPressing;
}
private void _EnterDrag()
{
_curDragState = DragState.Dragging;
_upDragCalled = false;
_OnStartDrag?.Invoke();
}
private void _ExitDrag()
{
_curDragState = DragState.None;
_upDragCalled = false;
_OnEndDrag?.Invoke();
}
//按键放下和抬起
public override void OnPointerDown(PointerEventData data)
{
_pressedTime = 0f;
_isPressed = true;
_startDragPos = InputManager.Instance.GetTouchPosition();
_isLongPressing = false;
}
public override void OnPointerUp(PointerEventData data)
{
if ((_pressedTime > MIN_PRESSED_TIME && _pressedTime < MAX_PRESSED_TIME || _IsDragging()) && !_isLongPressing)
{
_OnPointUp?.Invoke();
}
else if(_pressedTime > 0)
{
_OnClick?.Invoke();
}
if (_IsDragging())
{
_ExitDrag();
}
_pressedTime = 0f;
_isPressed = false;
_isCalled = false;
_isLongPressing = false;
_upDragCalled = false;
}
//添加事件监听回调,外部调用接口
public void AddLongPressListener(OnLongPressCall func)
{
_OnLongPress += func;
}
public void AddPointUpListener(OnPointUpCall func)
{
_OnPointUp += func;
}
public void AddUpDragListener(OnUpDrag func)
{
_OnUpDrag += func;
}
public void AddClickListener(OnClick func)
{
_OnClick += func;
}
//移除事件绑定接口,外部调用
public void RemoveAllListener()
{
if (m_button)
{
m_button.onClick.RemoveAllListeners();
}
// Delegate[] onLongPressList = OnLongPress.GetInvocationList();
// Delegate[] onPointUpList = OnPointUp.GetInvocationList();
// foreach (var deleg in onLongPressList)
// {
// OnLongPress -= deleg as OnLongPressCall;
// }
// foreach (var deleg in onPointUpList)
// {
// OnPointUp -= deleg as OnPointUpCall;
// }
}
public void RemoveListener<T>(T call)
{
if (call is OnLongPressCall pressCall)
{
_OnLongPress -= pressCall;
}
}
}