AlicizaX/Client/Packages/com.alicizax.unity.ui/Runtime/UI/Base/Manager/UIManager.Create.cs
2025-01-24 16:21:00 +08:00

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;
}
}
}