780 lines
27 KiB
C#
780 lines
27 KiB
C#
// --------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="UxrControlInput.cs" company="VRMADA">
|
|
// Copyright (c) VRMADA, All rights reserved.
|
|
// </copyright>
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using UltimateXR.Extensions.System.Threading;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UltimateXR.UI.UnityInputModule.Controls
|
|
{
|
|
public delegate void DragStartedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void DraggedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void DragEndedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void DroppedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void PressedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void ReleasedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void ClickedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void PressHeldEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void CursorEnteredEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void CursorExitedEventHandler(UxrControlInput controlInput, PointerEventData eventData);
|
|
public delegate void UpdateSelectedEventHandler(UxrControlInput controlInput, BaseEventData eventData);
|
|
public delegate void InputSubmittedEventHandler(UxrControlInput controlInput, BaseEventData eventData);
|
|
|
|
/// <summary>
|
|
/// A component derived from <see cref="EventTrigger" /> that simplifies the handling of events triggered by UI
|
|
/// controls. Among the key benefits are:
|
|
/// <list type="bullet">
|
|
/// <item>
|
|
/// Be able to write UI code by subscribing to events generated by UI controls. Global static events are
|
|
/// also provided to handle events coming from any control.
|
|
/// </item>
|
|
/// <item>
|
|
/// New controls with more complex behaviour can inherit from this class and add their own logic. Event
|
|
/// triggers are provided so that handling events can be done by overriding the appropriate methods, making
|
|
/// sure the base class is always called at the beginning. An example is <see cref="UxrToggleControlInput" />.
|
|
/// </item>
|
|
/// <item>
|
|
/// Each <see cref="UxrControlInput" /> can specify the audio/haptic feedback for the click/down/up events.
|
|
/// </item>
|
|
/// </list>
|
|
/// </summary>
|
|
public class UxrControlInput : EventTrigger
|
|
{
|
|
#region Inspector Properties/Serialized Fields
|
|
|
|
[SerializeField] private float _pressAndHoldDuration = 1.0f;
|
|
[SerializeField] private UxrControlFeedback _feedbackOnPress;
|
|
[SerializeField] private UxrControlFeedback _feedbackOnRelease;
|
|
[SerializeField] private UxrControlFeedback _feedbackOnClick;
|
|
|
|
#endregion
|
|
|
|
#region Public Types & Data
|
|
|
|
/// <summary>
|
|
/// Event called whenever any <see cref="UxrControlInput" /> is pressed.
|
|
/// </summary>
|
|
public static event PressedEventHandler GlobalPressed;
|
|
|
|
/// <summary>
|
|
/// Event called whenever any <see cref="UxrControlInput" /> press is released.
|
|
/// </summary>
|
|
public static event ReleasedEventHandler GlobalReleased;
|
|
|
|
/// <summary>
|
|
/// Event called whenever any <see cref="UxrControlInput" /> is clicked. A click depending on the operating mode can be
|
|
/// a press or a release after a press.
|
|
/// </summary>
|
|
public static event ClickedEventHandler GlobalClicked;
|
|
|
|
/// <summary>
|
|
/// Event called whenever any <see cref="UxrControlInput" /> started being dragged.
|
|
/// </summary>
|
|
public static event DragStartedEventHandler GlobalDragStarted;
|
|
|
|
/// <summary>
|
|
/// Event called during the frames any <see cref="UxrControlInput" /> is being dragged.
|
|
/// </summary>
|
|
public static event DraggedEventHandler GlobalDragged;
|
|
|
|
/// <summary>
|
|
/// Event called whenever any <see cref="UxrControlInput" /> stopped being dragged.
|
|
/// </summary>
|
|
public static event DragEndedEventHandler GlobalDragEnded;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control started being dragged.
|
|
/// </summary>
|
|
public event DragStartedEventHandler DragStarted;
|
|
|
|
/// <summary>
|
|
/// Event called each frame the control is being dragged.
|
|
/// </summary>
|
|
public event DraggedEventHandler Dragged;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control stopped being dragged.
|
|
/// </summary>
|
|
public event DragEndedEventHandler DragEnded;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control was dropped.
|
|
/// </summary>
|
|
public event DroppedEventHandler Dropped;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control was pressed.
|
|
/// </summary>
|
|
public event PressedEventHandler Pressed;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control was released after being pressed.
|
|
/// </summary>
|
|
public event ReleasedEventHandler Released;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control was clicked. A click depending on the operating mode can be a press or a release
|
|
/// after a press.
|
|
/// </summary>
|
|
public event ClickedEventHandler Clicked;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control was kept being pressed for <see cref="PressAndHoldDuration" /> seconds without
|
|
/// being dragged.
|
|
/// </summary>
|
|
public event PressHeldEventHandler PressHeld;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the pointer entered the control.
|
|
/// </summary>
|
|
public event CursorEnteredEventHandler CursorEntered;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the pointer exited the control.
|
|
/// </summary>
|
|
public event CursorExitedEventHandler CursorExited;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the selected control's input field is updated/changed.
|
|
/// </summary>
|
|
public event UpdateSelectedEventHandler UpdateSelected;
|
|
|
|
/// <summary>
|
|
/// Event called whenever the control's input field was submitted (OK was pressed).
|
|
/// </summary>
|
|
public event InputSubmittedEventHandler InputSubmitted;
|
|
|
|
/// <summary>
|
|
/// Gets the control's GameObject
|
|
/// </summary>
|
|
public GameObject GameObject => gameObject;
|
|
|
|
/// <summary>
|
|
/// Gets the Unity RectTransform component.
|
|
/// </summary>
|
|
public RectTransform RectTransform { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the Unity Image component on the same object if it exists.
|
|
/// </summary>
|
|
public Image Image { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the ScrollRect reference used in drag/scroll events.
|
|
/// </summary>
|
|
public ScrollRect ScrollRect { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets whether the control is currently being dragged.
|
|
/// </summary>
|
|
public bool IsDragging { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets whether the component is being destroyed. This means OnDestroy() was called the same frame
|
|
/// and will effectively be destroyed at the end of it.
|
|
/// </summary>
|
|
public bool IsBeingDestroyed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether the object can be interacted with and will send any events.
|
|
/// </summary>
|
|
public bool Enabled
|
|
{
|
|
get => enabled;
|
|
set
|
|
{
|
|
enabled = value;
|
|
|
|
if (_selectable != null)
|
|
{
|
|
_selectable.interactable = value && _interactable;
|
|
}
|
|
|
|
if (_graphic != null)
|
|
{
|
|
_graphic.raycastTarget = value && _raycastTarget;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether the widget is interactable or not. The widget should have a <see cref="Selectable" />
|
|
/// component.
|
|
/// </summary>
|
|
public bool Interactable
|
|
{
|
|
get => _interactable;
|
|
set
|
|
{
|
|
if (_selectable != null)
|
|
{
|
|
_selectable.interactable = value;
|
|
}
|
|
|
|
_interactable = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the custom data property.
|
|
/// </summary>
|
|
public object Tag { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets whether the control was clicked since the last time it was set to false.
|
|
/// </summary>
|
|
public bool WasClicked { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets how many seconds need to pass to trigger a <see cref="PressHeld" /> event
|
|
/// </summary>
|
|
public float PressAndHoldDuration
|
|
{
|
|
get => _pressAndHoldDuration;
|
|
set => _pressAndHoldDuration = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the feedback when the UI element was pressed.
|
|
/// </summary>
|
|
public UxrControlFeedback FeedbackOnDown
|
|
{
|
|
get => _feedbackOnPress;
|
|
set => _feedbackOnPress = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the feedback when the UI element was released.
|
|
/// </summary>
|
|
public UxrControlFeedback FeedbackOnUp
|
|
{
|
|
get => _feedbackOnRelease;
|
|
set => _feedbackOnRelease = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the feedback when the UI element was clicked.
|
|
/// </summary>
|
|
public UxrControlFeedback FeedbackOnClick
|
|
{
|
|
get => _feedbackOnClick;
|
|
set => _feedbackOnClick = value;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Creates an awaitable task that blocks until a control from a given set is clicked, and returns the control that was
|
|
/// clicked.
|
|
/// </summary>
|
|
/// <param name="ct">Cancellation token, to cancel the task</param>
|
|
/// <param name="controls">Controls to listen to</param>
|
|
/// <returns>Awaitable <see cref="Task" /> returning the control that was clicked, or null if the task was cancelled</returns>
|
|
public static async Task<UxrControlInput> WaitForClickAsync(CancellationToken ct, params UxrControlInput[] controls)
|
|
{
|
|
async Task<UxrControlInput> ReadControl(UxrControlInput control, CancellationToken ct = default)
|
|
{
|
|
await control.WaitForClickAsync(ct);
|
|
return ct.IsCancellationRequested ? null : control;
|
|
}
|
|
|
|
using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
|
IEnumerable<Task<UxrControlInput>> tasks = controls.Select(b => ReadControl(b, ct));
|
|
Task<UxrControlInput> finishedTask = await Task.WhenAny(tasks);
|
|
|
|
if (!finishedTask.IsCanceled)
|
|
{
|
|
cts.Cancel();
|
|
}
|
|
|
|
return await finishedTask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an awaitable task that blocks until the control is clicked.
|
|
/// </summary>
|
|
/// <param name="ct">Optional cancellation token, to cancel the task</param>
|
|
/// <returns>Awaitable <see cref="Task" /> returning the control that was clicked or null if the task was cancelled</returns>
|
|
public async Task WaitForClickAsync(CancellationToken ct = default)
|
|
{
|
|
bool isClicked = false;
|
|
|
|
void ControlClicked(UxrControlInput localControl, PointerEventData eventData)
|
|
{
|
|
isClicked = localControl.Interactable;
|
|
}
|
|
|
|
Clicked += ControlClicked;
|
|
await TaskExt.WaitUntil(() => isClicked, ct);
|
|
Clicked -= ControlClicked;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Unity
|
|
|
|
/// <summary>
|
|
/// Sets up the internal references.
|
|
/// </summary>
|
|
protected virtual void Awake()
|
|
{
|
|
RectTransform = GetComponent<RectTransform>();
|
|
Image = GetComponent<Image>();
|
|
ScrollRect = GetComponentInParent<ScrollRect>();
|
|
_selectable = GetComponent<Selectable>();
|
|
_graphic = GetComponent<Graphic>();
|
|
|
|
if (_graphic)
|
|
{
|
|
_raycastTarget = _graphic.raycastTarget;
|
|
}
|
|
|
|
if (_selectable != null)
|
|
{
|
|
Interactable &= _selectable.interactable;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity OnDestroy() method.
|
|
/// </summary>
|
|
protected virtual void OnDestroy()
|
|
{
|
|
IsBeingDestroyed = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity OnEnable() method.
|
|
/// </summary>
|
|
protected virtual void OnEnable()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity OnDisable() method.
|
|
/// </summary>
|
|
protected virtual void OnDisable()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the component.
|
|
/// </summary>
|
|
protected virtual void Reset()
|
|
{
|
|
_feedbackOnPress = UxrControlFeedback.FeedbackDown;
|
|
_feedbackOnRelease = UxrControlFeedback.FeedbackUp;
|
|
_feedbackOnClick = UxrControlFeedback.FeedbackClick;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity Start() method.
|
|
/// </summary>
|
|
protected virtual void Start()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks for the press held event.
|
|
/// </summary>
|
|
protected virtual void Update()
|
|
{
|
|
CheckPressHeldEvent();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Event Trigger Methods
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control started being dragged.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnBeginDrag(PointerEventData eventData)
|
|
{
|
|
base.OnBeginDrag(eventData);
|
|
|
|
OnDragStarted(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity each frame the control is being dragged.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnDrag(PointerEventData eventData)
|
|
{
|
|
base.OnDrag(eventData);
|
|
|
|
OnDragged(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when a drag event ended on the control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnEndDrag(PointerEventData eventData)
|
|
{
|
|
base.OnEndDrag(eventData);
|
|
|
|
OnDragEnded(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was dropped.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnDrop(PointerEventData eventData)
|
|
{
|
|
base.OnDrop(eventData);
|
|
|
|
OnDropped(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was pressed.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
base.OnPointerDown(eventData);
|
|
|
|
OnPressed(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was released after being pressed.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnPointerUp(PointerEventData eventData)
|
|
{
|
|
base.OnPointerUp(eventData);
|
|
|
|
OnReleased(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was clicked. A click depending on the operating mode can be a press or a
|
|
/// release after a press.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
base.OnPointerClick(eventData);
|
|
|
|
OnClicked(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the cursor entered the control rect.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
base.OnPointerEnter(eventData);
|
|
|
|
OnCursorEntered(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the cursor exited the control rect.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
base.OnPointerExit(eventData);
|
|
|
|
OnCursorExited(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the content of an InputField was updated on the control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnUpdateSelected(BaseEventData eventData)
|
|
{
|
|
base.OnUpdateSelected(eventData);
|
|
|
|
if (enabled && UpdateSelected != null)
|
|
{
|
|
UpdateSelected?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the content of an InputField was validated (OK was pressed) on the control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnSubmit(BaseEventData eventData)
|
|
{
|
|
base.OnSubmit(eventData);
|
|
|
|
OnInputSubmitted(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the content was scrolled on the control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnScroll(PointerEventData eventData)
|
|
{
|
|
base.OnScroll(eventData);
|
|
|
|
if (ScrollRect != null)
|
|
{
|
|
ScrollRect.OnScroll(eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was selected.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnSelect(BaseEventData eventData)
|
|
{
|
|
base.OnSelect(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when a Cancel event was sent to control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnCancel(BaseEventData eventData)
|
|
{
|
|
base.OnCancel(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when the control was deselected.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnDeselect(BaseEventData eventData)
|
|
{
|
|
base.OnDeselect(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called by Unity when a potential drag could be started on the the control but the drag did not start yet.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnInitializePotentialDrag(PointerEventData eventData)
|
|
{
|
|
base.OnInitializePotentialDrag(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called when navigating through the control.
|
|
/// </summary>
|
|
/// <param name="eventData">Event data</param>
|
|
public override void OnMove(AxisEventData eventData)
|
|
{
|
|
base.OnMove(eventData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="DragStarted" /> and <see cref="GlobalDragStarted" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnDragStarted(PointerEventData eventData)
|
|
{
|
|
if (ScrollRect != null)
|
|
{
|
|
ScrollRect.OnBeginDrag(eventData);
|
|
}
|
|
|
|
if (enabled)
|
|
{
|
|
IsDragging = true;
|
|
|
|
DragStarted?.Invoke(this, eventData);
|
|
GlobalDragStarted?.Invoke(this, eventData);
|
|
}
|
|
|
|
ResetTapAndHoldEventInfo();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="Dragged" /> and <see cref="GlobalDragged" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnDragged(PointerEventData eventData)
|
|
{
|
|
if (ScrollRect != null)
|
|
{
|
|
ScrollRect.OnDrag(eventData);
|
|
}
|
|
|
|
if (enabled)
|
|
{
|
|
Dragged?.Invoke(this, eventData);
|
|
GlobalDragged?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="DragEnded" /> and <see cref="GlobalDragEnded" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnDragEnded(PointerEventData eventData)
|
|
{
|
|
if (ScrollRect != null)
|
|
{
|
|
ScrollRect.OnEndDrag(eventData);
|
|
}
|
|
|
|
if (enabled)
|
|
{
|
|
IsDragging = false;
|
|
|
|
DragEnded?.Invoke(this, eventData);
|
|
GlobalDragEnded?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="Dropped" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnDropped(PointerEventData eventData)
|
|
{
|
|
if (enabled && Dropped != null)
|
|
{
|
|
Dropped?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="Pressed" /> and <see cref="GlobalPressed" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnPressed(PointerEventData eventData)
|
|
{
|
|
if (enabled)
|
|
{
|
|
_isPressAndHold = true;
|
|
_pressAndHoldEventData = eventData;
|
|
_pressAndHoldTimer = 0.0f;
|
|
|
|
GlobalPressed?.Invoke(this, eventData);
|
|
Pressed?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="Released" /> and <see cref="GlobalReleased" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnReleased(PointerEventData eventData)
|
|
{
|
|
if (enabled)
|
|
{
|
|
GlobalReleased?.Invoke(this, eventData);
|
|
Released?.Invoke(this, eventData);
|
|
}
|
|
|
|
ResetTapAndHoldEventInfo();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="Clicked" /> and <see cref="GlobalClicked" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnClicked(PointerEventData eventData)
|
|
{
|
|
if (!IsDragging && enabled && Interactable)
|
|
{
|
|
WasClicked = true;
|
|
GlobalClicked?.Invoke(this, eventData);
|
|
Clicked?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="CursorEntered" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnCursorEntered(PointerEventData eventData)
|
|
{
|
|
if (enabled)
|
|
{
|
|
CursorEntered?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="CursorExited" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnCursorExited(PointerEventData eventData)
|
|
{
|
|
if (enabled)
|
|
{
|
|
CursorExited?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overridable event trigger for <see cref="InputSubmitted" />.
|
|
/// </summary>
|
|
/// <param name="eventData">Event parameters</param>
|
|
protected virtual void OnInputSubmitted(BaseEventData eventData)
|
|
{
|
|
if (enabled && InputSubmitted != null)
|
|
{
|
|
InputSubmitted?.Invoke(this, eventData);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Checks if the TapAndHold timer reached its goal.
|
|
/// </summary>
|
|
private void CheckPressHeldEvent()
|
|
{
|
|
if (PressHeld != null && _isPressAndHold)
|
|
{
|
|
_pressAndHoldTimer += Time.deltaTime;
|
|
if (_pressAndHoldTimer > _pressAndHoldDuration)
|
|
{
|
|
PressHeld(this, _pressAndHoldEventData);
|
|
ResetTapAndHoldEventInfo();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the TapAndHold timers and state
|
|
/// </summary>
|
|
private void ResetTapAndHoldEventInfo()
|
|
{
|
|
_isPressAndHold = false;
|
|
_pressAndHoldEventData = null;
|
|
_pressAndHoldTimer = 0.0f;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Types & Data
|
|
|
|
private Selectable _selectable;
|
|
private Graphic _graphic;
|
|
private bool _raycastTarget;
|
|
private float _pressAndHoldTimer;
|
|
private bool _isPressAndHold;
|
|
private PointerEventData _pressAndHoldEventData;
|
|
private bool _interactable = true;
|
|
|
|
#endregion
|
|
}
|
|
} |