import { createApp } from 'vue'; import { SceneObjectTypeGetting } from '@/scripts/SceneObjectTypeGetting'; import { CustomDiv, ESSceneObject, FunctionProperty, GroupProperty, StringProperty, Viewer } from "xbsj-xe2/dist-node/xe2-base-objects"; import { Destroyable, PartialWithUndefinedReactivePropsToNativeProps, ReactivePropsToNativePropsAndChanged, bind, extendClassProps, react, track } from "xbsj-xe2/dist-node/xe2-base-utils"; import { createProcessingFromAsyncFunc } from 'xbsj-xe2/dist-node/xe2-utils'; import SceneObjectsCreator from "../common/SceneObjectsCreator.vue"; function createDivClass(sceneObject: SceneObjectsCreatorUI) { return class MyDiv extends Destroyable { // subContainer是外部视口的div容器,可以在这里创建自己需要的DOM元素 // customDiv指向当前的CustomDiv场景对象 // viewer指定当前的视口 private _sceneTreeApp: any get sceneTreeApp() { return this._sceneTreeApp } constructor(subContainer: HTMLDivElement, customDiv: CustomDiv, viewer?: Viewer | undefined) { super(); const div = document.createElement('div'); subContainer.appendChild(div); this.dispose(() => subContainer.removeChild(div)); this._sceneTreeApp = createApp(SceneObjectsCreator, { show: sceneObject.showSceneObjectsCreatorRef, getTypeName: (type: string) => sceneObject.sceneObjectTypeGetting.setTypeName(type), }); console.log("demo", this._sceneTreeApp); this._sceneTreeApp.mount(div); this.dispose(() => this._sceneTreeApp.unmount()); // div.style.width = '200px'; // div.style.height = '400px'; div.style.left = '10px'; div.style.top = '10px'; // div.style.background = 'rgba(120, 120, 0, 0.7)'; // div.style.color = 'white'; // div.style.fontSize = '30px'; // div.style.lineHeight = '50px'; // div.style.border = '1px solid white'; div.style.zIndex = '100'; // 特别重要,不能丢!很可能导致保存后打开看不到! div.style.pointerEvents = 'all'; { // 控制显示隐藏 const update = () => { div.style.display = (customDiv.show ?? true) ? 'block' : 'none'; }; update(); this.dispose(customDiv.showChanged.disposableOn(update)); } { const update = () => { if (!this._sceneTreeApp) return; this._sceneTreeApp._container._vnode.component.props.show = sceneObject.showSceneObjectsCreatorRef; } update(); this.dispose(sceneObject.showSceneObjectsCreatorRefChanged.disposableOn(update)) } } } } export class SceneObjectsCreatorUI extends ESSceneObject { static readonly type = this.register('SceneObjectsCreatorUI', this, { chsName: 'SceneObjectsCreatorUI', tags: ['MiscObjects'], description: "SceneObjectsCreatorUI" }); get typeName() { return 'SceneObjectsCreatorUI'; } override get defaultProps() { return SceneObjectsCreatorUI.createDefaultProps(); } get json() { return this._innerGetJson() as JsonType; } set json(value: JsonType) { this._innerSetJson(value); } private _sceneObjectTypeGetting = this.disposeVar(new SceneObjectTypeGetting()); get sceneObjectTypeGetting() { return this._sceneObjectTypeGetting; } private _customDiv = this.disposeVar(new CustomDiv()); get customDiv() { return this._customDiv; } // get container() { return this._customDiv.container; } // get containerChanged() { return this._customDiv.containerChanged; } // set container(value) { this._customDiv.container = value; } private _showSceneObjectsCreatorRef = this.disposeVar(react(false)) get showSceneObjectsCreatorRef() { return this._showSceneObjectsCreatorRef.value } set showSceneObjectsCreatorRef(value: boolean) { this._showSceneObjectsCreatorRef.value = value } get showSceneObjectsCreatorRefChanged() { return this._showSceneObjectsCreatorRef.changed } private _container = this.disposeVar(react(undefined)); get container() { return this._container.value; } get containerChanged() { return this._container.changed; } set container(value: HTMLElement | undefined) { this._container.value = value; } getTypeName() { return new Promise((resolve, reject) => { this.processing.restart(); this.processing.completeFunc = typeName => resolve(typeName); this.processing.errorFunc = error => reject(error); }); } private _processing = this.disposeVar(createProcessingFromAsyncFunc(async cancelsManager => { const promise = this.sceneObjectTypeGetting.start() const typeName = await cancelsManager.promise(promise); return typeName; })) get processing() { return this._processing; } constructor(id?: string) { super(id); const customDiv = this._customDiv; this.dispose(this.components.disposableAdd(customDiv)); customDiv.instanceClass = createDivClass(this) this.dispose(bind([this, 'showSceneObjectsCreatorRef'], [this.sceneObjectTypeGetting, 'showDialog'])); this.dispose(track([customDiv, 'show'], [this, 'showSceneObjectsCreatorRef'])); { const update = () => { // @ts-ignore customDiv.container = this.container ?? document.body; }; update(); this.dispose(this.containerChanged.disposableOn(update)); } { const update = () => { if (this.containerId === undefined || this.containerId === '') { this.container = undefined; } else { const e = document.getElementById(this.containerId); if (e instanceof HTMLElement) { this.container = e; } else { this.container = undefined; console.warn(`Div from containerId(${this.containerId}) is not HTMLDivElement!`); } } }; update(); this.dispose(this.containerIdChanged.disposableOn(update)); } } static override defaults = { ...ESSceneObject.defaults, containerId: '', } override getProperties(language?: string) { return [ ...super.getProperties(language), new GroupProperty('通用', '通用', [ new StringProperty("containerId", "containerId", true, false, [this, 'containerId'], SceneObjectsCreatorUI.defaults.containerId), new FunctionProperty("getTypeName", "getTypeName", [], () => this.getTypeName(), []), ]), ]; } } export namespace SceneObjectsCreatorUI { export const createDefaultProps = () => ({ ...ESSceneObject.createDefaultProps(), containerId: undefined as string | undefined, }); } extendClassProps(SceneObjectsCreatorUI.prototype, SceneObjectsCreatorUI.createDefaultProps); export interface SceneObjectsCreatorUI extends ReactivePropsToNativePropsAndChanged> { } type JsonType = PartialWithUndefinedReactivePropsToNativeProps & { type: string }>;