Files
oops-plugin-framework/assets/core/gui/layer/LayerPopup.ts

146 lines
4.4 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.
/*
* @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!;
}
}