marineparkclient/assets/common/ui/UIManager.ts
2023-08-15 11:09:12 +08:00

333 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import UIBase from "./base/UIBase";
import { SysDefine, PanelType } from "./config/SysDefine";
import ResManager from "../res/ResManager";
import UIMaskMgr from "./UIMaskMgr";
import AdapterManager, { AdaptaterType } from "./AdapterManager";
const {ccclass, property} = cc._decorator;
@ccclass
export default class UIManager extends cc.Component {
private _NoNormal: cc.Node = null; // 全屏显示的UI 挂载结点
private _NoFixed: cc.Node = null; // 固定显示的UI
private _NoPopUp: cc.Node = null; // 弹出窗口
private _NoTips: cc.Node = null; // 独立窗体
private _StaCurrentUIPanels:Array<UIBase> = []; // 存储弹出的窗体
private _MapAllUIPanels: {[key: string]: UIBase} = cc.js.createMap(); // 所有的窗体
private _MapCurrentShowUIPanels: {[key: string]: UIBase} = cc.js.createMap(); // 正在显示的窗体(不包括弹窗)
private _MapIndependentPanels: {[key: string]: UIBase} = cc.js.createMap(); // 独立窗体 独立于其他窗体, 不受其他窗体的影响
private _LoadingPanel: {[key: string]: boolean} = cc.js.createMap(); // 正在加载的Panel
private _currWindowId = '';
public get currWindowId() {
return this._currWindowId;
}
private _currScreenId = '';
public get currScreenId() {
return this._currScreenId;
}
private static instance: UIManager = null; // 单例
public static getInstance(): UIManager {
if(this.instance == null) {
this.instance = cc.find(SysDefine.SYS_UIROOT_NAME).addComponent<UIManager>(this);
cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, () => {
this.instance = null;
});
}
return this.instance;
}
onLoad () {
// 初始化结点
this._NoNormal = this.node.getChildByName(SysDefine.SYS_SCREEN_NODE);
this._NoFixed = this.node.getChildByName(SysDefine.SYS_FIXEDUI_NODE);
this._NoPopUp = this.node.getChildByName(SysDefine.SYS_POPUP_NODE);
this._NoTips = this.node.getChildByName(SysDefine.SYS_TOPTIPS_NODE);
}
start() {
}
/** */
public getComponentByUid(uid: string) {
return this._MapAllUIPanels[uid];
}
/**
* 重要方法 加载显示一个UIPanel
* @param prefabPath
* @param obj 初始化信息, 可以不要
*/
public async openUIPanel(prefabPath: string, ...params: any) {
if(prefabPath === "" || prefabPath == null) return ;
if(this.checkUIPanelIsShowing(prefabPath) || this.checkUIPanelIsLoading(prefabPath)) {
cc.warn(`${prefabPath}窗体已经在显示,或者正在加载中!`);
return null;
}
let uiBase = await this.loadPanelsToAllUIPanelsCatch(prefabPath);
if(uiBase == null) {
cc.warn(`${prefabPath}未加载!`);
return null;
}
switch(uiBase.panelType) {
case PanelType.Screen:
await this.enterUIPanelsAndHideOther(prefabPath, ...params);
break;
case PanelType.FixedUI:
await this.loadUIToCurrentCache(prefabPath, ...params);
break;
case PanelType.PopUp:
await this.pushUIPanelToStack(prefabPath, ...params);
break;
case PanelType.TopTips: // 独立显示
await this.loadUIPanelsToIndependent(prefabPath, ...params);
break;
}
return uiBase;
}
/**
* 重要方法 关闭一个UIPanel
* @param prefabPath
*/
public async closeUIPanel(prefabPath: string) {
if(prefabPath == "" || prefabPath == null) return ;
let UIBase = this._MapAllUIPanels[prefabPath];
if(UIBase == null) return true;
switch(UIBase.panelType) {
case PanelType.Screen:
await this.exitUIPanelsAndDisplayOther(prefabPath);
break;
case PanelType.FixedUI: // 普通模式显示
await this.exitUIPanels(prefabPath);
break;
case PanelType.PopUp:
await this.popUIPanel();
break;
case PanelType.TopTips:
await this.exitIndependentPanels(prefabPath);
break;
}
// 判断是否销毁该窗体
if(UIBase.canDestory) {
this.destoryPanel(UIBase, prefabPath);
}
return true;
}
/**
* 从全部的UI窗口中加载, 并挂载到结点上
*/
private async loadPanelsToAllUIPanelsCatch(prefabPath: string) {
let baseUIResult = this._MapAllUIPanels[prefabPath];
// 判断窗体不在mapAllUIPanels中 也不再loadingPanels中
if (baseUIResult == null && !this._LoadingPanel[prefabPath]) {
//加载指定名称的“UI窗体
this._LoadingPanel[prefabPath] = true;
baseUIResult = await this.loadUIPanel(prefabPath);
this._LoadingPanel[prefabPath] = false;
delete this._LoadingPanel[prefabPath];
}
return baseUIResult;
}
/**
* 从resources中加载
* @param prefabPath
*/
//加载UI,自动添加的层级
private async loadUIPanel(PrefabPath: string,parent?:cc.Node) {
if(PrefabPath == "" || PrefabPath == null){
return ;
}
let node = await ResManager.inst.loadPrefab(PrefabPath);
if(!node) {
return ;
}
// 初始化窗体名称
let baseUI = node.getComponent(UIBase);
node.active = false;
switch(baseUI.panelType) {
case PanelType.Screen:
UIManager.getInstance()._NoNormal.addChild(node);
break;
case PanelType.FixedUI:
UIManager.getInstance()._NoFixed.addChild(node);
break;
case PanelType.PopUp:
UIManager.getInstance()._NoPopUp.addChild(node);
break;
case PanelType.TopTips:
UIManager.getInstance()._NoTips.addChild(node);
break;
default:
ResManager.inst.destoryPrefab(baseUI)
return;
}
this._MapAllUIPanels[PrefabPath] = baseUI;
return baseUI
}
/**
* 加载到缓存中,
* @param prefabPath
*/
private async loadUIToCurrentCache(prefabPath: string, ...params: any) {
let UIBase: UIBase = null;
let UIBaseFromAllCache: UIBase = null;
UIBase = this._MapCurrentShowUIPanels[prefabPath];
if(UIBase != null) return ; // 要加载的窗口正在显示
UIBaseFromAllCache = this._MapAllUIPanels[prefabPath];
if(UIBaseFromAllCache != null) {
await UIBaseFromAllCache._preInit();
this._MapCurrentShowUIPanels[prefabPath] = UIBaseFromAllCache;
UIBaseFromAllCache.onShow(...params);
await this.showPanel(UIBaseFromAllCache);
}
}
/**
* 加载到栈中
* @param prefabPath
*/
private async pushUIPanelToStack(prefabPath: string, ...params: any) {
if(this._StaCurrentUIPanels.length > 0) {
let topUIPanel = this._StaCurrentUIPanels[this._StaCurrentUIPanels.length-1];
}
let baseUI = this._MapAllUIPanels[prefabPath];
if(baseUI == null) return ;
await baseUI._preInit();
// 加入栈中, 同时设置其zIndex 使得后进入的窗体总是显示在上面
this._StaCurrentUIPanels.push(baseUI);
baseUI.node.zIndex = this._StaCurrentUIPanels.length;
baseUI.onShow(...params);
this._currWindowId = baseUI.uid;
UIMaskMgr.inst.checkMaskWindow(this._StaCurrentUIPanels);
await this.showPanel(baseUI);
}
/**
* 加载时, 关闭其他窗口
*/
private async enterUIPanelsAndHideOther(prefabPath: string, ...params: any) {
let UIBase = this._MapCurrentShowUIPanels[prefabPath];
if(UIBase != null) return ;
// 隐藏其他窗口
for(let key in this._MapCurrentShowUIPanels) {
await this._MapCurrentShowUIPanels[key].closeUIPanel();
}
this._StaCurrentUIPanels.forEach(async uiPanel => {
await uiPanel.closeUIPanel();
});
let UIBaseFromAll = this._MapAllUIPanels[prefabPath];
if(UIBaseFromAll == null) return ;
AdapterManager.inst.adapatByType(AdaptaterType.FullScreen, UIBaseFromAll.node);
await UIBaseFromAll._preInit();
this._MapCurrentShowUIPanels[prefabPath] = UIBaseFromAll;
UIBaseFromAll.onShow(...params);
this._currScreenId = UIBaseFromAll.uid;
await this.showPanel(UIBaseFromAll);
}
/** 加载到独立map中 */
private async loadUIPanelsToIndependent(prefabPath: string, ...params: any) {
let UIBase = this._MapAllUIPanels[prefabPath];
if(UIBase == null) return ;
await UIBase._preInit();
this._MapIndependentPanels[prefabPath] = UIBase;
UIBase.onShow(...params);
await this.showPanel(UIBase);
}
/**
* --------------------------------- 关闭窗口 --------------------------
*/
/**
* 关闭一个UIPanel
* @param prefabPath
*/
private async exitUIPanels(prefabPath: string) {
let UIBase = this._MapAllUIPanels[prefabPath];
if(UIBase == null) return ;
UIBase.onHide();
await this.hidePanel(UIBase);
this._MapCurrentShowUIPanels[prefabPath] = null;
delete this._MapCurrentShowUIPanels[prefabPath];
}
private async popUIPanel() {
if(this._StaCurrentUIPanels.length >= 1) {
let topUIPanel = this._StaCurrentUIPanels.pop();
topUIPanel.onHide();
UIMaskMgr.inst.checkMaskWindow(this._StaCurrentUIPanels);
await this.hidePanel(topUIPanel);
this._currWindowId = this._StaCurrentUIPanels.length > 0 ? this._StaCurrentUIPanels[this._StaCurrentUIPanels.length-1].uid : '';
}
}
private async exitUIPanelsAndDisplayOther(prefabPath: string) {
if(prefabPath == "" || prefabPath == null) return ;
let UIBase = this._MapCurrentShowUIPanels[prefabPath];
if(UIBase == null) return ;
UIBase.onHide();
await this.hidePanel(UIBase);
this._MapCurrentShowUIPanels[prefabPath] = null;
delete this._MapCurrentShowUIPanels[prefabPath];
}
private async exitIndependentPanels(prefabPath: string) {
let UIBase = this._MapAllUIPanels[prefabPath];
if(UIBase == null) return ;
UIBase.onHide();
await this.hidePanel(UIBase);
this._MapIndependentPanels[prefabPath] = null;
delete this._MapIndependentPanels[prefabPath];
}
private async showPanel(baseUI: UIBase) {
baseUI.node.active = true;
await baseUI.showAnimation();
}
private async hidePanel(baseUI: UIBase) {
await baseUI.hideAnimation();
baseUI.node.active = false;
}
/** 销毁 */
private destoryPanel(UIBase: UIBase, prefabPath: string) {
UIBase.onRemove()
ResManager.inst.destoryPrefab(UIBase)
// 从allmap中删除
this._MapAllUIPanels[prefabPath] = null;
delete this._MapAllUIPanels[prefabPath];
}
/** 窗体是否正在显示 */
public checkUIPanelIsShowing(prefabPath: string) {
let UIBases = this._MapAllUIPanels[prefabPath];
if (UIBases == null) {
return false;
}
return UIBases.node.active;
}
/** 窗体是否正在加载 */
public checkUIPanelIsLoading(prefabPath: string) {
let UIBase = this._LoadingPanel[prefabPath];
return !!UIBase;
}
}