2025-06-07 17:43:34 +08:00

156 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using UnityEngine;
namespace FairyGUI
{
/// <summary>
/// 长按手势。当按下一定时间后(duration)派发onAction如果once为false则间隔duration时间持续派发onAction直到手指释放。
/// </summary>
public class LongPressGesture : EventDispatcher
{
/// <summary>
///
/// </summary>
public GObject host { get; private set; }
/// <summary>
/// 当手指按下时派发该事件。
/// </summary>
public EventListener onBegin { get; private set; }
/// <summary>
/// 手指离开屏幕时派发该事件。
/// </summary>
public EventListener onEnd { get; private set; }
/// <summary>
/// 当手指按下后一段时间后派发该事件。并且在手指离开前按一定周期派发该事件。
/// </summary>
public EventListener onAction { get; private set; }
/// <summary>
/// 第一次派发事件的触发时间。单位秒
/// </summary>
public float trigger;
/// <summary>
/// 派发onAction事件的时间间隔。单位秒。
/// </summary>
public float interval;
/// <summary>
/// 如果为真则onAction再一次按下释放过程只派发一次。如果为假则每隔duration时间派发一次。
/// </summary>
public bool once;
/// <summary>
/// 手指按住后,移动超出此半径范围则手势停止。
/// </summary>
public int holdRangeRadius;
Vector2 _startPoint;
bool _started;
int _touchId;
public static float TRIGGER = 1.5f;
public static float INTERVAL = 1f;
public LongPressGesture(GObject host)
{
this.host = host;
trigger = TRIGGER;
interval = INTERVAL;
holdRangeRadius = 50;
Enable(true);
onBegin = new EventListener(this, "onLongPressBegin");
onEnd = new EventListener(this, "onLongPressEnd");
onAction = new EventListener(this, "onLongPressAction");
}
public void Dispose()
{
Enable(false);
host = null;
}
public void Enable(bool value)
{
if (value)
{
if (host == GRoot.inst)
{
Stage.inst.onTouchBegin.Add(__touchBegin);
Stage.inst.onTouchEnd.Add(__touchEnd);
}
else
{
host.onTouchBegin.Add(__touchBegin);
host.onTouchEnd.Add(__touchEnd);
}
}
else
{
if (host == GRoot.inst)
{
Stage.inst.onTouchBegin.Remove(__touchBegin);
Stage.inst.onTouchEnd.Remove(__touchEnd);
}
else
{
host.onTouchBegin.Remove(__touchBegin);
host.onTouchEnd.Remove(__touchEnd);
}
Timers.inst.Remove(__timer);
}
}
public void Cancel()
{
Timers.inst.Remove(__timer);
_started = false;
}
void __touchBegin(EventContext context)
{
InputEvent evt = context.inputEvent;
_startPoint = host.GlobalToLocal(new Vector2(evt.x, evt.y));
_started = false;
_touchId = evt.touchId;
Timers.inst.Add(trigger, 1, __timer);
context.CaptureTouch();
}
void __timer(object param)
{
Vector2 pt = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touchId));
if (Mathf.Pow(pt.x - _startPoint.x, 2) + Mathf.Pow(pt.y - _startPoint.y, 2) > Mathf.Pow(holdRangeRadius, 2))
{
Timers.inst.Remove(__timer);
return;
}
if (!_started)
{
_started = true;
onBegin.Call();
if (!once)
Timers.inst.Add(interval, 0, __timer);
}
onAction.Call();
}
void __touchEnd(EventContext context)
{
Timers.inst.Remove(__timer);
if (_started)
{
_started = false;
onEnd.Call();
}
}
}
}