Files
bim_engine/src/managers/measure-dialog-manager.ts
2025-12-22 18:48:38 +08:00

150 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {BimComponent} from '../core/component';
import {BimEngine} from '../bim-engine';
import {BimDialog} from "../components/dialog";
import { MeasurePanel } from '../components/measure-panel';
import type { MeasureMode, MeasureResult } from '../components/measure-panel/types';
/**
* 测量弹窗管理器
*/
export class MeasureDialogManager extends BimComponent {
private dialogId = 'measure-dialog';
private dialog: BimDialog | null = null;
private panel: MeasurePanel | null = null;
constructor(engine: BimEngine) {
super(engine);
}
public init(): void {
// 可以在这里监听事件
}
/**
* 显示测量弹窗
*/
public show() {
if (!this.engine.dialog || !this.engine.container) {
console.warn('Dialog manager or container is not initialized');
return;
}
const dialogWidth = 250;
const dialogHeight = 300;
const paddingRight = 20; // 你想要的右边距
const container = this.engine.container;
const containerWidth = container.clientWidth;
const containerHeight = container.clientHeight;
const x = containerWidth - dialogWidth - paddingRight;
const y = (containerHeight - dialogHeight) / 2;
// 如果已打开过,先销毁旧实例,避免重复创建/重复订阅
this.destroy();
// 创建测量面板(只做 UI不实现真实测量
this.panel = new MeasurePanel({
defaultMode: 'distance', // 默认展示前四个,且默认选中“距离”
defaultExpanded: false,
onModeChange: (mode) => {
// 这里只做事件/占位:未来可在这里切换引擎内置工具
// 本次需求不实现真实测量,因此仅保留回调位置
console.log('[MeasureDialogManager] 当前测量方式已切换:', mode);
},
onClearAll: () => {
// 预留:未来可清理引擎测量绘制/标注
console.log('[MeasureDialogManager] 删除全部(仅 UI 清空,本次不清理引擎侧内容)');
},
onSettings: () => {
// 预留:未来可打开设置弹窗/面板
console.log('[MeasureDialogManager] 打开设置(仅预留接口)');
},
onExpandedChange: () => {
// 展开/收起时,动态适配 Dialog 高度,避免遮挡底部操作按钮
this.dialog?.fitHeight(false);
}
});
this.panel.init();
// 注意:你要求“组件本身不加边距”,因此在 Manager 这里用 wrapper 增加左右内边距
// 这样 MeasurePanel 可以保持通用性,避免在不同场景复用时产生多余 padding。
const panelWrapper = document.createElement('div');
panelWrapper.style.padding = '12px';
panelWrapper.appendChild(this.panel.element);
this.dialog = this.engine.dialog.create({
id: this.dialogId,
title: 'measure.dialogTitle',
content: panelWrapper,
width: dialogWidth,
// 高度交给 fitHeight 动态计算(避免内容展开后遮挡底部操作区)
height: 'auto',
position: {
x: x,
y: y
},
onClose: () => {
this.engine.toolbar?.setBtnActive('measure', false)
}
});
this.dialog.init();
// 初次打开时也执行一次自适应高度(收起态)
this.dialog.fitHeight(false);
}
/**
* 获取当前测量方式
* 说明:如果面板未创建,则返回 null
*/
public getActiveMode(): MeasureMode | null {
return this.panel ? this.panel.getActiveMode() : null;
}
/**
* 切换测量方式(你要求的“切换类型的方法”)
* @param mode 测量方式
*/
public switchMode(mode: MeasureMode): void {
if (!this.panel) return;
this.panel.switchMode(mode);
}
/**
* 设置测量结果(由外部注入,仅用于显示)
* @param result 测量结果;传 null 表示清空
*/
public setResult(result: MeasureResult | null): void {
if (!this.panel) return;
this.panel.setResult(result);
}
/**
* 删除全部(仅清空 UI真实测量清理逻辑后续再接
*/
public clearAll(): void {
if (!this.panel) return;
this.panel.clearAll();
}
/**
* 打开设置(仅预留方法/回调)
*/
public openSettings(): void {
if (!this.panel) return;
this.panel.openSettings();
}
public destroy(): void {
// 关闭弹窗
if (this.dialog) {
this.dialog.destroy();
this.dialog = null;
}
// 销毁测量面板(清理订阅与 DOM
if (this.panel) {
this.panel.destroy();
this.panel = null;
}
}
}