mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-06-19 19:17:21 +08:00
146 lines
4.4 KiB
TypeScript
146 lines
4.4 KiB
TypeScript
/*
|
||
* @Date: 2021-11-24 16:08:36
|
||
* @LastEditors: dgflash
|
||
* @LastEditTime: 2022-09-02 13:44:28
|
||
*/
|
||
import type { EventTouch } from 'cc';
|
||
import { BlockInputEvents, Node } from 'cc';
|
||
import { ViewUtil } from '../../utils/ViewUtil';
|
||
import { PromptResType } from '../GuiEnum';
|
||
import { LayerUI } from './LayerUI';
|
||
import type { UIState } from './LayerUIElement';
|
||
import type { UIConfig } from './UIConfig';
|
||
|
||
/* 弹窗层,允许同时弹出多个窗口 */
|
||
export class LayerPopUp extends LayerUI {
|
||
/** 触摸事件阻挡 */
|
||
protected black!: BlockInputEvents;
|
||
/** 半透明遮罩资源 */
|
||
protected mask!: Node;
|
||
|
||
protected onChildAdded(child: Node) {
|
||
this.mask && this.mask.setSiblingIndex(this.children.length - 2);
|
||
}
|
||
|
||
protected onChildRemoved(child: Node) {
|
||
this.mask && this.mask.setSiblingIndex(this.children.length - 2);
|
||
super.onChildRemoved(child);
|
||
}
|
||
|
||
protected uiInit(state: UIState): Promise<boolean> {
|
||
return new Promise(async (resolve) => {
|
||
const r = await super.uiInit(state);
|
||
if (r) {
|
||
// 界面加载完成显示时,启动触摸非窗口区域关闭
|
||
this.openVacancyRemove(state.config);
|
||
|
||
// 界面加载完成显示时,层级事件阻挡
|
||
this.black.enabled = true;
|
||
}
|
||
resolve(r);
|
||
});
|
||
}
|
||
|
||
protected closeUi(state: UIState) {
|
||
super.closeUi(state);
|
||
|
||
// 界面关闭后,关闭触摸事件阻挡、关闭触摸非窗口区域关闭、关闭遮罩
|
||
this.closeBlack();
|
||
}
|
||
|
||
/** 检查是否存在需要 mask 的窗口 */
|
||
private hasMaskWindow(): boolean {
|
||
for (const value of this.ui_nodes.values()) {
|
||
if (value.config.mask) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/** 检查是否存在需要 vacancy 的窗口 */
|
||
private hasVacancyWindow(): boolean {
|
||
for (const value of this.ui_nodes.values()) {
|
||
if (value.config.vacancy) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/** 设置触摸事件阻挡 */
|
||
protected closeBlack() {
|
||
// 检查是否还需要阻挡输入(mask 或 vacancy)
|
||
const needsBlocking = this.hasMaskWindow() || this.hasVacancyWindow();
|
||
|
||
if (!needsBlocking) {
|
||
if (this.black) this.black.enabled = false;
|
||
this.closeVacancyRemove();
|
||
}
|
||
|
||
this.closeMask();
|
||
}
|
||
|
||
/** 关闭遮罩 */
|
||
protected closeMask() {
|
||
if (this.mask == null) return;
|
||
|
||
// 如果不存在需要 mask 的窗口,则完全移除 mask
|
||
if (!this.hasMaskWindow()) {
|
||
this.mask.uiSprite.enabled = false;
|
||
this.mask.parent = null;
|
||
}
|
||
}
|
||
|
||
/** 启动触摸非窗口区域关闭 */
|
||
protected openVacancyRemove(config: UIConfig) {
|
||
// 背景半透明遮罩
|
||
if (this.mask == null) {
|
||
this.mask = ViewUtil.createPrefabNode(PromptResType.Mask);
|
||
this.mask.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
|
||
|
||
this.black = this.mask.addComponent(BlockInputEvents);
|
||
this.black.enabled = false;
|
||
}
|
||
|
||
if (config.mask) {
|
||
this.mask.parent = this;
|
||
this.mask.uiSprite.enabled = true;
|
||
}
|
||
}
|
||
|
||
/** 关闭触摸非窗口区域关闭 */
|
||
protected closeVacancyRemove() {
|
||
if (!this.hasVacancyWindow() && this.hasEventListener(Node.EventType.TOUCH_END, this.onTouchEnd, this)) {
|
||
this.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
|
||
}
|
||
}
|
||
|
||
/** 触摸非窗口区域关闭 */
|
||
private onTouchEnd(event: EventTouch) {
|
||
if (this.ui_nodes.size > 0) {
|
||
const vp = this.ui_nodes.array[this.ui_nodes.size - 1];
|
||
if (vp.valid && vp.config.vacancy) {
|
||
this.remove(vp.config.prefab);
|
||
}
|
||
}
|
||
}
|
||
|
||
clear(isDestroy: boolean) {
|
||
super.clear(isDestroy);
|
||
this.closeBlack();
|
||
}
|
||
|
||
/** 销毁时释放资源 */
|
||
onDestroy() {
|
||
// 清理遮罩节点
|
||
if (this.mask) {
|
||
this.mask.destroy();
|
||
this.mask = null!;
|
||
}
|
||
|
||
// 清理事件阻挡组件引用
|
||
this.black = null!;
|
||
}
|
||
}
|