using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; using UnityEngine.Events; using Sirenix.OdinInspector; using Cysharp.Threading.Tasks; using System.Threading; namespace BITKit.UX { public abstract class UXElement : Provider, IProvider, IActivable, IEnabled { protected bool isActive = true; public virtual bool Get() => isActive; public virtual void Set(bool active) { } public virtual void OnStart() { } public override void Set(T obj) { (this as IProvider).Set(obj); } public virtual void SetActive(bool active) { GetVisualElement().SetActive(active); } public virtual void SetPosition(Vector3 worldPosition) { if (Camera.main != null) { var cameraTrans = Camera.main.transform; var visualElement = GetVisualElement(); var pos = RuntimePanelUtils .CameraTransformWorldToPanel(visualElement.panel, worldPosition, Camera.main); pos.x = (pos.x - visualElement.layout.width / 2); Rect elementRect = new() { position = pos, size = visualElement.layout.size, }; visualElement.style.left = 0; visualElement.style.top = 0; visualElement.style.position = Position.Absolute; visualElement.transform.position = pos; visualElement.SetOpacity(Vector3.Dot(cameraTrans.forward, worldPosition - cameraTrans.position) > 0 ? 1 : 0); } } public virtual VisualElement GetVisualElement() => null; public virtual bool IsEnabled() { return GetVisualElement().enabledSelf; } public virtual void SetEnabled(bool enabled) { GetVisualElement().SetEnabled(enabled); } } public abstract class UXElement : UXElement, IProvider where UX : VisualElement { public static implicit operator UX(UXElement self) { return self.visualElement; } [Header(Constant.Header.Components)] public UIDocument document; [Header(Constant.Header.Settings)] public string bindName; [SerializeField, SerializeReference, SubclassSelector] IReference bindNameProvider = new GetNameFromGameobject(); [Header(Constant.Header.InternalVariables)] private UX m_visualElement; protected IStyle style => visualElement.style; public UX visualElement { get { if (m_visualElement is null) { var bindName = this.bindName; if (string.IsNullOrEmpty(bindName)) { bindName = bindNameProvider.Get(); } var split = bindName.Split(@"."); var visualElement = document.rootVisualElement; foreach (var name in split) { try { visualElement = visualElement.Q(name); } catch (System.Exception) { Debug.LogWarning(name); throw; } } m_visualElement = visualElement as UX; if (m_visualElement is null) { Debug.LogWarning(bindName); } } return m_visualElement; } } public override bool Get() => isActive; public override VisualElement GetVisualElement() => visualElement; protected CancellationToken cancellationToken; public override async void Set(bool active) { await UniTask.SwitchToMainThread(cancellationToken); visualElement.SetEnabled(active); if (active != isActive) { isActive = active; visualElement.SetEnabled(active); } } void Awake() { cancellationToken = gameObject.GetCancellationTokenOnDestroy(); OnStart(); } void OnValidate() { if (bindNameProvider is GetNameFromGameobject x) { x.gameobject = gameObject; } if (document is null) { document = GetComponentInParent(); } } UX IProvider.Get() => visualElement; public override T Get() { if (visualElement is T t) { return t; } return base.Get(); } public void Set(UX t) { var root = visualElement.parent; root.Remove(visualElement); root.Add(t); m_visualElement = t; } protected virtual void OnVistualElementDisabled() { } public void AddToClassList(string className) { visualElement.AddToClassList(className); } public void RemoveFromClassList(string className) { visualElement.RemoveFromClassList(className); } } }