You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
778 lines
29 KiB
778 lines
29 KiB
//UI管理器
|
|
/*
|
|
*功能:是整个UI框架的核心,用户通过本脚本,来实现框架绝大多数的功能实现。
|
|
*/
|
|
import { _decorator, Camera, Component, director, Input, instantiate, isValid, KeyCode, Node, Size, tween, Tween, UIOpacity, UITransform, v3, Vec3 } from "cc";
|
|
import { EDITOR_NOT_IN_PREVIEW, PREVIEW } from "cc/env";
|
|
import { EBundleName } from "../const/GameEnum";
|
|
import { UIFormsValue } from "../const/GameInterface";
|
|
import { EUIForms } from "../const/UIFormCnf";
|
|
import { EGlobalEvent } from "../MesEvent/EGlobalEvent";
|
|
import { EResUrls } from "../ResUrl/EResUrls";
|
|
import { EKeyResName } from "../ResUrl/KeyResManager";
|
|
import ResLoad from "../ResUrl/ResLoad";
|
|
import BaseUIForm from "./BaseUIForm";
|
|
import { EUIFormsToIUIRes, IUIPrefabQueue, IUIRes, SysDefine, UIFromShowType, UIFromType } from "./Config/SysDefine";
|
|
import MesMgr from "../MesEvent/MesMgr";
|
|
import { Utils } from "../ExUtils/Utils";
|
|
import { InputMgr } from "../Mgr_Load/InputMgr";
|
|
import { MainConfig } from "../../Launch/_MainConfig";
|
|
import { TDAnalyticsMgr } from "../Mgr_Ge/TDAnalyticsMgr";
|
|
import { GEData } from "../Mgr_Ge/GeDifine";
|
|
import LocalStorage from "../Mgr_LocalData/LocalStorage";
|
|
/**
|
|
* 脚本执行逻辑:
|
|
* ShowUIForms 执行打开UI
|
|
* LodeFormsToAllUIFormsCatch 执行加载UI 并且将UI添加到 UI层级节点之下
|
|
* LoadUIToCurrentCache “普通”窗口模式
|
|
* PushUIFormToStack “反向切换”窗口模式
|
|
* EnterUIFormsAndHideOther “隐藏其他”窗口模式
|
|
*
|
|
* CloseUIForms 执行关闭UI
|
|
* ExitUIForms 普通窗体的关闭
|
|
* PopUIFroms 反向切换窗体的关闭
|
|
* ExitUIFormsAndDisplayOther 隐藏其他窗体关闭
|
|
*
|
|
*/
|
|
|
|
const { ccclass, property, menu } = _decorator;
|
|
@ccclass
|
|
@menu("UIScript/UIMgr")
|
|
export default class UIMgr extends Component {
|
|
/*字段*/
|
|
private static _Instance: UIMgr = null;
|
|
/**缓存所有UI窗体 */
|
|
private _ALLCacheUIFroms: Map<string, BaseUIForm>;
|
|
/**当前显示的UI窗体 */
|
|
private _DicCurrentShowUIFroms: Map<string, BaseUIForm>;
|
|
/**定义“栈”集合,存储显示当前所有[反向切换]的窗体类型 */
|
|
private _StaCurrentUIForms: BaseUIForm[] = [];
|
|
/**UI根节点 */
|
|
@property({ type: Node, visible: true })
|
|
private _RootUI: Node = null;
|
|
/**UI层级节点 */
|
|
private _UILayer: { [key: string]: Node } = {};
|
|
/**加载屏蔽层级 避免多个UI同时加载 */
|
|
@property({ type: Node, visible: true })
|
|
private _Loding: Node = null;
|
|
/**黑屏加载过度 */
|
|
@property({ type: Node, visible: true })
|
|
private _MaskLoding: Node = null;
|
|
/**加载屏蔽层级 避免多个UI同时加载 */
|
|
@property({ type: UIOpacity, visible: true })
|
|
private _LodingUIOpacity: UIOpacity = null;
|
|
/**UI摄像机 */
|
|
private _UICamera: Camera = null;
|
|
/**等待UI关闭时 打开UI队列 */
|
|
private _BackQueue: IUIPrefabQueue[] = [];
|
|
/**加载中的队列 */
|
|
private _UIQueue: IUIPrefabQueue[] = [];
|
|
private _UIloding: number = 0;
|
|
/**主要UI 用于处理 只有相关UI存在时 处理弹出队列中的UI */
|
|
private _MainUI: IUIRes[] = [
|
|
EUIFormsToIUIRes(EUIForms.TipsUI),
|
|
]
|
|
|
|
get UICamera(): Camera {
|
|
return this._UICamera;
|
|
}
|
|
|
|
/**游戏加载界面过度 */
|
|
GameLoading = false;
|
|
|
|
protected onLoad() {
|
|
if (EDITOR_NOT_IN_PREVIEW) { return; }
|
|
if (UIMgr._Instance != null) { this.node.destroy(); return; }
|
|
UIMgr._Instance = this.node.getComponent(UIMgr);
|
|
if (PREVIEW) { window["UIMgr"] = UIMgr; }
|
|
//“根UI窗体”在场景转换中,不允许销毁
|
|
director.addPersistRootNode(this.node)
|
|
this.init_node();
|
|
}
|
|
protected onDestroy(): void {
|
|
UIMgr._Instance = null;
|
|
InputMgr.ins.offAllCaller(this)
|
|
MesMgr.offAllCaller(this)
|
|
}
|
|
|
|
/// <summary>
|
|
/// 得到实例
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static get Ins(): UIMgr {
|
|
if (!this._Instance) {
|
|
let tempCavas = ResLoad.Ins.GetRes(EResUrls.UIPrefabs(SysDefine.SYS_CANVAS_NAME), EBundleName.Presets);
|
|
director.getScene().addChild(tempCavas);
|
|
}
|
|
return this._Instance;
|
|
}
|
|
|
|
//初始化核心数据,加载“UI窗体路径”到集合中
|
|
private init_node() {
|
|
//字段的初始化
|
|
this._DicCurrentShowUIFroms = new Map<string, BaseUIForm>();
|
|
/**缓存的所有UI */
|
|
this._ALLCacheUIFroms = new Map<string, BaseUIForm>();
|
|
/**当前显示的堆栈 */
|
|
this._StaCurrentUIForms = [];
|
|
/**获取层级预设 */
|
|
let tLayer = this._RootUI.getChildByName(SysDefine.SYS_PATH_LAYER);
|
|
/**获取内嵌型层级预设 */
|
|
let tEmbeddedLayer = this._RootUI.getChildByName(SysDefine.SYS_PATH_EMBEDDED_LAYER);
|
|
//得到UI根节点,全屏节点,固定节点,弹出节点
|
|
this._UILayer = {}
|
|
let index = 0;
|
|
let _keys: string[] = Object.keys(UIFromType);
|
|
for (let _key of _keys) {
|
|
//先删除ts枚举自带的反向映射
|
|
if (/^[0-9]+$/.test(_key)) {
|
|
delete UIFromType[_key];
|
|
} else {
|
|
let tNode: Node = null;
|
|
if (UIFromType[_key] == UIFromType.Embedded) {
|
|
tNode = instantiate(tEmbeddedLayer);
|
|
} else {
|
|
tNode = instantiate(tLayer);
|
|
}
|
|
tNode.name = _key;
|
|
tNode.active = true;
|
|
tNode.setSiblingIndex(index++);
|
|
this._RootUI.addChild(tNode);
|
|
this._UILayer[UIFromType[_key]] = tNode
|
|
}
|
|
}
|
|
tEmbeddedLayer.destroy();
|
|
tLayer.destroy();
|
|
this._Loding.setSiblingIndex(index + 2);
|
|
this._LodingUIOpacity.opacity = 0;
|
|
this._Loding.active = false;
|
|
this._UICamera = this.node.getChildByName(SysDefine.SYS_PATH_UICAMERA).getComponent(Camera);
|
|
this._MaskLoding.setSiblingIndex(index + 2);
|
|
this._MaskLoding.getComponent(UIOpacity).opacity = 0;
|
|
this._MaskLoding.active = false;
|
|
MesMgr.on(EGlobalEvent.E_OPEN_UI, this.EventOpenUI, this);
|
|
MesMgr.on(EGlobalEvent.E_CLOSE_UI, this.EventCloserUI, this);
|
|
MesMgr.on(EGlobalEvent.E_CLOSE_UIFORMS, this.CloseUIFormsByForm, this);
|
|
InputMgr.ins.onKey(Input.EventType.KEY_UP, this.TestKeyUp, this)
|
|
|
|
}//Func_End
|
|
|
|
private TestKeyUp(Code: KeyCode) {
|
|
// switch (Code) {
|
|
// case KeyCode.F2:
|
|
// !MainConfig.isMiniGame && this.ShowUI(EUIForms.DebugUI);
|
|
// break;
|
|
// }
|
|
}
|
|
|
|
|
|
/**是否拥有目标UI */
|
|
hasUIFrom(uiName: string, bundle?: string | BaseUIForm) {
|
|
const Base = this.getUIFrom(uiName, bundle);
|
|
return !!Base;
|
|
}
|
|
|
|
/**是否拥有目标UI */
|
|
hasUIFromByType(uForms: UIFormsValue): boolean {
|
|
return this.hasUIFrom(uForms.url, uForms.bundle);
|
|
}
|
|
|
|
/**获取层级的节点 */
|
|
getLayer(type: UIFromType): Node {
|
|
return this._UILayer[type];
|
|
}
|
|
|
|
/**获取UI */
|
|
getUIFrom(uiName: string, bundle?: string | BaseUIForm): BaseUIForm {
|
|
|
|
if (bundle) {
|
|
let key = `${bundle}_${uiName}`;
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
return this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
}
|
|
let _keys: string[] = Object.keys(EBundleName);
|
|
for (let _key of _keys) {
|
|
//先删除ts枚举自带的反向映射
|
|
if (/^[0-9]+$/.test(_key)) {
|
|
|
|
} else {
|
|
let key = `${_key}_${uiName}`;
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
return this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**显示游戏加载UI */
|
|
ShowGameLoadingUI() {
|
|
this.GameLoading = true;
|
|
// this.ShowUI(EUIForms.GameLodingUI)
|
|
}
|
|
|
|
/**游戏加载完成 */
|
|
GameLodingUIComplete() {
|
|
this.GameLoading = false;
|
|
}
|
|
|
|
/**加载Tips */
|
|
private _tipsQueue: string[] = []; // 存储待显示的提示队列
|
|
private _isTipsProcessing: boolean = false; // 标记是否正在处理提示队列
|
|
|
|
ShowTipsUI(Tips: string) {
|
|
if(LocalStorage.mReBuilding) return;
|
|
this._tipsQueue.push(Tips);
|
|
this._processTipsQueue();
|
|
}
|
|
|
|
private _processTipsQueue() {
|
|
// 如果已经在处理或者没有待处理的提示,则直接返回
|
|
if (!ResLoad.allDoen || this._isTipsProcessing || this._tipsQueue.length === 0) {
|
|
// if (this._tipsQueue.length === 0) {
|
|
return;
|
|
}
|
|
|
|
this._isTipsProcessing = true;
|
|
const tips = this._tipsQueue.shift();
|
|
|
|
// 显示当前提示
|
|
this.ShowUIForms("TipsUI", tips, EBundleName.Presets, () => {
|
|
// 在下一个帧处理剩余的提示
|
|
this.scheduleOnce(() => {
|
|
this._isTipsProcessing = false;
|
|
// 如果还有待显示的提示,继续处理队列
|
|
if (this._tipsQueue.length > 0) {
|
|
this._processTipsQueue();
|
|
}
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
/**事件打开UI */
|
|
private EventOpenUI(uiFormName: string, param: any = null, bundle?: string, CallBack?: Function) {
|
|
this.ShowUIForms(uiFormName, param, bundle, CallBack);
|
|
}
|
|
|
|
/**事件关闭UI */
|
|
private EventCloserUI(uiFormName: string, bundle?: string) {
|
|
this.CloseUIForms(uiFormName, bundle);
|
|
}
|
|
|
|
/**显示加载 */
|
|
showUILoding(time: number = 0.5) {
|
|
this._UIloding++;
|
|
if (this._UIloding == 1) {
|
|
this.isShowUILoding(true, time)
|
|
}
|
|
}
|
|
/**关闭加载显示 */
|
|
HideUILoding(isPopUI: boolean = true) {
|
|
this._UIloding--;
|
|
if (this._UIloding <= 0) {
|
|
this._UIloding = 0;
|
|
this.isShowUILoding(false);
|
|
isPopUI && this.UIQueueLoading();
|
|
}
|
|
}
|
|
|
|
private isShowUILoding(show: boolean, time: number = 0.5) {
|
|
if (show) {
|
|
this._LodingUIOpacity.opacity = 0;
|
|
this._Loding.active = true;
|
|
tween(this._LodingUIOpacity).delay(time).to(0.5, { opacity: 255 }).start();
|
|
} else {
|
|
Tween.stopAllByTarget(this._LodingUIOpacity);
|
|
this._LodingUIOpacity.opacity = 0;
|
|
this._Loding.active = false;
|
|
}
|
|
}
|
|
|
|
/**添加UI到队列中 */
|
|
AddUIToBackQueue(uForms: UIFormsValue, param: any = null, BackFontion?: Function) {
|
|
this._BackQueue.push({
|
|
uiUrl: uForms.url,
|
|
param: param,
|
|
bundle: uForms.bundle,
|
|
CallBack: BackFontion,
|
|
});
|
|
}
|
|
|
|
/**弹出显示队列中的UI */
|
|
ShiftBackQueueUI() {
|
|
if (this._BackQueue.length > 0) {
|
|
let tConfig = this._BackQueue.shift();
|
|
this.ShowUIForms(tConfig.uiUrl, tConfig.param, tConfig.bundle, tConfig.CallBack);
|
|
}
|
|
}
|
|
/**记载时长记录 */
|
|
loadingtime: number = 0;
|
|
/**根据UI配置类型 加载UI */
|
|
ShowUI<T>(uForms: UIFormsValue, value?: { param?: T, BackFun?: Function }) {
|
|
if (value) {
|
|
this.ShowUIForms(uForms.url, value.param, uForms.bundle, value.BackFun);
|
|
} else {
|
|
this.ShowUIForms(uForms.url, null, uForms.bundle, null);
|
|
}
|
|
}
|
|
/**
|
|
* 加载UI
|
|
* @param uiFormName UI名称
|
|
* @param param 参数
|
|
* @param bundle UI所在Bundle
|
|
* @param BackFontion 加载完成后调用
|
|
* @returns
|
|
*/
|
|
ShowUIForms(uiFormName: string, param: any = null, bundle: string, BackFontion?: Function) {
|
|
if (this._Loding.active) {
|
|
this._UIQueue.push(
|
|
{
|
|
uiUrl: uiFormName,
|
|
param: param,
|
|
bundle: bundle,
|
|
CallBack: BackFontion,
|
|
}
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (this._ALLCacheUIFroms.has(`${bundle}_${uiFormName}`)) {
|
|
BackFontion && BackFontion();
|
|
this._ShowUIForms(uiFormName, param, bundle);
|
|
this.UIQueueLoading();
|
|
} else {
|
|
this.showUILoding();
|
|
this.loadingtime = Date.now();
|
|
ResLoad.Ins.Perfab(EResUrls.UIPrefabs(uiFormName), bundle, (error, assets) => {
|
|
this.HideUILoding(false);
|
|
if (error) {
|
|
ConsoleEx.Warn("资源加载失败", error);
|
|
return;
|
|
}
|
|
BackFontion && BackFontion();
|
|
this._ShowUIForms(uiFormName, param, bundle);
|
|
if (PREVIEW) {
|
|
let tTime = Date.now() - this.loadingtime;
|
|
tTime > 50 && ConsoleEx.Warn(uiFormName, "(建议提前预加载)UI加载耗时", tTime)
|
|
}
|
|
this.UIQueueLoading();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**UI队列加载中 */
|
|
private UIQueueLoading() {
|
|
if (this._UIQueue.length > 0) {
|
|
let value = this._UIQueue.shift();
|
|
this.ShowUIForms(value.uiUrl, value.param, value.bundle, value.CallBack);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 显示(打开)UI窗体
|
|
/// 功能:
|
|
/// 1:根据UI窗体名称,加载到"所有UI窗体"缓存集合中
|
|
/// 2:根据不同的UI窗体显示模式,分别做不同的加载处理
|
|
/// </summary>
|
|
///<param name="uiFormName"> ui窗体的预设名称 </param>
|
|
private async _ShowUIForms(uiFormName: string, param: any = null, bundle: string) {
|
|
if (!isValid(this._RootUI)) { return ConsoleEx.Warn("UI未初始化数据"); }
|
|
//UI窗体的基类
|
|
let baseUIForm: BaseUIForm;
|
|
//参数的检查
|
|
if (!uiFormName) { return ConsoleEx.Warn("uiFormName错误"); };
|
|
//根据UI窗体名称,加载到"所有UI窗体"缓存集合中
|
|
baseUIForm = await this.LodeFormsToAllUIFormsCatchAsync(uiFormName, bundle);
|
|
if (baseUIForm == null) { return ConsoleEx.Warn("获取UI预设失败"); }
|
|
/**参数传递 */
|
|
baseUIForm.onShow(param);
|
|
//是否清空"栈集合"中得数据
|
|
if (baseUIForm.mUIType.IsClearStack) {
|
|
this.ClearStackArray();
|
|
}
|
|
//根据不同的UI窗体显示模式,分别做不同的加载处理
|
|
switch (baseUIForm.mUIType.FromsShowType) {
|
|
case UIFromShowType.Nomal: //"普通显示"窗口模式
|
|
this.LoadUIToCurrentCache(uiFormName, bundle);
|
|
break;
|
|
case UIFromShowType.Reversechange: //"反向切换"窗口模式
|
|
this.PushUIFormToStack(uiFormName, bundle);
|
|
break;
|
|
case UIFromShowType.HideOther: //"隐藏其他"窗口模式
|
|
this.EnterUIFormsAndHideOther(uiFormName, bundle);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
MesMgr.event(EGlobalEvent.E_UI_OPEN_CALL_BACK, uiFormName);
|
|
// TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.open_ui, { ui_name: uiFormName, ui_amount_open: 1 })
|
|
}//Func_End
|
|
|
|
|
|
/// <summary>
|
|
/// 关闭(返回上一个)窗体
|
|
/// </summary>
|
|
/// <param name="uiFormName"></param>
|
|
public CloseUIFormsByForm(baseUiForm: BaseUIForm) {
|
|
if (baseUiForm?.node) {
|
|
this.CloseUIForms(baseUiForm.node.name, baseUiForm.UIBundle);
|
|
}
|
|
}
|
|
/**关闭窗口 */
|
|
public CloseUIFormsByType(Value: UIFormsValue) {
|
|
this.CloseUIForms(Value.url, Value.bundle);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关闭(返回上一个)窗体
|
|
/// </summary>
|
|
/// <param name="uiFormName"></param>
|
|
public CloseUIForms(uiFormName: string, bundle: string) {
|
|
let baseUiForm: BaseUIForm; //窗体基类
|
|
//参数检查
|
|
if (!uiFormName) return;
|
|
let key = `${bundle}_${uiFormName}`
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
//“所有UI窗体”集合中,如果没有记录,则直接返回
|
|
baseUiForm = this._ALLCacheUIFroms.get(key);
|
|
}
|
|
if (baseUiForm == null) return;
|
|
let time_s = baseUiForm.ExistTime;
|
|
//根据窗体不同的显示类型,分别作不同的关闭处理
|
|
switch (baseUiForm.mUIType.FromsShowType) {
|
|
case UIFromShowType.Nomal:
|
|
//普通窗体的关闭
|
|
this.ExitUIForms(uiFormName, bundle);
|
|
break;
|
|
case UIFromShowType.Reversechange:
|
|
//反向切换窗体的关闭
|
|
this.PopUIFroms();
|
|
break;
|
|
case UIFromShowType.HideOther:
|
|
//隐藏其他窗体关闭
|
|
this.ExitUIFormsAndDisplayOther(uiFormName, bundle);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!baseUiForm.misCache) {
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
this._ALLCacheUIFroms.delete(key);
|
|
}
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
this._DicCurrentShowUIFroms.delete(key);
|
|
}
|
|
baseUiForm.ClearSpriteFrame();
|
|
baseUiForm.node.removeFromParent();
|
|
baseUiForm.node.destroy();
|
|
}
|
|
PREVIEW && ConsoleEx.Log("关闭UI—— ", uiFormName);
|
|
MesMgr.event(EGlobalEvent.E_UI_CLOSE_CALL_BACK, uiFormName);
|
|
// TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.hide_ui, { ui_name: uiFormName, ui_time: Utils.MathUtils.MsToFloat(time_s), ui_amount_close: 1 })
|
|
if (this._BackQueue.length > 0 && !this._UIloding && this.CheckOnlyMainUI()) {
|
|
let tConfig = this._BackQueue.shift();
|
|
this.ShowUIForms(tConfig.uiUrl, tConfig.param, tConfig.bundle, tConfig.CallBack);
|
|
}
|
|
|
|
}
|
|
|
|
/**检测是否只存在主UI */
|
|
private CheckOnlyMainUI() {
|
|
let keys: string[] = [];
|
|
for (let i = 0; i < this._MainUI.length; i++) {
|
|
const tConfig = this._MainUI[i];
|
|
if (!tConfig) { continue; }
|
|
let key = `${tConfig.bundle}_${tConfig.uiUrl}`;
|
|
keys.push(key);
|
|
}
|
|
let isFalse = true;
|
|
this._DicCurrentShowUIFroms.forEach((value, Key) => {
|
|
if (!keys.includes(Key)) {
|
|
isFalse = false;
|
|
return false;
|
|
}
|
|
})
|
|
return isFalse;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据UI窗体名称,加载到"所有UI窗体"缓存集合中
|
|
/// 功能:检查"所有UI窗体"集合中,是否已经加载过,否则才加载
|
|
/// </summary>
|
|
/// <param name="uiFormName">UI窗体(预设)的名称</param>
|
|
/// <returns></returns>
|
|
private async LodeFormsToAllUIFormsCatchAsync(uiFormName: string, bundle: string): Promise<BaseUIForm> {
|
|
let baseUIResult: BaseUIForm = null;
|
|
let key = `${bundle}_${uiFormName}`
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
baseUIResult = this._ALLCacheUIFroms.get(key);
|
|
}
|
|
if (baseUIResult == null) {
|
|
baseUIResult = await this.LoadUIFormAsync(uiFormName, bundle);
|
|
if (baseUIResult != null) {
|
|
//把克隆体,加入到"所有UI窗体"(缓存)集合中
|
|
this._ALLCacheUIFroms.set(key, baseUIResult);
|
|
}
|
|
}
|
|
return baseUIResult;
|
|
}//Func_End
|
|
|
|
/**
|
|
* 加载指定的UI窗体名称
|
|
* @param uiFormName UI窗体(预设)的名称
|
|
* @returns Promise<BaseUIForm>
|
|
*/
|
|
private async LoadUIFormAsync(uiFormName: string, bundle: string): Promise<BaseUIForm> {
|
|
return new Promise((resolve) => {
|
|
// 异步执行,避免阻塞主线程
|
|
setTimeout(() => {
|
|
try {
|
|
/**创建的UI克隆体预设 */
|
|
let goCloneUIPrefabs: Node = null;
|
|
/**创建基类 */
|
|
let baseUIForm: BaseUIForm = null;
|
|
|
|
//根据UI窗体(预设)的名称,加载预设克隆体
|
|
if (uiFormName.includes(EKeyResName.UIPrefabs)) {
|
|
goCloneUIPrefabs = ResLoad.Ins.GetRes(uiFormName, bundle);
|
|
} else {
|
|
goCloneUIPrefabs = ResLoad.Ins.GetRes(EResUrls.UIPrefabs(uiFormName), bundle);
|
|
}
|
|
|
|
if (this._RootUI != null && goCloneUIPrefabs != null) {
|
|
baseUIForm = goCloneUIPrefabs.getComponent(BaseUIForm);
|
|
if (baseUIForm == null) {
|
|
ConsoleEx.Error("添加失败 没有继承BaseUIForm 的子类脚本 uiFormName=" + uiFormName);
|
|
resolve(null);
|
|
return;
|
|
}
|
|
|
|
//设置UI克隆体的父节点(根据克隆体中带的脚本中不同的"位置信息")
|
|
goCloneUIPrefabs.setParent(this._UILayer[baseUIForm.mUIType.FromsType]);
|
|
goCloneUIPrefabs.active = false;
|
|
|
|
resolve(baseUIForm);
|
|
} else {
|
|
ConsoleEx.Error("添加失败 没有当前名字的预制体 uiFormName=" + uiFormName," || bundle=",bundle);
|
|
resolve(null);
|
|
}
|
|
} catch (e) {
|
|
ConsoleEx.Error("加载UI异常:", e);
|
|
resolve(null);
|
|
}
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 把当前窗体加载到“当前窗体”集合中
|
|
/// </summary>
|
|
/// <param name="uiFormName">窗体的预设名称</param>
|
|
private LoadUIToCurrentCache(uiFormName: string, bundle: string) {
|
|
let baseUIForm: BaseUIForm = null; //UI窗体基类
|
|
let baseUIFormFormAllCache: BaseUIForm = null; //从“所有窗体集合”中得到的窗体
|
|
let key = `${bundle}_${uiFormName}`
|
|
//如果“正在显示”的集合中,存在整个窗体,则直接返回
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
baseUIForm = this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
if (baseUIForm != null) { baseUIForm.ReDisplay(); return; };
|
|
//把当前窗体 加载到“正在显示”的集合中
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
baseUIFormFormAllCache = this._ALLCacheUIFroms.get(key);
|
|
}
|
|
if (baseUIFormFormAllCache != null) {
|
|
this._DicCurrentShowUIFroms.set(key, baseUIFormFormAllCache);
|
|
baseUIFormFormAllCache.Display(); //显示当前窗体
|
|
}
|
|
}//Func_End
|
|
|
|
/// <summary>
|
|
/// UI窗体入栈
|
|
/// </summary>
|
|
/// <param name="uiFormName">窗体的名称</param>
|
|
private PushUIFormToStack(uiFormName: string, bundle: string) {
|
|
/**UI窗体 */
|
|
let baseUIForm: BaseUIForm;
|
|
|
|
//判断“栈”集合中,是否有其他的窗体,有则“冻结”处理。
|
|
if (this._StaCurrentUIForms.length > 0) {
|
|
let topUIForm: BaseUIForm = this._StaCurrentUIForms[this._StaCurrentUIForms.length - 1];
|
|
//栈顶元素作冻结处理
|
|
topUIForm.Freeze();
|
|
}
|
|
let key = `${bundle}_${uiFormName}`
|
|
//判断“UI所有窗体”集合是否有指定的UI窗体,有则处理。
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
baseUIForm = this._ALLCacheUIFroms.get(key)
|
|
}
|
|
if (baseUIForm != null) {
|
|
//当前窗口显示状态
|
|
baseUIForm.Display();
|
|
//把指定的UI窗体,入栈操作。
|
|
this._StaCurrentUIForms.push(baseUIForm);
|
|
} else {
|
|
ConsoleEx.Error("baseUIForm==null,Please Check, 参数 uiFormName=" + uiFormName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否清空“栈集合”中得数据
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private ClearStackArray(): boolean {
|
|
if (this._StaCurrentUIForms != null && this._StaCurrentUIForms.length >= 1) {
|
|
//清空栈集合
|
|
this._StaCurrentUIForms = [];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 退出指定UI窗体
|
|
* @param strUIFormName
|
|
* @param bundle
|
|
* @returns
|
|
*/
|
|
private ExitUIForms(strUIFormName: string, bundle: string) {
|
|
let baseUIForm: BaseUIForm; //窗体基类
|
|
let key = `${bundle}_${strUIFormName}`
|
|
//"正在显示集合"中如果没有记录,则直接返回。
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
baseUIForm = this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
if (baseUIForm == null) return;
|
|
//指定窗体,标记为“隐藏状态”,且从"正在显示集合"中移除。
|
|
baseUIForm.Hideing();
|
|
this._DicCurrentShowUIFroms.delete(key);
|
|
}
|
|
|
|
/**
|
|
* (“反向切换”属性)窗体的出栈逻辑
|
|
*/
|
|
private PopUIFroms() {
|
|
if (this._StaCurrentUIForms.length >= 2) {
|
|
//出栈处理
|
|
let topUIForms: BaseUIForm = this._StaCurrentUIForms.pop();
|
|
//做隐藏处理
|
|
topUIForms.Hideing();
|
|
//出栈后,下一个窗体做“重新显示”处理。
|
|
let nextUIForms: BaseUIForm = this._StaCurrentUIForms[this._StaCurrentUIForms.length - 1];
|
|
nextUIForms.ReDisplay();
|
|
}
|
|
else if (this._StaCurrentUIForms.length == 1) {
|
|
//出栈处理
|
|
let topUIForms: BaseUIForm = this._StaCurrentUIForms.pop();
|
|
//做隐藏处理
|
|
topUIForms.Hideing();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* (“隐藏其他”属性)打开窗体,且隐藏其他窗体
|
|
* @param strUIName 打开的指定窗体名称
|
|
* @param bundle
|
|
* @returns
|
|
*/
|
|
private EnterUIFormsAndHideOther(strUIName: string, bundle: string) {
|
|
let baseUIForm: BaseUIForm; //UI窗体基类
|
|
let baseUIFormFromALL: BaseUIForm; //从集合中得到的UI窗体基类
|
|
|
|
//参数检查
|
|
if (!strUIName) return;
|
|
let key = `${bundle}_${strUIName}`;
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
baseUIForm = this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
if (baseUIForm != null) return;
|
|
|
|
//把“正在显示集合”与“栈集合”中所有窗体都隐藏。
|
|
|
|
this._DicCurrentShowUIFroms.forEach((value, key) => {
|
|
value.Hideing();
|
|
});
|
|
|
|
this._StaCurrentUIForms.forEach((staUI, key) => {
|
|
staUI.Hideing();
|
|
});
|
|
|
|
//把当前窗体加入到“正在显示窗体”集合中,且做显示处理。
|
|
if (this._ALLCacheUIFroms.has(key)) {
|
|
baseUIFormFromALL = this._ALLCacheUIFroms.get(key);
|
|
}
|
|
if (baseUIFormFromALL != null) {
|
|
this._DicCurrentShowUIFroms.set(key, baseUIFormFromALL);
|
|
//窗体显示
|
|
baseUIFormFromALL.Display();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* (“隐藏其他”属性)关闭窗体,且显示其他窗体
|
|
* @param strUIName 打开的指定窗体名称
|
|
* @param bundle
|
|
* @returns
|
|
*/
|
|
private ExitUIFormsAndDisplayOther(strUIName: string, bundle: string) {
|
|
//UI窗体基类
|
|
let baseUIForm: BaseUIForm;
|
|
//参数检查
|
|
if (!strUIName) return;
|
|
let key = `${bundle}_${strUIName}`;
|
|
if (this._DicCurrentShowUIFroms.has(key)) {
|
|
baseUIForm = this._DicCurrentShowUIFroms.get(key);
|
|
}
|
|
if (baseUIForm == null) return;
|
|
|
|
//当前窗体隐藏状态,且“正在显示”集合中,移除本窗体
|
|
baseUIForm.Hideing();
|
|
this._DicCurrentShowUIFroms.delete(key);
|
|
|
|
//把“正在显示集合”与“栈集合”中所有窗体都定义重新显示状态。
|
|
this._DicCurrentShowUIFroms.forEach((baseUI, key) => {
|
|
baseUI.ReDisplay();
|
|
});
|
|
|
|
this._StaCurrentUIForms.forEach((staUI, key) => {
|
|
staUI.ReDisplay();
|
|
});
|
|
|
|
}
|
|
|
|
/**关闭所有 某个类型的窗口 */
|
|
CloseAllUIByType(type: UIFromType = UIFromType.PopUp) {
|
|
this._DicCurrentShowUIFroms.forEach((value, key) => {
|
|
if (value.mUIType.FromsType == type) {
|
|
value.onClick_closeBtn();
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/**销毁所有窗口 */
|
|
ClearAllWindow() {
|
|
this._ALLCacheUIFroms.forEach((value, key) => {
|
|
if (!this._DicCurrentShowUIFroms.has(key)) {
|
|
value.node.destroy();
|
|
this._ALLCacheUIFroms.delete(key);
|
|
}
|
|
});
|
|
}
|
|
|
|
DestroyAllWinow() {
|
|
this._DicCurrentShowUIFroms.forEach((value, key) => {
|
|
value.node.destroy();
|
|
this._DicCurrentShowUIFroms.delete(key);
|
|
});
|
|
this._ALLCacheUIFroms.forEach((value, key) => {
|
|
value.node.destroy();
|
|
this._ALLCacheUIFroms.delete(key);
|
|
});
|
|
}
|
|
|
|
//#endregion
|
|
|
|
}
|