增加测量窗口
This commit is contained in:
@@ -94,13 +94,13 @@ export class BimButtonGroup implements IBimComponent {
|
||||
}
|
||||
|
||||
this.updatePosition();
|
||||
|
||||
|
||||
// 添加事件拦截,防止点击穿透到 3D 引擎
|
||||
this.setupEventInterception(this.container);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件拦截,防止事件<EFBFBD><EFBFBD>泡到下层元素(如 3D 引擎)
|
||||
* 设置事件拦截,防止事件冒泡到下层元素(如 3D 引擎)
|
||||
*/
|
||||
private setupEventInterception(el: HTMLElement): void {
|
||||
const stopPropagation = (e: Event) => {
|
||||
@@ -319,6 +319,11 @@ export class BimButtonGroup implements IBimComponent {
|
||||
const btnEl = document.createElement('div');
|
||||
btnEl.className = 'opt-btn';
|
||||
|
||||
// 初始化时根据 button 自身的属性同步 active 状态
|
||||
if (button.isActive) {
|
||||
this.activeBtnIds.add(button.id);
|
||||
}
|
||||
|
||||
// 按钮优先使用自己的 align,否则使用全局配置,默认为 vertical
|
||||
const align = button.align || this.options.align || 'vertical';
|
||||
if (align === 'horizontal') {
|
||||
@@ -380,14 +385,34 @@ export class BimButtonGroup implements IBimComponent {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置按钮的激活状态
|
||||
* @param id 按钮 ID
|
||||
* @param active 可选,如果不传则切换(toggle)当前状态
|
||||
*/
|
||||
public setBtnActive(id: string, active?: boolean): void {
|
||||
const button = this.findButtonById(id);
|
||||
if (!button) return;
|
||||
|
||||
// 确定最终状态
|
||||
const newState = active !== undefined ? active : !this.activeBtnIds.has(id);
|
||||
|
||||
if (newState) {
|
||||
this.activeBtnIds.add(id);
|
||||
} else {
|
||||
this.activeBtnIds.delete(id);
|
||||
}
|
||||
|
||||
// 同步对象状态并更新 DOM
|
||||
button.isActive = newState;
|
||||
this.updateButtonState(id);
|
||||
}
|
||||
|
||||
private handleClick(button: OptButton): void {
|
||||
if (button.disabled) return;
|
||||
if (!button.children || button.children.length === 0) {
|
||||
if (button.keepActive) {
|
||||
const wasActive = this.activeBtnIds.has(button.id);
|
||||
if (wasActive) this.activeBtnIds.delete(button.id);
|
||||
else this.activeBtnIds.add(button.id);
|
||||
this.updateButtonState(button.id);
|
||||
this.setBtnActive(button.id);
|
||||
}
|
||||
this.closeDropdown();
|
||||
if (button.onClick) button.onClick(button);
|
||||
@@ -428,7 +453,7 @@ export class BimButtonGroup implements IBimComponent {
|
||||
|
||||
// 先添加到 DOM 以便计算尺寸
|
||||
document.body.appendChild(dropdown);
|
||||
|
||||
|
||||
// 添加事件拦截
|
||||
this.setupEventInterception(dropdown);
|
||||
|
||||
@@ -518,16 +543,22 @@ export class BimButtonGroup implements IBimComponent {
|
||||
private updateButtonState(buttonId: string): void {
|
||||
const btnEl = this.btnRefs.get(buttonId);
|
||||
if (btnEl) {
|
||||
this.activeBtnIds.has(buttonId) ? btnEl.classList.add('active') : btnEl.classList.remove('active');
|
||||
if (this.activeBtnIds.has(buttonId)) {
|
||||
btnEl.classList.add('active');
|
||||
} else {
|
||||
btnEl.classList.remove('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getIcon(icon?: string): string { return icon || this.DEFAULT_ICON; }
|
||||
|
||||
public updateButtonVisibility(id: string, visible: boolean): void {
|
||||
if (!this.options.visibility) this.options.visibility = {};
|
||||
this.options.visibility[id] = visible;
|
||||
this.render();
|
||||
}
|
||||
|
||||
public setShowLabel(show: boolean): void {
|
||||
this.options.showLabel = show;
|
||||
this.updateLabelsVisibility();
|
||||
@@ -557,8 +588,10 @@ export class BimButtonGroup implements IBimComponent {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public setBackgroundColor(color: string): void { this.setColors({ backgroundColor: color }); }
|
||||
private isVisible(id: string): boolean { return this.options.visibility?.[id] !== false; }
|
||||
|
||||
public destroy(): void {
|
||||
if (this.unsubscribeLocale) {
|
||||
this.unsubscribeLocale();
|
||||
|
||||
@@ -7,6 +7,7 @@ export interface ButtonConfig {
|
||||
label: string;
|
||||
icon?: string;
|
||||
keepActive?: boolean;
|
||||
isActive?:boolean;
|
||||
disabled?: boolean;
|
||||
onClick?: (button: OptButton) => void;
|
||||
children?: ButtonConfig[];
|
||||
@@ -43,10 +44,10 @@ export interface ButtonGroupColors {
|
||||
// --- 新增布局类型 ---
|
||||
|
||||
/** 弹窗/按钮组位置 */
|
||||
export type GroupPosition =
|
||||
| 'center'
|
||||
| 'top-left' | 'top-center' | 'top-right'
|
||||
| 'left-center' | 'right-center'
|
||||
export type GroupPosition =
|
||||
| 'center'
|
||||
| 'top-left' | 'top-center' | 'top-right'
|
||||
| 'left-center' | 'right-center'
|
||||
| 'bottom-left' | 'bottom-center' | 'bottom-right'
|
||||
| { x: number; y: number }
|
||||
| 'static'; // static 表示不绝对定位,随文档流
|
||||
@@ -62,16 +63,16 @@ export type ExpandDirection = 'up' | 'down' | 'left' | 'right';
|
||||
|
||||
export interface ButtonGroupOptions extends ButtonGroupColors {
|
||||
container: HTMLElement | string;
|
||||
|
||||
|
||||
/** 屏幕位置 (如 top-left) */
|
||||
position?: GroupPosition;
|
||||
|
||||
|
||||
/** 按钮组排列方向 (默认 row) */
|
||||
direction?: GroupDirection;
|
||||
|
||||
|
||||
/** 按钮内部图标文字排列 (默认 vertical) */
|
||||
align?: ButtonAlign;
|
||||
|
||||
|
||||
/** 菜单展开方向 */
|
||||
expand?: ExpandDirection;
|
||||
|
||||
@@ -84,4 +85,4 @@ export interface ClickPayload {
|
||||
button: OptButton;
|
||||
action: 'activate' | 'deactivate' | 'trigger';
|
||||
isActive?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
24
src/components/button-group/toolbar/buttons/measure/index.ts
Normal file
24
src/components/button-group/toolbar/buttons/measure/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type {ButtonConfig} from '../../../index.type';
|
||||
import type {BimEngine} from '../../../../../bim-engine';
|
||||
|
||||
/**
|
||||
* 测量按钮配置
|
||||
* 使用工厂函数模式,注入 engine 实例
|
||||
*/
|
||||
export const createMeasureButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'measure',
|
||||
groupId: 'group-1',
|
||||
type: 'button',
|
||||
label: 'toolbar.measure',
|
||||
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 6a3 3 0 0 0-3 3v7a3 3 0 0 0 3 3h18a3 3 0 0 0 3-3V9a3 3 0 0 0-3-3zm6 2H7v5a1 1 0 1 1-2 0V8H3a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1h-2v3a1 1 0 1 1-2 0V8h-2v5a1 1 0 1 1-2 0V8h-2v3a1 1 0 1 1-2 0z" clip-rule="evenodd"/></svg>',
|
||||
keepActive: true,
|
||||
onClick: (button) => {
|
||||
if (button.isActive) {
|
||||
engine.measure?.show()
|
||||
} else {
|
||||
engine.measure?.destroy()
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -19,12 +19,14 @@ export class Toolbar extends BimButtonGroup {
|
||||
const { walkBirdButton } = await import('./buttons/walk/walk-bird');
|
||||
const { settingButton } = await import('./buttons/setting');
|
||||
const { infoButton } = await import('./buttons/info');
|
||||
const { createMeasureButton } = await import('./buttons/measure');
|
||||
|
||||
this.addGroup('group-1');
|
||||
|
||||
// 使用工厂函数创建按钮,并注入 engine
|
||||
if (this.engine) {
|
||||
this.addButton(createHomeButton(this.engine));
|
||||
this.addButton(createMeasureButton(this.engine));
|
||||
} else {
|
||||
console.warn('[Toolbar] Engine not available when creating buttons.');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user