333 lines
12 KiB
TypeScript
333 lines
12 KiB
TypeScript
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;
|
||
}
|
||
}
|