diff --git a/crates/ui-egui/src/i18n.rs b/crates/ui-egui/src/i18n.rs index 8324137c..08a7e4d8 100644 --- a/crates/ui-egui/src/i18n.rs +++ b/crates/ui-egui/src/i18n.rs @@ -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 { diff --git a/crates/ui-egui/src/i18n/ui.rs b/crates/ui-egui/src/i18n/ui.rs index 88ddc0a3..fdcaa27e 100644 --- a/crates/ui-egui/src/i18n/ui.rs +++ b/crates/ui-egui/src/i18n/ui.rs @@ -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:", "Назва відстеження:"), diff --git a/crates/ui-egui/src/panels/viewer_tools.rs b/crates/ui-egui/src/panels/viewer_tools.rs index 2161a030..06679783 100644 --- a/crates/ui-egui/src/panels/viewer_tools.rs +++ b/crates/ui-egui/src/panels/viewer_tools.rs @@ -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),