mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-10 23:45:54 +08:00
313 lines
9.3 KiB
TypeScript
313 lines
9.3 KiB
TypeScript
import { Camera, Layers, Node, warn, Widget } from "cc";
|
||
import { GUI } from "../GUI";
|
||
import { UICallbacks } from "./Defines";
|
||
import { DelegateComponent } from "./DelegateComponent";
|
||
import { LayerDialog } from "./LayerDialog";
|
||
import { LayerNotify } from "./LayerNotify";
|
||
import { LayerPopUp } from "./LayerPopup";
|
||
import { LayerUI } from "./LayerUI";
|
||
import { UIMap } from "./UIMap";
|
||
|
||
/** 界面层类型 */
|
||
export enum LayerType {
|
||
/** 游戏层 */
|
||
Game = "LayerGame",
|
||
/** 主界面层 */
|
||
UI = "LayerUI",
|
||
/** 弹窗层 */
|
||
PopUp = "LayerPopUp",
|
||
/** 模式窗口层 */
|
||
Dialog = "LayerDialog",
|
||
/** 系统触发模式窗口层 */
|
||
System = "LayerSystem",
|
||
/** 滚动消息提示层 */
|
||
Notify = "LayerNotify",
|
||
/** 新手引导层 */
|
||
Guide = "LayerGuide"
|
||
}
|
||
|
||
/**
|
||
* 界面配置结构体
|
||
* @example
|
||
// 界面唯一标识
|
||
export enum UIID {
|
||
Loading = 1,
|
||
Window,
|
||
Netinstable
|
||
}
|
||
|
||
// 打开界面方式的配置数据
|
||
export var UIConfigData: { [key: number]: UIConfig } = {
|
||
[UIID.Loading]: { layer: LayerType.UI, prefab: "loading/prefab/loading", bundle: "resources" },
|
||
[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
|
||
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" }
|
||
}
|
||
*/
|
||
export interface UIConfig {
|
||
/** 远程包名 */
|
||
bundle?: string;
|
||
/** 窗口层级 */
|
||
layer: LayerType;
|
||
/** 预制资源相对路径 */
|
||
prefab: string;
|
||
}
|
||
|
||
export class LayerManager {
|
||
/** 界面根节点 */
|
||
root!: Node;
|
||
/** 界面摄像机 */
|
||
camera!: Camera;
|
||
/** 游戏界面特效层 */
|
||
game!: Node;
|
||
/** 新手引导层 */
|
||
guide!: Node;
|
||
/** 界面地图 */
|
||
uiMap!: UIMap;
|
||
|
||
/** 界面层 */
|
||
private ui!: LayerUI;
|
||
/** 弹窗层 */
|
||
private popup!: LayerPopUp;
|
||
/** 只能弹出一个的弹窗 */
|
||
private dialog!: LayerDialog;
|
||
/** 游戏系统提示弹窗 */
|
||
private system!: LayerDialog;
|
||
/** 消息提示控制器,请使用show方法来显示 */
|
||
private notify!: LayerNotify;
|
||
/** UI配置 */
|
||
private configs: { [key: number]: UIConfig } = {};
|
||
|
||
/** 是否为竖屏显示 */
|
||
get portrait() {
|
||
return this.root.getComponent(GUI)!.portrait;
|
||
}
|
||
|
||
/**
|
||
* 初始化所有UI的配置对象
|
||
* @param configs 配置对象
|
||
*/
|
||
init(configs: { [key: number]: UIConfig }): void {
|
||
this.configs = configs;
|
||
}
|
||
|
||
/**
|
||
* 渐隐飘过提示
|
||
* @param content 文本表示
|
||
* @param useI18n 是否使用多语言
|
||
* @example
|
||
* oops.gui.toast("提示内容");
|
||
*/
|
||
toast(content: string, useI18n: boolean = false) {
|
||
this.notify.show(content, useI18n)
|
||
}
|
||
|
||
/**
|
||
* 设置界面配置
|
||
* @param uiId 要设置的界面id
|
||
* @param config 要设置的配置
|
||
*/
|
||
setConfig(uiId: number, config: UIConfig): void {
|
||
this.configs[uiId] = config;
|
||
}
|
||
|
||
/**
|
||
* 设置界面地图配置
|
||
* @param data 界面地图数据
|
||
*/
|
||
setUIMap(data: any) {
|
||
if (this.uiMap == null) {
|
||
this.uiMap = new UIMap();
|
||
}
|
||
this.uiMap.init(this, data);
|
||
}
|
||
|
||
/**
|
||
* 同步打开一个窗口
|
||
* @param uiId 窗口唯一编号
|
||
* @param uiArgs 窗口参数
|
||
* @param callbacks 回调对象
|
||
* @example
|
||
var uic: UICallbacks = {
|
||
onAdded: (node: Node, params: any) => {
|
||
var comp = node.getComponent(LoadingViewComp) as ecs.Comp;
|
||
}
|
||
onRemoved:(node: Node | null, params: any) => {
|
||
|
||
}
|
||
};
|
||
oops.gui.open(UIID.Loading, null, uic);
|
||
*/
|
||
open(uiId: number, uiArgs: any = null, callbacks?: UICallbacks): void {
|
||
var config = this.configs[uiId];
|
||
if (config == null) {
|
||
warn(`打开编号为【${uiId}】的界面失败,配置信息不存在`);
|
||
return;
|
||
}
|
||
|
||
switch (config.layer) {
|
||
case LayerType.UI:
|
||
this.ui.add(config, uiArgs, callbacks);
|
||
break;
|
||
case LayerType.PopUp:
|
||
this.popup.add(config, uiArgs, callbacks);
|
||
break;
|
||
case LayerType.Dialog:
|
||
this.dialog.add(config, uiArgs, callbacks);
|
||
break;
|
||
case LayerType.System:
|
||
this.system.add(config, uiArgs, callbacks);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 异步打开一个窗口
|
||
* @param uiId 窗口唯一编号
|
||
* @param uiArgs 窗口参数
|
||
* @example
|
||
* var node = await oops.gui.openAsync(UIID.Loading);
|
||
*/
|
||
async openAsync(uiId: number, uiArgs: any = null): Promise<Node | null> {
|
||
return new Promise<Node | null>((resolve, reject) => {
|
||
var callbacks: UICallbacks = {
|
||
onAdded: (node: Node, params: any) => {
|
||
resolve(node)
|
||
}
|
||
};
|
||
this.open(uiId, uiArgs, callbacks);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 缓存中是否存在指定标识的窗口
|
||
* @param uiId 窗口唯一标识
|
||
* @example
|
||
* oops.gui.has(UIID.Loading);
|
||
*/
|
||
has(uiId: number): boolean {
|
||
var config = this.configs[uiId];
|
||
if (config == null) {
|
||
warn(`编号为【${uiId}】的界面失败,配置信息不存在`);
|
||
return false;
|
||
}
|
||
|
||
var result = false;
|
||
switch (config.layer) {
|
||
case LayerType.UI:
|
||
result = this.ui.has(config.prefab);
|
||
break;
|
||
case LayerType.PopUp:
|
||
result = this.popup.has(config.prefab);
|
||
break;
|
||
case LayerType.Dialog:
|
||
result = this.dialog.has(config.prefab);
|
||
break;
|
||
case LayerType.System:
|
||
result = this.system.has(config.prefab);
|
||
break;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 移除指定标识的窗口
|
||
* @param uiId 窗口唯一标识
|
||
* @param isDestroy 移除后是否释放
|
||
* @example
|
||
* oops.gui.remove(UIID.Loading);
|
||
*/
|
||
remove(uiId: number, isDestroy: boolean = true) {
|
||
var config = this.configs[uiId];
|
||
if (config == null) {
|
||
warn(`删除编号为【${uiId}】的界面失败,配置信息不存在`);
|
||
return;
|
||
}
|
||
|
||
switch (config.layer) {
|
||
case LayerType.UI:
|
||
this.ui.remove(config.prefab, isDestroy);
|
||
break;
|
||
case LayerType.PopUp:
|
||
this.popup.remove(config.prefab, isDestroy);
|
||
break;
|
||
case LayerType.Dialog:
|
||
this.dialog.remove(config.prefab, isDestroy);
|
||
break;
|
||
case LayerType.System:
|
||
this.system.remove(config.prefab, isDestroy);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除一个通过this框架添加进来的节点
|
||
* @param node 窗口节点
|
||
* @param isDestroy 移除后是否释放
|
||
* @example
|
||
* oops.gui.removeByNode(cc.Node);
|
||
*/
|
||
removeByNode(node: Node, isDestroy: boolean = false) {
|
||
if (node instanceof Node) {
|
||
let comp = node.getComponent(DelegateComponent);
|
||
if (comp && comp.viewParams) {
|
||
// @ts-ignore 注:不对外使用
|
||
(node.parent as LayerUI).removeByUuid(comp.viewParams.uuid, isDestroy);
|
||
}
|
||
else {
|
||
warn(`当前删除的node不是通过界面管理器添加到舞台上`);
|
||
node.destroy();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清除所有窗口
|
||
* @param isDestroy 移除后是否释放
|
||
* @example
|
||
* oops.gui.clear();
|
||
*/
|
||
clear(isDestroy: boolean = false) {
|
||
this.ui.clear(isDestroy);
|
||
this.popup.clear(isDestroy);
|
||
this.dialog.clear(isDestroy);
|
||
this.system.clear(isDestroy);
|
||
}
|
||
|
||
/**
|
||
* 构造函数
|
||
* @param root 界面根节点
|
||
*/
|
||
constructor(root: Node) {
|
||
this.root = root;
|
||
this.camera = this.root.getComponentInChildren(Camera)!;
|
||
|
||
this.game = this.create_node(LayerType.Game);
|
||
|
||
this.ui = new LayerUI(LayerType.UI);
|
||
this.popup = new LayerPopUp(LayerType.PopUp);
|
||
this.dialog = new LayerDialog(LayerType.Dialog);
|
||
this.system = new LayerDialog(LayerType.System);
|
||
this.notify = new LayerNotify(LayerType.Notify);
|
||
|
||
this.guide = this.create_node(LayerType.Guide);
|
||
|
||
root.addChild(this.game);
|
||
root.addChild(this.ui);
|
||
root.addChild(this.popup);
|
||
root.addChild(this.dialog);
|
||
root.addChild(this.system);
|
||
root.addChild(this.notify);
|
||
root.addChild(this.guide);
|
||
}
|
||
|
||
private create_node(name: string) {
|
||
var node = new Node(name);
|
||
node.layer = Layers.Enum.UI_2D;
|
||
var w: Widget = node.addComponent(Widget);
|
||
w.isAlignLeft = w.isAlignRight = w.isAlignTop = w.isAlignBottom = true;
|
||
w.left = w.right = w.top = w.bottom = 0;
|
||
w.alignMode = 2;
|
||
w.enabled = true;
|
||
return node;
|
||
}
|
||
} |