feat: add settings dialog with render mode selection
- Add SettingDialogManager with radio-style render mode picker (simple/balance/advanced) - Add getRenderMode/setRenderMode API to Engine and EngineManager layers - Wire setting toolbar button to toggle the settings dialog - Add i18n keys for settings dialog (zh-CN/en-US) - Add version display at bottom-right of engine wrapper - Bump version to 1.1.7, rebuild and sync demo libs
This commit is contained in:
107
src/managers/setting-dialog-manager.ts
Normal file
107
src/managers/setting-dialog-manager.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { BaseDialogManager } from '../core/base-dialog-manager';
|
||||
import { ManagerRegistry } from '../core/manager-registry';
|
||||
import { t } from '../services/locale';
|
||||
|
||||
type RenderMode = 'simple' | 'balance' | 'advanced';
|
||||
|
||||
export class SettingDialogManager extends BaseDialogManager {
|
||||
protected get dialogId() { return 'setting-dialog'; }
|
||||
protected get dialogTitle() { return 'setting.dialogTitle'; }
|
||||
protected get dialogWidth() { return 280; }
|
||||
|
||||
constructor(registry: ManagerRegistry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
public init(): void {}
|
||||
|
||||
protected getDialogPosition() {
|
||||
const container = this.registry.container;
|
||||
if (!container) return { x: 100, y: 100 };
|
||||
|
||||
const containerWidth = container.clientWidth;
|
||||
const containerHeight = container.clientHeight;
|
||||
|
||||
return {
|
||||
x: (containerWidth - this.dialogWidth) / 2,
|
||||
y: (containerHeight - 200) / 2
|
||||
};
|
||||
}
|
||||
|
||||
protected createContent(): HTMLElement {
|
||||
const currentMode = this.registry.engine3d?.getRenderMode() ?? 'balance';
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.style.cssText = 'padding: 16px;';
|
||||
|
||||
// 渲染模式标题
|
||||
const label = document.createElement('div');
|
||||
label.style.cssText = 'font-size: 13px; color: var(--bim-text-secondary, #94a3b8); margin-bottom: 12px;';
|
||||
label.textContent = t('setting.renderMode');
|
||||
content.appendChild(label);
|
||||
|
||||
// 三个模式选项
|
||||
const modes: { key: RenderMode; labelKey: string }[] = [
|
||||
{ key: 'simple', labelKey: 'setting.modes.simple' },
|
||||
{ key: 'balance', labelKey: 'setting.modes.balance' },
|
||||
{ key: 'advanced', labelKey: 'setting.modes.advanced' },
|
||||
];
|
||||
|
||||
const group = document.createElement('div');
|
||||
group.style.cssText = 'display: flex; flex-direction: column; gap: 4px;';
|
||||
|
||||
for (const mode of modes) {
|
||||
const item = document.createElement('div');
|
||||
item.style.cssText = `
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 10px 12px; border-radius: 6px; cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
background: ${mode.key === currentMode ? 'var(--bim-primary, #3b82f6)' : 'transparent'};
|
||||
color: ${mode.key === currentMode ? 'var(--bim-text-inverse, #fff)' : 'var(--bim-text-primary, #fff)'};
|
||||
`;
|
||||
|
||||
// 圆点指示器
|
||||
const dot = document.createElement('div');
|
||||
dot.style.cssText = `
|
||||
width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
|
||||
border: 2px solid ${mode.key === currentMode ? 'var(--bim-text-inverse, #fff)' : 'var(--bim-text-tertiary, #64748b)'};
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
`;
|
||||
if (mode.key === currentMode) {
|
||||
const inner = document.createElement('div');
|
||||
inner.style.cssText = 'width: 8px; height: 8px; border-radius: 50%; background: var(--bim-text-inverse, #fff);';
|
||||
dot.appendChild(inner);
|
||||
}
|
||||
|
||||
const text = document.createElement('span');
|
||||
text.style.cssText = 'font-size: 14px; font-weight: 500;';
|
||||
text.textContent = t(mode.labelKey);
|
||||
|
||||
item.appendChild(dot);
|
||||
item.appendChild(text);
|
||||
|
||||
item.addEventListener('mouseenter', () => {
|
||||
if (mode.key !== currentMode) {
|
||||
item.style.background = 'var(--bim-floating-btn-bg, rgba(255,255,255,0.08))';
|
||||
}
|
||||
});
|
||||
item.addEventListener('mouseleave', () => {
|
||||
if (mode.key !== currentMode) {
|
||||
item.style.background = 'transparent';
|
||||
}
|
||||
});
|
||||
|
||||
item.addEventListener('click', () => {
|
||||
this.registry.engine3d?.setRenderMode(mode.key);
|
||||
// 重新渲染弹窗内容
|
||||
this.hide();
|
||||
this.show();
|
||||
});
|
||||
|
||||
group.appendChild(item);
|
||||
}
|
||||
|
||||
content.appendChild(group);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user