Files
bim_engine/src/managers/section-box-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

168 lines
5.4 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 { BaseDialogManager } from '../core/base-dialog-manager';
import { SectionBoxPanel } from '../components/section-box-panel';
import type { SectionBoxRange } from '../components/section-box-panel/types';
export class SectionBoxDialogManager extends BaseDialogManager {
private panel: SectionBoxPanel | null = null;
private unsubscribeSectionMove: (() => void) | null = null;
/** 对话框唯一标识 */
protected get dialogId(): string {
return 'section-box-dialog';
}
/** 对话框标题(国际化 key */
protected get dialogTitle(): string {
return 'sectionBox.dialogTitle';
}
/** 对话框宽度 */
protected get dialogWidth(): number {
return 280;
}
/**
* 获取对话框位置
* 定位在容器右下角
*/
protected getDialogPosition(): { x: number; y: number } {
const container = this.registry.container;
if (!container) return { x: 100, y: 100 };
const containerWidth = container.clientWidth;
const containerHeight = container.clientHeight;
const paddingRight = 20;
const paddingBottom = 50;
return {
x: containerWidth - this.dialogWidth - paddingRight,
y: containerHeight - paddingBottom - 300
};
}
/**
* 创建对话框内容
* 初始化剖切盒面板并设置回调
*/
protected createContent(): HTMLElement {
this.panel = new SectionBoxPanel({
defaultHidden: false,
defaultReversed: false,
onHideToggle: (isHidden) => {
console.log('[SectionBoxDialogManager] 隐藏切换:', isHidden);
if (isHidden) {
this.registry.engine3d?.hideSection();
} else {
this.registry.engine3d?.recoverSection();
}
},
onReverseToggle: (isReversed) => {
console.log('[SectionBoxDialogManager] 反向切换:', isReversed);
// 底层 reverse() 为“切换一次”,这里不使用 isReversed 作为入参,只要用户点击就触发。
this.registry.engine3d?.reverseSection();
},
onFitToModel: () => {
// 对接底层 scaleBox():缩放剖切盒到场景整体包围盒
this.registry.engine3d?.scaleSectionBox();
},
onReset: () => {
// 重置定义:关闭剖切再打开剖切盒。
// UI 侧会自行将滑块强制恢复到 0-100并将隐藏/反向按钮恢复为关闭状态。
this.registry.engine3d?.deactivateSection();
this.registry.engine3d?.activeSection('box');
// 确保剖切可见(避免上一次处于隐藏状态导致“看起来没重置”)
this.registry.engine3d?.recoverSection();
},
onRangeChange: (range) => {
this.registry.engine3d?.setSectionBoxRange(range);
}
});
this.panel.init();
return this.panel.element;
}
protected onDialogCreated(): void {
this.registry.engine3d?.activeSection('box');
this.dialog?.fitHeight(false);
const engine = this.registry.engine3d?.getEngine();
if (engine?.events) {
const handler = (data: any) => {
if (data && this.panel) {
this.panel.setRange(data as Partial<SectionBoxRange>);
}
};
engine.events.on('section-move', handler);
this.unsubscribeSectionMove = () => engine.events.off('section-move', handler);
}
}
protected onDialogClose(): void {
if (this.unsubscribeSectionMove) {
this.unsubscribeSectionMove();
this.unsubscribeSectionMove = null;
}
this.registry.toolbar?.setBtnActive('section-box', false);
}
protected onBeforeDestroy(): void {
if (this.unsubscribeSectionMove) {
this.unsubscribeSectionMove();
this.unsubscribeSectionMove = null;
}
this.registry.engine3d?.deactivateSection();
if (this.panel) {
this.panel.destroy();
this.panel = null;
}
}
/**
* 获取剖切盒隐藏状态
* @returns 是否隐藏
*/
public getHiddenState(): boolean {
return this.panel?.getHiddenState() ?? false;
}
/**
* 设置剖切盒隐藏状态
* @param isHidden 是否隐藏
*/
public setHiddenState(isHidden: boolean): void {
this.panel?.setHiddenState(isHidden);
}
/**
* 获取剖切盒反向状态
* @returns 是否反向(显示盒内/盒外)
*/
public getReversedState(): boolean {
return this.panel?.getReversedState() ?? false;
}
/**
* 设置剖切盒反向状态
* @param isReversed 是否反向
*/
public setReversedState(isReversed: boolean): void {
this.panel?.setReversedState(isReversed);
}
/**
* 获取剖切盒范围
* @returns 六面体范围 { minX, maxX, minY, maxY, minZ, maxZ }
*/
public getRange(): SectionBoxRange | null {
return this.panel?.getRange() ?? null;
}
/**
* 设置剖切盒范围
* @param range 部分或全部范围值
*/
public setRange(range: Partial<SectionBoxRange>): void {
this.panel?.setRange(range);
}
}