UNPKG

avg-core-ts

Version:

Develop Adventure Game (or ADV, Visual Novel, Galgame, etc.) on your own!

232 lines (211 loc) 7.83 kB
/** * @file Textwindow component * @author MicroMatrix <yangpan.1985@bytedance.com> * @copyright 2012-2020 bytedance * @link git@code.byted.org:yangpan.1985/avg.git */ import React from 'react'; import core from 'core/core'; import createComponent from 'components/createComponent'; import ContainerMixin from 'components/ContainerMixin'; import NodeMixin from 'components/NodeMixin'; import PixiTextwindow from 'classes/TextWindow'; import pixiPropTypes from './pixi/propTypes'; import { Transition } from 'components/transition'; import transition from 'plugins/transition'; const RawTextwindow = createComponent('RawTextwindow', ContainerMixin, NodeMixin, { createNode() { this.node = new PixiTextwindow(); }, mountNode(props) { // color, opacity, width, height, x, y, etc. const layer = this.node; props.textRect && layer.setTextRectangle(props.textRect); props.xInterval != null && layer.setXInterval(props.xInterval); props.yInterval != null && layer.setYInterval(props.yInterval); props.bgFile && layer.setBackgroundFile(props.bgFile); props.opacity != null && layer.setOpacity(props.opacity); props.visible != null && layer.setVisible(props.visible); props.font && layer.setTextFont(props.font); props.size && layer.setTextSize(props.size); props.color != null && layer.setTextColor(props.color); props.bold != null && layer.setTextBold(props.bold); props.italic != null && layer.setTextItalic(props.italic); props.speed && layer.setTextSpeed(props.speed); props.text && layer.drawText(props.text, true); layer.x = props.x || 0; layer.y = props.y || 0; return layer; }, updateNode(prevProps, props) { const layer = this.node; prevProps.textRect !== props.textRect && layer.setTextRectangle(props.textRect); prevProps.xInterval !== props.xInterval && layer.setXInterval(props.xInterval || 0); prevProps.yInterval !== props.yInterval && layer.setYInterval(props.yInterval || 0); prevProps.bgFile !== props.bgFile && layer.setBackgroundFile(props.bgFile); prevProps.opacity !== props.opacity && layer.setOpacity(props.opacity); prevProps.visible !== props.visible && layer.setVisible(props.visible); prevProps.font !== props.font && layer.setTextFont(props.font); prevProps.size !== props.size && layer.setTextSize(props.size); prevProps.color !== props.color && layer.setTextColor(props.color); prevProps.bold !== props.bold && layer.setTextBold(props.bold); prevProps.italic !== props.italic && layer.setTextItalic(props.italic); prevProps.speed !== props.speed && layer.setTextSpeed(props.speed); layer.x = props.x || 0; layer.y = props.y || 0; // layer.setProperties(props); }, }); export class Textwindow extends React.Component { static displayName = 'Textwindow'; static propTypes = pixiPropTypes; constructor(props) { super(props); this.handleScriptExec = this.handleScriptExec.bind(this); this.handleScriptTrigger = this.handleScriptTrigger.bind(this); this.handleArchiveSave = this.handleArchiveSave.bind(this); this.handleArchiveLoad = this.handleArchiveLoad.bind(this); this.transitionHandler = null; this.state = { props: {}, }; } componentWillMount() { this.setState({ props: this.props, clickCallback: false, switchPageAfterClick: false, waitClick: false }); } componentDidMount() { core.use('script-trigger', this.handleScriptTrigger); core.use('script-exec', this.handleScriptExec); core.use('save-archive', this.handleArchiveSave); core.use('load-archive', this.handleArchiveLoad); this.execute = transition(this.transLayer, this.execute.bind(this)); } componentWillUnmount() { core.unuse('script-trigger', this.handleScriptTrigger); core.unuse('script-exec', this.handleScriptExec); core.unuse('save-archive', this.handleArchiveSave); core.unuse('load-archive', this.handleArchiveLoad); } async execute(ctx, next) { const { command, flags, params } = ctx; const layer = this.layer; let promise = Promise.resolve(); let waitClick = false; let clickCallback = false; let switchPageAfterClick = false; if (command === 'r') { // waitClick = true; promise = layer.drawText('\n', false); clickCallback = true; } else if (command === 'l') { waitClick = true; } else if (command === 'p') { waitClick = true; // promise = layer.drawText('', true); clickCallback = true; switchPageAfterClick = true; } else if (flags.includes('clear')) { // layer.clearText(); // it is a hack layer.drawText('', true); } else if (flags.includes('set')) { params.bgfile && (params.bgFile = params.bgfile); params.textrect && (params.textRect = params.textrect); params.xinterval != null && (params.xInterval = params.xinterval); params.yinterval != null && (params.yInterval = params.yinterval); this.setState({ props: Object.assign({}, this.state.props, params), }); } else if (flags.includes('reset')) { this.setState({ props: this.props, }); } else if (flags.includes('show')) { layer.setVisible(true); } else if (flags.includes('hide')) { this.reshowWhenScriptTrigger = flags.includes('soft'); layer.setVisible(false); } else if (flags.includes('continue')) { waitClick = true; promise = layer.drawText(params.text, false); clickCallback = true; } else { waitClick = false; promise = layer.drawText(params.text, false); clickCallback = true; } this.state.clickCallback = clickCallback; this.state.switchPageAfterClick = switchPageAfterClick; ctx.break = waitClick; await ((flags.includes('nowait') || flags.includes('_skip_')) ? Promise.resolve() : promise); if (flags.includes('_skip_')) { await this.layer.completeText(); } this.state.clickCallback = false; await next(); } async handleScriptTrigger(ctx, next) { const layer = this.layer; if (!layer.visible && this.reshowWhenScriptTrigger) { layer.setVisible(true); return; } if (this.state.switchPageAfterClick) { await this.layer.drawText('', true); this.state.switchPageAfterClick = false; } if (this.state.clickCallback) { this.layer.completeText(); this.state.clickCallback = false; } else { await next(); } } async handleScriptExec(ctx, next) { if (['text', 'r', 'l', 'p', '*'].includes(ctx.command)) { if (typeof ctx.params.raw === 'string') { ctx.params.text = ctx.params.raw; } await this.execute(ctx, next); } else { await next(); } } async handleArchiveSave(ctx, next) { const layer = this.layer; ctx.data.textwindow = { props: { ...this.state.props, children: null }, text: layer.text, children: null, switchPageAfterClick: this.state.switchPageAfterClick }; await next(); } async handleArchiveLoad(ctx, next) { const { props, text, children, switchPageAfterClick } = ctx.data.textwindow; this.setState({ props: { ...this.props, ...props, text, children }, switchPageAfterClick }); const layer = this.layer; layer.setVisible(true); layer.drawText(ctx.data.textwindow.text, true); // layer.completeText(); await next(); } render() { return ( <Transition ref={transLayer => (this.transLayer = transLayer)}> <RawTextwindow {...this.state.props} ref={layer => (this.layer = layer)}> {this.props.children} </RawTextwindow> </Transition> ); } } // module.exports = Textwindow;