Files
bim_engine/src/managers/measure-dialog-manager.ts
yuding 191c571f40 refactor: sync managers and section box actions
Wire section box scale/reverse/reset to clipping APIs and sync demo artifacts.
2026-02-04 18:20:30 +08:00

200 lines
6.3 KiB
TypeScript

import { BaseDialogManager } from '../core/base-dialog-manager';
import { MeasurePanel } from '../components/measure-panel';
import type { MeasureConfig, MeasureResult } from '../components/measure-panel/types';
import { MEASURE_TYPES, getModeBycallBackType, getValueType, type MeasureMode, type CallBackType } from '../types/measure';
interface EngineMeasureData {
id: string;
text: number;
textX?: number;
textY?: number;
textZ?: number;
type: CallBackType;
isSelect: boolean;
container: any;
}
export class MeasureDialogManager extends BaseDialogManager {
private panel: MeasurePanel | null = null;
private config: MeasureConfig | null = null;
private unsubscribeMeasureChanged: (() => void) | null = null;
protected get dialogId(): string {
return 'measure-dialog';
}
protected get dialogTitle(): string {
return 'measure.dialogTitle';
}
protected get dialogWidth(): number {
return 250;
}
protected createContent(): HTMLElement {
this.panel = new MeasurePanel({
defaultMode: 'distance',
defaultExpanded: false,
onModeChange: (mode) => {
console.log('[MeasureDialogManager] 当前测量方式已切换:', mode);
this.registry.engine3d?.activateMeasure(mode);
},
onClearAll: () => {
console.log('[MeasureDialogManager] 删除全部');
this.registry.engine3d?.clearAllMeasures();
},
onSettings: () => {
console.log('[MeasureDialogManager] 打开设置');
},
onExpandedChange: () => {
this.dialog?.fitHeight(false);
},
onConfigSave: (config) => {
console.log('[MeasureDialogManager] 保存设置:', config);
this.registry.engine3d?.saveMeasureSetting({
unit: config.unit,
precision: config.precision
});
}
});
this.panel.init();
this.config = this.panel.getConfig();
if (this.config) {
console.log('[MeasureDialogManager] 同步缓存设置到引擎:', this.config);
this.registry.engine3d?.saveMeasureSetting({
unit: this.config.unit,
precision: this.config.precision
});
}
const panelWrapper = document.createElement('div');
panelWrapper.style.padding = '12px';
panelWrapper.appendChild(this.panel.element);
return panelWrapper;
}
protected onDialogCreated(): void {
this.dialog?.fitHeight(false);
const engine = this.registry.engine3d?.getEngine();
if (engine?.events) {
const handler = (data: EngineMeasureData) => {
console.log('[MeasureDialogManager] 测量值回调:', data);
if (data && this.panel) {
this.handleMeasureChanged(data);
}
};
engine.events.on('measure-changed', handler);
engine.events.on('measure-click', handler);
this.unsubscribeMeasureChanged = () => {
engine.events.off('measure-changed', handler);
engine.events.on('measure-click', handler);
}
}
}
private handleMeasureChanged(data: EngineMeasureData): void {
if (!this.panel) return;
const targetMode = getModeBycallBackType(data.type);
if (!targetMode) {
console.warn('[MeasureDialogManager] 未知测量类型:', data.type);
return;
}
const currentMode = this.panel.getActiveMode();
if (currentMode !== targetMode) {
this.panel.switchMode(targetMode, false);
}
const result = this.convertToMeasureResult(data, targetMode);
this.panel.setResult(result);
}
private convertToMeasureResult(data: EngineMeasureData, mode: MeasureMode): MeasureResult {
const config = MEASURE_TYPES[mode];
const result: MeasureResult = {};
if (getValueType(mode) === 'point') {
if (data.textX !== undefined && data.textY !== undefined && data.textZ !== undefined) {
result.xyz = { x: data.textX, y: data.textY, z: data.textZ };
}
} else {
(result as any)[config.callBackType] = data.text;
}
return result;
}
protected onDialogClose(): void {
if (this.unsubscribeMeasureChanged) {
this.unsubscribeMeasureChanged();
this.unsubscribeMeasureChanged = null;
}
this.registry.toolbar?.setBtnActive('measure', false);
}
protected onBeforeDestroy(): void {
if (this.unsubscribeMeasureChanged) {
this.unsubscribeMeasureChanged();
this.unsubscribeMeasureChanged = null;
}
if (this.registry.engine3d) {
this.registry.engine3d.deactivateMeasure();
}
if (this.panel) {
this.panel.destroy();
this.panel = null;
}
}
public getActiveMode(): MeasureMode | null {
return this.panel ? this.panel.getActiveMode() : null;
}
public switchMode(mode: MeasureMode): void {
if (!this.panel) return;
this.panel.switchMode(mode);
}
public setMeasureResult(result: MeasureResult | null): void {
if (!this.panel) return;
this.panel.setResult(result);
}
public getConfig(): MeasureConfig | null {
if (this.panel) {
this.config = this.panel.getConfig();
}
return this.config ? { ...this.config } : null;
}
public setConfig(partial: Partial<MeasureConfig>, persist: boolean = true): void {
if (this.panel) {
this.panel.setConfig(partial, persist);
this.config = this.panel.getConfig();
this.dialog?.fitHeight(false);
return;
}
const prev = this.config;
const next: MeasureConfig = {
unit: partial.unit ?? prev?.unit ?? 'mm',
precision: partial.precision ?? prev?.precision ?? 2
};
this.config = next;
}
public clearAll(): void {
if (!this.panel) return;
this.panel.clearAll();
}
public openSettings(): void {
if (!this.panel) return;
this.panel.openSettings();
}
}