import { useState, useEffect } from 'react'; import { X, Settings as SettingsIcon, ChevronRight } from 'lucide-react'; import { SettingsService } from '../services/SettingsService'; import { SettingsRegistry, SettingCategory, SettingDescriptor } from '@esengine/editor-core'; import '../styles/SettingsWindow.css'; interface SettingsWindowProps { onClose: () => void; settingsRegistry: SettingsRegistry; } export function SettingsWindow({ onClose, settingsRegistry }: SettingsWindowProps) { const [categories, setCategories] = useState([]); const [selectedCategoryId, setSelectedCategoryId] = useState(null); const [values, setValues] = useState>(new Map()); const [errors, setErrors] = useState>(new Map()); useEffect(() => { const allCategories = settingsRegistry.getAllCategories(); setCategories(allCategories); if (allCategories.length > 0 && !selectedCategoryId) { const firstCategory = allCategories[0]; if (firstCategory) { setSelectedCategoryId(firstCategory.id); } } const settings = SettingsService.getInstance(); const allSettings = settingsRegistry.getAllSettings(); const initialValues = new Map(); for (const [key, descriptor] of allSettings.entries()) { const value = settings.get(key, descriptor.defaultValue); initialValues.set(key, value); } setValues(initialValues); }, [settingsRegistry, selectedCategoryId]); const handleValueChange = (key: string, value: any, descriptor: SettingDescriptor) => { const newValues = new Map(values); newValues.set(key, value); setValues(newValues); const newErrors = new Map(errors); if (!settingsRegistry.validateSetting(descriptor, value)) { newErrors.set(key, descriptor.validator?.errorMessage || 'Invalid value'); } else { newErrors.delete(key); } setErrors(newErrors); }; const handleSave = () => { if (errors.size > 0) { return; } const settings = SettingsService.getInstance(); const changedSettings: Record = {}; for (const [key, value] of values.entries()) { settings.set(key, value); changedSettings[key] = value; } window.dispatchEvent(new CustomEvent('settings:changed', { detail: changedSettings })); onClose(); }; const handleCancel = () => { onClose(); }; const renderSettingInput = (setting: SettingDescriptor) => { const value = values.get(setting.key) ?? setting.defaultValue; const error = errors.get(setting.key); switch (setting.type) { case 'boolean': return (
{error && {error}}
); case 'number': return (
handleValueChange(setting.key, parseInt(e.target.value) || 0, setting)} placeholder={setting.placeholder} min={setting.min} max={setting.max} step={setting.step} /> {error && {error}}
); case 'string': return (
handleValueChange(setting.key, e.target.value, setting)} placeholder={setting.placeholder} /> {error && {error}}
); case 'select': return (
{error && {error}}
); case 'range': return (
handleValueChange(setting.key, parseFloat(e.target.value), setting)} min={setting.min} max={setting.max} step={setting.step} /> {value}
{error && {error}}
); case 'color': return (
handleValueChange(setting.key, e.target.value, setting)} /> {error && {error}}
); default: return null; } }; const selectedCategory = categories.find((c) => c.id === selectedCategoryId); return (

设置

{categories.map((category) => ( ))}
{selectedCategory && selectedCategory.sections.map((section) => (

{section.title}

{section.description && (

{section.description}

)} {section.settings.map((setting) => (
{renderSettingInput(setting)}
))}
))} {!selectedCategory && (

请选择一个设置分类

)}
); }