refactor(measure): centralize measure type config and migrate API
- Add unified MEASURE_TYPES config in types/measure.ts - Export MEASURE_MODES_ORDERED, ENGINE_TYPE_TO_MODE, MODE_TO_ENGINE_TYPE - Refactor measure-dialog-manager to use centralized config - Refactor measure-panel to use MEASURE_TYPES for icons/order/valueType - Simplify engine/index.ts measureMap with dynamic key access - Add measure settings API (saveMeasureSetting) with cache sync - Add direct engine event listening for measure-changed and section-move - Update i18n keys for 8 measure modes
This commit is contained in:
@@ -6,6 +6,7 @@ import { Engine, type EngineOptions, type ModelLoadOptions } from '../components
|
||||
import { BaseManager } from '../core/base-manager';
|
||||
import { RightKeyManager } from './right-key-manager';
|
||||
import type { MeasureMode } from '../types/measure';
|
||||
import type { MeasureUnit, MeasurePrecision } from '../components/measure-panel/types';
|
||||
import type { SectionBoxRange } from '../components/section-box-panel/types';
|
||||
import type { MenuItemConfig } from '../components/menu/item';
|
||||
import { ManagerRegistry } from '../core/manager-registry';
|
||||
@@ -246,7 +247,6 @@ export class EngineManager extends BaseManager {
|
||||
return this.engineInstance.getCurrentMeasureType();
|
||||
}
|
||||
|
||||
/** 清除所有测量标注 */
|
||||
public clearAllMeasures(): void {
|
||||
if (!this.engineInstance) {
|
||||
return;
|
||||
@@ -254,11 +254,13 @@ export class EngineManager extends BaseManager {
|
||||
this.engineInstance.clearAllMeasures();
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活剖切功能(统一入口)
|
||||
* @param mode 剖切模式: 'x' | 'y' | 'z' (轴向剖切) | 'box' (剖切盒) | 'face' (拾取面剖切)
|
||||
* @remarks 代理调用 Engine.activeSection(mode)
|
||||
*/
|
||||
public saveMeasureSetting(setting: { unit: MeasureUnit; precision: MeasurePrecision }): void {
|
||||
if (!this.engineInstance) {
|
||||
return;
|
||||
}
|
||||
this.engineInstance.saveMeasureSetting(setting);
|
||||
}
|
||||
|
||||
public activeSection(mode: 'x' | 'y' | 'z' | 'box' | 'face'): void {
|
||||
if (!this.engineInstance) {
|
||||
console.warn('[EngineManager] 3D Engine not initialized.');
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
/**
|
||||
* 测量对话框管理器
|
||||
* 负责管理测量工具对话框的显示、隐藏和测量面板的交互
|
||||
*/
|
||||
import { BaseDialogManager } from '../core/base-dialog-manager';
|
||||
import { MeasurePanel } from '../components/measure-panel';
|
||||
import type { MeasureConfig, MeasureMode, MeasureResult } from '../components/measure-panel/types';
|
||||
import type { MeasureConfig, MeasureResult } from '../components/measure-panel/types';
|
||||
import { ENGINE_TYPE_TO_MODE, MEASURE_TYPES, type MeasureMode } from '../types/measure';
|
||||
|
||||
interface EngineMeasureData {
|
||||
id: string;
|
||||
point1?: { x: number; y: number; z: number };
|
||||
point2?: { x: number; y: number; z: number };
|
||||
text: number;
|
||||
type: string;
|
||||
isSelect: boolean;
|
||||
container: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量对话框管理器
|
||||
* 继承自 BaseDialogManager,提供测量工具的对话框管理功能
|
||||
*/
|
||||
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';
|
||||
}
|
||||
|
||||
/** 对话框标题(国际化 key) */
|
||||
protected get dialogTitle(): string {
|
||||
return 'measure.dialogTitle';
|
||||
}
|
||||
|
||||
/** 对话框宽度 */
|
||||
protected get dialogWidth(): number {
|
||||
return 250;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建对话框内容
|
||||
* 初始化测量面板并设置回调
|
||||
*/
|
||||
protected createContent(): HTMLElement {
|
||||
this.panel = new MeasurePanel({
|
||||
defaultMode: 'distance',
|
||||
@@ -52,10 +47,25 @@ export class MeasureDialogManager extends BaseDialogManager {
|
||||
},
|
||||
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';
|
||||
@@ -64,18 +74,66 @@ export class MeasureDialogManager extends BaseDialogManager {
|
||||
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);
|
||||
this.unsubscribeMeasureChanged = () => engine.events.off('measure-changed', handler);
|
||||
}
|
||||
}
|
||||
|
||||
private handleMeasureChanged(data: EngineMeasureData): void {
|
||||
if (!this.panel) return;
|
||||
|
||||
const targetMode = ENGINE_TYPE_TO_MODE[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 (config.valueType === 'point' && data.point1) {
|
||||
result.xyz = { x: data.point1.x, y: data.point1.y, z: data.point1.z };
|
||||
} else {
|
||||
(result as any)[config.resultField] = 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();
|
||||
}
|
||||
@@ -85,36 +143,20 @@ export class MeasureDialogManager extends BaseDialogManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前激活的测量模式
|
||||
* @returns 当前测量模式,如 'distance'、'angle' 等
|
||||
*/
|
||||
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 测量结果对象
|
||||
*/
|
||||
public setMeasureResult(result: MeasureResult | null): void {
|
||||
if (!this.panel) return;
|
||||
this.panel.setResult(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取测量配置
|
||||
* @returns 测量配置副本
|
||||
*/
|
||||
public getConfig(): MeasureConfig | null {
|
||||
if (this.panel) {
|
||||
this.config = this.panel.getConfig();
|
||||
@@ -122,11 +164,6 @@ export class MeasureDialogManager extends BaseDialogManager {
|
||||
return this.config ? { ...this.config } : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置测量配置
|
||||
* @param partial 部分配置
|
||||
* @param persist 是否持久化
|
||||
*/
|
||||
public setConfig(partial: Partial<MeasureConfig>, persist: boolean = true): void {
|
||||
if (this.panel) {
|
||||
this.panel.setConfig(partial, persist);
|
||||
@@ -143,13 +180,11 @@ export class MeasureDialogManager extends BaseDialogManager {
|
||||
this.config = next;
|
||||
}
|
||||
|
||||
/** 清除所有测量结果 */
|
||||
public clearAll(): void {
|
||||
if (!this.panel) return;
|
||||
this.panel.clearAll();
|
||||
}
|
||||
|
||||
/** 打开测量设置面板 */
|
||||
public openSettings(): void {
|
||||
if (!this.panel) return;
|
||||
this.panel.openSettings();
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
/**
|
||||
* 剖切盒对话框管理器
|
||||
* 负责管理剖切盒工具对话框的显示、隐藏和剖切盒面板的交互
|
||||
*/
|
||||
import { BaseDialogManager } from '../core/base-dialog-manager';
|
||||
import { SectionBoxPanel } from '../components/section-box-panel';
|
||||
import type { SectionBoxRange } from '../components/section-box-panel/types';
|
||||
|
||||
/**
|
||||
* 剖切盒对话框管理器
|
||||
* 继承自 BaseDialogManager,提供六面体剖切盒的对话框管理功能
|
||||
*/
|
||||
export class SectionBoxDialogManager extends BaseDialogManager {
|
||||
/** 剖切盒面板实例 */
|
||||
private panel: SectionBoxPanel | null = null;
|
||||
private unsubscribeSectionMove: (() => void) | null = null;
|
||||
|
||||
/** 对话框唯一标识 */
|
||||
protected get dialogId(): string {
|
||||
@@ -82,19 +74,35 @@ export class SectionBoxDialogManager extends BaseDialogManager {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user