feat(all): 迁移扩展相关功能
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import * as THREE from "three";
|
||||
import { InlineBlock } from "@/core/libs/three-mesh-ui/src/three-mesh-ui.js";
|
||||
import App from "@/core/app/App";
|
||||
import { findUIPanelRoot } from "@/utils/scene/uipanel";
|
||||
import {
|
||||
UIPanelElementController,
|
||||
UIPanelElementInit,
|
||||
UIPanelNode,
|
||||
extractUIPanelProps,
|
||||
normalizeUIPanelElementOptions,
|
||||
} from "./UIPanelElementBase";
|
||||
|
||||
const InlineBlockBase = InlineBlock as unknown as new (options?: Record<string, any>) => THREE.Object3D;
|
||||
|
||||
export default class UIPanelInlineBlock extends InlineBlockBase {
|
||||
type = "UIPanelInlineBlock";
|
||||
isUIPanelElement = true;
|
||||
options: UIPanelNode;
|
||||
declare set: (options: Record<string, any>) => void;
|
||||
private controller: UIPanelElementController;
|
||||
private handleAdded = () => {
|
||||
const parent = this.parent as any;
|
||||
if (!parent || !this.isValidParent(parent)) {
|
||||
parent?.remove?.(this);
|
||||
return;
|
||||
}
|
||||
const panel = findUIPanelRoot(this) as any;
|
||||
if (!panel) return;
|
||||
this.controller.updateRootId(panel.uuid);
|
||||
panel.registerElement?.(this);
|
||||
panel.requestUpdate?.();
|
||||
};
|
||||
private handleRemoved = () => {
|
||||
const rootId = (this as any).metadata?.__uiPanelRootId;
|
||||
const panel = rootId ? App.getObjectByUuid(rootId) : null;
|
||||
panel?.unregisterElement?.(this);
|
||||
};
|
||||
|
||||
constructor(options: Partial<UIPanelNode> = {}, init: UIPanelElementInit = {}) {
|
||||
const normalized = normalizeUIPanelElementOptions(options, "inlineBlock", "InlineBlock");
|
||||
const { props } = extractUIPanelProps(normalized);
|
||||
super(props);
|
||||
this.options = normalized;
|
||||
this.name = normalized.name || "InlineBlock";
|
||||
this.controller = new UIPanelElementController(this, this.options, this.type, init);
|
||||
|
||||
this.addEventListener("added", this.handleAdded);
|
||||
this.addEventListener("removed", this.handleRemoved);
|
||||
}
|
||||
|
||||
updateRootId(rootId: string) {
|
||||
this.controller.updateRootId(rootId);
|
||||
}
|
||||
|
||||
updateOptions(options: Partial<UIPanelNode>) {
|
||||
if (options.name !== undefined) {
|
||||
this.options.name = options.name;
|
||||
this.name = options.name || this.name;
|
||||
}
|
||||
if (options.props) this.setProps(options.props);
|
||||
if (options.states !== undefined) this.setStates(options.states);
|
||||
}
|
||||
|
||||
setProps(patch: Record<string, any>) {
|
||||
this.controller.setProps(patch);
|
||||
}
|
||||
|
||||
setStates(states?: Record<string, Record<string, any>>) {
|
||||
this.controller.setStates(states);
|
||||
const rootId = (this as any).metadata?.__uiPanelRootId;
|
||||
const panel = rootId ? App.getObjectByUuid(rootId) : null;
|
||||
panel?.refreshInteraction?.();
|
||||
}
|
||||
|
||||
applyState(state: string | null) {
|
||||
this.controller.applyState(state);
|
||||
}
|
||||
|
||||
hasInteractiveState() {
|
||||
return this.controller.hasInteractiveState();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.controller.dispose();
|
||||
}
|
||||
|
||||
toJSON(meta?: THREE.JSONMeta) {
|
||||
const snapshot = this.controller.detachInternalMeshes();
|
||||
const data = super.toJSON(meta) as any;
|
||||
this.controller.restoreInternalMeshes(snapshot);
|
||||
|
||||
data.object.type = this.type;
|
||||
const options = JSON.parse(JSON.stringify(this.options)) as UIPanelNode;
|
||||
options.name = this.name;
|
||||
data.object.options = options;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static fromJSON(json: { options: UIPanelNode }, init: UIPanelElementInit = {}) {
|
||||
return new UIPanelInlineBlock(json.options, init);
|
||||
}
|
||||
|
||||
private isValidParent(parent: any) {
|
||||
return parent?.type === "UIPanel" || parent?.type === "UIPanelBlock";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user