using System; using System.Collections.Generic; using UnityEngine; namespace FairyGUI { /// /// 长按手势。当按下一定时间后(duration),派发onAction,如果once为false,则间隔duration时间持续派发onAction,直到手指释放。 /// public class LongPressGesture : EventDispatcher { /// /// /// public GObject host { get; private set; } /// /// 当手指按下时派发该事件。 /// public EventListener onBegin { get; private set; } /// /// 手指离开屏幕时派发该事件。 /// public EventListener onEnd { get; private set; } /// /// 当手指按下后一段时间后派发该事件。并且在手指离开前按一定周期派发该事件。 /// public EventListener onAction { get; private set; } /// /// 第一次派发事件的触发时间。单位秒 /// public float trigger; /// /// 派发onAction事件的时间间隔。单位秒。 /// public float interval; /// /// 如果为真,则onAction再一次按下释放过程只派发一次。如果为假,则每隔duration时间派发一次。 /// public bool once; /// /// 手指按住后,移动超出此半径范围则手势停止。 /// 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(); } } } }