refactor: 重构 Manager 架构,引入 ManagerRegistry 和 BaseManager 基类
- 新增 ManagerRegistry 单例注册表,统一管理所有 Manager 实例 - 新增 BaseManager 基类,自动管理事件订阅清理 - 新增 BaseDialogManager 基类,统一对话框生命周期管理 - 重构 15 个 Manager 使用新基类 - 重构 Toolbar 按钮和 Menu 按钮移除 engine 参数依赖 - 删除 BimComponent 基类(已不再使用) - 为所有 Manager 和核心模块添加中文 JSDoc 注释
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
|
||||
/**
|
||||
* 全屏按钮配置
|
||||
*/
|
||||
export const createFullscreenButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createFullscreenButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'fullscreen',
|
||||
groupId: 'group-2',
|
||||
@@ -16,14 +12,12 @@ export const createFullscreenButton = (_engine: BimEngine): ButtonConfig => {
|
||||
onClick: async () => {
|
||||
console.log('全屏按钮被点击');
|
||||
|
||||
// 0. 环境检查 (帮助调试 Iframe 问题)
|
||||
const isIframe = window.self !== window.top;
|
||||
if (isIframe) {
|
||||
console.warn('检测到在 Iframe 中运行,请确保父级 iframe 标签拥有 allow="fullscreen" 属性');
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. 获取当前全屏状态 (使用 any 绕过 TS 检查)
|
||||
const doc = document as any;
|
||||
const fullscreenElement = doc.fullscreenElement ||
|
||||
doc.webkitFullscreenElement ||
|
||||
@@ -33,43 +27,32 @@ export const createFullscreenButton = (_engine: BimEngine): ButtonConfig => {
|
||||
const isFullscreen = !!fullscreenElement;
|
||||
console.log('当前是否全屏:', isFullscreen);
|
||||
|
||||
// 2. 确定要全屏的目标元素
|
||||
// 优先查找 BIM 容器,如果找不到则使用 document.body
|
||||
const bimContainer = document.querySelector('.bim-engine-container') as HTMLElement;
|
||||
const targetElem = bimContainer || document.body;
|
||||
|
||||
// 将 targetElem 断言为 any,解决 "Property 'webkitRequestFullscreen' does not exist" 报错
|
||||
const el = targetElem as any;
|
||||
|
||||
if (!isFullscreen) {
|
||||
// === 进入全屏 ===
|
||||
console.log('准备进入全屏...');
|
||||
|
||||
// 关键:防止全屏后背景变黑
|
||||
if (targetElem.style.backgroundColor === '' || targetElem.style.backgroundColor === 'transparent') {
|
||||
targetElem.style.backgroundColor = '#ffffff'; // 根据你的主题颜色调整
|
||||
targetElem.style.backgroundColor = '#ffffff';
|
||||
}
|
||||
|
||||
// 兼容不同浏览器的 API
|
||||
const requestMethod = el.requestFullscreen ||
|
||||
el.webkitRequestFullscreen ||
|
||||
el.mozRequestFullScreen ||
|
||||
el.msRequestFullscreen;
|
||||
|
||||
if (requestMethod) {
|
||||
// 使用 call 绑定正确的上下文
|
||||
await requestMethod.call(el, { navigationUI: 'hide' });
|
||||
console.log('全屏请求已发送');
|
||||
} else {
|
||||
console.warn('当前浏览器不支持全屏 API');
|
||||
alert('当前浏览器不支持全屏功能');
|
||||
}
|
||||
|
||||
} else {
|
||||
// === 退出全屏 ===
|
||||
console.log('准备退出全屏...');
|
||||
|
||||
// 兼容不同浏览器的退出 API
|
||||
const exitMethod = doc.exitFullscreen ||
|
||||
doc.webkitExitFullscreen ||
|
||||
doc.mozCancelFullScreen ||
|
||||
@@ -82,11 +65,10 @@ export const createFullscreenButton = (_engine: BimEngine): ButtonConfig => {
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('全屏操作失败:', error);
|
||||
// 专门提示权限问题
|
||||
if (error && error.message && error.message.includes('denied')) {
|
||||
console.error('全屏请求被拒绝。如果是 Iframe,请检查 allow="fullscreen"。如果是自动触发,请确保由用户点击触发。');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 首页按钮配置
|
||||
* 使用工厂函数模式,注入 engine 实例
|
||||
*/
|
||||
export const createHomeButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createHomeButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'home',
|
||||
groupId: 'group-1',
|
||||
@@ -16,7 +12,8 @@ export const createHomeButton = (engine: BimEngine): ButtonConfig => {
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
console.log('首页按钮被点击:', button.id);
|
||||
engine.engine?.CameraGoHome()
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.engine3d?.CameraGoHome();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { infoIcon } from './icon';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 信息按钮配置
|
||||
* 说明:当前仍保留 demo 的事件触发方式;engine 已注入,便于未来替换为 SDK 内部逻辑。
|
||||
*/
|
||||
export const createInfoButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createInfoButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'toolbar-info',
|
||||
id: 'info',
|
||||
groupId: 'group-2',
|
||||
type: 'button',
|
||||
label: 'toolbar.info',
|
||||
icon: infoIcon,
|
||||
icon: getIcon('信息'),
|
||||
keepActive: false,
|
||||
onClick: () => {
|
||||
// WORKAROUND: Dispatch a standard custom event on document
|
||||
document.dispatchEvent(new CustomEvent('bim-demo:open-property-panel'));
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.emit('ui:open-dialog', { id: 'info' });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 地图按钮配置(开关按钮)
|
||||
*/
|
||||
export const createMapButton = (engine: BimEngine): ButtonConfig => {
|
||||
// 监听地图打开/关闭事件,同步按钮状态
|
||||
engine.on('map:opened', () => {
|
||||
engine.toolbar?.setBtnActive('map', true);
|
||||
export const createMapButton = (): ButtonConfig => {
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
|
||||
registry.on('map:opened', () => {
|
||||
registry.toolbar?.setBtnActive('map', true);
|
||||
});
|
||||
|
||||
engine.on('map:closed', () => {
|
||||
engine.toolbar?.setBtnActive('map', false);
|
||||
registry.on('map:closed', () => {
|
||||
registry.toolbar?.setBtnActive('map', false);
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -24,11 +22,10 @@ export const createMapButton = (engine: BimEngine): ButtonConfig => {
|
||||
keepActive: true,
|
||||
icon: getIcon('地图'),
|
||||
onClick: () => {
|
||||
// 切换地图显示状态
|
||||
if (engine.map?.isOpen()) {
|
||||
engine.map?.hide();
|
||||
if (registry.map?.isOpen()) {
|
||||
registry.map?.hide();
|
||||
} else {
|
||||
engine.map?.show();
|
||||
registry.map?.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import type {ButtonConfig} from '../../../index.type';
|
||||
import type {BimEngine} from '../../../../../bim-engine';
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 测量按钮配置
|
||||
* 使用工厂函数模式,注入 engine 实例
|
||||
*/
|
||||
export const createMeasureButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createMeasureButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'measure',
|
||||
groupId: 'group-1',
|
||||
@@ -15,10 +11,11 @@ export const createMeasureButton = (engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('测量'),
|
||||
keepActive: true,
|
||||
onClick: (button) => {
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
if (button.isActive) {
|
||||
engine.measure?.show()
|
||||
registry.measure?.show();
|
||||
} else {
|
||||
engine.measure?.destroy()
|
||||
registry.measure?.destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 构件详情按钮配置
|
||||
*/
|
||||
export const createPropertyButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createPropertyButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'property',
|
||||
groupId: 'group-1',
|
||||
@@ -15,7 +12,8 @@ export const createPropertyButton = (engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('文档'),
|
||||
onClick: () => {
|
||||
console.log('构件详情按钮被点击');
|
||||
engine.propertyPanel?.show();
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.propertyPanel?.show();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 轴向剖切按钮配置
|
||||
*/
|
||||
export const createSectionAxisButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createSectionAxisButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-axis',
|
||||
groupId: 'group-1',
|
||||
@@ -17,10 +14,11 @@ export const createSectionAxisButton = (engine: BimEngine): ButtonConfig => {
|
||||
label: 'toolbar.sectionAxis',
|
||||
icon: getIcon('轴向剖切'),
|
||||
onClick: (button) => {
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
if (button.isActive) {
|
||||
engine.sectionAxis?.show();
|
||||
registry.sectionAxis?.show();
|
||||
} else {
|
||||
engine.sectionAxis?.destroy();
|
||||
registry.sectionAxis?.destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 剖切盒按钮配置
|
||||
*/
|
||||
export const createSectionBoxButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createSectionBoxButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-box',
|
||||
groupId: 'group-1',
|
||||
@@ -18,12 +15,11 @@ export const createSectionBoxButton = (engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('剖切盒'),
|
||||
onClick: (button) => {
|
||||
console.log('剖切盒被点击:', button.id, '激活状态:', button.isActive);
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
if (button.isActive) {
|
||||
// 激活时显示弹窗
|
||||
engine.sectionBox?.show();
|
||||
registry.sectionBox?.show();
|
||||
} else {
|
||||
// 关闭时隐藏弹窗
|
||||
engine.sectionBox?.hide();
|
||||
registry.sectionBox?.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
|
||||
/**
|
||||
* 剖切菜单按钮配置
|
||||
*/
|
||||
export const createSectionMenuButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createSectionMenuButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'section',
|
||||
groupId: 'group-1',
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 拾取面剖切按钮配置
|
||||
*/
|
||||
export const createSectionPlaneButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createSectionPlaneButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'section-plane',
|
||||
groupId: 'group-1',
|
||||
@@ -18,12 +15,11 @@ export const createSectionPlaneButton = (engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('拾曲面剖切'),
|
||||
onClick: (button) => {
|
||||
console.log('拾取面剖切被点击:', button.id, '激活状态:', button.isActive);
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
if (button.isActive) {
|
||||
// 激活时显示弹窗
|
||||
engine.sectionPlane?.show();
|
||||
registry.sectionPlane?.show();
|
||||
} else {
|
||||
// 关闭时隐藏弹窗
|
||||
engine.sectionPlane?.hide();
|
||||
registry.sectionPlane?.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
|
||||
/**
|
||||
* 设置按钮配置
|
||||
*/
|
||||
export const createSettingButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createSettingButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'setting',
|
||||
groupId: 'group-2',
|
||||
@@ -14,7 +10,6 @@ export const createSettingButton = (_engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('设置'),
|
||||
keepActive: false,
|
||||
onClick: (button) => {
|
||||
// 预留:未来接入设置逻辑(此处已注入 engine)
|
||||
console.log('设置按钮被点击:', button.id);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
|
||||
/**
|
||||
* 第三人称(鸟瞰)漫游按钮配置
|
||||
*/
|
||||
export const createWalkBirdButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createWalkBirdButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk-bird',
|
||||
groupId: 'group-1',
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 漫游按钮配置(普通按钮,不带子菜单)
|
||||
*/
|
||||
export const createWalkMenuButton = (engine: BimEngine): ButtonConfig => {
|
||||
export const createWalkMenuButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk',
|
||||
groupId: 'group-1',
|
||||
@@ -15,7 +12,8 @@ export const createWalkMenuButton = (engine: BimEngine): ButtonConfig => {
|
||||
icon: getIcon('漫游'),
|
||||
onClick: () => {
|
||||
console.log('漫游按钮被点击');
|
||||
engine.walkControl?.show();
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.walkControl?.show();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import type { ButtonConfig } from '../../../../index.type';
|
||||
import type { BimEngine } from '../../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../../utils/icon-manager';
|
||||
|
||||
/**
|
||||
* 第一人称漫游按钮配置
|
||||
*/
|
||||
export const createWalkPersonButton = (_engine: BimEngine): ButtonConfig => {
|
||||
export const createWalkPersonButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'walk-person',
|
||||
groupId: 'group-1',
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
import type { ButtonConfig } from '../../../index.type';
|
||||
import type { BimEngine } from '../../../../../bim-engine';
|
||||
import { getIcon } from '../../../../../utils/icon-manager';
|
||||
import { ManagerRegistry } from '../../../../../core/manager-registry';
|
||||
|
||||
/**
|
||||
* 选框放大按钮配置
|
||||
*
|
||||
* 说明:
|
||||
* - 当前仅添加 UI 按钮,点击事件先留空(后续接入引擎能力再实现)
|
||||
* - 使用工厂函数模式注入 engine,便于未来调用 engine API
|
||||
*/
|
||||
export const createZoomBoxButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'zoom-box',
|
||||
groupId: 'group-1',
|
||||
keepActive: false,
|
||||
type: 'button',
|
||||
label: 'toolbar.zoomBox',
|
||||
icon: getIcon('框选放大'),
|
||||
onClick: () => {
|
||||
engine.engine?.getEngine().rangeScale.active();
|
||||
// 事件先留空:后续实现“框选放大/框选缩放”能力时再接入
|
||||
// 这里不做任何动作,避免误触影响用户操作
|
||||
}
|
||||
};
|
||||
export const createZoomBoxButton = (): ButtonConfig => {
|
||||
return {
|
||||
id: 'zoom-box',
|
||||
groupId: 'group-1',
|
||||
keepActive: false,
|
||||
type: 'button',
|
||||
label: 'toolbar.zoomBox',
|
||||
icon: getIcon('框选放大'),
|
||||
onClick: () => {
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.engine3d?.getEngine().rangeScale.active();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import { BimButtonGroup } from '../index';
|
||||
|
||||
/**
|
||||
* 底部工具栏 (Toolbar)
|
||||
* BimButtonGroup 的子类,专门用于加载工具栏默认按钮。
|
||||
*/
|
||||
export class Toolbar extends BimButtonGroup {
|
||||
/**
|
||||
* 重写初始化,加载默认按钮
|
||||
*/
|
||||
public async init(): Promise<void> {
|
||||
await super.init();
|
||||
|
||||
// 动态加载默认按钮配置
|
||||
const { createHomeButton } = await import('./buttons/home');
|
||||
const { createZoomBoxButton } = await import('./buttons/zoom-box');
|
||||
const { createWalkMenuButton } = await import('./buttons/walk/walk-menu');
|
||||
@@ -28,26 +20,20 @@ export class Toolbar extends BimButtonGroup {
|
||||
|
||||
this.addGroup('group-1');
|
||||
|
||||
// 使用工厂函数创建按钮,并注入 engine
|
||||
if (this.engine) {
|
||||
this.addButton(createHomeButton(this.engine));
|
||||
// 你要求:在"首页"后面添加"选框放大"
|
||||
this.addButton(createZoomBoxButton(this.engine));
|
||||
this.addButton(createMeasureButton(this.engine));
|
||||
this.addButton(createSectionMenuButton(this.engine));
|
||||
this.addButton(createSectionPlaneButton(this.engine));
|
||||
this.addButton(createSectionAxisButton(this.engine));
|
||||
this.addButton(createSectionBoxButton(this.engine));
|
||||
this.addButton(createWalkMenuButton(this.engine));
|
||||
this.addButton(createMapButton(this.engine));
|
||||
this.addButton(createPropertyButton(this.engine));
|
||||
this.addGroup('group-2');
|
||||
this.addButton(createSettingButton(this.engine));
|
||||
this.addButton(createInfoButton(this.engine));
|
||||
this.addButton(createFullscreenButton(this.engine));
|
||||
} else {
|
||||
console.warn('[Toolbar] Engine not available when creating buttons.');
|
||||
}
|
||||
this.addButton(createHomeButton());
|
||||
this.addButton(createZoomBoxButton());
|
||||
this.addButton(createMeasureButton());
|
||||
this.addButton(createSectionMenuButton());
|
||||
this.addButton(createSectionPlaneButton());
|
||||
this.addButton(createSectionAxisButton());
|
||||
this.addButton(createSectionBoxButton());
|
||||
this.addButton(createWalkMenuButton());
|
||||
this.addButton(createMapButton());
|
||||
this.addButton(createPropertyButton());
|
||||
this.addGroup('group-2');
|
||||
this.addButton(createSettingButton());
|
||||
this.addButton(createInfoButton());
|
||||
this.addButton(createFullscreenButton());
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user