Files
riversong-code-showcase/Source/Riversong/Game/UI/Framework/UIRoot.cs
2026-05-21 16:04:49 +02:00

83 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
namespace DanieleMarotta.RiversongCodeShowcase
{
[RequireComponent(typeof(UIDocument))]
public class UIRoot : MonoBehaviour, IUIRoot
{
private UIDocument _document;
private Dictionary<Type, UIView> _views = new();
public VisualElement RootVisualElement { get; private set; }
public event Action<ClickEvent> ElementClicked;
private void Awake()
{
_document = GetComponent<UIDocument>();
}
public async UniTask Initialize(UIService uiService)
{
RootVisualElement = _document.rootVisualElement;
await DiscoverViewsAsync(uiService);
InitializeDragging();
RootVisualElement.RegisterCallback<ClickEvent>(OnClick);
}
public void Dispose()
{
foreach (var view in _views.Values) view.Dispose();
RootVisualElement.UnregisterCallback<ClickEvent>(OnClick);
}
private void OnClick(ClickEvent evt)
{
ElementClicked?.Invoke(evt);
}
private async UniTask DiscoverViewsAsync(UIService uiService)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
foreach (var type in assembly.GetTypes())
{
var viewAttribute = type.GetCustomAttribute<UIViewAttribute>();
if (viewAttribute == null) continue;
var element = RootVisualElement.Q(className: viewAttribute.UssClassName);
var view = await uiService.CreateView(type, element);
_views.Add(type, view);
}
}
private void InitializeDragging()
{
var targets = RootVisualElement.Query<VisualElement>(className: "drag-target").ToList();
foreach (var target in targets) MakeDraggable(target);
}
public void MakeDraggable(VisualElement target)
{
var handle = target.Q<VisualElement>(className: "drag-handle") ?? target;
handle.AddManipulator(new DraggableManipulator(target));
}
public T GetView<T>() where T : UIView
{
return _views.TryGetValue(typeof(T), out var view) ? (T)view : null;
}
}
}