284 lines
8.9 KiB
C#
284 lines
8.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace AlicizaX.UI.Runtime
|
|
{
|
|
internal sealed partial class UIManager
|
|
{
|
|
private readonly Dictionary<UILayer, List<PanelInfo>> mShowUIWindow = new Dictionary<UILayer, List<PanelInfo>>((int)UILayer.All);
|
|
|
|
|
|
private async UniTask<UIWindow> ShowUIImplAsync(Type type, params System.Object[] userDatas)
|
|
{
|
|
var panelInfo = CreateUIClsInstance(type);
|
|
panelInfo.UIBasePanel.RefreshParams(userDatas);
|
|
if (panelInfo.PanelState == EPanelState.None && !panelInfo.UIBasePanel.IsLoaded)
|
|
{
|
|
await CreateUIResInstanceAsync(panelInfo);
|
|
panelInfo.UIBasePanel.InternalInitlize();
|
|
Push(panelInfo);
|
|
}
|
|
else if (panelInfo.PanelState == EPanelState.Show)
|
|
{
|
|
Pop(panelInfo);
|
|
Push(panelInfo);
|
|
}
|
|
else if (panelInfo.PanelState == EPanelState.Cache)
|
|
{
|
|
RemoveFromCache(panelInfo);
|
|
Push(panelInfo);
|
|
}
|
|
|
|
BeforeShowUI(panelInfo).Forget();
|
|
|
|
return panelInfo.UIBasePanel;
|
|
}
|
|
|
|
public UIWindow ShowUIImpl(Type type, params System.Object[] userDatas)
|
|
{
|
|
var panelInfo = CreateUIClsInstance(type);
|
|
panelInfo.UIBasePanel.RefreshParams(userDatas);
|
|
if (panelInfo.PanelState == EPanelState.None && !panelInfo.UIBasePanel.IsLoaded)
|
|
{
|
|
CreateUIResInstance(panelInfo);
|
|
panelInfo.UIBasePanel.InternalInitlize();
|
|
Push(panelInfo);
|
|
}
|
|
else if (panelInfo.PanelState == EPanelState.Show)
|
|
{
|
|
Pop(panelInfo);
|
|
Push(panelInfo);
|
|
}
|
|
else if (panelInfo.PanelState == EPanelState.Cache)
|
|
{
|
|
RemoveFromCache(panelInfo);
|
|
Push(panelInfo);
|
|
}
|
|
|
|
BeforeShowUI(panelInfo).Forget();
|
|
|
|
return panelInfo.UIBasePanel;
|
|
}
|
|
|
|
|
|
public void CloseUIImpl(Type type, bool force)
|
|
{
|
|
var panelInfo = GetWindowInfo(type);
|
|
|
|
if (panelInfo.UIBasePanel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AfterCloseUI(panelInfo, force).Forget();
|
|
}
|
|
|
|
private PanelInfo CreateUIClsInstance(Type type)
|
|
{
|
|
var info = GetWindowInfo(type);
|
|
if (info.PanelState == EPanelState.None && info.UIBasePanel == null)
|
|
{
|
|
info.Reset((UIWindow)Activator.CreateInstance(info.UIClsType));
|
|
}
|
|
else if (info.PanelState == EPanelState.Cache && info.UIBasePanel == null)
|
|
{
|
|
RemoveFromCache(info);
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
private async UniTask CreateUIResInstanceAsync(PanelInfo panelInfo)
|
|
{
|
|
if (panelInfo.UIResLoadType == EUIResLoadType.AssetBundle)
|
|
{
|
|
var uiInstance = await _resourceManager.LoadGameObjectAsync(panelInfo.Res, parent: GetLayerRect(panelInfo.UIPanelLayer));
|
|
panelInfo.UIBasePanel.InternalCreate(uiInstance);
|
|
}
|
|
else
|
|
{
|
|
var uiPrefab = Resources.Load<GameObject>(panelInfo.Res);
|
|
var uiInstance = Object.Instantiate(uiPrefab, GetLayerRect(panelInfo.UIPanelLayer));
|
|
panelInfo.UIBasePanel.InternalCreate(uiInstance);
|
|
}
|
|
}
|
|
|
|
private void CreateUIResInstance(PanelInfo panelInfo)
|
|
{
|
|
if (panelInfo.UIResLoadType == EUIResLoadType.AssetBundle)
|
|
{
|
|
var uiInstance = _resourceManager.LoadGameObject(panelInfo.Res, parent: GetLayerRect(panelInfo.UIPanelLayer));
|
|
panelInfo.UIBasePanel.InternalCreate(uiInstance);
|
|
}
|
|
else
|
|
{
|
|
var uiPrefab = Resources.Load<GameObject>(panelInfo.Res);
|
|
var uiInstance = Object.Instantiate(uiPrefab, GetLayerRect(panelInfo.UIPanelLayer));
|
|
panelInfo.UIBasePanel.InternalCreate(uiInstance);
|
|
}
|
|
}
|
|
|
|
private void Push(PanelInfo info)
|
|
{
|
|
// 如果已经存在
|
|
if (IsContains(info))
|
|
throw new System.Exception($"Window {info.Name} is exist.");
|
|
|
|
var list = GetLayerPanelInfoList(info.UIPanelLayer);
|
|
int insertIndex = -1;
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
if (info.UIPanelLayer == list[i].UIPanelLayer)
|
|
{
|
|
insertIndex = i + 1;
|
|
}
|
|
}
|
|
|
|
// 如果没有所属层级,找到相邻层级
|
|
if (insertIndex == -1)
|
|
{
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
if (info.UIPanelLayer > list[i].UIPanelLayer)
|
|
{
|
|
insertIndex = i + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果是空栈或没有找到插入位置
|
|
if (insertIndex == -1)
|
|
{
|
|
insertIndex = 0;
|
|
}
|
|
|
|
// 最后插入到堆栈
|
|
mShowUIWindow[info.UIPanelLayer].Insert(insertIndex, info);
|
|
}
|
|
|
|
private void Pop(PanelInfo info)
|
|
{
|
|
mShowUIWindow[info.UIPanelLayer].Remove(info);
|
|
}
|
|
|
|
private async UniTaskVoid BeforeShowUI(PanelInfo info)
|
|
{
|
|
info.SetPanelState(EPanelState.Show);
|
|
SetPanelLayer(info, info.UIPanelLayer);
|
|
info.UIBasePanel.InternalOpen();
|
|
SortWindowVisible();
|
|
SortWindowDepth(info);
|
|
if (info.UIBasePanel is IUIOpenTween tweenUI)
|
|
{
|
|
await tweenUI.OnOpenTween();
|
|
}
|
|
}
|
|
|
|
private async UniTaskVoid AfterCloseUI(PanelInfo panelInfo, bool force)
|
|
{
|
|
if (panelInfo.UIBasePanel is IUICloseTween tweenUI)
|
|
{
|
|
await tweenUI.OnCloseTween();
|
|
}
|
|
|
|
panelInfo.UIBasePanel.InternalClose();
|
|
Pop(panelInfo);
|
|
SortWindowVisible();
|
|
if (force || panelInfo.DelayedClose == 0)
|
|
{
|
|
panelInfo.UIBasePanel.InternalDestroy();
|
|
panelInfo.Reset(null);
|
|
panelInfo.SetPanelState(EPanelState.None);
|
|
return;
|
|
}
|
|
|
|
CacheWindow(panelInfo);
|
|
}
|
|
|
|
private void SetPanelLayer(PanelInfo info, UILayer layer)
|
|
{
|
|
if (info.UIBasePanel != null)
|
|
{
|
|
info.UIBasePanel.transform.SetParent(GetLayerRect(layer));
|
|
}
|
|
}
|
|
|
|
private void SortWindowVisible()
|
|
{
|
|
//Panel TODO
|
|
var list = GetLayerPanelInfoList(UILayer.UI);
|
|
bool isHideNext = false;
|
|
for (int i = list.Count - 1; i >= 0; i--)
|
|
{
|
|
PanelInfo panelInfo = list[i];
|
|
if (isHideNext == false)
|
|
{
|
|
panelInfo.UIBasePanel.Visible = true;
|
|
if (panelInfo.UIBasePanel.IsLoaded && panelInfo.FullScreen)
|
|
{
|
|
isHideNext = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
panelInfo.UIBasePanel.Visible = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SortWindowDepth(PanelInfo info)
|
|
{
|
|
int depth = (int)info.UIPanelLayer * LAYER_DEEP;
|
|
var _stack = GetLayerPanelInfoList(info.UIPanelLayer);
|
|
for (int i = 0; i < _stack.Count; i++)
|
|
{
|
|
if (_stack[i].UIPanelLayer == info.UIPanelLayer)
|
|
{
|
|
_stack[i].UIBasePanel.Depth = depth;
|
|
depth += WINDOW_DEEP;
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<PanelInfo> GetLayerPanelInfoList(UILayer panelLayer)
|
|
{
|
|
return mShowUIWindow[panelLayer];
|
|
}
|
|
|
|
|
|
private bool IsContains(PanelInfo info)
|
|
{
|
|
var list = GetLayerPanelInfoList(info.UIPanelLayer);
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
PanelInfo window = list[i];
|
|
if (window.Name == info.Name)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private UIWindow GetUIInstance(Type type)
|
|
{
|
|
var info = GetWindowInfo(type);
|
|
var list = GetLayerPanelInfoList(info.UIPanelLayer);
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
PanelInfo window = list[i];
|
|
if (window.Name == info.Name)
|
|
{
|
|
return window.UIBasePanel;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|