mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-27 03:17:05 -06:00
* Brazilian Portuguese UI translation (pt-br) Add a pt-br catalog covering every key in the existing catalogs (2,492 entries), register it as "Português (Brasil)" with Portuguese plural rules, and resolve pt, pt-BR and pt-PT locales to it. i18n coverage 1404/1404. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keyboard Shortcuts dialog: show menus and commands in the UI language The command list showed the raw English menu paths and labels while the rest of the dialog was translated. Translate them the way the menus do (tr / tr_id); search matches the translated and the English names, like the command palette. Also rustfmt the pt-br registry row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * pt-br: gate it in xtask i18n-coverage (from #637, thanks @RicSchonfelder); licence note covers German too Co-Authored-By: RicSchonfelder <RicSchonfelder@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: RicSchonfelder <RicSchonfelder@users.noreply.github.com>
92 lines
4.7 KiB
Markdown
92 lines
4.7 KiB
Markdown
# UI localisation and live language switching
|
|
|
|
PhotoCraft uses the same Rust catalog implementation in the native egui shell and the
|
|
WebAssembly build. English source strings are lookup keys. UTF-8 TSV catalogs supply plain,
|
|
contextual, command-ID and plural translations; missing entries fall back to English.
|
|
|
|
## Supported languages
|
|
|
|
| Language | Preference code | Integer plural forms |
|
|
|---|---|---|
|
|
| English | `en` | one / other |
|
|
| 简体中文 | `zh-hans` | one form |
|
|
| 日本語 | `ja` | one form |
|
|
| 한국어 | `ko` | one form |
|
|
| Русский | `ru` | one / few / many |
|
|
| Français | `fr` | singular for 0 and 1 / plural for 2+ |
|
|
| 繁體中文 | `zh-hant` | one form |
|
|
| Español | `es` | one / other |
|
|
| Čeština | `cs` | one / few / other |
|
|
| Deutsch | `de` | one / other |
|
|
| Bahasa Indonesia | `id` | one form |
|
|
| Português (Brasil) | `pt-br` | singular for 0 and 1 / plural for 2+ |
|
|
|
|
Every non-English catalog covers the current menu labels, `tl!` literals, blend mode names,
|
|
and generated preference labels. Tests enforce that coverage. This does not include every
|
|
engine error or status message: those remain English, as do automation command IDs and
|
|
user-provided document, layer and preset names.
|
|
|
|
## Switch without restarting
|
|
|
|
Open **Edit > Preferences > Interface > Language** and choose a language. The Preferences
|
|
dialog previews its title, controls and buttons in the chosen language. **Cancel** discards
|
|
the preview, **Apply** commits it without closing the dialog, and **OK** commits and closes.
|
|
The rest of the interface follows the committed preference on its next draw. Existing
|
|
documents, undo history and tools remain available throughout a language change.
|
|
|
|
The existing preference store saves the selection for future launches. `auto` follows the
|
|
native system locale; an unsupported code follows the same fallback. Regional tags such as
|
|
`fr-CA`, `ko-KR` and `zh-CN` resolve to the corresponding registered catalog. Traditional and
|
|
Simplified Chinese remain distinct. Every Portuguese locale (`pt`, `pt-BR`, `pt-PT`) uses the
|
|
Brazilian Portuguese catalog.
|
|
|
|
Agents use the existing `prefs.set` command through CLI, MCP or the desktop control channel:
|
|
|
|
```json
|
|
{"method":"engine.execute","params":{"command":"prefs.set","params":{"path":"interface.language","value":"ko"}}}
|
|
```
|
|
|
|
Control requests are processed before synchronising the drawing language, so a request
|
|
updates the labels in the same rendered frame. Drawing language is local to the UI thread;
|
|
a scoped preview restores the previous language even if drawing unwinds. Menu and dialog
|
|
identity continues to use command IDs, independent of translated labels.
|
|
|
|
This is hot switching among the bundled catalogs. Catalog files are embedded with
|
|
`include_str!`; editing a TSV file requires a rebuild. External catalog watching and
|
|
file-resource hot reload are not implemented.
|
|
|
|
## Fonts
|
|
|
|
The native lazy CJK font loader prioritises the selected Japanese, Korean or Chinese script.
|
|
Switching languages rebuilds the font definitions and resets the existing loader, so fonts
|
|
removed from the definitions can be registered again. Idle frames keep their font cache.
|
|
Other languages retain the system's CJK fallback preference for document names and text.
|
|
|
|
Font files are not added to this repository. Native rendering uses installed system fonts
|
|
and the optional craft-fonts build input; see [Fonts](development.md#fonts-craft-fonts).
|
|
The web build can select every catalog, but CJK glyph delivery and automatic browser-locale
|
|
detection remain separate outstanding work. Switching catalogs does not supply missing fonts.
|
|
|
|
## Add or maintain a catalog
|
|
|
|
1. Add `<code>.tsv` under `crates/ui-egui/src/i18n`, following the header in `ja.tsv`.
|
|
2. Register its code, native name and plural rule in `i18n::LANGUAGES`.
|
|
3. Translate the meaning of the English source keys. Preserve `{name}` placeholders, escaped
|
|
characters and the trailing `…` on dialog commands. Use `@id` to disambiguate a command
|
|
label and `@plural` for count-sensitive text. Keep product names such as PhotoCraft.
|
|
4. Set `complete_menus` when the catalog covers all enforced keys. Add source and license
|
|
attribution for translation assets, then run the catalog and shell tests.
|
|
|
|
```sh
|
|
cargo test -p photocraft-ui-egui --locked
|
|
cargo clippy -p photocraft-ui-egui --all-targets --locked -- -D warnings
|
|
cargo xtask i18n-coverage
|
|
cargo xtask layers
|
|
cargo xtask wasm
|
|
```
|
|
|
|
Render representative dialogs with the offscreen `snapshot` example, including a sequence
|
|
of language changes in one process. Inspect the PNGs for missing glyphs and truncated labels.
|
|
Translations are original work or reuse the open PhotoCraft contributions credited in
|
|
[ATTRIBUTION.md](../ATTRIBUTION.md); no proprietary localisation resources are used.
|