NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIManager.cs

489 lines
14 KiB
C#
Raw Normal View History

2023-08-22 19:08:45 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
2023-11-21 13:31:06 +08:00
using System.Linq;
2023-08-22 19:08:45 +08:00
using Cysharp.Threading.Tasks;
using Framework;
2023-10-19 15:00:19 +08:00
using PhxhSDK;
2023-08-22 19:08:45 +08:00
using UnityEngine;
2023-10-19 15:00:19 +08:00
public partial class UIManager : Singlenton<UIManager>, IInitable
2023-08-22 19:08:45 +08:00
{
public const string UI_PREFAB_PATH = "Assets/Art/UI/Prefab/{0}.prefab";
public Dictionary<string, UIWindow> mMemoryWindows = new Dictionary<string, UIWindow>();
private Dictionary<int, LinkedList<UIWindow>> _layerList = new Dictionary<int, LinkedList<UIWindow>>(16);
private ScreenOrientation _currentOrientation;
private Dictionary<string, string> _openingWindows = new Dictionary<string, string>();
2023-12-29 15:09:18 +08:00
private List<UIWindow> _hideCache = new List<UIWindow>();
2023-08-22 19:08:45 +08:00
public void Init()
{
_AllWindowMeta();
if (DeviceHelper.IsFullScreenIOS())
{
SetFullScreenIOS();
}
2023-12-08 18:41:26 +08:00
EventManager.Instance.Register(EventManager.EventName.Android_Click_Back, _OnAndroidClickBack);
EventManager.Instance.Register(EventManager.EventName.HideAllUIExcept, (Action<string[]>)_OnHideAllUIExcept);
EventManager.Instance.Register(EventManager.EventName.ShowAllUIHiden, _OnShowAllUIHiden);
2023-08-22 19:08:45 +08:00
}
public void Release()
{
2023-12-08 18:41:26 +08:00
EventManager.Instance.Unregister(EventManager.EventName.Android_Click_Back, _OnAndroidClickBack);
EventManager.Instance.Unregister(EventManager.EventName.HideAllUIExcept, (Action<string[]>)_OnHideAllUIExcept);
EventManager.Instance.Unregister(EventManager.EventName.ShowAllUIHiden, _OnShowAllUIHiden);
2023-08-22 19:08:45 +08:00
}
/// <summary>
/// 打开一个UI
/// UIManager.Instance.OpenWindow("Common/GameUI")
/// </summary>
2023-11-15 12:55:00 +08:00
2023-08-22 19:08:45 +08:00
//重载一下传参的Open
2023-11-16 15:32:40 +08:00
public async UniTask<UIWindow> OpenWindow(string path, object data = null)
2023-08-22 19:08:45 +08:00
{
2023-11-16 15:32:40 +08:00
var window = await _LoadWindow(path, true);
2023-10-19 15:00:19 +08:00
if (window)
{
window.OpenWindow(data);
}
2023-08-22 19:08:45 +08:00
return window;
}
2023-10-19 15:00:19 +08:00
2023-08-22 19:08:45 +08:00
public bool Back()
{
return false;
}
2023-11-21 13:31:06 +08:00
public bool RemoveWindow(string wName)
2023-08-22 19:08:45 +08:00
{
string windowName = wName;
bool result = false;
UIWindow window;
if (mMemoryWindows.TryGetValue(windowName, out window))
{
2023-11-21 13:31:06 +08:00
LayerListRemoveWindow(window);
mMemoryWindows.Remove(windowName);
2023-08-22 19:08:45 +08:00
result = true;
}
return result;
}
2023-11-21 13:31:06 +08:00
public void CloseWindow(string wName, UIWindowCloseType closeType = UIWindowCloseType.OnlyHide)
{
var window = GetOpenedWindowByPath<UIWindow>(wName);
if (window)
{
window.CloseWindow(closeType);
}
}
2023-08-22 19:08:45 +08:00
public T GetOpenedWindowByPath<T>(string uipath) where T : UIWindow
{
if (mMemoryWindows.ContainsKey(uipath))
{
var window = (T)(mMemoryWindows[uipath]);
return window.gameObject.activeSelf ? window : null;
}
return default(T);
}
void LayerListInsertWindow(UIWindow window)
{
try
{
if (window != null)
{
LinkedList<UIWindow> currentLayerWindows;
if (_layerList.TryGetValue((int) window.uiWindowLayer, out currentLayerWindows)
&& currentLayerWindows != null
&& currentLayerWindows.Count > 0)
{
if (currentLayerWindows.Remove(window))
{
}
currentLayerWindows.AddLast(window);
2023-10-19 15:00:19 +08:00
//DebugUtil.Log($"{window.WindowName} sibling index is {window.transform.GetSiblingIndex()}");
2023-08-22 19:08:45 +08:00
//return;
}
else
{
if (currentLayerWindows == null)
{
currentLayerWindows = new LinkedList<UIWindow>();
_layerList.Add((int) window.uiWindowLayer, currentLayerWindows);
}
currentLayerWindows.AddLast(window);
}
int siblingIndex = 5; // 让出loading其他想挂在canvas下的奇怪东西
LinkedList<UIWindow> layerWindows;
for (int i = 0; i <= (int) UIWindowLayer.Max; i++)
{
if (_layerList.TryGetValue(i, out layerWindows) && layerWindows != null)
{
if (layerWindows.Count > 0)
{
var e = layerWindows.GetEnumerator();
while (e.MoveNext())
{
2023-10-26 20:20:11 +08:00
var currWindow = e.Current;
if (currWindow != null)
currWindow.transform?.SetSiblingIndex(siblingIndex++);
2023-08-22 19:08:45 +08:00
}
}
}
}
var index = window.transform.GetSiblingIndex();
2023-10-19 15:00:19 +08:00
//DebugUtil.Log($"{window.WindowName} sibling index is {index}");
2023-08-22 19:08:45 +08:00
}
}
catch (Exception e)
{
DebugUtil.LogError(e);
2023-10-19 15:00:19 +08:00
DebugUtil.LogError("{0}.LayerListInsertWindow error, window name = {1}", GetType(), window.name);
2023-08-22 19:08:45 +08:00
}
}
void LayerListRemoveWindow(UIWindow window)
{
try
{
if (window != null)
{
LinkedList<UIWindow> currentLayerWindows;
if (_layerList.TryGetValue((int)window.uiWindowLayer, out currentLayerWindows))
{
currentLayerWindows?.Remove(window);
}
}
}
catch (Exception e)
{
DebugUtil.LogError(e);
}
}
public bool GetTopWindow(out UIWindow window, out UIWindowLayer layer, int banLayerMask)
{
for (int i = (int)UIWindowLayer.Max; i >= 0; i--)
{
if (((1 << i) & banLayerMask) == 0)
{
LinkedList<UIWindow> highLayerWindows;
if (_layerList.TryGetValue(i, out highLayerWindows))
{
if (highLayerWindows.Count > 0)
{
window = highLayerWindows.Last.Value;
if (window != null)
{
layer = (UIWindowLayer)i;
return true;
}
}
}
}
}
window = null;
layer = UIWindowLayer.Max;
return false;
}
public int LayerMask(UIWindowLayer layer)
{
return 1 << ((int)layer);
}
async void SetFullScreenIOS()
{
await UniTask.Delay(670);
// while (true)
// {
// var screenOrientation = DragonNativeBridge.GetScreenOrientation();
// if (screenOrientation != _currentOrientation)
// {
// _currentOrientation = screenOrientation;
// EventDispatcher.Instance.DispatchEvent(new ScreenOrientationChangedEvent(_currentOrientation));
// }
// yield return wait;
// }
}
2023-11-16 15:32:40 +08:00
public async UniTask<UIWindow> LoadWindow(string path)
2023-08-22 19:08:45 +08:00
{
2023-11-16 15:32:40 +08:00
return await _LoadWindow(path, false);
}
private async UniTask<UIWindow> _LoadWindow(string path, bool isActive = false)
{
2023-08-22 19:08:45 +08:00
string uipath = path;
UIWindow window = null;
2023-11-16 15:32:40 +08:00
2023-08-22 19:08:45 +08:00
WindowInfo wInfo;
if (!_windowsInfo.ContainsKey(uipath))
{
//if (_windowsInfo.TryGetValue(uipath, out wInfo))
{
2023-10-19 15:00:19 +08:00
DebugUtil.LogError("Create ui fail: {0}, no windows info inited", uipath);
2023-11-16 15:32:40 +08:00
return window;
2023-08-22 19:08:45 +08:00
}
}
wInfo = _windowsInfo[uipath];
var uiWindowLayer = wInfo.windowLayer;
if (!mMemoryWindows.TryGetValue(uipath, out window))
{
2023-11-16 15:32:40 +08:00
if (_openingWindows.ContainsKey(uipath))
{
return window;
}
_openingWindows.Add(uipath, uipath);
2023-11-21 13:31:06 +08:00
window = await UIRoot.Instance.CreateWindow(uipath);
2023-11-16 15:32:40 +08:00
_openingWindows.Remove(uipath);
2023-08-22 19:08:45 +08:00
if (window != null)
{
mMemoryWindows[uipath] = window;
window.WindowName = uipath;
window.uiWindowLayer = uiWindowLayer;
}
else
{
2023-10-19 15:00:19 +08:00
DebugUtil.LogError("Create ui fail: {0}", uipath);
2023-11-16 15:32:40 +08:00
return window;
2023-08-22 19:08:45 +08:00
}
}
LayerListInsertWindow(window);
if (!window)
{
2023-10-19 15:00:19 +08:00
DebugUtil.LogError("Create ui fail: {0}", uipath);
2023-11-16 15:32:40 +08:00
return null;
2023-08-22 19:08:45 +08:00
}
if (!isActive)
{
2023-11-16 15:32:40 +08:00
window.gameObject.SetActive(false);
2023-08-22 19:08:45 +08:00
}
2023-11-16 15:32:40 +08:00
return window;
2023-08-22 19:08:45 +08:00
}
2023-11-16 15:32:40 +08:00
2023-08-22 19:08:45 +08:00
//展示全部已加载的NormalUI
public void OpenLoadedNormalUI(string uiName)
{
WindowInfo wInfo;
wInfo = _windowsInfo[uiName];
if (mMemoryWindows.ContainsKey(uiName))
{
2023-11-16 15:32:40 +08:00
mMemoryWindows[uiName].OpenWindow(null);
2023-08-22 19:08:45 +08:00
}
}
public void ForeachUI(Action<UIWindow> action)
{
var windowList = mMemoryWindows.ToList();
foreach (var kv in windowList)
{
var window = kv.Value;
if (window != null)
{
action?.Invoke(kv.Value);
}
}
}
2023-11-21 13:31:06 +08:00
public void CloseAllUI(UIWindowCloseType closeType )
2023-08-22 19:08:45 +08:00
{
2023-11-21 13:31:06 +08:00
var windowList = mMemoryWindows.ToList();
foreach (var kv in windowList)
2023-08-22 19:08:45 +08:00
{
var window = kv.Value;
2023-11-21 13:31:06 +08:00
window.CloseWindow(closeType);
2023-08-22 19:08:45 +08:00
}
2023-11-21 13:31:06 +08:00
if (closeType == UIWindowCloseType.HideAndDestroy)
2023-08-22 19:08:45 +08:00
{
mMemoryWindows.Clear();
_layerList.Clear();
2023-11-21 15:12:51 +08:00
ClearHideStack();
2023-08-22 19:08:45 +08:00
}
}
2024-01-03 17:25:13 +08:00
public void HideAllUI(params string[] exceptions)
2023-12-29 15:03:59 +08:00
{
var windowList = mMemoryWindows.ToList();
foreach (var kv in windowList)
{
var window = kv.Value;
2024-01-03 17:25:13 +08:00
if (window.gameObject.activeInHierarchy && !exceptions.Contains(window.WindowName))
2023-12-29 15:09:18 +08:00
{
_hideCache.Add(window);
window.HideWindow(true);
}
2023-12-29 15:03:59 +08:00
}
}
public void ShowAllUI()
{
2023-12-29 15:09:18 +08:00
foreach (var v in _hideCache)
2023-12-29 15:03:59 +08:00
{
2023-12-29 15:09:18 +08:00
var window = v;
2024-01-03 17:25:13 +08:00
if (window != null)
window.ShowWindow();
2023-12-29 15:03:59 +08:00
}
2023-12-29 15:09:18 +08:00
_hideCache.Clear();
2023-12-29 15:03:59 +08:00
}
2023-08-22 19:08:45 +08:00
public async void ShowUITips(string uiName, string content, int showTime = 1500)
{
//放到最上层
if (!_windowsInfo.ContainsKey(uiName))
{
return;
}
2023-11-21 13:31:06 +08:00
var window = await OpenWindow(uiName, content);
2023-08-22 19:08:45 +08:00
await UniTask.Delay(showTime);
2023-11-21 13:31:06 +08:00
window.CloseWindow(UIWindowCloseType.HideAndDestroy);
2023-08-22 19:08:45 +08:00
}
public async void ShowClickShield(string uiPath, int time = 0)
{
//放到最上层
if (!_windowsInfo.ContainsKey(uiPath))
{
return;
}
2023-11-21 13:31:06 +08:00
2023-08-22 19:08:45 +08:00
OpenWindow(uiPath);
mMemoryWindows.TryGetValue(uiPath, out var window);
2023-08-22 19:08:45 +08:00
if (time > 0)
{
await UniTask.Delay(time);
2023-11-21 13:31:06 +08:00
window.CloseWindow(UIWindowCloseType.HideAndDestroy);
2023-08-22 19:08:45 +08:00
}
}
public void CloseClickShield(string uiPath)
{
if (mMemoryWindows.ContainsKey(uiPath))
{
2023-11-21 13:31:06 +08:00
var window = mMemoryWindows[uiPath];
window.CloseWindow(UIWindowCloseType.HideAndDestroy);
2023-08-22 19:08:45 +08:00
}
}
2023-11-21 13:24:42 +08:00
//根据路径判断UI界面是否打开
2023-08-22 19:08:45 +08:00
public bool IsWindowOpening(string uiPath)
{
string windowName;
if (_openingWindows.TryGetValue(uiPath, out windowName))
{
if (windowName != null)
{
return true;
}
}
return false;
}
2023-11-21 13:24:42 +08:00
//关掉所有Normal层已打开的界面保留传参的界面
public void CloseAllNormalExcept(string path)
{
var windowsL = _GetLayerWindowList(UIWindowLayer.Normal);
if (!mMemoryWindows.ContainsKey(path))
{
DebugUtil.LogError("请检查Home返回方法传入UI窗口路径参数{0}", path);
return;
}
List<UIWindow> toBeRemoved = new List<UIWindow>();
if (windowsL.Count > 0)
{
var node = windowsL.First;
while (node != null)
{
var window = node.Value;
2023-11-21 16:22:19 +08:00
if (window.WindowName != path)
{
toBeRemoved.Add(window);
}
2023-11-21 13:24:42 +08:00
if (node == windowsL.Last)
{
break;
}
node = node.Next;
}
}
2023-11-21 15:30:03 +08:00
ClearHideStack();
2023-11-21 13:24:42 +08:00
for (int i = toBeRemoved.Count - 1; i >= 0; i--)
{
2023-11-21 13:34:26 +08:00
CloseWindow(toBeRemoved[i].WindowName, UIWindowCloseType.HideAndDestroy);
2023-11-21 13:24:42 +08:00
}
}
2023-12-08 18:41:26 +08:00
private async void _OnAndroidClickBack()
2023-11-21 13:24:42 +08:00
{
2023-12-08 18:41:26 +08:00
var window = GetTopWindowInLayer(UIWindowLayer.Tips);
if (window)
2023-11-21 13:24:42 +08:00
{
await window.OnBack();
2023-12-08 18:41:26 +08:00
return;
}
window = GetTopWindowInLayer(UIWindowLayer.ForeGround);
if (window)
{
await window.OnBack();
2023-12-08 18:41:26 +08:00
return;
}
window = GetTopWindowInLayer(UIWindowLayer.Normal);
if (window)
{
await window.OnBack();
2023-12-08 18:41:26 +08:00
return;
2023-11-21 13:24:42 +08:00
}
2023-12-08 18:41:26 +08:00
await OpenWindow(UINameConst.UIBackReturn);
2023-11-21 13:24:42 +08:00
}
private void _OnHideAllUIExcept(params string[] exceptions)
{
HideAllUI(exceptions);
}
private void _OnShowAllUIHiden()
{
ShowAllUI();
}
2023-08-22 19:08:45 +08:00
}