mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
i18n: one Red/Green/Blue row per language, Title/Action Safe keeps After Effects' label, no process spawn to read the locale (#490, #571 follow-up)
- #571's Red/Green/Blue rows duplicated #490's; keep 红色/绿色/蓝色 and give Traditional Chinese 紅色/綠色/藍色 instead of the English copies. - The viewer's grid menu says Title/Action Safe again (as in After Effects and the View menu), with its own catalog rows. - Half is 二分之一, as in After Effects' Simplified Chinese resolution menu. - Drop the macOS 'defaults read' fallback for a C locale: sys-locale never reports one on Apple, so it never ran. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
This commit is contained in:
3 files changed
+10
-52
No files matched your search
@@ -54,51 +54,13 @@ fn system_language() -> &'static str {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
static LANGUAGE: std::sync::OnceLock<&'static str> = std::sync::OnceLock::new();
|
||||
LANGUAGE.get_or_init(|| {
|
||||
let locale = sys_locale::get_locale();
|
||||
// `C` / `POSIX` (and variants like `C.UTF-8`) mean "no particular locale": don't force
|
||||
// English, ask the macOS preferred-languages list instead.
|
||||
if locale.as_deref().is_some_and(is_c_locale) {
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Some(l) = macos_preferred_language() {
|
||||
return l;
|
||||
}
|
||||
return "en";
|
||||
}
|
||||
supported(locale.as_deref())
|
||||
})
|
||||
LANGUAGE.get_or_init(|| supported(sys_locale::get_locale().as_deref()))
|
||||
}
|
||||
// No system locale in the browser build: English.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
supported(None)
|
||||
}
|
||||
|
||||
/// True when `locale` names the generic `C` / `POSIX` locale (or a variant like `C.UTF-8`).
|
||||
fn is_c_locale(locale: &str) -> bool {
|
||||
let base = locale.split(['.', '@']).next().unwrap_or("").to_ascii_lowercase();
|
||||
matches!(base.as_str(), "c" | "posix")
|
||||
}
|
||||
|
||||
/// The first supported language in the macOS `defaults read -g AppleLanguages` list.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn macos_preferred_language() -> Option<&'static str> {
|
||||
let out = std::process::Command::new("/usr/bin/defaults")
|
||||
.args(["read", "-g", "AppleLanguages"])
|
||||
.output()
|
||||
.ok()?;
|
||||
if !out.status.success() {
|
||||
return None;
|
||||
}
|
||||
String::from_utf8_lossy(&out.stdout)
|
||||
.split(['(', ')', ',', '"', '\n'])
|
||||
.map(str::trim)
|
||||
.filter(|s| !s.is_empty())
|
||||
.find_map(|tag| {
|
||||
let lang = supported(Some(tag));
|
||||
(lang != "en").then_some(lang)
|
||||
})
|
||||
}
|
||||
|
||||
/// The language EffectCraft shows for a BCP 47 locale (`ja-JP` → `ja`, `zh-Hans-CN` → `zh-hans`,
|
||||
/// `zh-TW` → `zh-hant`, `uk-UA` → `uk`).
|
||||
fn supported(locale: Option<&str>) -> &'static str {
|
||||
|
||||
@@ -464,6 +464,7 @@ const JAPANESE: &[(&str, &str)] = &[
|
||||
("Time Stretch…", "時間伸縮…"),
|
||||
("Time:", "時間:"),
|
||||
("Time: {}", "時間:{}"),
|
||||
("Title/Action Safe", "タイトル/アクションセーフ"),
|
||||
("Title/action safe", "タイトル/アクションセーフ"),
|
||||
("Toggle Switches / Modes", "スイッチ/モードを切り替え"),
|
||||
("Track Name:", "トラック名:"),
|
||||
@@ -554,7 +555,6 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
|
||||
("Background Color:", "背景颜色:"),
|
||||
("Blend Mode:", "混合模式:"),
|
||||
("Blending Mode", "混合模式"),
|
||||
("Blue", "蓝"),
|
||||
("Blur", "模糊"),
|
||||
("Blur Level", "模糊级别"),
|
||||
("Boundary", "边界"),
|
||||
@@ -670,7 +670,6 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
|
||||
("Frame Target:", "帧目标:"),
|
||||
("Freeze", "冻结"),
|
||||
("Grab bag", "列表"),
|
||||
("Green", "绿"),
|
||||
("Grid", "网格"),
|
||||
("Guide Layers: {}", "参考图层:{}"),
|
||||
("Guides", "参考线"),
|
||||
@@ -808,7 +807,6 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
|
||||
("Rate Control: {}", "比特率控制:{}"),
|
||||
("Recent", "最近使用"),
|
||||
("Recording", "录制中"),
|
||||
("Red", "红"),
|
||||
("Remove", "移除"),
|
||||
("Rename", "重命名"),
|
||||
("Render: {} ms • UI {} fps{}", "渲染:{} 毫秒 • 界面 {} fps{}"),
|
||||
@@ -901,6 +899,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
|
||||
("Time Stretch…", "时间伸缩…"),
|
||||
("Time:", "时间:"),
|
||||
("Time: {}", "时间:{}"),
|
||||
("Title/Action Safe", "字幕/动作安全框"),
|
||||
("Title/action safe", "字幕/动作安全框"),
|
||||
("Toggle Switches / Modes", "切换开关/模式"),
|
||||
("Track Name:", "跟踪名称:"),
|
||||
@@ -951,7 +950,7 @@ const SIMPLIFIED_CHINESE: &[(&str, &str)] = &[
|
||||
("Fit", "适合"),
|
||||
("Fit up to 100%", "适合(最大 100%)"),
|
||||
("Full", "完整"),
|
||||
("Half", "一半"),
|
||||
("Half", "二分之一"),
|
||||
("Only this layer uses this solid.", "仅此图层使用该纯色。"),
|
||||
("Proportional Grid", "比例网格"),
|
||||
("Quarter", "四分之一"),
|
||||
@@ -1047,7 +1046,6 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("Background Color:", "背景顏色:"),
|
||||
("Blend Mode:", "混合模式:"),
|
||||
("Blending Mode", "混合模式"),
|
||||
("Blue", "藍"),
|
||||
("Blur", "模糊"),
|
||||
("Blur Level", "模糊級別"),
|
||||
("Boundary", "邊界"),
|
||||
@@ -1163,7 +1161,6 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("Frame Target:", "幀目標:"),
|
||||
("Freeze", "凍結"),
|
||||
("Grab bag", "清單"),
|
||||
("Green", "綠"),
|
||||
("Grid", "格點"),
|
||||
("Guide Layers: {}", "參考圖層:{}"),
|
||||
("Guides", "參考線"),
|
||||
@@ -1301,7 +1298,6 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("Rate Control: {}", "位元速率控制:{}"),
|
||||
("Recent", "最近使用"),
|
||||
("Recording", "錄製中"),
|
||||
("Red", "紅"),
|
||||
("Remove", "移除"),
|
||||
("Rename", "重命名"),
|
||||
("Render: {} ms • UI {} fps{}", "算圖:{} 毫秒 • 介面 {} fps{}"),
|
||||
@@ -1394,6 +1390,7 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("Time Stretch…", "時間伸縮…"),
|
||||
("Time:", "時間:"),
|
||||
("Time: {}", "時間:{}"),
|
||||
("Title/Action Safe", "字幕/動作安全框"),
|
||||
("Title/action safe", "字幕/動作安全框"),
|
||||
("Toggle Switches / Modes", "切換開關/模式"),
|
||||
("Track Name:", "追蹤名稱:"),
|
||||
@@ -1455,21 +1452,19 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("Third", "Third"),
|
||||
("Toggle Mask and Shape Path Visibility", "Toggle Mask and Shape Path Visibility"),
|
||||
("Toggle Transparency Grid", "Toggle Transparency Grid"),
|
||||
// The same rows as the Simplified catalog (the tests require both lists to match). The
|
||||
// Traditional wording is the translator's call and stays the English source until then.
|
||||
("16 bits per channel", "16 bits per channel"),
|
||||
("32 bits per channel (float)", "32 bits per channel (float)"),
|
||||
("8 bits per channel", "8 bits per channel"),
|
||||
("Adaptive Resolution", "Adaptive Resolution"),
|
||||
("Adobe-style built-in", "Adobe-style built-in"),
|
||||
("Blue", "Blue"),
|
||||
("Blue", "藍色"),
|
||||
("Current Settings", "Current Settings"),
|
||||
("Disable Per-character 3D", "Disable Per-character 3D"),
|
||||
("Draft", "Draft"),
|
||||
("Enable Per-character 3D", "Enable Per-character 3D"),
|
||||
("Fast Draft", "Fast Draft"),
|
||||
("Fast Previews (Draft 3D, Faster Effects)", "Fast Previews (Draft 3D, Faster Effects)"),
|
||||
("Green", "Green"),
|
||||
("Green", "綠色"),
|
||||
("Import Image Sequence", "Import Image Sequence"),
|
||||
("Import PDF / Illustrator File", "Import PDF / Illustrator File"),
|
||||
("Import Photoshop File", "Import Photoshop File"),
|
||||
@@ -1482,7 +1477,7 @@ const TRADITIONAL_CHINESE: &[(&str, &str)] = &[
|
||||
("OpenGL (compatibility)", "OpenGL (compatibility)"),
|
||||
("Opus Bitrate: {} kbps", "Opus Bitrate: {} kbps"),
|
||||
("RGB Straight", "RGB Straight"),
|
||||
("Red", "Red"),
|
||||
("Red", "紅色"),
|
||||
("Tone map", "Tone map"),
|
||||
("Use In-Window Menu Bar on macOS", "Use In-Window Menu Bar on macOS"),
|
||||
("Wireframe", "Wireframe"),
|
||||
@@ -1878,6 +1873,7 @@ const UKRAINIAN: &[(&str, &str)] = &[
|
||||
("Time Stretch…", "Розтягнення часу…"),
|
||||
("Time:", "Час:"),
|
||||
("Time: {}", "Час: {}"),
|
||||
("Title/Action Safe", "Безпечні області титрів і дії"),
|
||||
("Title/action safe", "Безпечні області титрів і дії"),
|
||||
("Toggle Switches / Modes", "Перемкнути перемикачі / режими"),
|
||||
("Track Name:", "Назва відстеження:"),
|
||||
|
||||
@@ -636,7 +636,7 @@ pub(crate) fn bottom_bar(app: &mut EffectcraftApp, ui: &mut egui::Ui, bar: Rect,
|
||||
}
|
||||
let v = &app.ui.viewer;
|
||||
let items = vec![
|
||||
("Title/action safe".to_string(), v.safe_margins),
|
||||
("Title/Action Safe".to_string(), v.safe_margins),
|
||||
("Proportional Grid".to_string(), v.proportional_grid),
|
||||
("Grid".to_string(), v.grid),
|
||||
("Guides".to_string(), v.guides),
|
||||
|
||||
Reference in new issue
Block a user