feat(i18n): 统一国际化系统架构,支持插件独立翻译 (#301)
* feat(i18n): 统一国际化系统架构,支持插件独立翻译 ## 主要改动 ### 核心架构 - 增强 LocaleService,支持插件命名空间翻译扩展 - 新增 editor-runtime/i18n 模块,提供 createPluginLocale/createPluginTranslator - 新增 editor-core/tokens.ts,定义 LocaleServiceToken 等服务令牌 - 改进 PluginAPI 类型安全,使用 ServiceToken<T> 替代 any ### 编辑器本地化 - 扩展 en.ts/zh.ts 翻译文件,覆盖所有 UI 组件 - 新增 es.ts 西班牙语支持 - 重构 40+ 组件使用 useLocale() hook ### 插件本地化系统 - behavior-tree-editor: 新增 locales/ 和 useBTLocale hook - material-editor: 新增 locales/ 和 useMaterialLocale hook - particle-editor: 新增 locales/ 和 useParticleLocale hook - tilemap-editor: 新增 locales/ 和 useTilemapLocale hook - ui-editor: 新增 locales/ 和 useUILocale hook ### 类型安全改进 - 修复 Debug 工具使用公共接口替代 as any - 修复 ChunkStreamingSystem 添加 forEachChunk 公共方法 - 修复 blueprint-editor 移除不必要的向后兼容代码 * fix(behavior-tree-editor): 使用 ServiceToken 模式修复服务解析 - 创建 BehaviorTreeServiceToken 遵循"谁定义接口,谁导出Token"原则 - 使用 ServiceToken.id (symbol) 注册服务到 ServiceContainer - 更新 PluginSDKRegistry.resolveService 支持 ServiceToken 检测 - BehaviorTreeEditorPanel 现在使用类型安全的 PluginAPI.resolve * fix(behavior-tree-editor): 使用 ServiceContainer.resolve 获取类注册的服务 * fix: 修复多个包的依赖和类型问题 - core: EntityDataCollector.getEntityDetails 使用 HierarchySystem 获取父实体 - ui-editor: 添加 @esengine/editor-runtime 依赖 - tilemap-editor: 添加 @esengine/editor-runtime 依赖 - particle-editor: 添加 @esengine/editor-runtime 依赖
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"devDependencies": {
|
||||
"@esengine/ecs-framework": "workspace:*",
|
||||
"@esengine/editor-core": "workspace:*",
|
||||
"@esengine/editor-runtime": "workspace:*",
|
||||
"@esengine/build-config": "workspace:*",
|
||||
"lucide-react": "^0.545.0",
|
||||
"react": "^18.3.1",
|
||||
|
||||
61
packages/ui-editor/src/hooks/useUILocale.ts
Normal file
61
packages/ui-editor/src/hooks/useUILocale.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* UI Editor Locale Hook
|
||||
* UI 编辑器语言钩子
|
||||
*
|
||||
* Uses the unified plugin i18n infrastructure from editor-runtime.
|
||||
* 使用 editor-runtime 的统一插件国际化基础设施。
|
||||
*/
|
||||
import {
|
||||
createPluginLocale,
|
||||
createPluginTranslator,
|
||||
getCurrentLocale
|
||||
} from '@esengine/editor-runtime';
|
||||
import { en, zh, es } from '../locales';
|
||||
import type { Locale, TranslationParams } from '@esengine/editor-core';
|
||||
|
||||
// Create translations bundle
|
||||
// 创建翻译包
|
||||
const translations = { en, zh, es };
|
||||
|
||||
/**
|
||||
* Hook for accessing UI editor translations
|
||||
* 访问 UI 编辑器翻译的 Hook
|
||||
*
|
||||
* Uses the unified createPluginLocale factory from editor-runtime.
|
||||
* 使用 editor-runtime 的统一 createPluginLocale 工厂。
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { t, locale } = useUILocale();
|
||||
* return <label>{t('inspector.position')}</label>;
|
||||
* ```
|
||||
*/
|
||||
export const useUILocale = createPluginLocale(translations);
|
||||
|
||||
// Create non-React translator using the unified infrastructure
|
||||
// 使用统一基础设施创建非 React 翻译器
|
||||
const uiTranslator = createPluginTranslator(translations);
|
||||
|
||||
/**
|
||||
* Non-React translation function for UI editor
|
||||
* UI 编辑器的非 React 翻译函数
|
||||
*
|
||||
* Use this in services, utilities, and other non-React contexts.
|
||||
* 在服务、工具类和其他非 React 上下文中使用。
|
||||
*
|
||||
* @param key - Translation key | 翻译键
|
||||
* @param locale - Optional locale, defaults to current locale | 可选语言,默认使用当前语言
|
||||
* @param params - Optional interpolation parameters | 可选插值参数
|
||||
*/
|
||||
export function translateUI(
|
||||
key: string,
|
||||
locale?: Locale,
|
||||
params?: TranslationParams
|
||||
): string {
|
||||
const targetLocale = locale || getCurrentLocale();
|
||||
return uiTranslator(key, targetLocale, params);
|
||||
}
|
||||
|
||||
// Re-export for external use
|
||||
// 重新导出供外部使用
|
||||
export { getCurrentLocale } from '@esengine/editor-runtime';
|
||||
52
packages/ui-editor/src/locales/en.ts
Normal file
52
packages/ui-editor/src/locales/en.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* English translations for UI Editor
|
||||
* UI 编辑器英文翻译
|
||||
*/
|
||||
export const en = {
|
||||
// ========================================
|
||||
// Inspector
|
||||
// ========================================
|
||||
inspector: {
|
||||
title: 'UITransform Inspector',
|
||||
anchor: 'Anchor',
|
||||
stretch: 'Stretch',
|
||||
position: 'Position',
|
||||
size: 'Size',
|
||||
anchorMin: 'Anchor Min',
|
||||
anchorMax: 'Anchor Max',
|
||||
pivot: 'Pivot',
|
||||
rotation: 'Rotation',
|
||||
scale: 'Scale',
|
||||
zIndex: 'Z Index',
|
||||
alpha: 'Alpha',
|
||||
visible: 'Visible'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Anchor Presets
|
||||
// ========================================
|
||||
anchorPresets: {
|
||||
topLeft: 'Top Left',
|
||||
topCenter: 'Top Center',
|
||||
topRight: 'Top Right',
|
||||
middleLeft: 'Middle Left',
|
||||
middleCenter: 'Middle Center',
|
||||
middleRight: 'Middle Right',
|
||||
bottomLeft: 'Bottom Left',
|
||||
bottomCenter: 'Bottom Center',
|
||||
bottomRight: 'Bottom Right',
|
||||
stretchAll: 'Stretch All'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Components
|
||||
// ========================================
|
||||
components: {
|
||||
uiTransform: 'UI Transform',
|
||||
uiRender: 'UI Render',
|
||||
uiText: 'UI Text',
|
||||
uiButton: 'UI Button',
|
||||
uiLayout: 'UI Layout',
|
||||
uiInteractable: 'UI Interactable'
|
||||
}
|
||||
};
|
||||
52
packages/ui-editor/src/locales/es.ts
Normal file
52
packages/ui-editor/src/locales/es.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Spanish translations for UI Editor
|
||||
* Traducciones en español del editor de UI
|
||||
*/
|
||||
export const es = {
|
||||
// ========================================
|
||||
// Inspector
|
||||
// ========================================
|
||||
inspector: {
|
||||
title: 'Inspector UITransform',
|
||||
anchor: 'Ancla',
|
||||
stretch: 'Estirar',
|
||||
position: 'Posición',
|
||||
size: 'Tamaño',
|
||||
anchorMin: 'Ancla Mín',
|
||||
anchorMax: 'Ancla Máx',
|
||||
pivot: 'Pivote',
|
||||
rotation: 'Rotación',
|
||||
scale: 'Escala',
|
||||
zIndex: 'Índice Z',
|
||||
alpha: 'Alfa',
|
||||
visible: 'Visible'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Anchor Presets
|
||||
// ========================================
|
||||
anchorPresets: {
|
||||
topLeft: 'Superior Izquierda',
|
||||
topCenter: 'Superior Centro',
|
||||
topRight: 'Superior Derecha',
|
||||
middleLeft: 'Centro Izquierda',
|
||||
middleCenter: 'Centro',
|
||||
middleRight: 'Centro Derecha',
|
||||
bottomLeft: 'Inferior Izquierda',
|
||||
bottomCenter: 'Inferior Centro',
|
||||
bottomRight: 'Inferior Derecha',
|
||||
stretchAll: 'Estirar Todo'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Components
|
||||
// ========================================
|
||||
components: {
|
||||
uiTransform: 'UI Transform',
|
||||
uiRender: 'UI Render',
|
||||
uiText: 'UI Text',
|
||||
uiButton: 'UI Button',
|
||||
uiLayout: 'UI Layout',
|
||||
uiInteractable: 'UI Interactable'
|
||||
}
|
||||
};
|
||||
11
packages/ui-editor/src/locales/index.ts
Normal file
11
packages/ui-editor/src/locales/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* UI Editor Locales
|
||||
* UI 编辑器语言包
|
||||
*
|
||||
* Export all locale translations for the UI editor plugin.
|
||||
* 导出 UI 编辑器插件的所有语言翻译。
|
||||
*/
|
||||
|
||||
export { en } from './en';
|
||||
export { zh } from './zh';
|
||||
export { es } from './es';
|
||||
52
packages/ui-editor/src/locales/zh.ts
Normal file
52
packages/ui-editor/src/locales/zh.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Chinese translations for UI Editor
|
||||
* UI 编辑器中文翻译
|
||||
*/
|
||||
export const zh = {
|
||||
// ========================================
|
||||
// Inspector
|
||||
// ========================================
|
||||
inspector: {
|
||||
title: 'UI变换检查器',
|
||||
anchor: '锚点',
|
||||
stretch: '拉伸',
|
||||
position: '位置',
|
||||
size: '大小',
|
||||
anchorMin: '锚点最小值',
|
||||
anchorMax: '锚点最大值',
|
||||
pivot: '轴心',
|
||||
rotation: '旋转',
|
||||
scale: '缩放',
|
||||
zIndex: 'Z 顺序',
|
||||
alpha: '透明度',
|
||||
visible: '可见'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Anchor Presets
|
||||
// ========================================
|
||||
anchorPresets: {
|
||||
topLeft: '左上',
|
||||
topCenter: '上中',
|
||||
topRight: '右上',
|
||||
middleLeft: '左中',
|
||||
middleCenter: '中心',
|
||||
middleRight: '右中',
|
||||
bottomLeft: '左下',
|
||||
bottomCenter: '下中',
|
||||
bottomRight: '右下',
|
||||
stretchAll: '拉伸全部'
|
||||
},
|
||||
|
||||
// ========================================
|
||||
// Components
|
||||
// ========================================
|
||||
components: {
|
||||
uiTransform: 'UI 变换',
|
||||
uiRender: 'UI 渲染',
|
||||
uiText: 'UI 文本',
|
||||
uiButton: 'UI 按钮',
|
||||
uiLayout: 'UI 布局',
|
||||
uiInteractable: 'UI 交互'
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user