using System; using System.Collections; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UIElements; // ReSharper disable MemberCanBeProtected.Global // ReSharper disable ClassWithVirtualMembersNeverInherited.Global // ReSharper disable UnusedMember.Global namespace BITKit.UX { public class UIToolKitPanel : MonoBehaviour,IUXPanel { public const string USSEntry = "transition_entry"; public const string USSEntryAsync = "transition_entry_async"; public const string USSEntered = "transition_entried"; public const string USSExit = "transition_exit"; public const string USSExitAsync = "transition_exit_async"; public const string USSExited = "transition_exited"; [RuntimeInitializeOnLoadMethod] private static void Reload() { InputActionGroup = new InputActionGroup { allowGlobalActivation = false, Source = nameof(UIToolKitPanel) }; InputActionGroup.allowInput.AddElement(0); } public UIToolKitPanel() { Index = GetType().FullName; } [Header(Constant.Header.Components)] [SerializeField] protected UIDocument document; [Header(Constant.Header.Settings)] [SerializeField] private bool isWindow; [SerializeField] private bool closeWhenClickOutside; [SerializeField] private bool isAnimate; [SerializeField] private bool allowCursor; [SerializeField] private bool allowInput; [Header(Constant.Header.Settings)] [SerializeField] private Optional entryDuration; [SerializeField] private Optional exitDuration; protected static InputActionGroup InputActionGroup = new() { allowGlobalActivation = false, Source = nameof(UIToolKitPanel) }; public bool IsWindow => isWindow; public string Index { get; private set; } public bool AllowCursor => allowCursor; public bool AllowInput => allowInput; protected float TargetOpacity { get; private set; } protected virtual VisualElement background => document.rootVisualElement; // protected float CurrentOpacity // { // get => background?.GetOpacity() ?? currentOpacity; // set // { // currentOpacity = value; // background?.SetOpacity(value); // } // } protected virtual void Awake() { Index= typeof(UIToolKitPanel) == GetType() ? gameObject.name : GetType().Name; document.rootVisualElement.SetActive(false); //background?.SetOpacity(0); if (IsWindow) document.sortingOrder++; } protected virtual void Start() { UXUtils.Inject(this); document.rootVisualElement.AddToClassList(USSEntry); UxService.Register(this); destroyCancellationToken.Register(() => { UxService.UnRegister(this); }); var returnButton = document.rootVisualElement.Q("return-button"); returnButton?.RegisterCallback(x => { if (x.button is 0) OnReturn(); }); var invisible = document.rootVisualElement.Create(); invisible.name = "invisible_return_generate"; invisible.style.position = Position.Absolute; invisible.pickingMode = PickingMode.Ignore; invisible.style.left = 0; invisible.style.right = 0; invisible.style.top = 0; invisible.style.bottom = 0; invisible.SendToBack(); if (closeWhenClickOutside) { invisible.RegisterCallback(x => { OnReturn(); }); invisible.pickingMode = PickingMode.Position; } if (isWindow) { invisible.style.backgroundColor = new Color(0, 0, 0, 0.9f); } } public bool IsEntered { get; set; } [BIT] public void Entry() { UxService.Entry(this); } protected virtual void OnReturn() { UxService.Return(); } protected virtual void OnEnable(){} protected virtual void OnDisable(){} protected virtual void OnPanelEntry(){} protected virtual void OnPanelExit(){} void IEntryElement.Entry() { try { document.rootVisualElement.SetActive(true); OnEntry?.Invoke(); } catch (Exception e) { Debug.Log(gameObject.name); throw; } } async UniTask IEntryElement.EntryAsync() { document.rootVisualElement.AddToClassList(USSEntry); document.rootVisualElement.AddToClassList(USSEntryAsync); if (entryDuration.Allow) { var task = EntryAsync(); var durationTask = UniTask.Delay(TimeSpan.FromSeconds(entryDuration.Value), cancellationToken: destroyCancellationToken); await durationTask; document.rootVisualElement.RemoveFromClassList(USSEntry); document.rootVisualElement.RemoveFromClassList(USSEntryAsync); document.rootVisualElement.AddToClassList(USSEntered); await task; } else { await EntryAsync(); } } public virtual UniTask EntryAsync() { return UniTask.CompletedTask; } void IEntryElement.Entered() { OnPanelEntry(); } void IEntryElement.Exit() { document.rootVisualElement.AddToClassList(USSExit); //if (IsValid is false) return; OnPanelExit(); } async UniTask IEntryElement.ExitAsync() { document.rootVisualElement.RemoveFromClassList(USSEntered); document.rootVisualElement.AddToClassList(USSExitAsync); if (entryDuration.Allow is false) return; await UniTask.Delay(TimeSpan.FromSeconds(entryDuration.Value), cancellationToken: destroyCancellationToken); } void IEntryElement.Exited() { document.rootVisualElement.RemoveFromClassList(USSExit); document.rootVisualElement.RemoveFromClassList(USSExitAsync); document.rootVisualElement.AddToClassList(USSEntry); document.rootVisualElement.SetActive(false); OnExit?.Invoke(); } public event Action OnEntry; public event Action OnExit; public virtual void OnUpdate(float deltaTime) { } } }