using System; using System.Collections; using System.Collections.Generic; using Cysharp.Threading.Tasks; using Framework; using PhxhSDK; using UnityEngine; public partial class UIManager : Singlenton, IInitable { public const string UI_PREFAB_PATH = "Assets/Art/UI/Prefab/{0}.prefab"; public Dictionary mMemoryWindows = new Dictionary(); public Stack mStackWindows = new Stack(); private Dictionary> _layerList = new Dictionary>(16); private ScreenOrientation _currentOrientation; private Dictionary _openingWindows = new Dictionary(); public void Init() { _AllWindowMeta(); if (DeviceHelper.IsFullScreenIOS()) { SetFullScreenIOS(); } } public void Release() { } /// /// 打开一个UI /// UIManager.Instance.OpenWindow("Common/GameUI") /// public async UniTask 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 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 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 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(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 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(); _layerList.Add((int) window.uiWindowLayer, currentLayerWindows); } currentLayerWindows.AddLast(window); } int siblingIndex = 5; // 让出loading其他想挂在canvas下的奇怪东西 LinkedList 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()) { var currWindow = e.Current; if (currWindow != null) currWindow.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 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 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 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; } }