import { EditorProperties, Infer, fillDefaultValue, getDefaultValue } from "@iplusplus/y-model" import { AnchorProp, Control, ControlData, ControlFactory, ControlMeta, ControlTypeInfo, defaultAnchor, DesignerApi, GroupControlAttchInfo, PageApi, Size, } from "./types" import * as createjs from "createjs-module" type TypedControlConstructor

= { new (propDefine: P, controlTypeInfo: ControlTypeInfo, data?: ControlData): TypedControl

typeName: string title: string } export function createControlFactory

( propDefine: P, ctor: TypedControlConstructor

, ): ControlFactory { const ti = { typeName: ctor.typeName, title: ctor.title } return { create(controlData?: ControlData) { const control = new ctor(propDefine, ti, controlData) // control.initControl(); return control }, ...ti, } } export abstract class TypedControl

implements Control { p: Infer

size: Size api?: DesignerApi | PageApi metaInfo?: ControlMeta container: createjs.Container = new createjs.Container() destroyCallback: (() => void)[] = [] anchored: AnchorProp destroyed = false isLocked: boolean = false customName?: string abstract getDefaultSize(): Size /** * */ constructor( protected props: P, public controlTypeInfo: ControlTypeInfo, protected controlData?: ControlData, ) { this.p = getDefaultValue(props) this.size = this.getDefaultSize() this.updateDefaultProps() this.anchored = controlData?.anchored || defaultAnchor if (controlData) this.loadControlData(controlData) // this.initControl(); } getProperty(propertyName: string) { return (this.p as Record)[propertyName] } groupControlAttchInfo?: GroupControlAttchInfo | undefined initControl(api: DesignerApi | PageApi): void { if (this.api === undefined) { this.api = api this.assembleComponents() } } assembleComponents(): void {} updateDefaultProps(): void {} isInPage(api?: DesignerApi | PageApi): api is PageApi { return api !== undefined && api.apiName === "PageApi" } startRun(): void { // if(!this.isInPage(this.api) ) return; } getDefaultMeta(): ControlMeta { const originTitle = this.controlTypeInfo.title const controlType = this.controlTypeInfo.typeName let propIndex = 1 const properties = this.props.map(p => ({ originName: p.name, sortIndex: propIndex++, propertyType: p.editorType, originTitle: p.title, customTitle: "", isExport: 0, customName: "", })) return { originTitle, controlType, properties } } setMeta(metaInfo: ControlMeta) { this.metaInfo = metaInfo } getMeta(): ControlMeta { return this.metaInfo || this.getDefaultMeta() } private loadControlData(controlData: ControlData) { this.size.width = controlData.width this.size.height = controlData.height this.isLocked = controlData.isLocked ? true : false this.p = fillDefaultValue(this.props, controlData.customProperties) // this.setProperty(controlData.customProperties) if (controlData.metaInfo) this.setMeta(controlData.metaInfo) // const customProperties = this.p as Record // this.getPropertiesInfo().forEach(p=>{ // if(Object.hasOwn(c,p.name)){ // customProperties[p.name] = c[p.name] // } // }) } getControlData(): ControlData { return { controlType: this.controlTypeInfo.typeName, width: this.size.width, height: this.size.height, customProperties: { ...this.p }, metaInfo: this.metaInfo, anchored: this.anchored, isLocked: this.isLocked, customName: this.customName, } } abstract reDraw(): void setProperty(newProperties: { [index: string]: unknown }): void { const customProperties = this.p as Record for (const k in newProperties) { if (k in customProperties) { customProperties[k] = newProperties[k] } } } 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 } run(_pageApi: PageApi) {} getDisplayObject(): createjs.Container { return this.container } getProperties(): EditorProperties { return this.props } protected addDestroyCallback(cb: () => void) { this.destroyCallback.push(cb) } protected callDestroyCallback() { this.destroyCallback.forEach(cb => cb()) } destroy(): void { this.destroyed = true this.callDestroyCallback() } }