summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-10-08 09:50:33 +0800
committerchai <chaifix@163.com>2020-10-08 09:50:33 +0800
commit00dae1bd426d892dff73a50f1c505afd1ac00a90 (patch)
tree5d75f8495406f5b8dd01595e3dd9216887996a34 /Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs
+init
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs588
1 files changed, 588 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs
new file mode 100644
index 0000000..ee6f216
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs
@@ -0,0 +1,588 @@
+using System;
+using UnityEngine;
+using UnityEngine.Serialization;
+
+namespace UnityEngine.EventSystems
+{
+ [AddComponentMenu("Event/Standalone Input Module")]
+ public class StandaloneInputModule : PointerInputModule
+ {
+ private float m_PrevActionTime;
+ private Vector2 m_LastMoveVector;
+ private int m_ConsecutiveMoveCount = 0;
+
+ private Vector2 m_LastMousePosition;
+ private Vector2 m_MousePosition;
+
+ private GameObject m_CurrentFocusedGameObject;
+
+ protected StandaloneInputModule()
+ {
+ }
+
+ [Obsolete("Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.", false)]
+ public enum InputMode
+ {
+ Mouse,
+ Buttons
+ }
+
+ [Obsolete("Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.", false)]
+ public InputMode inputMode
+ {
+ get { return InputMode.Mouse; }
+ }
+
+ [SerializeField]
+ private string m_HorizontalAxis = "Horizontal";
+
+ /// <summary>
+ /// Name of the vertical axis for movement (if axis events are used).
+ /// </summary>
+ [SerializeField]
+ private string m_VerticalAxis = "Vertical";
+
+ /// <summary>
+ /// Name of the submit button.
+ /// </summary>
+ [SerializeField]
+ private string m_SubmitButton = "Submit";
+
+ /// <summary>
+ /// Name of the submit button.
+ /// </summary>
+ [SerializeField]
+ private string m_CancelButton = "Cancel";
+
+ [SerializeField]
+ private float m_InputActionsPerSecond = 10;
+
+ [SerializeField]
+ private float m_RepeatDelay = 0.5f;
+
+ [SerializeField]
+ [FormerlySerializedAs("m_AllowActivationOnMobileDevice")]
+ private bool m_ForceModuleActive;
+
+ [Obsolete("allowActivationOnMobileDevice has been deprecated. Use forceModuleActive instead (UnityUpgradable) -> forceModuleActive")]
+ public bool allowActivationOnMobileDevice
+ {
+ get { return m_ForceModuleActive; }
+ set { m_ForceModuleActive = value; }
+ }
+
+ public bool forceModuleActive
+ {
+ get { return m_ForceModuleActive; }
+ set { m_ForceModuleActive = value; }
+ }
+
+ public float inputActionsPerSecond
+ {
+ get { return m_InputActionsPerSecond; }
+ set { m_InputActionsPerSecond = value; }
+ }
+
+ public float repeatDelay
+ {
+ get { return m_RepeatDelay; }
+ set { m_RepeatDelay = value; }
+ }
+
+ /// <summary>
+ /// Name of the horizontal axis for movement (if axis events are used).
+ /// </summary>
+ public string horizontalAxis
+ {
+ get { return m_HorizontalAxis; }
+ set { m_HorizontalAxis = value; }
+ }
+
+ /// <summary>
+ /// Name of the vertical axis for movement (if axis events are used).
+ /// </summary>
+ public string verticalAxis
+ {
+ get { return m_VerticalAxis; }
+ set { m_VerticalAxis = value; }
+ }
+
+ public string submitButton
+ {
+ get { return m_SubmitButton; }
+ set { m_SubmitButton = value; }
+ }
+
+ public string cancelButton
+ {
+ get { return m_CancelButton; }
+ set { m_CancelButton = value; }
+ }
+
+ private bool ShouldIgnoreEventsOnNoFocus()
+ {
+ switch (SystemInfo.operatingSystemFamily)
+ {
+ case OperatingSystemFamily.Windows:
+ case OperatingSystemFamily.Linux:
+ case OperatingSystemFamily.MacOSX:
+#if UNITY_EDITOR
+ if (UnityEditor.EditorApplication.isRemoteConnected)
+ return false;
+#endif
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public override void UpdateModule()
+ {
+ if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())
+ return;
+
+ m_LastMousePosition = m_MousePosition;
+ m_MousePosition = input.mousePosition;
+ }
+
+ public override bool IsModuleSupported()
+ {
+ return m_ForceModuleActive || input.mousePresent || input.touchSupported;
+ }
+
+ public override bool ShouldActivateModule()
+ {
+ if (!base.ShouldActivateModule())
+ return false;
+
+ var shouldActivate = m_ForceModuleActive;
+ shouldActivate |= input.GetButtonDown(m_SubmitButton);
+ shouldActivate |= input.GetButtonDown(m_CancelButton);
+ shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_HorizontalAxis), 0.0f);
+ shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_VerticalAxis), 0.0f);
+ shouldActivate |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f;
+ shouldActivate |= input.GetMouseButtonDown(0);
+
+ if (input.touchCount > 0)
+ shouldActivate = true;
+
+ return shouldActivate;
+ }
+
+ public override void ActivateModule()
+ {
+ if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())
+ return;
+
+ base.ActivateModule();
+ m_MousePosition = input.mousePosition;
+ m_LastMousePosition = input.mousePosition;
+
+ var toSelect = eventSystem.currentSelectedGameObject;
+ if (toSelect == null)
+ toSelect = eventSystem.firstSelectedGameObject;
+
+ eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData());
+ }
+
+ public override void DeactivateModule()
+ {
+ base.DeactivateModule();
+ ClearSelection();
+ }
+
+ public override void Process()
+ {
+ if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())
+ return;
+
+ bool usedEvent = SendUpdateEventToSelectedObject();
+
+ if (eventSystem.sendNavigationEvents)
+ {
+ if (!usedEvent)
+ usedEvent |= SendMoveEventToSelectedObject();
+
+ if (!usedEvent)
+ SendSubmitEventToSelectedObject();
+ }
+
+ // touch needs to take precedence because of the mouse emulation layer
+ if (!ProcessTouchEvents() && input.mousePresent)
+ ProcessMouseEvent();
+ }
+
+ private bool ProcessTouchEvents()
+ {
+ for (int i = 0; i < input.touchCount; ++i)
+ {
+ Touch touch = input.GetTouch(i);
+
+ if (touch.type == TouchType.Indirect)
+ continue;
+
+ bool released;
+ bool pressed;
+ var pointer = GetTouchPointerEventData(touch, out pressed, out released);
+
+ ProcessTouchPress(pointer, pressed, released);
+
+ if (!released)
+ {
+ ProcessMove(pointer);
+ ProcessDrag(pointer);
+ }
+ else
+ RemovePointerData(pointer);
+ }
+ return input.touchCount > 0;
+ }
+
+ protected void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released)
+ {
+ var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;
+
+ // PointerDown notification
+ if (pressed)
+ {
+ pointerEvent.eligibleForClick = true;
+ pointerEvent.delta = Vector2.zero;
+ pointerEvent.dragging = false;
+ pointerEvent.useDragThreshold = true;
+ pointerEvent.pressPosition = pointerEvent.position;
+ pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;
+
+ DeselectIfSelectionChanged(currentOverGo, pointerEvent);
+
+ if (pointerEvent.pointerEnter != currentOverGo)
+ {
+ // send a pointer enter to the touched element if it isn't the one to select...
+ HandlePointerExitAndEnter(pointerEvent, currentOverGo);
+ pointerEvent.pointerEnter = currentOverGo;
+ }
+
+ // search for the control that will receive the press
+ // if we can't find a press handler set the press
+ // handler to be what would receive a click.
+ var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler);
+
+ // didnt find a press handler... search for a click handler
+ if (newPressed == null)
+ newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
+
+ // Debug.Log("Pressed: " + newPressed);
+
+ float time = Time.unscaledTime;
+
+ if (newPressed == pointerEvent.lastPress)
+ {
+ var diffTime = time - pointerEvent.clickTime;
+ if (diffTime < 0.3f)
+ ++pointerEvent.clickCount;
+ else
+ pointerEvent.clickCount = 1;
+
+ pointerEvent.clickTime = time;
+ }
+ else
+ {
+ pointerEvent.clickCount = 1;
+ }
+
+ pointerEvent.pointerPress = newPressed;
+ pointerEvent.rawPointerPress = currentOverGo;
+
+ pointerEvent.clickTime = time;
+
+ // Save the drag handler as well
+ pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
+
+ if (pointerEvent.pointerDrag != null)
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag);
+ }
+
+ // PointerUp notification
+ if (released)
+ {
+ // Debug.Log("Executing pressup on: " + pointer.pointerPress);
+ ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
+
+ // Debug.Log("KeyCode: " + pointer.eventData.keyCode);
+
+ // see if we mouse up on the same element that we clicked on...
+ var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
+
+ // PointerClick and Drop events
+ if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick)
+ {
+ ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler);
+ }
+ else if (pointerEvent.pointerDrag != null && pointerEvent.dragging)
+ {
+ ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler);
+ }
+
+ pointerEvent.eligibleForClick = false;
+ pointerEvent.pointerPress = null;
+ pointerEvent.rawPointerPress = null;
+
+ if (pointerEvent.pointerDrag != null && pointerEvent.dragging)
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler);
+
+ pointerEvent.dragging = false;
+ pointerEvent.pointerDrag = null;
+
+ // send exit events as we need to simulate this on touch up on touch device
+ ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler);
+ pointerEvent.pointerEnter = null;
+ }
+ }
+
+ /// <summary>
+ /// Process submit keys.
+ /// </summary>
+ protected bool SendSubmitEventToSelectedObject()
+ {
+ if (eventSystem.currentSelectedGameObject == null)
+ return false;
+
+ var data = GetBaseEventData();
+ if (input.GetButtonDown(m_SubmitButton))
+ ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler);
+
+ if (input.GetButtonDown(m_CancelButton))
+ ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler);
+ return data.used;
+ }
+
+ private Vector2 GetRawMoveVector()
+ {
+ Vector2 move = Vector2.zero;
+ move.x = input.GetAxisRaw(m_HorizontalAxis);
+ move.y = input.GetAxisRaw(m_VerticalAxis);
+
+ if (input.GetButtonDown(m_HorizontalAxis))
+ {
+ if (move.x < 0)
+ move.x = -1f;
+ if (move.x > 0)
+ move.x = 1f;
+ }
+ if (input.GetButtonDown(m_VerticalAxis))
+ {
+ if (move.y < 0)
+ move.y = -1f;
+ if (move.y > 0)
+ move.y = 1f;
+ }
+ return move;
+ }
+
+ /// <summary>
+ /// Process keyboard events.
+ /// </summary>
+ protected bool SendMoveEventToSelectedObject()
+ {
+ float time = Time.unscaledTime;
+
+ Vector2 movement = GetRawMoveVector();
+ if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f))
+ {
+ m_ConsecutiveMoveCount = 0;
+ return false;
+ }
+
+ // If user pressed key again, always allow event
+ bool allow = input.GetButtonDown(m_HorizontalAxis) || input.GetButtonDown(m_VerticalAxis);
+ bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0);
+ if (!allow)
+ {
+ // Otherwise, user held down key or axis.
+ // If direction didn't change at least 90 degrees, wait for delay before allowing consequtive event.
+ if (similarDir && m_ConsecutiveMoveCount == 1)
+ allow = (time > m_PrevActionTime + m_RepeatDelay);
+ // If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate.
+ else
+ allow = (time > m_PrevActionTime + 1f / m_InputActionsPerSecond);
+ }
+ if (!allow)
+ return false;
+
+ // Debug.Log(m_ProcessingEvent.rawType + " axis:" + m_AllowAxisEvents + " value:" + "(" + x + "," + y + ")");
+ var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f);
+
+ if (axisEventData.moveDir != MoveDirection.None)
+ {
+ ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);
+ if (!similarDir)
+ m_ConsecutiveMoveCount = 0;
+ m_ConsecutiveMoveCount++;
+ m_PrevActionTime = time;
+ m_LastMoveVector = movement;
+ }
+ else
+ {
+ m_ConsecutiveMoveCount = 0;
+ }
+
+ return axisEventData.used;
+ }
+
+ protected void ProcessMouseEvent()
+ {
+ ProcessMouseEvent(0);
+ }
+
+ [Obsolete("This method is no longer checked, overriding it with return true does nothing!")]
+ protected virtual bool ForceAutoSelect()
+ {
+ return false;
+ }
+
+ /// <summary>
+ /// Process all mouse events.
+ /// </summary>
+ protected void ProcessMouseEvent(int id)
+ {
+ var mouseData = GetMousePointerEventData(id);
+ var leftButtonData = mouseData.GetButtonState(PointerEventData.InputButton.Left).eventData;
+
+ m_CurrentFocusedGameObject = leftButtonData.buttonData.pointerCurrentRaycast.gameObject;
+
+ // Process the first mouse button fully
+ ProcessMousePress(leftButtonData);
+ ProcessMove(leftButtonData.buttonData);
+ ProcessDrag(leftButtonData.buttonData);
+
+ // Now process right / middle clicks
+ ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData);
+ ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData.buttonData);
+ ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData);
+ ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData.buttonData);
+
+ if (!Mathf.Approximately(leftButtonData.buttonData.scrollDelta.sqrMagnitude, 0.0f))
+ {
+ var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(leftButtonData.buttonData.pointerCurrentRaycast.gameObject);
+ ExecuteEvents.ExecuteHierarchy(scrollHandler, leftButtonData.buttonData, ExecuteEvents.scrollHandler);
+ }
+ }
+
+ protected bool SendUpdateEventToSelectedObject()
+ {
+ if (eventSystem.currentSelectedGameObject == null)
+ return false;
+
+ var data = GetBaseEventData();
+ ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
+ return data.used;
+ }
+
+ /// <summary>
+ /// Process the current mouse press.
+ /// </summary>
+ protected void ProcessMousePress(MouseButtonEventData data)
+ {
+ var pointerEvent = data.buttonData;
+ var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;
+
+ // PointerDown notification
+ if (data.PressedThisFrame())
+ {
+ pointerEvent.eligibleForClick = true;
+ pointerEvent.delta = Vector2.zero;
+ pointerEvent.dragging = false;
+ pointerEvent.useDragThreshold = true;
+ pointerEvent.pressPosition = pointerEvent.position;
+ pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;
+
+ DeselectIfSelectionChanged(currentOverGo, pointerEvent);
+
+ // search for the control that will receive the press
+ // if we can't find a press handler set the press
+ // handler to be what would receive a click.
+ var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler);
+
+ // didnt find a press handler... search for a click handler
+ if (newPressed == null)
+ newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
+
+ // Debug.Log("Pressed: " + newPressed);
+
+ float time = Time.unscaledTime;
+
+ if (newPressed == pointerEvent.lastPress)
+ {
+ var diffTime = time - pointerEvent.clickTime;
+ if (diffTime < 0.3f)
+ ++pointerEvent.clickCount;
+ else
+ pointerEvent.clickCount = 1;
+
+ pointerEvent.clickTime = time;
+ }
+ else
+ {
+ pointerEvent.clickCount = 1;
+ }
+
+ pointerEvent.pointerPress = newPressed;
+ pointerEvent.rawPointerPress = currentOverGo;
+
+ pointerEvent.clickTime = time;
+
+ // Save the drag handler as well
+ pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
+
+ if (pointerEvent.pointerDrag != null)
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag);
+ }
+
+ // PointerUp notification
+ if (data.ReleasedThisFrame())
+ {
+ // Debug.Log("Executing pressup on: " + pointer.pointerPress);
+ ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
+
+ // Debug.Log("KeyCode: " + pointer.eventData.keyCode);
+
+ // see if we mouse up on the same element that we clicked on...
+ var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
+
+ // PointerClick and Drop events
+ if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick)
+ {
+ ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler);
+ }
+ else if (pointerEvent.pointerDrag != null && pointerEvent.dragging)
+ {
+ ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler);
+ }
+
+ pointerEvent.eligibleForClick = false;
+ pointerEvent.pointerPress = null;
+ pointerEvent.rawPointerPress = null;
+
+ if (pointerEvent.pointerDrag != null && pointerEvent.dragging)
+ ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler);
+
+ pointerEvent.dragging = false;
+ pointerEvent.pointerDrag = null;
+
+ // redo pointer enter / exit to refresh state
+ // so that if we moused over somethign that ignored it before
+ // due to having pressed on something else
+ // it now gets it.
+ if (currentOverGo != pointerEvent.pointerEnter)
+ {
+ HandlePointerExitAndEnter(pointerEvent, null);
+ HandlePointerExitAndEnter(pointerEvent, currentOverGo);
+ }
+ }
+ }
+
+ protected GameObject GetCurrentFocusedGameObject()
+ {
+ return m_CurrentFocusedGameObject;
+ }
+ }
+}