设置界面
This commit is contained in:
192
packages/editor-core/src/Services/SettingsRegistry.ts
Normal file
192
packages/editor-core/src/Services/SettingsRegistry.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import { Injectable, IService } from '@esengine/ecs-framework';
|
||||
|
||||
export type SettingType = 'string' | 'number' | 'boolean' | 'select' | 'color' | 'range';
|
||||
|
||||
export interface SettingOption {
|
||||
label: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface SettingValidator {
|
||||
validate: (value: any) => boolean;
|
||||
errorMessage: string;
|
||||
}
|
||||
|
||||
export interface SettingDescriptor {
|
||||
key: string;
|
||||
label: string;
|
||||
type: SettingType;
|
||||
defaultValue: any;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
options?: SettingOption[];
|
||||
validator?: SettingValidator;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
}
|
||||
|
||||
export interface SettingSection {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
settings: SettingDescriptor[];
|
||||
}
|
||||
|
||||
export interface SettingCategory {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
sections: SettingSection[];
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SettingsRegistry implements IService {
|
||||
private categories: Map<string, SettingCategory> = new Map();
|
||||
|
||||
public dispose(): void {
|
||||
this.categories.clear();
|
||||
}
|
||||
|
||||
public registerCategory(category: SettingCategory): void {
|
||||
if (this.categories.has(category.id)) {
|
||||
console.warn(`[SettingsRegistry] Category ${category.id} already registered, overwriting`);
|
||||
}
|
||||
this.categories.set(category.id, category);
|
||||
}
|
||||
|
||||
public registerSection(categoryId: string, section: SettingSection): void {
|
||||
let category = this.categories.get(categoryId);
|
||||
|
||||
if (!category) {
|
||||
category = {
|
||||
id: categoryId,
|
||||
title: categoryId,
|
||||
sections: []
|
||||
};
|
||||
this.categories.set(categoryId, category);
|
||||
}
|
||||
|
||||
const existingIndex = category.sections.findIndex(s => s.id === section.id);
|
||||
if (existingIndex >= 0) {
|
||||
category.sections[existingIndex] = section;
|
||||
console.warn(`[SettingsRegistry] Section ${section.id} in category ${categoryId} already exists, overwriting`);
|
||||
} else {
|
||||
category.sections.push(section);
|
||||
}
|
||||
}
|
||||
|
||||
public registerSetting(categoryId: string, sectionId: string, setting: SettingDescriptor): void {
|
||||
let category = this.categories.get(categoryId);
|
||||
|
||||
if (!category) {
|
||||
category = {
|
||||
id: categoryId,
|
||||
title: categoryId,
|
||||
sections: []
|
||||
};
|
||||
this.categories.set(categoryId, category);
|
||||
}
|
||||
|
||||
let section = category.sections.find(s => s.id === sectionId);
|
||||
if (!section) {
|
||||
section = {
|
||||
id: sectionId,
|
||||
title: sectionId,
|
||||
settings: []
|
||||
};
|
||||
category.sections.push(section);
|
||||
}
|
||||
|
||||
const existingIndex = section.settings.findIndex(s => s.key === setting.key);
|
||||
if (existingIndex >= 0) {
|
||||
section.settings[existingIndex] = setting;
|
||||
console.warn(`[SettingsRegistry] Setting ${setting.key} in section ${sectionId} already exists, overwriting`);
|
||||
} else {
|
||||
section.settings.push(setting);
|
||||
}
|
||||
}
|
||||
|
||||
public unregisterCategory(categoryId: string): void {
|
||||
this.categories.delete(categoryId);
|
||||
}
|
||||
|
||||
public unregisterSection(categoryId: string, sectionId: string): void {
|
||||
const category = this.categories.get(categoryId);
|
||||
if (category) {
|
||||
category.sections = category.sections.filter(s => s.id !== sectionId);
|
||||
if (category.sections.length === 0) {
|
||||
this.categories.delete(categoryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getCategory(categoryId: string): SettingCategory | undefined {
|
||||
return this.categories.get(categoryId);
|
||||
}
|
||||
|
||||
public getAllCategories(): SettingCategory[] {
|
||||
return Array.from(this.categories.values());
|
||||
}
|
||||
|
||||
public getSetting(categoryId: string, sectionId: string, key: string): SettingDescriptor | undefined {
|
||||
const category = this.categories.get(categoryId);
|
||||
if (!category) return undefined;
|
||||
|
||||
const section = category.sections.find(s => s.id === sectionId);
|
||||
if (!section) return undefined;
|
||||
|
||||
return section.settings.find(s => s.key === key);
|
||||
}
|
||||
|
||||
public getAllSettings(): Map<string, SettingDescriptor> {
|
||||
const allSettings = new Map<string, SettingDescriptor>();
|
||||
|
||||
for (const category of this.categories.values()) {
|
||||
for (const section of category.sections) {
|
||||
for (const setting of section.settings) {
|
||||
allSettings.set(setting.key, setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allSettings;
|
||||
}
|
||||
|
||||
public validateSetting(setting: SettingDescriptor, value: any): boolean {
|
||||
if (setting.validator) {
|
||||
return setting.validator.validate(value);
|
||||
}
|
||||
|
||||
switch (setting.type) {
|
||||
case 'number':
|
||||
if (typeof value !== 'number') return false;
|
||||
if (setting.min !== undefined && value < setting.min) return false;
|
||||
if (setting.max !== undefined && value > setting.max) return false;
|
||||
return true;
|
||||
|
||||
case 'boolean':
|
||||
return typeof value === 'boolean';
|
||||
|
||||
case 'string':
|
||||
return typeof value === 'string';
|
||||
|
||||
case 'select':
|
||||
if (!setting.options) return false;
|
||||
return setting.options.some(opt => opt.value === value);
|
||||
|
||||
case 'range':
|
||||
if (typeof value !== 'number') return false;
|
||||
if (setting.min !== undefined && value < setting.min) return false;
|
||||
if (setting.max !== undefined && value > setting.max) return false;
|
||||
return true;
|
||||
|
||||
case 'color':
|
||||
return typeof value === 'string' && /^#[0-9A-Fa-f]{6}$/.test(value);
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,6 @@ export * from './Services/ProjectService';
|
||||
export * from './Services/ComponentDiscoveryService';
|
||||
export * from './Services/ComponentLoaderService';
|
||||
export * from './Services/LogService';
|
||||
export * from './Services/SettingsRegistry';
|
||||
|
||||
export * from './Types/UITypes';
|
||||
|
||||
Reference in New Issue
Block a user