summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs342
1 files changed, 342 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs
new file mode 100644
index 0000000..3aa8e09
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs
@@ -0,0 +1,342 @@
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine.UI;
+
+namespace UnityEngine.EventSystems
+{
+
+ // 会处理触屏和鼠标
+ public abstract class PointerInputModule : BaseInputModule
+ {
+ public const int kMouseLeftId = -1;
+ public const int kMouseRightId = -2;
+ public const int kMouseMiddleId = -3;
+
+ public const int kFakeTouchesId = -4;
+
+ // 一个池子
+ protected Dictionary<int, PointerEventData> m_PointerData = new Dictionary<int, PointerEventData>();
+
+ protected bool GetPointerData(int id, out PointerEventData data, bool create)
+ {
+ if (!m_PointerData.TryGetValue(id, out data) && create) // 一个池子
+ {
+ data = new PointerEventData(eventSystem)
+ {
+ pointerId = id,
+ };
+ m_PointerData.Add(id, data);
+ return true;
+ }
+ return false;
+ }
+
+ protected void RemovePointerData(PointerEventData data)
+ {
+ m_PointerData.Remove(data.pointerId);
+ }
+
+ //c 根据touch数据得到pointEventData,并且保存raycaster结果
+ protected PointerEventData GetTouchPointerEventData(Touch input, out bool pressed, out bool released)
+ {
+ PointerEventData pointerData;
+ // 从池子里拿到存储结构,返回是否是新建结构
+ var created = GetPointerData(input.fingerId, out pointerData, true);
+
+ pointerData.Reset();
+
+ // pressed和released用来判断抬起或者放下
+
+ pressed = created || (input.phase == TouchPhase.Began); // 如果结构是新建的或input phase是bagan,说明是刚按下
+ released = (input.phase == TouchPhase.Canceled) || (input.phase == TouchPhase.Ended); // 如果phase是这两种,说明是抬起来了
+
+ if (created)//如果是新建的,记录下起始位置,否则还保留旧值,下面用来计算delta
+ pointerData.position = input.position;
+
+ if (pressed)//如果是刚按下,delta置为0
+ pointerData.delta = Vector2.zero;
+ else
+ pointerData.delta = input.position - pointerData.position; // 计算delta
+
+ pointerData.position = input.position; // 计算完delta后覆盖
+
+ pointerData.button = PointerEventData.InputButton.Left; // 这里不知道为什么
+
+ // 用这个触摸数据做射线检测,检测结果在m_RaycastResultCache
+ eventSystem.RaycastAll(pointerData, m_RaycastResultCache);
+
+ // 只取第一个,舍弃其他的
+ var raycast = FindFirstRaycast(m_RaycastResultCache);
+ Debug.Log("raycast: " + raycast.index);
+ pointerData.pointerCurrentRaycast = raycast;
+ m_RaycastResultCache.Clear();
+ return pointerData;
+ }
+
+ protected void CopyFromTo(PointerEventData @from, PointerEventData @to)
+ {
+ @to.position = @from.position;
+ @to.delta = @from.delta;
+ @to.scrollDelta = @from.scrollDelta;
+ @to.pointerCurrentRaycast = @from.pointerCurrentRaycast;
+ @to.pointerEnter = @from.pointerEnter;
+ }
+
+ protected PointerEventData.FramePressState StateForMouseButton(int buttonId)
+ {
+ var pressed = input.GetMouseButtonDown(buttonId);
+ var released = input.GetMouseButtonUp(buttonId);
+ if (pressed && released)
+ return PointerEventData.FramePressState.PressedAndReleased;
+ if (pressed)
+ return PointerEventData.FramePressState.Pressed;
+ if (released)
+ return PointerEventData.FramePressState.Released;
+ return PointerEventData.FramePressState.NotChanged;
+ }
+
+ protected class ButtonState
+ {
+ private PointerEventData.InputButton m_Button = PointerEventData.InputButton.Left;
+
+ public MouseButtonEventData eventData
+ {
+ get { return m_EventData; }
+ set { m_EventData = value; }
+ }
+
+ public PointerEventData.InputButton button
+ {
+ get { return m_Button; }
+ set { m_Button = value; }
+ }
+
+ private MouseButtonEventData m_EventData;
+ }
+
+ protected class MouseState
+ {
+ private List<ButtonState> m_TrackedButtons = new List<ButtonState>();
+
+ public bool AnyPressesThisFrame()
+ {
+ for (int i = 0; i < m_TrackedButtons.Count; i++)
+ {
+ if (m_TrackedButtons[i].eventData.PressedThisFrame())
+ return true;
+ }
+ return false;
+ }
+
+ public bool AnyReleasesThisFrame()
+ {
+ for (int i = 0; i < m_TrackedButtons.Count; i++)
+ {
+ if (m_TrackedButtons[i].eventData.ReleasedThisFrame())
+ return true;
+ }
+ return false;
+ }
+
+ public ButtonState GetButtonState(PointerEventData.InputButton button)
+ {
+ ButtonState tracked = null;
+ for (int i = 0; i < m_TrackedButtons.Count; i++)
+ {
+ if (m_TrackedButtons[i].button == button)
+ {
+ tracked = m_TrackedButtons[i];
+ break;
+ }
+ }
+
+ if (tracked == null)
+ {
+ tracked = new ButtonState { button = button, eventData = new MouseButtonEventData() };
+ m_TrackedButtons.Add(tracked);
+ }
+ return tracked;
+ }
+
+ public void SetButtonState(PointerEventData.InputButton button, PointerEventData.FramePressState stateForMouseButton, PointerEventData data)
+ {
+ var toModify = GetButtonState(button);
+ toModify.eventData.buttonState = stateForMouseButton;
+ toModify.eventData.buttonData = data;
+ }
+ }
+
+ public class MouseButtonEventData
+ {
+ public PointerEventData.FramePressState buttonState;
+ public PointerEventData buttonData;
+
+ public bool PressedThisFrame()
+ {
+ return buttonState == PointerEventData.FramePressState.Pressed || buttonState == PointerEventData.FramePressState.PressedAndReleased;
+ }
+
+ public bool ReleasedThisFrame()
+ {
+ return buttonState == PointerEventData.FramePressState.Released || buttonState == PointerEventData.FramePressState.PressedAndReleased;
+ }
+ }
+
+ private readonly MouseState m_MouseState = new MouseState();
+
+ protected virtual MouseState GetMousePointerEventData()
+ {
+ return GetMousePointerEventData(0);
+ }
+
+ protected virtual MouseState GetMousePointerEventData(int id)
+ {
+ // Populate the left button...
+ PointerEventData leftData;
+ var created = GetPointerData(kMouseLeftId, out leftData, true);
+
+ leftData.Reset();
+
+ if (created)
+ leftData.position = input.mousePosition;
+
+ Vector2 pos = input.mousePosition;
+ if (Cursor.lockState == CursorLockMode.Locked)
+ {
+ // We don't want to do ANY cursor-based interaction when the mouse is locked
+ leftData.position = new Vector2(-1.0f, -1.0f);
+ leftData.delta = Vector2.zero;
+ }
+ else
+ {
+ leftData.delta = pos - leftData.position;
+ leftData.position = pos;
+ }
+ leftData.scrollDelta = input.mouseScrollDelta;
+ leftData.button = PointerEventData.InputButton.Left;
+ eventSystem.RaycastAll(leftData, m_RaycastResultCache);
+
+ // 只要第一个raycast结果
+ var raycast = FindFirstRaycast(m_RaycastResultCache);
+ leftData.pointerCurrentRaycast = raycast;
+ m_RaycastResultCache.Clear();
+
+ // copy the apropriate data into right and middle slots
+ PointerEventData rightData;
+ GetPointerData(kMouseRightId, out rightData, true);
+ CopyFromTo(leftData, rightData);
+ rightData.button = PointerEventData.InputButton.Right;
+
+ PointerEventData middleData;
+ GetPointerData(kMouseMiddleId, out middleData, true);
+ CopyFromTo(leftData, middleData);
+ middleData.button = PointerEventData.InputButton.Middle;
+
+ // 设置按键状态
+ m_MouseState.SetButtonState(PointerEventData.InputButton.Left, StateForMouseButton(0), leftData);
+ m_MouseState.SetButtonState(PointerEventData.InputButton.Right, StateForMouseButton(1), rightData);
+ m_MouseState.SetButtonState(PointerEventData.InputButton.Middle, StateForMouseButton(2), middleData);
+
+ return m_MouseState;
+ }
+
+ protected PointerEventData GetLastPointerEventData(int id)
+ {
+ PointerEventData data;
+ GetPointerData(id, out data, false);
+ return data;
+ }
+
+ private static bool ShouldStartDrag(Vector2 pressPos, Vector2 currentPos, float threshold, bool useDragThreshold)
+ {
+ if (!useDragThreshold)
+ return true;
+
+ return (pressPos - currentPos).sqrMagnitude >= threshold * threshold;
+ }
+
+ protected virtual void ProcessMove(PointerEventData pointerEvent)
+ {
+ var targetGO = (Cursor.lockState == CursorLockMode.Locked ? null : pointerEvent.pointerCurrentRaycast.gameObject);
+ HandlePointerExitAndEnter(pointerEvent, targetGO);
+ }
+
+ // 发送drag事件
+ protected virtual void ProcessDrag(PointerEventData pointerEvent)
+ {
+ if (!pointerEvent.IsPointerMoving() ||
+ Cursor.lockState == CursorLockMode.Locked ||
+ pointerEvent.pointerDrag == null)
+ return;
+
+ if (!pointerEvent.dragging
+ && ShouldStartDrag(pointerEvent.pressPosition, pointerEvent.position, eventSystem.pixelDragThreshold, pointerEvent.useDragThreshold))
+ {
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler);
+ pointerEvent.dragging = true;
+ }
+
+ // Drag notification
+ if (pointerEvent.dragging)
+ {
+ // Before doing drag we should cancel any pointer down state
+ // And clear selection!
+ if (pointerEvent.pointerPress != pointerEvent.pointerDrag)
+ {
+ ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
+
+ pointerEvent.eligibleForClick = false;
+ pointerEvent.pointerPress = null;
+ pointerEvent.rawPointerPress = null;
+ }
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler);
+ }
+ }
+
+ public override bool IsPointerOverGameObject(int pointerId)
+ {
+ var lastPointer = GetLastPointerEventData(pointerId);
+ if (lastPointer != null)
+ return lastPointer.pointerEnter != null;
+ return false;
+ }
+
+ protected void ClearSelection()
+ {
+ var baseEventData = GetBaseEventData();
+
+ foreach (var pointer in m_PointerData.Values)
+ {
+ // clear all selection
+ HandlePointerExitAndEnter(pointer, null);
+ }
+
+ m_PointerData.Clear();
+ eventSystem.SetSelectedGameObject(null, baseEventData);
+ }
+
+ public override string ToString()
+ {
+ var sb = new StringBuilder("<b>Pointer Input Module of type: </b>" + GetType());
+ sb.AppendLine();
+ foreach (var pointer in m_PointerData)
+ {
+ if (pointer.Value == null)
+ continue;
+ sb.AppendLine("<B>Pointer:</b> " + pointer.Key);
+ sb.AppendLine(pointer.Value.ToString());
+ }
+ return sb.ToString();
+ }
+
+ protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent)
+ {
+ // Selection tracking
+ var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo);
+ // if we have clicked something new, deselect the old thing
+ // leave 'selection handling' up to the press event though.
+ if (selectHandlerGO != eventSystem.currentSelectedGameObject)
+ eventSystem.SetSelectedGameObject(null, pointerEvent);
+ }
+ }
+}