UNPKG

@senspark/ee

Version:

utility library for cocos creator

160 lines (129 loc) 4.66 kB
import assert = require('assert'); import { DialogManager } from './DialogManager'; const { ccclass, disallowMultiple, menu } = cc._decorator; type DialogEvent = (dialog: Dialog) => void; type Transition = cc.FiniteTimeAction; export enum DialogEventType { WillShow, DidShow, WillHide, DidHide, } @ccclass @disallowMultiple @menu('ee/Dialog') export class Dialog extends cc.Component { private active: boolean; /** Used to run transtitions. */ private actor: cc.Node; private showingTransitions: Transition[]; private hidingTransitions: Transition[]; private eventDictionary: { [key: number]: DialogEvent[] }; protected manager?: DialogManager; public constructor() { super(); this.active = false; this.actor = new cc.Node(); this.showingTransitions = []; this.hidingTransitions = []; this.eventDictionary = {}; } public onLoad(): void { this.node.addChild(this.actor); } public getContainer(): cc.Node { return this.node.parent; } /** Shows this dialog using the specified dialog manager. */ public show(manager: DialogManager): void { const container = new cc.Node(); container.setContentSize(cc.winSize); container.addChild(this.node); container.addComponent(cc.BlockInputEvents); this.manager = manager; manager.pushDialog(this); } /** Hides this dialog using the current dialog manager. */ public hide(): void { const manager = this.manager; assert(manager !== undefined); if (manager !== undefined) { manager.popDialog(this); } } /** Attempts to show the specified dialog using the current dialog manager. */ public showDialog(dialog: Dialog): void { const manager = this.manager; if (manager === undefined) { assert(false, 'The current dialog is not active.'); return; } dialog.show(manager); } /** Checks whether this dialog is active. */ public isActive(): boolean { return this.active; } /** Sets this dialog to be active. */ public setActive(active: boolean): void { this.active = active; } /** Adds a will-show event. */ public onWillShow(event: DialogEvent): this { return this.addEvent(DialogEventType.WillShow, event); } /** Adds a did-show event. */ public onDidShow(event: DialogEvent): this { return this.addEvent(DialogEventType.DidShow, event); } /** Adds a will-hide event. */ public onWillHide(event: DialogEvent): this { return this.addEvent(DialogEventType.WillHide, event); } /** Adds a did-hide event. */ public onDidHide(event: DialogEvent): this { return this.addEvent(DialogEventType.DidHide, event); } /** Adds a showing transition. */ public addShowingTransition(transition: Transition): this { this.showingTransitions.push(transition); return this; } /** Adds a hiding transition. */ public addHidingTransition(transition: Transition): this { this.hidingTransitions.push(transition); return this; } public playShowingTransition(callback: () => void): void { this.playTransition(this.showingTransitions, callback); } public playHidingTransition(callback: () => void): void { this.playTransition(this.hidingTransitions, callback); } private playTransition(actions: Transition[], callback: () => void): void { assert(this.actor.getNumberOfRunningActions() === 0); this.actor.stopAllActions(); const transitions = [] as Transition[]; actions.forEach(action => transitions.push(...[ cc.delayTime(0), // Add dummy action to prevent callback runs twice. cc.targetedAction(this.node, action), ])); transitions.push(cc.callFunc(callback)); this.actor.runAction(actions.length === 0 ? cc.callFunc(callback) : cc.sequence(transitions)); } public addEvent(type: DialogEventType, event: DialogEvent): this { const events = this.getEvents(type); events.push(event); return this; } /** Processes all events for the specified event type. */ public processEvent(type: DialogEventType): void { const events = this.getEvents(type); events.forEach(event => event(this)); } private getEvents(type: DialogEventType): DialogEvent[] { return this.eventDictionary[type] = this.eventDictionary[type] || []; } }