using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine.UIElements; namespace DanieleMarotta.RiversongCodeShowcase { public abstract class UIView : IDisposable { private UIVisibilityAnimation _visibilityAnimation; public UIService UIService { get; private set; } public VisualElement RootElement { get; private set; } public event Action OpenedOrClosed; public virtual UniTask InitializeAsync(UIService uiService, VisualElement rootElement) { UIService = uiService; RootElement = rootElement; _visibilityAnimation = new UIVisibilityAnimation(rootElement, isOpen => OpenedOrClosed?.Invoke(isOpen)); return UniTask.CompletedTask; } public bool IsOpen() { return _visibilityAnimation.IsOpen; } public void Show(bool show, bool animate = false) { _visibilityAnimation.Show(show, animate); } public virtual void Dispose() { } } public abstract class UIView : UIView where T : class { public T Model { get; private set; } public void SetModel(T model) { if (EqualityComparer.Default.Equals(Model, model)) return; var oldModel = Model; Model = model; if (oldModel is IUIModel oldUiModel) oldUiModel.Changed -= OnModelChanged; if (oldModel is INotifyBindablePropertyChanged oldNotifyingModel) oldNotifyingModel.propertyChanged -= OnModelPropertyChanged; if (model is IUIModel uiModel) uiModel.Changed += OnModelChanged; if (model is INotifyBindablePropertyChanged notifyingModel) notifyingModel.propertyChanged += OnModelPropertyChanged; RootElement.dataSource = model; OnNewModel(model); } protected virtual void OnNewModel(T model) { } protected virtual void OnModelChanged() { } protected virtual void OnModelPropertyChanged(object sender, BindablePropertyChangedEventArgs e) { } } public static class UIViewExtensions { public static void Toggle(this UIView view, bool animate = false) { view.Show(!view.IsOpen(), animate); } } }