|  |  |  |  | using System; | 
					
						
							|  |  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  |  | using UnityEngine; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace FairyGUI | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// 手指反向操作的手势。 | 
					
						
							|  |  |  |  |     /// </summary> | 
					
						
							|  |  |  |  |     public class RotationGesture : 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 rotation; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 从上次通知后的改变量。 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         public float delta; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 是否把变化量强制为整数。默认true。 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         public bool snapping; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         Vector2 _startVector; | 
					
						
							|  |  |  |  |         float _lastRotation; | 
					
						
							|  |  |  |  |         int[] _touches; | 
					
						
							|  |  |  |  |         bool _started; | 
					
						
							|  |  |  |  |         bool _touchBegan; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         public RotationGesture(GObject host) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             this.host = host; | 
					
						
							|  |  |  |  |             Enable(true); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _touches = new int[2]; | 
					
						
							|  |  |  |  |             snapping = true; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             onBegin = new EventListener(this, "onRotationBegin"); | 
					
						
							|  |  |  |  |             onEnd = new EventListener(this, "onRotationEnd"); | 
					
						
							|  |  |  |  |             onAction = new EventListener(this, "onRotationAction"); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         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.onTouchMove.Add(__touchMove); | 
					
						
							|  |  |  |  |                     Stage.inst.onTouchEnd.Add(__touchEnd); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 else | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     host.onTouchBegin.Add(__touchBegin); | 
					
						
							|  |  |  |  |                     host.onTouchMove.Add(__touchMove); | 
					
						
							|  |  |  |  |                     host.onTouchEnd.Add(__touchEnd); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             else | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _started = false; | 
					
						
							|  |  |  |  |                 _touchBegan = false; | 
					
						
							|  |  |  |  |                 if (host == GRoot.inst) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     Stage.inst.onTouchBegin.Remove(__touchBegin); | 
					
						
							|  |  |  |  |                     Stage.inst.onTouchMove.Remove(__touchMove); | 
					
						
							|  |  |  |  |                     Stage.inst.onTouchEnd.Remove(__touchEnd); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 else | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     host.onTouchBegin.Remove(__touchBegin); | 
					
						
							|  |  |  |  |                     host.onTouchMove.Remove(__touchMove); | 
					
						
							|  |  |  |  |                     host.onTouchEnd.Remove(__touchEnd); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         void __touchBegin(EventContext context) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (Stage.inst.touchCount == 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (!_started && !_touchBegan) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     _touchBegan = true; | 
					
						
							|  |  |  |  |                     Stage.inst.GetAllTouch(_touches); | 
					
						
							|  |  |  |  |                     Vector2 pt1 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[0])); | 
					
						
							|  |  |  |  |                     Vector2 pt2 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[1])); | 
					
						
							|  |  |  |  |                     _startVector = pt1 - pt2; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     context.CaptureTouch(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         void __touchMove(EventContext context) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (!_touchBegan || Stage.inst.touchCount != 2) | 
					
						
							|  |  |  |  |                 return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             InputEvent evt = context.inputEvent; | 
					
						
							|  |  |  |  |             Vector2 pt1 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[0])); | 
					
						
							|  |  |  |  |             Vector2 pt2 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[1])); | 
					
						
							|  |  |  |  |             Vector2 vec = pt1 - pt2; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             float rot = Mathf.Rad2Deg * ((Mathf.Atan2(vec.y, vec.x) - Mathf.Atan2(_startVector.y, _startVector.x))); | 
					
						
							|  |  |  |  |             if (snapping) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 rot = Mathf.Round(rot); | 
					
						
							|  |  |  |  |                 if (rot == 0) | 
					
						
							|  |  |  |  |                     return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (!_started && rot > 5) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _started = true; | 
					
						
							|  |  |  |  |                 rotation = 0; | 
					
						
							|  |  |  |  |                 _lastRotation = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 onBegin.Call(evt); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (_started) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 delta = rot - _lastRotation; | 
					
						
							|  |  |  |  |                 _lastRotation = rot; | 
					
						
							|  |  |  |  |                 this.rotation += delta; | 
					
						
							|  |  |  |  |                 onAction.Call(evt); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         void __touchEnd(EventContext context) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             _touchBegan = false; | 
					
						
							|  |  |  |  |             if (_started) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _started = false; | 
					
						
							|  |  |  |  |                 onEnd.Call(context.inputEvent); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |