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

641 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Framework;
using PhxhSDK;
using UnityEngine;
public partial class UIManager : Singlenton<UIManager>, IInitable
{
public const string UI_PREFAB_PATH = "Assets/Art/UI/Prefab/{0}.prefab";
public Dictionary<string, UIWindow> mMemoryWindows = new Dictionary<string, UIWindow>();
public Stack<UIWindow> mStackWindows = new Stack<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>();
public void Init()
{
_AllWindowMeta();
if (DeviceHelper.IsFullScreenIOS())
{
SetFullScreenIOS();
}
}
public void Release()
{
}
/// <summary>
/// 打开一个UI
/// UIManager.Instance.OpenWindow("Common/GameUI")
/// </summary>
public async UniTask<UIWindow> OpenWindow(string path)
{
string uipath = path;
UIWindow window = null;
//if (windowType != UIWindowType.Fixed && ConflictDialogManager.Instance.CheckConflict(uipath, mMemoryWindows))
//{
// return window;
//}
WindowInfo wInfo;
if (!_windowsInfo.ContainsKey(uipath))
{
//if (_windowsInfo.TryGetValue(uipath, out wInfo))
{
DebugUtil.LogError("Create ui fail: {0}, no windows info inited", uipath);
return window;
}
}
wInfo = _windowsInfo[uipath];
var windowType = wInfo.windowType;
var uiWindowLayer = wInfo.windowLayer;
if (!mMemoryWindows.TryGetValue(uipath, out window))
{
if (_openingWindows.ContainsKey(uipath))
{
return window;
}
_openingWindows.Add(uipath, uipath);
window = await UIRoot.Instance.CreateWindow(uipath, windowType);
_openingWindows.Remove(uipath);
if (window != null)
{
mMemoryWindows[uipath] = window;
window.WindowName = uipath;
window.m_WindowType = windowType;
window.uiWindowLayer = uiWindowLayer;
}
else
{
DebugUtil.LogError("Create ui fail: {0}", uipath);
return window;
}
}
if (windowType != UIWindowType.Fixed && !mMemoryWindows.TryGetValue(uipath, out window))//不是常显UI
{
if (!mStackWindows.Contains(window))// 不在打开队列里
{
if (windowType == UIWindowType.Normal)//对于Normal类型的UI需要在打开的时候将前面打开的UI关闭掉
{
if (mStackWindows.Count > 0)
{
UIWindow stackWindow = mStackWindows.Peek();
if (stackWindow != null)
{
//List<string> friends = ConflictDialogManager.Instance.GetFrinends(uipath);
//if (!friends.Contains(stackWindow.WindowName))//如果不在白名单里, 则关闭
{
CloseWindow(stackWindow.WindowName, true);
}
}
}
}
mStackWindows.Push(window);//添加到打开队列
}
else
{
if (mStackWindows.Count > 0)
{
try
{
UIWindow currentWindow = mStackWindows.Peek();
while (!currentWindow.Equals(window))
{
CloseWindow(currentWindow.WindowName, true);
currentWindow = mStackWindows.Peek();
}
}
catch (Exception e)
{
DebugUtil.LogError(e.Message);
}
}
}
}
else
{
//常显UI单独处理
}
LayerListInsertWindow(window);
window.OpenWindow();
return window;
}
//重载一下传参的Open
public async UniTask<UIWindow> OpenWindow(string path, object data)
{
string uipath = path;
UIWindow window = null;
//if (windowType != UIWindowType.Fixed && ConflictDialogManager.Instance.CheckConflict(uipath, mMemoryWindows))
//{
// return window;
//}
WindowInfo wInfo;
if (!_windowsInfo.ContainsKey(uipath))
{
//if (_windowsInfo.TryGetValue(uipath, out wInfo))
{
DebugUtil.LogError("Create ui fail: {0}, no windows info inited", uipath);
return window;
}
}
wInfo = _windowsInfo[uipath];
var windowType = wInfo.windowType;
var uiWindowLayer = wInfo.windowLayer;
if (!mMemoryWindows.TryGetValue(uipath, out window))
{
window = await UIRoot.Instance.CreateWindow(uipath, windowType);
if (window != null)
{
mMemoryWindows[uipath] = window;
window.WindowName = uipath;
window.m_WindowType = windowType;
window.uiWindowLayer = uiWindowLayer;
}
else
{
DebugUtil.LogError("Create ui fail: {0}", uipath);
return window;
}
}
if (windowType != UIWindowType.Fixed && !mMemoryWindows.TryGetValue(uipath, out window))//不是常显UI
{
if (!mStackWindows.Contains(window))// 不在打开队列里
{
if (windowType == UIWindowType.Normal)//对于Normal类型的UI需要在打开的时候将前面打开的UI关闭掉
{
if (mStackWindows.Count > 0)
{
UIWindow stackWindow = mStackWindows.Peek();
if (stackWindow != null)
{
//List<string> friends = ConflictDialogManager.Instance.GetFrinends(uipath);
//if (!friends.Contains(stackWindow.WindowName))//如果不在白名单里, 则关闭
{
CloseWindow(stackWindow.WindowName, true);
}
}
}
}
mStackWindows.Push(window);//添加到打开队列
}
else
{
if (mStackWindows.Count > 0)
{
try
{
UIWindow currentWindow = mStackWindows.Peek();
while (!currentWindow.Equals(window))
{
CloseWindow(currentWindow.WindowName, true);
currentWindow = mStackWindows.Peek();
}
}
catch (Exception e)
{
DebugUtil.LogError(e.Message);
}
}
}
}
else
{
//常显UI单独处理
}
LayerListInsertWindow(window);
if (window)
{
window.OpenWindow(data);
}
return window;
}
public bool Back()
{
if (mMemoryWindows == null || mMemoryWindows.Count <= 0)
{
return false;
}
foreach (var key in mMemoryWindows.Keys)
{
if (mMemoryWindows[key] != null && mMemoryWindows[key].m_WindowType != UIWindowType.Fixed)
{
return mMemoryWindows[key].OnBack();
}
}
return false;
}
public bool CloseWindow(string wName, bool destroy = false)
{
string windowName = wName;
bool result = false;
UIWindow window;
if (mMemoryWindows.TryGetValue(windowName, out window))
{
window.CloseWindow(destroy);
if (destroy)
{
LayerListRemoveWindow(window);
mMemoryWindows.Remove(windowName);
}
if (mStackWindows.Count > 0)
{
if (mStackWindows.Peek().Equals(window))
{
mStackWindows.Pop();
//只有是普通界面 才刷新 2018.12.20 wwc 注释 原因:购买道具弹出商店界面需要关闭后刷新后面的UI更新道具数量
//if (window.m_WindowType == UIWindowType.Normal)
//{
//2018.12.20.17:25 qu 移除栈顶的已经destroy掉的, 因为前面的窗口有可能destroy了 (窗口关闭有延时, 导致关闭时不一定被pop出去)
while (mStackWindows.Count > 0 && !mMemoryWindows.ContainsKey(mStackWindows.Peek().WindowName))
{
mStackWindows.Pop();
}
if (mStackWindows.Count > 0)
{
mStackWindows.Peek().ReloadWindow();
}
//}
}
}
result = true;
}
//var fsName = FSModel.Instance.GetFSWindowName(windowName);
//if (!fsName.Equals(windowName))
//{
// CloseWindow(fsName, destroy);
//}
return result;
}
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);
//DebugUtil.Log($"{window.WindowName} sibling index is {window.transform.GetSiblingIndex()}");
//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())
{
e.Current?.transform?.SetSiblingIndex(siblingIndex++);
}
}
}
}
var index = window.transform.GetSiblingIndex();
//DebugUtil.Log($"{window.WindowName} sibling index is {index}");
}
}
catch (Exception e)
{
DebugUtil.LogError(e);
DebugUtil.LogError("{0}.LayerListInsertWindow error, window name = {1}", GetType(), window.name);
}
}
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;
// }
}
public async UniTask LoadNormalUI(string path, bool isActive = false)
{
//var windows = OpenWindow(path);
string uipath = path;
UIWindow window = null;
//if (windowType != UIWindowType.Fixed && ConflictDialogManager.Instance.CheckConflict(uipath, mMemoryWindows))
//{
// return window;
//}
WindowInfo wInfo;
if (!_windowsInfo.ContainsKey(uipath))
{
//if (_windowsInfo.TryGetValue(uipath, out wInfo))
{
DebugUtil.LogError("Create ui fail: {0}, no windows info inited", uipath);
return;
}
}
wInfo = _windowsInfo[uipath];
var windowType = wInfo.windowType;
var uiWindowLayer = wInfo.windowLayer;
if (!mMemoryWindows.TryGetValue(uipath, out window))
{
window = await UIRoot.Instance.CreateWindow(uipath, windowType);
if (window != null)
{
mMemoryWindows[uipath] = window;
window.WindowName = uipath;
window.m_WindowType = windowType;
window.uiWindowLayer = uiWindowLayer;
}
else
{
DebugUtil.LogError("Create ui fail: {0}", uipath);
return;
}
}
if (windowType != UIWindowType.Fixed && !mMemoryWindows.TryGetValue(uipath, out window))//不是常显UI
{
if (!mStackWindows.Contains(window))// 不在打开队列里
{
if (windowType == UIWindowType.Normal)//对于Normal类型的UI需要在打开的时候将前面打开的UI关闭掉
{
if (mStackWindows.Count > 0)
{
UIWindow stackWindow = mStackWindows.Peek();
if (stackWindow != null)
{
//List<string> friends = ConflictDialogManager.Instance.GetFrinends(uipath);
//if (!friends.Contains(stackWindow.WindowName))//如果不在白名单里, 则关闭
{
CloseWindow(stackWindow.WindowName, true);
}
}
}
}
mStackWindows.Push(window);//添加到打开队列
}
else
{
if (mStackWindows.Count > 0)
{
try
{
UIWindow currentWindow = mStackWindows.Peek();
while (!currentWindow.Equals(window))
{
CloseWindow(currentWindow.WindowName, true);
currentWindow = mStackWindows.Peek();
}
}
catch (Exception e)
{
DebugUtil.LogError(e.Message);
}
}
}
}
else
{
//常显UI单独处理
}
LayerListInsertWindow(window);
if (!window)
{
DebugUtil.LogError("Create ui fail: {0}", uipath);
return;
}
if (!isActive)
{
window.HideWindow();
}
else
{
window.OpenWindow();
}
}
//展示全部已加载的NormalUI
public void OpenLoadedNormalUI(string uiName)
{
WindowInfo wInfo;
wInfo = _windowsInfo[uiName];
if (mMemoryWindows.ContainsKey(uiName))
{
mMemoryWindows[uiName].OpenWindow();
}
}
public void CloseAllUI(bool destroy)
{
foreach (var kv in mMemoryWindows)
{
var window = kv.Value;
window.CloseWindow(destroy);
if (destroy)
{
LayerListRemoveWindow(window);
}
}
if (destroy)
{
mMemoryWindows.Clear();
mStackWindows.Clear();
_layerList.Clear();
}
}
public async void ShowUITips(string uiName, string content, int showTime = 1500)
{
//放到最上层
if (!_windowsInfo.ContainsKey(uiName))
{
return;
}
WindowInfo wInfo = _windowsInfo[uiName];
if (wInfo.windowType != UIWindowType.PopupTip)
{
DebugUtil.LogError("UI弹窗注册有误uiName: {0}", uiName);
return;
}
OpenWindow(uiName, content);
await UniTask.Delay(showTime);
CloseWindow(uiName);
}
public async void ShowClickShield(string uiPath, int time = 0)
{
//放到最上层
if (!_windowsInfo.ContainsKey(uiPath))
{
return;
}
WindowInfo wInfo = _windowsInfo[uiPath];
if (wInfo.windowType != UIWindowType.PopupTip)
{
DebugUtil.LogError("UI遮挡弹窗注册有误uiName: {0}", uiPath);
return;
}
OpenWindow(uiPath);
UIWindow window;
if (mMemoryWindows.TryGetValue(uiPath, out window))
{
if (window.isOpen)
{
window.transform.SetAsLastSibling();
}
}
if (time > 0)
{
await UniTask.Delay(time);
CloseWindow(uiPath);
}
}
public void CloseClickShield(string uiPath)
{
if (mMemoryWindows.ContainsKey(uiPath))
{
if (mMemoryWindows[uiPath].isOpen)
{
CloseWindow(uiPath);
}
}
}
public bool IsWindowOpening(string uiPath)
{
string windowName;
if (_openingWindows.TryGetValue(uiPath, out windowName))
{
if (windowName != null)
{
return true;
}
}
return false;
}
}