Files
bim_engine/src/managers/right-key-manager.ts
yuding 73edf0b3b8 refactor(managers): accept registry parameter via constructor injection
All 16 managers now receive ManagerRegistry instance through constructor
instead of calling ManagerRegistry.getInstance(). This enables each
BimEngine instance to have its own isolated set of managers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-28 10:08:36 +08:00

89 lines
2.5 KiB
TypeScript

/**
* 右键菜单管理器
* 负责管理右键上下文菜单的显示和交互
*/
import { BaseManager } from '../core/base-manager';
import { ManagerRegistry } from '../core/manager-registry';
import { BimRightKey } from '../components/right-key';
import { BimMenu } from '../components/menu';
import { MenuItemConfig } from '../components/menu/item';
/**
* 右键菜单管理器
* 支持注册多个上下文处理器,动态生成右键菜单
*/
export class RightKeyManager extends BaseManager {
/** 容器元素 */
private container: HTMLElement;
/** 右键面板实例 */
private rightKeyPanel: BimRightKey;
/** 上下文处理器列表 */
private contextHandlers: Array<(e: MouseEvent) => MenuItemConfig[] | null> = [];
constructor(container: HTMLElement, registry: ManagerRegistry) {
super(registry);
this.container = container;
this.rightKeyPanel = new BimRightKey({
zIndex: 9000,
container: this.container,
onContext: this.handleContextMenu
});
this.rightKeyPanel.init();
}
/** 销毁管理器 */
public destroy(): void {
this.rightKeyPanel.destroy();
super.destroy();
}
/**
* 注册上下文处理器
* @param handler 处理器函数,返回菜单项配置
*/
public registerHandler(handler: (e: MouseEvent) => MenuItemConfig[] | null): void {
this.contextHandlers.push(handler);
}
/**
* 显示菜单
* @param x 横坐标
* @param y 纵坐标
* @param items 菜单项配置
* @param groupOrder 分组顺序
*/
public showMenu(x: number, y: number, items: MenuItemConfig[], groupOrder?: string[]): void {
if (!items || items.length === 0) return;
const menu = new BimMenu({ items, groupOrder });
menu.init();
this.rightKeyPanel.mount(menu);
this.rightKeyPanel.show(x, y);
}
/** 隐藏菜单 */
public hide(): void {
this.rightKeyPanel.hide();
}
/** 处理右键点击事件 */
private handleContextMenu = (e: MouseEvent): void => {
let items: MenuItemConfig[] | null = null;
for (const handler of this.contextHandlers) {
const result = handler(e);
if (result && result.length > 0) {
if (!items) items = [];
items = items.concat(result);
}
}
if (items && items.length > 0) {
this.showMenu(e.clientX, e.clientY, items);
} else {
this.hide();
}
};
}