import { BimComponent } from '../core/component'; import { BimEngine } from '../bim-engine'; import { BimDialog } from "../components/dialog"; import { MeasurePanel } from '../components/measure-panel'; import type { MeasureConfig, 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; /** * 测量配置项(单位/精度) * 说明:MeasurePanel 会自行从缓存加载默认配置,Manager 这里只做“对外读取/设置”的镜像。 */ private config: MeasureConfig | 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); this.engine.engine?.activateMeasure(mode); }, onClearAll: () => { // 预留:未来可清理引擎测量绘制/标注 console.log('[MeasureDialogManager] 删除全部(仅 UI 清空,本次不清理引擎侧内容)'); }, onSettings: () => { // 预留:未来可打开设置弹窗/面板 console.log('[MeasureDialogManager] 打开设置(仅预留接口)'); }, onExpandedChange: () => { // 展开/收起时,动态适配 Dialog 高度,避免遮挡底部操作按钮 this.dialog?.fitHeight(false); } }); this.panel.init(); // 同步一次当前配置(由组件从缓存/默认加载) this.config = this.panel.getConfig(); // 注意:你要求“组件本身不加边距”,因此在 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.destroy() } }); 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); } /** * 设置测量结果(推荐使用的新方法名) * 说明:内部直接调用 MeasurePanel.setResult() * @param result 测量结果;传 null 表示清空 */ public setMeasureResult(result: MeasureResult | null): void { // 按你的要求:仅当 panel 存在时才调用,不做缓存 if (!this.panel) { return; } this.panel.setResult(result); } /** * 获取测量配置(单位/精度) * - 如果面板存在:返回面板当前配置 * - 否则:返回 Manager 缓存的最后一次配置(可能为 null) */ public getConfig(): MeasureConfig | null { if (this.panel) { this.config = this.panel.getConfig(); } return this.config ? { ...this.config } : null; } /** * 设置测量配置(单位/精度) * @param partial 部分更新 * @param persist 是否写入缓存(默认 true) */ public setConfig(partial: Partial, persist: boolean = true): void { // 面板存在则直接设置面板;否则仅更新 Manager 缓存 if (this.panel) { this.panel.setConfig(partial, persist); this.config = this.panel.getConfig(); // 配置变化可能影响高度(比如设置面板显示/隐藏),安全起见做一次 fit 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; // 注意:缓存写入由 MeasurePanel 负责(你要求默认维护在组件里) // 这里不写 localStorage,避免重复逻辑。 } /** * 删除全部(仅清空 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.engine.engine) { this.engine.engine.deactivateMeasure(); } // 关闭弹窗 if (this.dialog) { this.dialog.destroy(); this.dialog = null; } // 销毁测量面板(清理订阅与 DOM) if (this.panel) { this.panel.destroy(); this.panel = null; } } }