BITKit/Packages/Runtime/UX/Core/UXElement.cs

169 lines
5.5 KiB
C#

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<bool>, 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>(T obj)
{
(this as IProvider<T>).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<UX> : UXElement, IProvider<UX> where UX : VisualElement
{
public static implicit operator UX(UXElement<UX> 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<UIDocument>();
}
}
UX IProvider<UX>.Get() => visualElement;
public override T Get<T>()
{
if (visualElement is T t)
{
return t;
}
return base.Get<T>();
}
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);
}
}
}