import * as createjs from "createjs-module" import { AnchorProp, Control, ControlData, ControlFactory, ControlMeta, ControlTypeInfo, DesignerApi, GroupControlAttchInfo, PageApi, Size, defaultAnchor, } from "../types" import { EditorProperties, EditorProperty } from "@iplusplus/y-model" export type GroupControlData = ControlData & { subControls: ControlData[] customName?: string } const typeName = "Group" const title = "组合控件" type SortedEditorProperty = EditorProperty & { sortIndex: number } export class GroupControl implements Control { size: Size = { width: 100, height: 100 } isLocked: boolean = false originConfig: GroupControlData container: createjs.Container = new createjs.Container() innerContainer: createjs.Container = new createjs.Container() controlTypeInfo: ControlTypeInfo = { typeName, title, } metaInfo?: ControlMeta anchored: AnchorProp // p:Record propertyMapping: Record = {} properties: SortedEditorProperty[] = [] controlList: Control[] = [] api?: DesignerApi | PageApi customName?: string constructor(private controlData: GroupControlData) { this.originConfig = controlData this.isLocked = controlData.isLocked ? true : false this.size.width = controlData.width this.size.height = controlData.height this.customName = controlData.customName this.anchored = controlData.anchored || defaultAnchor if (controlData.metaInfo) this.setMeta(controlData.metaInfo) // this.p = controlData.customProperties; // this.initSubControls(); } groupControlAttchInfo?: GroupControlAttchInfo | undefined setMeta(metaInfo: ControlMeta): void { this.metaInfo = metaInfo } getDefaultMeta(): ControlMeta { const originTitle = this.controlTypeInfo.title const controlType = this.controlTypeInfo.typeName let propIndex = 1 const properties = this.properties.map(p => ({ originName: p.name, sortIndex: propIndex++, propertyType: p.editorType, originTitle: p.title, customTitle: "", isExport: 0, customName: "", })) return { originTitle, controlType, properties } } getMeta(): ControlMeta { return this.metaInfo || this.getDefaultMeta() } initSubControls() { const api = this.api! this.originConfig.subControls.forEach(c => { const control: Control = api.createControl(c) const displayObject = control.getDisplayObject() displayObject.x = c.x === undefined ? 0 : c.x displayObject.y = c.y === undefined ? 0 : c.y control.size.width = c.width control.size.height = c.height control.groupControlAttchInfo = { originX: displayObject.x, originY: displayObject.y, originWidth: c.width, originHeight: c.height, } this.controlList.push(control) control.initControl(api) this.innerContainer.addChild(control.getDisplayObject()) }) // this.controlList.forEach(c=>{ // }) } getValueType(c: Control, propertyName: string) { const prop = c.getProperties().find(p => p.name === propertyName) return prop ? prop.valueType : undefined } initSubMeta() { this.controlList.forEach(control => { const controlData = control.getControlData() const metaInfo = controlData.metaInfo if (!metaInfo) return metaInfo.properties.forEach(p => { if (!p.isExport) return const exportName = p.customName || p.originName const valueType = this.getValueType(control, p.originName) if (valueType === undefined) return if (this.propertyMapping[exportName] === undefined) { this.propertyMapping[exportName] = [] this.properties.push({ title: p.customTitle || p.originTitle, name: exportName, editorType: p.propertyType, valueType, sortIndex: p.sortIndex, }) } const items = this.propertyMapping[exportName] items.push([p.originName, control]) // if(valueType && this.propertyMapping[exportName] === undefined){ // this.propertyMapping[exportName] = [p.originName,control] // // this.p[exportName] = controlData.customProperties[p.originName]; // this.properties.push({ // title:p.customTitle || p.originTitle, // name:exportName, // editorType:p.propertyType, // valueType, // sortIndex : p.sortIndex // }) // } }) }) this.properties.sort((p1, p2) => p1.sortIndex - p2.sortIndex) } getProperty(propertyName: string) { const x = this.propertyMapping[propertyName] if (x === undefined) return undefined return x[0][1].getProperty(x[0][0]) } getCustomProperties(): Record { const result: Record = {} this.properties.forEach(p => { result[p.name] = this.getProperty(p.name) }) return result } getControlData(): GroupControlData { const data: GroupControlData = { controlType: this.controlTypeInfo.typeName, width: this.size.width, height: this.size.height, customProperties: this.getCustomProperties(), metaInfo: this.metaInfo, subControls: this.controlList.map(c => { const d = c.getControlData() d.x = c.getDisplayObject().x d.y = c.getDisplayObject().y return d }), customName: this.customName, anchored: this.anchored, isLocked: this.isLocked, } return data } reDraw(): void { const scaleX = this.size.width / this.originConfig.width const scaleY = this.size.height / this.originConfig.height this.controlList.forEach(c => { const displayObject = c.getDisplayObject() const anchored = c.anchored const { originX, originY, originWidth, originHeight } = c.groupControlAttchInfo! if (anchored.left && !anchored.right) { displayObject.x = originX c.size.width = originWidth } else if (!anchored.left && anchored.right) { const right = this.controlData.width - originX - originWidth displayObject.x = this.size.width - right - originWidth c.size.width = originWidth } else if (anchored.left && anchored.right) { const left = originX const right = this.controlData.width - originX - originWidth displayObject.x = left c.size.width = Math.max(5, this.size.width - right - left) } else { displayObject.x = c.groupControlAttchInfo!.originX * scaleX c.size.width = c.groupControlAttchInfo!.originWidth * scaleX } if (anchored.top && !anchored.bottom) { displayObject.y = originY c.size.height = originHeight } else if (!anchored.top && anchored.bottom) { const bottom = this.controlData.height - originY - originHeight displayObject.y = this.size.height - bottom - originHeight c.size.height = originHeight } else if (anchored.top && anchored.bottom) { const top = originY const bottom = this.controlData.height - originY - originHeight displayObject.y = top c.size.height = Math.max(5, this.size.height - bottom - top) } else { displayObject.y = c.groupControlAttchInfo!.originY * scaleY c.size.height = c.groupControlAttchInfo!.originHeight * scaleY } c.reDraw() }) } setProperty(newProperties: { [index: string]: unknown }): void { for (const k in newProperties) { const mapping = this.propertyMapping[k] if (mapping) { mapping.forEach(m => m[1].setProperty({ [m[0]]: newProperties[k] })) } } } initControl(api: DesignerApi | PageApi): void { if (this.api !== undefined) return this.api = api this.initSubControls() this.initSubMeta() this.container.addChild(this.innerContainer) this.reDraw() const pageApi = this.inPage() if (pageApi) { this.controlList.forEach(c => { c.initControl(pageApi) }) } } startRun(): void { const api = this.inPage() if (api) { this.controlList.forEach(c => { c.startRun() }) } // throw new Error("Method not implemented."); } getDisplayObject(): createjs.DisplayObject { return this.container } getProperties(): EditorProperties { return this.properties } destroy(): void { this.controlList.forEach(c => c.destroy()) this.container.removeAllEventListeners() } inPage(): PageApi | undefined { return this.api !== undefined && this.api.apiName === "PageApi" ? this.api : undefined } inDesign(): DesignerApi | undefined { return this.api !== undefined && this.api.apiName === "DesignerApi" ? this.api : undefined } } function checkIsGroupControlData(data: ControlData | undefined): data is GroupControlData { if (data === undefined) return false if ((data as GroupControlData).subControls === undefined) return false return true } export const groupControlFactory: ControlFactory = { create: function (data?: ControlData | undefined): Control { if (checkIsGroupControlData(data)) { return new GroupControl(data) } throw new Error("data is not GroupControlData") }, typeName, title, }