import * as React from 'react'; import { BaseSprite } from '../../../utils/BaseSprite'; import { Tabs, Menu, Icon, Button, Input, Checkbox, Collapse, Dropdown, Select, message } from 'antd'; import { Paths } from '../../../utils/Paths'; import { TsParser, ClassNode, Props as TsProps } from './TsParser'; import { FileUtils } from '../../../utils/FileUtils'; import { MessageUtils, Message } from '../../message/MessageUtils'; import { PropertyMessage } from '../events/PropertyMessage'; import { Global } from '../../../utils/Global'; import { ProjectMessage } from '../../project/events/ProjectMessage'; import { Project } from '../../project/data/Project'; import { GameUIScene } from '../../project/data/GameUIScene'; import { GameUIObject } from '../../project/data/GameUIObject'; import { GameUIComponent } from '../../project/data/GameUIComponent'; import { PropertyItem, IPropertyChange } from './PropertyItem'; import { PropertyTransform } from './PropertyTransform'; import { PropertyChoosePanel } from './PropertyChoosePanel'; import { ComponentUtils } from '../../../utils/ComponentUtils'; import fs = require('fs'); const ipcRender = require('electron').ipcRenderer; export class PropertyPanel extends React.Component{ private _components: any[]; private _propertyView: HTMLElement; private selectedGameobject: els.GameObject; private selectTarget; private _transformProps: any[]; constructor(props: any, context: any) { super(props, context); this.state = { componentsNums: 0, options: [], defaultKeys: ["base", "transfrom"], componentProps: [], activeKey: [], chooseVisible: false,addPropertyVisible:false, }; this._components = []; this.onRPCReceived(); this.registerMessage(); } private registerMessage(): void { MessageUtils.register(PropertyMessage.SHOW_GAMEOBJECT_PROPERTY, this.onMessage, this); MessageUtils.register(PropertyMessage.UPDATE_COMPONENT_PROPERTY, this.onMessage, this); MessageUtils.register(PropertyMessage.UPDATE_TRANSFORM_PROPERTY, this.onMessage, this); } private onMessage(message: Message) { switch (message.type) { case PropertyMessage.SHOW_GAMEOBJECT_PROPERTY: this.onShowProperty(message.data); break; case PropertyMessage.UPDATE_COMPONENT_PROPERTY: this.onComponentPropertyUpdate(message.data); break; case PropertyMessage.UPDATE_TRANSFORM_PROPERTY: this.onTransformPropertyUpdate(message.data); break; } } onRPCReceived() { ipcRender.on("on-property-menu-callback", (sender, data: [string]) => { let type: string = data[0]; switch (type) { case "reset-component": this.onComponentReset(); break; case "remove-component": this.onComponentRemoved(); break; case "up-component": this.onComponentUp(); break; case "down-component": this.onComponentDown(); break; case "copy-component": this.onComponentCopy(); break; case "parse-component": this.onComponentParse(); break; case "edit-component": this.onComponentEdit(); break; } }); } private onComponentReset() { } private onComponentRemoved() { if (this.selectedGameobject) { let componentName: string = this.selectTarget['attributes'].id.value; let project: Project = Global.currentProject; if (!project || !project.uiScenes) return; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); let uiGameobject: GameUIObject = uiScene ? uiScene.getGameObjectByUID(this.selectedGameobject.UID) : null; if (uiGameobject) uiGameobject.removeComponent(componentName); this.selectedGameobject.removeComponentByName(componentName); this.onShowProperty(this.selectedGameobject); //移除当前组件 console.log('移除组件' + componentName + "成功!"); //通知更新组件并保存 MessageUtils.send(ProjectMessage.UPDATE_COMPONENTS); } } private onComponentUp() { } private onComponentDown() { } private onComponentCopy() { } private onComponentParse() { } private onComponentEdit() { } private onComponentPropertyUpdate(data: any) { let componentName = data.componentName; let props: any = data.props; let project: Project = Global.currentProject; if (!project || !project.uiScenes) return; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); if (!uiScene.children) return; for (let i: number = 0, l: number = uiScene.children.length; i < l; i++) { let gameobject: GameUIObject = uiScene.children[i]; if (!gameobject.components) continue; for (let j: number = 0, jl: number = gameobject.components.length; j < jl; j++) { let uiComponent: GameUIComponent = gameobject.components[j]; if (uiComponent.name === componentName) { for (let propkey in uiComponent.propertys) { //如果没有属性,那么,直接删除 if (props[propkey] === undefined) { delete uiComponent.propertys[propkey]; } } //再将分析出来的属性放到propertys里 // for (let propkey in props) { // uiComponent.propertys[propkey] = props[propkey].value; // } } } } this.onShowProperty(this.selectedGameobject); } private onTransformPropertyUpdate(data: { target: els.GameObject, propertys: any }) { if (!this._transformProps) return; let target = data.target; if (!target) return; let propertys = data.propertys; //更新uiComponent属性 //更新属性 for (let i: number = 0, l: number = this._transformProps.length; i < l; i++) { let tranform: PropertyTransform = this._transformProps[i]; for (let propkey in propertys) { if (tranform.props.name === propkey) { tranform.updateProperty(propkey, propertys[propkey]); if (target.transform) target.transform[propkey] = propertys[propkey]; } } } } /** 这里通过读取配置来读取游戏对象属性*/ private onShowProperty(gameobject: els.GameObject) { this.selectedGameobject = gameobject; if (!gameobject) return; const {componentProps, activeKey} = this.state; const Panel = Collapse.Panel; componentProps.length = 0; activeKey.length = 0; //----------------------最基础属性---------------------// let baseProps: any[] = []; //名称,guid,全局 baseProps.push({ name: 'name', value: gameobject.name }); baseProps.push({ name: 'UID', value: gameobject.UID }); baseProps.push({ name: 'global', value: true }); //----------------------添加变换属性---------------------// let transform = gameobject.transform; if (transform) { for (let transkey in transform) { baseProps.push({ name: transkey, value: transform[transkey] }); } } this._transformProps = []; let compProps: any[] = []; const Option = Select.Option; for (let i: number = 0, l: number = baseProps.length; i < l; i += 1) { let baseobject = baseProps[i]; compProps.push( { if (self) this._transformProps.push(self); } } key={baseobject.name} name={baseobject.name} value={baseobject.value} onChanged={this.onTransformChanged.bind(this)} />); } let tables = {compProps}
; let panel =

{'基本属性'}

}> {tables}
; componentProps.push(panel); activeKey.push('baseprops'); //----------------------添加组件---------------------// let project: Project = Global.currentProject; if (!project || !project.uiScenes) return; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); let uiGameobject: GameUIObject = uiScene.getGameObjectByUID(gameobject.UID); let uiComponents: GameUIComponent[] = uiGameobject ? uiGameobject.components : null; if (uiComponents) { for (let m: number = 0, ml: number = uiComponents.length; m < ml; m++) { let uiComponent: GameUIComponent = uiComponents[m]; let compName: string = uiComponent.name; let propertys: any = uiComponent.propertys; let compProps: any[] = []; //渲染自定义渲染属性 for (let propkey in propertys) { let value = propertys[propkey]; let componentProperty: els.PropertyRender = Global.els.ComponentPropertyMaps.getPropertyRender(compName, propkey); let dom: HTMLElement; if (componentProperty) { dom = componentProperty.renderDOM; let htmlText: string = componentProperty.baseHTML; htmlText = htmlText.replace(/\$\{0\}/, value); dom.innerHTML = htmlText; componentProperty.renderDOM.onchange = (event) => { this.onValueChanged({ componentName:compName, oldProp: { name: componentProperty.propertyName, value: event.target['value'] }, currentProp: { name: componentProperty.propertyName, value: event.target['value'] } }); }; } let trs = ; compProps.push(trs); } let tables = {compProps}
; let panel =

{compName + '(脚本)'}

}> {tables}
; componentProps.push(panel); activeKey.push(compName); } } this.setState({ componentProps }); } onValueChanged(data: IPropertyChange) { let propName: string = data.currentProp.name; let propValue = data.currentProp.value; let componentName: string = data.componentName; //更新uiComponent属性 let project: Project = Global.currentProject; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); let uiGameobject: GameUIObject = uiScene ? uiScene.getGameObjectByUID(this.selectedGameobject.UID) : null; let uiComponents: GameUIComponent[] = (uiGameobject) ? uiGameobject.getComponents(componentName) : null; let uiComponent: GameUIComponent = uiComponents ? uiComponents[0] : null; if (uiComponent) { uiComponent.propertys[propName] = propValue; //更新场景属性 let gameobject: els.GameObject = Global.currentProject.currentScene.getChildByName(this.selectedGameobject.name); if (gameobject) { let components: els.Component[] = gameobject.getComponentsByName(componentName); let component: els.Component = components ? components[0] : null; if (component) { component.onPropertyChanged({ name: data.oldProp.name, value: data.oldProp.value }, { name: data.currentProp.name, value: data.currentProp.value }); } } } } onTransformChanged(data: { name: string, value: any }) { this.selectedGameobject[data.name] = data.value; } handleChange(e) { } onShowScript(event) { console.log('打开默认编辑器的脚本:', event.currentTarget.innerText); } private handleClick(): void { } //当组件添加时 onComponentAdd(data: { item, key: string, selectedKeys }) { switch (data.key) { case "createNewScript": this.onNewScriptComponentAdd(); break; default: if (data.key.slice(0, 4) === "els.") this.onUIScriptComponentAdd(data.key); break; } } private onNewScriptComponentAdd() { //创建新的组件面板,这里直接创建 const {componentProps, activeKey} = this.state; const Panel = Collapse.Panel; const compProps: any[] = []; let newScriptName: string = GameUIComponent.getNewScriptName(); GameUIComponent.addScript(newScriptName); let _propdatas: string[] = []; //let _propdatas: string[] = ['hp', 'mp', 'width', 'height']; for (let i: number = 0, l: number = _propdatas.length; i < l; i++) { let trs =
{_propdatas[i]}
this.handleChange(e)} /> ; compProps.push(trs); } let tables = {compProps}
; let panel =

{newScriptName + '(脚本)'}

} key={newScriptName}> {tables}
; activeKey.push(newScriptName); componentProps.push(panel); if (this._propertyView) { this._propertyView.scrollTop = this._propertyView.scrollHeight; } //创建组件文件 if (this.selectedGameobject) { let compFileData: string = `class ${newScriptName} extends els.Component { constructor() { super(); } onAwake(){ } update(){ } }` let tsUrl: string = Paths.getComponentUrlByName(newScriptName); fs.writeFile(tsUrl, compFileData, (err) => { if (err) throw err; console.log('创建文件成功,地址:', tsUrl); //创建组件 let compinst: els.Component = new els.Component(); compinst.name = newScriptName; this.selectedGameobject.addComponent(compinst); //给uiGameobject添加组件 let project: Project = Global.currentProject; if (!project || !project.uiScenes) return; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); let uiGameobject: GameUIObject = uiScene ? uiScene.getGameObjectByUID(this.selectedGameobject.UID) : null; let uiComponents: GameUIComponent[] = uiGameobject ? uiGameobject.components : null; let uiComponent: GameUIComponent = new GameUIComponent(); uiComponent.name = newScriptName; uiComponent.propertys = {}; uiComponents.push(uiComponent); //更新场景文件 MessageUtils.send(ProjectMessage.INSERT_COMPONENT, compinst); }); } this.setState({ componentProps, activeKey }); } //此种情况不创建ts代码,因为为内置组件库 private onUIScriptComponentAdd(className: string): void { const {componentProps, activeKey} = this.state; const Panel = Collapse.Panel; let project: Project = Global.currentProject; if (!project || !project.uiScenes) return; let uiScene: GameUIScene = project.getGameUIScene(project.currentSceneName); let uiGameobject: GameUIObject = uiScene.getGameObjectByUID(this.selectedGameobject.UID); let uiComponents: GameUIComponent[] = uiGameobject ? uiGameobject.components : null; let _uiComponnet: GameUIComponent = new GameUIComponent(); _uiComponnet.name = className; ComponentUtils.bindPropertys(_uiComponnet); if (uiGameobject) { uiGameobject.addComponent(_uiComponnet); } if (uiComponents) { for (let m: number = 0, ml: number = uiComponents.length; m < ml; m++) { let uiComponent: GameUIComponent = uiComponents[m]; let compName: string = uiComponent.name; let propertys: any = uiComponent.propertys; let compProps: any[] = []; for (let propkey in propertys) { let componentProperty: els.PropertyRender = Global.els.ComponentPropertyMaps.getPropertyRender(compName, propkey); let trs = ; compProps.push(trs); } let tables = {compProps}
; let panel =

{compName + '(脚本)'}

}> {tables}
; componentProps.push(panel); activeKey.push(compName); } //更新场景组件对象 let compClass = egret.getDefinitionByName(className); if (compClass) { let compinst: els.Component = new compClass(); compinst.name = className; compinst.gameobject = this.selectedGameobject; this.selectedGameobject.addComponent(compinst); MessageUtils.send(ProjectMessage.INSERT_COMPONENT, compinst); } } this.setState({ componentProps }); } private isSettingsClick: boolean = false; private showChoosePanel(): void { this.setState({ chooseVisible: !this.state.chooseVisible }); } onSettings(event) { this.isSettingsClick = true; } onCollapseChangled(data) { if (!this.isSettingsClick) this.setState({ activeKey: data }); this.isSettingsClick = false; } showMenu(event: MouseEvent) { this.selectTarget = event.target; if (this.selectTarget['attributes'].name && this.selectTarget['attributes'].name.value === 'panelBar') { ipcRender.send('on-property-menu'); } } render() { const {componentsNums} = this.state; const TabPane = Tabs.TabPane; const SubMenu = Menu.SubMenu; const options: any[] = []; const displayState: string = this.selectedGameobject ? "block" : "none"; return (
{ this._propertyView = self } } style={{ height: this.props.height, overflowY: 'auto', overflowX: 'hidden', position: "absolute", right: 0, top: 76, width: this.props.width, background: '#252526' }}>
{this.state.componentProps}
) } }