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()
}
}