using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.UIElements;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BITKit.UX
{
[Serializable]
public class AllowTouchWhenPointerNotOverUI : ICondition
{
public bool OnCheck() => UXAllowTouch.Singleton.AllowTouch;
}
/*
* 当指针进入区域时启用输入
* 当指针离开区域时禁用输入,直到所有设备都没有按下,才会再次启用输入
*/
///
/// Allow touch when pointer not over UI
///
public class UXAllowTouch : UXElement, ICondition
{
internal static UXAllowTouch Singleton { get; private set; }
public bool AllowTouch;
internal bool IsHoveringUI { get; private set; }
public bool IsTouching { get; private set; }
private int updateRequest;
private CancellationTokenSource cancellationTokenSource;
public override void OnAwake()
{
Singleton = this;
EnhancedTouchSupport.Enable();
Touch.onFingerUp += OnFingerUp;
Touch.onFingerDown += OnFingerDown;
cancellationTokenSource = new CancellationTokenSource();
}
private void OnDestroy()
{
cancellationTokenSource.Cancel();
}
private async void OnFingerDown(Finger obj)
{
IsTouching = true;
try
{
await Task.Delay(TimeSpan.FromSeconds(Time.deltaTime*2));
AllowTouch = !IsHoveringUI;
}
catch (OperationCanceledException)
{
}
}
private void OnFingerUp(Finger obj)
{
IsTouching = false;
}
public override void OnStart()
{
base.OnStart();
visualElement.RegisterCallback(OnPointerEnter);
visualElement.RegisterCallback(OnPointerLevel);
}
private void OnPointerLevel(PointerLeaveEvent evt)
{
IsHoveringUI = true;
if (isMouseInput) AllowTouch = false;
}
private void OnPointerEnter(PointerEnterEvent evt)
{
IsHoveringUI = false;
if (isMouseInput) AllowTouch = true;
}
public bool OnCheck() => AllowTouch;
private bool isMouseInput => Mouse.current?.delta.ReadValue().sqrMagnitude > 0;
}
#if UNITY_EDITOR
[CustomEditor(typeof(UXAllowTouch))]
public class UXAllowTouchInspector:BITInspector
{
private Label allowTouchLabel;
private Label isHoveringUILabel;
private Label isTouching;
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle("Editor");
allowTouchLabel = root.Create