291 lines
7.3 KiB
C#
291 lines
7.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
|
|
[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 bool _outDragCalled;
|
|
private DragState _curDragState;
|
|
private Vector2 _mousePos;
|
|
private Vector2 _lastFrameMousePos;
|
|
private Vector2 _startDragPos;
|
|
|
|
private bool _isDraggingUp;
|
|
|
|
private const float MAX_PRESSED_TIME = 0.35f;
|
|
private const float MIN_PRESSED_TIME = 0.15f;
|
|
private const float MIN_DRAG_DISTANCE = 10f;
|
|
private const float MIN_UP_DRAG_DIS = 40f;
|
|
|
|
public delegate void OnLongPressCall();
|
|
|
|
public delegate void OnPointUpCall();
|
|
|
|
public delegate void OnStartDrag();
|
|
public delegate void OnDraging();
|
|
public delegate void OnEndDrag();
|
|
public delegate void OnUpDrag(); //向上拖动
|
|
|
|
public delegate void OnDragOut(); //向外拖动
|
|
|
|
public delegate void OnClick();
|
|
|
|
private OnLongPressCall _OnLongPress;
|
|
private OnPointUpCall _OnPointUp; //长按后抬起
|
|
private OnStartDrag _OnStartDrag;
|
|
private OnDraging _OnDrag;
|
|
private OnEndDrag _OnEndDrag;
|
|
private OnUpDrag _OnUpDrag;
|
|
private OnDragOut _OnDragOut;
|
|
private OnClick _OnClick;
|
|
|
|
public OnUpDrag UpDrag
|
|
{
|
|
get { return _OnUpDrag; }
|
|
}
|
|
|
|
public OnDragOut DragOut
|
|
{
|
|
get { return _OnDragOut; }
|
|
}
|
|
|
|
public OnPointUpCall PointUp
|
|
{
|
|
get { return _OnPointUp; }
|
|
}
|
|
|
|
//测试代码
|
|
private int _count = 0;
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.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)
|
|
{
|
|
if(Math.Abs(_startDragPos.y - _mousePos.y) > MIN_UP_DRAG_DIS)
|
|
{
|
|
_OnUpDrag?.Invoke();
|
|
_upDragCalled = true;
|
|
}
|
|
}
|
|
|
|
if (!_outDragCalled)
|
|
{
|
|
if (Vector2.Distance(_startDragPos, _mousePos) > MIN_UP_DRAG_DIS)
|
|
{
|
|
_OnDragOut?.Invoke();
|
|
_outDragCalled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_pressedTime > MAX_PRESSED_TIME && !_isCalled && !_IsDragging())
|
|
{
|
|
_isCalled = true;
|
|
_isLongPressing = true;
|
|
_OnLongPress?.Invoke();
|
|
}
|
|
|
|
_lastFrameMousePos = _mousePos;
|
|
|
|
//如果是其他组件的拖动导致提前调用了OnPointerUp
|
|
if (_isDraggingUp)
|
|
{
|
|
if (!_upDragCalled)
|
|
{
|
|
if(Math.Abs(_startDragPos.y - _mousePos.y) > MIN_DRAG_DISTANCE)
|
|
{
|
|
_OnUpDrag?.Invoke();
|
|
_upDragCalled = true;
|
|
}
|
|
}
|
|
|
|
_isDraggingUp = false;
|
|
_isPressed = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _IsDragging()
|
|
{
|
|
return _curDragState == DragState.Dragging && !_isLongPressing;
|
|
}
|
|
|
|
private void _EnterDrag()
|
|
{
|
|
_curDragState = DragState.Dragging;
|
|
_upDragCalled = false;
|
|
_outDragCalled = false;
|
|
_OnStartDrag?.Invoke();
|
|
}
|
|
|
|
private void _ExitDrag()
|
|
{
|
|
_curDragState = DragState.None;
|
|
_upDragCalled = false;
|
|
_outDragCalled = false;
|
|
_OnEndDrag?.Invoke();
|
|
}
|
|
|
|
//按键放下和抬起
|
|
public override void OnPointerDown(PointerEventData data)
|
|
{
|
|
_pressedTime = 0f;
|
|
_isPressed = true;
|
|
_startDragPos = InputManager.Instance.GetTouchPosition();
|
|
_isLongPressing = false;
|
|
_upDragCalled = 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 (!data.dragging)
|
|
{
|
|
if (_IsDragging())
|
|
{
|
|
_ExitDrag();
|
|
}
|
|
|
|
_pressedTime = 0f;
|
|
_isPressed = false;
|
|
_isCalled = false;
|
|
_isLongPressing = false;
|
|
_upDragCalled = false;
|
|
_outDragCalled = false;
|
|
_isDraggingUp = false;
|
|
}
|
|
else
|
|
{
|
|
_pressedTime = 0f;
|
|
//_isPressed = false;
|
|
_isCalled = false;
|
|
_isLongPressing = false;
|
|
//_upDragCalled = false;
|
|
_outDragCalled = false;
|
|
_isDraggingUp = true;
|
|
}
|
|
|
|
// _pressedTime = 0f;
|
|
// _isPressed = false;
|
|
// _isCalled = false;
|
|
// _isLongPressing = false;
|
|
// _upDragCalled = false;
|
|
// _outDragCalled = false;
|
|
}
|
|
|
|
//添加事件监听回调,外部调用接口
|
|
public void AddLongPressListener(OnLongPressCall func)
|
|
{
|
|
_OnLongPress += func;
|
|
}
|
|
|
|
public void AddPointUpListener(OnPointUpCall func)
|
|
{
|
|
_OnPointUp += func;
|
|
}
|
|
|
|
public void AddUpDragListener(OnUpDrag func)
|
|
{
|
|
_OnUpDrag += func;
|
|
}
|
|
|
|
public void AddOutDragListener(OnDragOut func)
|
|
{
|
|
_OnDragOut += func;
|
|
}
|
|
|
|
public void AddStartDragListener(OnStartDrag func)
|
|
{
|
|
_OnStartDrag += func;
|
|
}
|
|
|
|
public void AddOnDragListener(OnDraging func)
|
|
{
|
|
_OnDrag += func;
|
|
}
|
|
|
|
public void AddEndDragListener(OnEndDrag func)
|
|
{
|
|
_OnEndDrag += 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;
|
|
}
|
|
}
|
|
} |