1
This commit is contained in:
219
Unity/Scripts/UX/Core/UXWindowManager.cs
Normal file
219
Unity/Scripts/UX/Core/UXWindowManager.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
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;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
namespace BITKit.UX
|
||||
{
|
||||
public interface IWindowElement
|
||||
{
|
||||
string GetName();
|
||||
UXElement Navigation { get; }
|
||||
UXElement Window { get; }
|
||||
UXWindowManager SubWindowManager { get; }
|
||||
Task Open(CancellationToken cancellationToken = default);
|
||||
Task Close(CancellationToken cancellationToken = default);
|
||||
}
|
||||
[System.Serializable]
|
||||
public class UXWindowElement : IWindowElement
|
||||
{
|
||||
[SerializeField]
|
||||
protected string name;
|
||||
[SerializeField]
|
||||
protected UXElement navigation;
|
||||
[SerializeField]
|
||||
protected UXElement window;
|
||||
[SerializeField]
|
||||
protected UXWindowManager subWindowManager;
|
||||
[SerializeField]
|
||||
protected bool enabled;
|
||||
public UXElement Navigation => navigation;
|
||||
public UXElement Window => window;
|
||||
public UXWindowManager SubWindowManager => subWindowManager;
|
||||
public async Task Close(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await UniTask.SwitchToMainThread(cancellationToken);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await UniTask.Yield();
|
||||
try
|
||||
{
|
||||
navigation.GetVisualElement().SetEnabled(true);
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
Debug.LogWarning($"Navgation:{name} 已丢失");
|
||||
throw;
|
||||
}
|
||||
try
|
||||
{
|
||||
window.Set(false);
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
Debug.LogWarning($"Window:{name} 已丢失");
|
||||
throw;
|
||||
}
|
||||
enabled = false;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
Debug.LogWarning(name);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Open(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await UniTask.SwitchToMainThread(cancellationToken);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
navigation.GetVisualElement().SetEnabled(false);
|
||||
window.Set(true);
|
||||
enabled = true;
|
||||
}
|
||||
public string GetName() => name;
|
||||
|
||||
|
||||
}
|
||||
public class UXWindowManager : MonoBehaviour, INextble
|
||||
{
|
||||
public enum WindowState
|
||||
{
|
||||
None,
|
||||
Flex,
|
||||
Hidden
|
||||
}
|
||||
[Header(Constant.Header.Components)]
|
||||
[SerializeReference, SubclassSelector] public List<IWindowElement> windows = new();
|
||||
public UXWindowManager subWindowManager;
|
||||
[Header(Constant.Header.Settings)]
|
||||
public UXElement startElement;
|
||||
[SerializeField] bool hidden;
|
||||
[Header(Constant.Header.Events)]
|
||||
public UnityEvent<string> OnEntry = new();
|
||||
public UnityEvent<string> OnExit = new();
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
List<IWindowElement> activeWindows = new();
|
||||
IWindowElement activeWindow;
|
||||
public int index { get; private set; }
|
||||
CancellationTokenSource cts;
|
||||
public async void Select(UXElement element)
|
||||
{
|
||||
cts.Cancel();
|
||||
cts = new();
|
||||
foreach (var activeWindow in activeWindows)
|
||||
{
|
||||
await activeWindow.Close(cts.Token);
|
||||
OnExit.Invoke(activeWindow.GetName());
|
||||
|
||||
}
|
||||
|
||||
activeWindows.Clear();
|
||||
var window = windows
|
||||
.Find(x => x.GetName() == element.name || x.Navigation == element || x.Window == element);
|
||||
index = windows.IndexOf(window);
|
||||
activeWindows.Add(window);
|
||||
activeWindow = window;
|
||||
// currentWindow = window;
|
||||
try
|
||||
{
|
||||
await window.Open();
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
Debug.LogWarning(name);
|
||||
if (window is null)
|
||||
{
|
||||
Debug.Log("Window is Null");
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
OnEntry.Invoke(window.GetName());
|
||||
}
|
||||
public bool Next()
|
||||
{
|
||||
if (activeWindow is not null && activeWindow.SubWindowManager)
|
||||
{
|
||||
if (activeWindow.SubWindowManager.Next())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (windows.Count > index + 1)
|
||||
{
|
||||
var element = windows[index + 1].Navigation;
|
||||
Select(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Previous()
|
||||
{
|
||||
if (activeWindow is not null && activeWindow.SubWindowManager)
|
||||
{
|
||||
if (activeWindow.SubWindowManager.Previous())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (index - 1 >= 0)
|
||||
{
|
||||
var element = windows[index - 1].Navigation;
|
||||
Select(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool Hidden
|
||||
{
|
||||
get => hidden;
|
||||
set
|
||||
{
|
||||
if (hidden)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
Recovery();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Exit()
|
||||
{
|
||||
hidden = true;
|
||||
activeWindow?.Close();
|
||||
}
|
||||
public void Recovery()
|
||||
{
|
||||
hidden = false;
|
||||
activeWindow?.Open();
|
||||
}
|
||||
void Awake()
|
||||
{
|
||||
cts = new();
|
||||
var ct = gameObject.GetCancellationTokenOnDestroy();
|
||||
ct.Register(cts.Cancel);
|
||||
}
|
||||
async void Start()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
foreach (var window in windows)
|
||||
{
|
||||
await window.Close(cts.Token);
|
||||
}
|
||||
Select(startElement);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user