diff --git a/Cargo.lock b/Cargo.lock index e3882ed..57c5b6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -149,6 +158,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayref" version = "0.3.9" @@ -342,6 +357,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "base62" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adf9755786e27479693dedd3271691a92b5e242ab139cacb9fb8e7fb5381111" + [[package]] name = "bit-set" version = "0.5.3" @@ -437,6 +458,16 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.19.0" @@ -1516,6 +1547,30 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + [[package]] name = "glow" version = "0.13.1" @@ -1882,6 +1937,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "ignore" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "image" version = "0.24.9" @@ -1925,6 +1996,15 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -2018,6 +2098,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "lebe" version = "0.5.3" @@ -2254,6 +2340,15 @@ dependencies = [ "libc", ] +[[package]] +name = "normpath" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2806,7 +2901,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.7", ] [[package]] @@ -2973,6 +3068,35 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + [[package]] name = "renderdoc-sys" version = "1.1.0" @@ -2985,6 +3109,60 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" +[[package]] +name = "rust-i18n" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda2551fdfaf6cc5ee283adc15e157047b92ae6535cf80f6d4962d05717dc332" +dependencies = [ + "globwalk", + "once_cell", + "regex", + "rust-i18n-macro", + "rust-i18n-support", + "smallvec", +] + +[[package]] +name = "rust-i18n-macro" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22baf7d7f56656d23ebe24f6bb57a5d40d2bce2a5f1c503e692b5b2fa450f965" +dependencies = [ + "glob", + "once_cell", + "proc-macro2", + "quote", + "rust-i18n-support", + "serde", + "serde_json", + "serde_yaml", + "syn 2.0.111", +] + +[[package]] +name = "rust-i18n-support" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940ed4f52bba4c0152056d771e563b7133ad9607d4384af016a134b58d758f19" +dependencies = [ + "arc-swap", + "base62", + "globwalk", + "itertools", + "lazy_static", + "normpath", + "once_cell", + "proc-macro2", + "regex", + "serde", + "serde_json", + "serde_yaml", + "siphasher", + "toml", + "triomphe", +] + [[package]] name = "rust-ini" version = "0.18.0" @@ -3156,6 +3334,28 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha1" version = "0.10.6" @@ -3344,6 +3544,12 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "static_assertions" version = "1.1.0" @@ -3581,6 +3787,8 @@ dependencies = [ "iced", "iced_font_awesome", "nix 0.30.1", + "rust-i18n", + "sys-locale", "test-case", "thiserror 2.0.17", "tiny4linux_assets", @@ -3619,6 +3827,27 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + [[package]] name = "toml_datetime" version = "0.7.3" @@ -3628,6 +3857,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + [[package]] name = "toml_edit" version = "0.23.7" @@ -3635,7 +3878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ "indexmap", - "toml_datetime", + "toml_datetime 0.7.3", "toml_parser", "winnow", ] @@ -3649,6 +3892,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tracing" version = "0.1.41" @@ -3681,6 +3930,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "triomphe" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" +dependencies = [ + "arc-swap", + "serde", + "stable_deref_trait", +] + [[package]] name = "ttf-parser" version = "0.20.0" @@ -3782,6 +4042,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index dfc33f1..b1e8c37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ cli = ["clap", "clap_complete", "dialoguer"] tiny4linux_assets = { git = "https://github.com/OpenFoxes/Tiny4Linux-Icons", rev = "57c10f204b75f1c61087fd9568814ee52d0ec036", optional = true } iced = { version = "0.13.0", features = ["image", "tokio"], optional = true } iced_font_awesome = { version = "0.3.0", optional = true } +rust-i18n = "3.1.5" nix = { version = "0.30.0", features = ["ioctl"] } bon = "3.8.1" errno = "0.3.14" @@ -29,6 +30,7 @@ glob = "0.3.3" enum_dispatch = "0.3.13" thiserror = "2.0.0" hexdump = "0.1.2" +sys-locale = "0.3.2" clap = { version = "4.4.18", features = ["derive"], optional = true } clap_complete = { version = "4.5.59", optional = true } dialoguer = { version = "0.12.0", features = ["fuzzy-select"], optional = true } diff --git a/README.md b/README.md index ede6a9e..09d26cc 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,14 @@ The UI is available in two variants: You can use the CLI by typing `t4l` or `tiny4linux-cli` in your terminal. To get the full list of available commands, type `t4l --help` or look into the [CLI documentation](docs/cli.md). +### Language Support + +The application supports multiple languages. +Per default, the language is automatically detected based on your system settings. +You can change the language by adding the flag `--lang ` to the CLI or GUI. +Currently, it is not possible to change the language in the GUI or to persist the setting across restarts, +but both features are planned for future releases. + ## Setup OBSBOT Center on Linux From my experience, it’s a good idea to have a Windows VM ready to run on Linux. diff --git a/src/cli/main.rs b/src/cli/main.rs index 354b34e..5fb96a0 100644 --- a/src/cli/main.rs +++ b/src/cli/main.rs @@ -3,9 +3,11 @@ use clap::{Parser, Subcommand}; use clap_complete::generate; use dialoguer::{FuzzySelect, Select}; -use tiny4linux::{AIMode, Camera, SleepMode, Tiny2Camera}; +use rust_i18n::{i18n, set_locale, t}; +use tiny4linux::{AIMode, Camera, SleepMode, Tiny2Camera, get_language}; + +i18n!("src/locales", fallback = "en"); -/// Simple program to greet a person #[derive(Parser)] #[command(name = "t4l", bin_name = "t4l", version, about, long_about = None, disable_version_flag = true)] struct Args { @@ -17,46 +19,42 @@ struct Args { #[derive(Subcommand)] enum Command { - /// Sets the camera to sleep + #[command(about = t!("cli.help.sleep"))] Sleep, - /// Wakes the camera up + #[command(about = t!("cli.help.wake"))] Wake, - /// Turns the camera on or off (alias for `sleep` and `wake`) - #[command(hide = true, subcommand_required = false)] + #[command(hide = true, subcommand_required = false, about = t!("cli.help.turn.command"))] Turn { #[command(subcommand)] action: Option, }, - /// Controls the AI-tracking-mode of the camera - #[command(alias = "track", subcommand_required = false)] + #[command(alias = "track", subcommand_required = false, about = t!("cli.help.tracking"))] Tracking { #[command(subcommand)] tracking_mode: Option, }, - /// Controls the tracking speed of the camera - #[command(alias = "tracking-speed", subcommand_required = false)] + #[command(alias = "tracking-speed", subcommand_required = false, about = t!("cli.help.speed"))] Speed { #[command(subcommand)] speed: Option, }, - /// Sets the camera to a specific preset position previously defined in OBSBOT Center - #[command(alias = "position", subcommand_required = false)] + #[command(alias = "position", subcommand_required = false, about = t!("cli.help.preset"))] Preset { position_id: Option }, - /// Controls the HDR-mode of the camera + #[command(about = t!("cli.help.hdr"))] Hdr { #[command(subcommand)] hdr_mode: Option, }, - /// Controls the exposure-mode of the camera + #[command(about = t!("cli.help.exposure"))] Exposure { #[command(subcommand)] exposure_mode: Option, }, - /// Displays information about the current state of the camera + #[command(about = t!("cli.help.info"))] Info, - /// Displays the version of the CLI-tool + #[command(about = t!("cli.help.version"))] Version, - /// Generates shell-completion scripts for the CLI-tool + #[command(about = t!("cli.help.completions"))] Completions { shell: clap_complete::Shell }, } @@ -100,12 +98,15 @@ enum ExposureArg { } fn main() { + let language = get_language(false); + set_locale(language.as_str()); + let args = Args::parse(); let mut camera = Camera::new("OBSBOT Tiny 2").ok(); if camera.is_none() { - println!("Camera could not be found. Please check the connection of the camera."); + println!("{}", t!("shared.errors.no_camera")); return; } @@ -128,18 +129,16 @@ fn main() { let info = camera.get_status(); if info.is_err() { - println!( - "Camera could not be found or gave a faulty info. Please check the connection of the camera." - ); + println!("{}", t!("cli.errors.info_error"),); return; } else { let info = info.unwrap(); - println!("Camera status:"); - println!(" 💤 Sleep Mode: {}", info.awake); - println!(" 🤖 AI Mode: {}", info.ai_mode); - println!(" 🏃 Tracking Speed: {}", info.speed); - println!(" 💐 HDR: {}", info.hdr_on); + println!("{}:", t!("shared.info.camera_status")); + println!(" 💤 {}: {}", t!("shared.info.sleep_mode"), info.awake); + println!(" 🤖 {}: {}", t!("shared.info.ai_mode"), info.ai_mode); + println!(" 🏃 {}: {}", t!("shared.info.tracking_speed"), info.speed); + println!(" 💐 {}: {}", t!("shared.info.hdr"), info.hdr_on); } } Command::Version => { @@ -161,38 +160,44 @@ struct SelectionOption<'a, T> { fn evaluate_sleep_arg(state: Option, camera: Camera) { match state { Some(OnOffArg::Off) => { - println!("Setting the camera to sleep"); + println!("{}", t!("cli.sleep.response_to_sleep")); camera.set_sleep_mode(SleepMode::Sleep).unwrap(); } Some(OnOffArg::On) => { - println!("Waking up the camera"); + println!("{}", t!("cli.sleep.response_to_awake")); camera.set_sleep_mode(SleepMode::Awake).unwrap(); } None => { + let option_on1 = t!("cli.sleep.option_on1"); + let option_off1 = t!("cli.sleep.option_off1"); + let option_on2 = t!("cli.sleep.option_on2"); + let option_off2 = t!("cli.sleep.option_off2"); + let option_off3 = t!("cli.sleep.option_off3"); + let options = [ SelectionOption { result: OnOffArg::On, - option: "awake", + option: &option_on1, }, SelectionOption { result: OnOffArg::Off, - option: "sleeping", + option: &option_off1, }, SelectionOption { result: OnOffArg::On, - option: "on", + option: &option_on2, }, SelectionOption { result: OnOffArg::Off, - option: "off", + option: &option_off2, }, SelectionOption { result: OnOffArg::Off, - option: "asleep", + option: &option_off3, }, ]; let selection = FuzzySelect::new() - .with_prompt("The camera should be") + .with_prompt(format!("{}", t!("cli.sleep.request_should_be"))) .default(0) .items( &options @@ -209,92 +214,104 @@ fn evaluate_sleep_arg(state: Option, camera: Camera) { } fn evaluate_tracking_arg(tracking_mode: Option, camera: Camera) { + let response_setting_to = t!("cli.tracking_mode.response_setting_to"); + let static_mode = t!("cli.tracking_mode.static"); + let normal = t!("cli.tracking_mode.normal"); + let close_up = t!("cli.tracking_mode.close_up"); + let upper_body = t!("cli.tracking_mode.upper_body"); + let headless = t!("cli.tracking_mode.headless"); + let lower_body = t!("cli.tracking_mode.lower_body"); + let desk = t!("cli.tracking_mode.desk"); + let whiteboard = t!("cli.tracking_mode.whiteboard"); + let hand = t!("cli.tracking_mode.hand"); + let group = t!("cli.tracking_mode.group"); + match tracking_mode { Some(TrackingArg::Static) => { - println!("Setting the camera to static (no tracking)"); + println!("{} {}", response_setting_to, static_mode); camera.set_ai_mode(AIMode::NoTracking).unwrap(); } Some(TrackingArg::Normal) => { - println!("Setting the camera to normal tracking"); + println!("{} {}", response_setting_to, normal); camera.set_ai_mode(AIMode::NormalTracking).unwrap(); } Some(TrackingArg::CloseUp) => { - println!("Setting the camera to close up tracking"); + println!("{} {}", response_setting_to, close_up); camera.set_ai_mode(AIMode::CloseUp).unwrap(); } Some(TrackingArg::UpperBody) => { - println!("Setting the camera to upper body tracking"); + println!("{} {}", response_setting_to, upper_body); camera.set_ai_mode(AIMode::UpperBody).unwrap(); } Some(TrackingArg::Headless) => { - println!("Setting the camera to headless tracking"); + println!("{} {}", response_setting_to, headless); camera.set_ai_mode(AIMode::Headless).unwrap(); } Some(TrackingArg::LowerBody) => { - println!("Setting the camera to lower body tracking"); + println!("{} {}", response_setting_to, lower_body); camera.set_ai_mode(AIMode::LowerBody).unwrap(); } Some(TrackingArg::Desk) => { - println!("Setting the camera to desk tracking"); + println!("{} {}", response_setting_to, desk); camera.set_ai_mode(AIMode::DeskMode).unwrap(); } Some(TrackingArg::Whiteboard) => { - println!("Setting the camera to whiteboard tracking"); + println!("{} {}", response_setting_to, whiteboard); camera.set_ai_mode(AIMode::Whiteboard).unwrap(); } Some(TrackingArg::Hand) => { - println!("Setting the camera to hand tracking"); + println!("{} {}", response_setting_to, hand); camera.set_ai_mode(AIMode::Hand).unwrap(); } Some(TrackingArg::Group) => { - println!("Setting the camera to group tracking"); + println!("{} {}", response_setting_to, group); camera.set_ai_mode(AIMode::Group).unwrap(); } None => { let options = [ SelectionOption { result: TrackingArg::Static, - option: "static (no tracking)", + option: &static_mode, }, SelectionOption { result: TrackingArg::Normal, - option: "normal tracking", + option: &normal, }, SelectionOption { result: TrackingArg::CloseUp, - option: "close up tracking", + option: &close_up, }, SelectionOption { result: TrackingArg::UpperBody, - option: "upper body tracking", + option: &upper_body, }, SelectionOption { result: TrackingArg::Headless, - option: "headless tracking", + option: &headless, }, SelectionOption { result: TrackingArg::LowerBody, - option: "lower body tracking", + option: &lower_body, }, SelectionOption { result: TrackingArg::Desk, - option: "desk", + option: &desk, }, SelectionOption { result: TrackingArg::Whiteboard, - option: "whiteboard", + option: &whiteboard, }, SelectionOption { result: TrackingArg::Hand, - option: "hand tracking", + option: &hand, }, SelectionOption { result: TrackingArg::Group, - option: "group tracking", + option: &group, }, ]; let selection = FuzzySelect::new() - .with_prompt("What tracking type should be set?") + .with_prompt(t!("cli.tracking_mode.request_should_be")) .default(0) .items( &options @@ -313,30 +330,33 @@ fn evaluate_tracking_arg(tracking_mode: Option, camera: Camera) { fn evaluate_speed_arg(speed: Option, camera: Camera) { match speed { Some(TrackingSpeedArg::Standard) => { - println!("Setting the camera to standard tracking speed"); + println!("{}", t!("cli.tracking_speed.response_to_standard")); camera .set_tracking_speed(tiny4linux::TrackingSpeed::Standard) .unwrap(); } Some(TrackingSpeedArg::Fast) => { - println!("Setting the camera to fast tracking speed"); + println!("{}", t!("cli.tracking_speed.response_to_fast")); camera .set_tracking_speed(tiny4linux::TrackingSpeed::Sport) .unwrap(); } None => { + let option_standard = t!("cli.tracking_speed.option_standard"); + let option_sport = t!("cli.tracking_speed.option_sport"); + let options = [ SelectionOption { result: TrackingSpeedArg::Standard, - option: "Standard (slower)", + option: &option_standard, }, SelectionOption { result: TrackingSpeedArg::Fast, - option: "Sport (fast)", + option: &option_sport, }, ]; let selection = FuzzySelect::new() - .with_prompt("Select the cameras tracking speed!") + .with_prompt(t!("cli.tracking_speed.request_should_be")) .default(0) .items( &options @@ -356,7 +376,7 @@ fn evaluate_preset_arg(position_id: Option, camera: Camera) { if position_id.is_none() { let options = [1, 2, 3]; let selection = Select::new() - .with_prompt("Select a predefined position preset!") + .with_prompt(t!("cli.preset_position.request_position_id")) .default(0) .items(options) .interact() @@ -365,12 +385,15 @@ fn evaluate_preset_arg(position_id: Option, camera: Camera) { return evaluate_preset_arg(Option::from(options[selection]), camera); } - println!("Stopping camera tracking"); + println!("{}", t!("cli.preset_position.stopping_tracking")); camera.set_ai_mode(AIMode::NoTracking).unwrap(); println!( - "Setting the camera to preset position {}", - position_id.unwrap() + "{}", + t!( + "cli.preset_position.response_to_position", + position_id = position_id.unwrap() + ), ); camera .goto_preset_position(position_id.unwrap() - 1) @@ -380,26 +403,29 @@ fn evaluate_preset_arg(position_id: Option, camera: Camera) { fn evaluate_hdr_arg(hdr_mode: Option, camera: Camera) { match hdr_mode { Some(OnOffArg::On) => { - println!("Enabling HDR"); + println!("{}", t!("cli.hdr.response_to_hdr_on")); camera.set_hdr_mode(true).unwrap(); } Some(OnOffArg::Off) => { - println!("Disabling HDR"); + println!("{}", t!("cli.hdr.response_to_hdr_off")); camera.set_hdr_mode(false).unwrap(); } None => { + let option_on = t!("shared.options.hdr.on"); + let option_off = t!("shared.options.hdr.off"); + let options = [ SelectionOption { result: OnOffArg::On, - option: "HDR on", + option: &option_on, }, SelectionOption { result: OnOffArg::Off, - option: "HDR off", + option: &option_off, }, ]; let selection = FuzzySelect::new() - .with_prompt("Select the HDR state!") + .with_prompt(t!("cli.hdr.request_should_be")) .default(0) .items( &options @@ -418,40 +444,44 @@ fn evaluate_hdr_arg(hdr_mode: Option, camera: Camera) { fn evaluate_exposure_arg(exposure_mode: Option, camera: Camera) { match exposure_mode { Some(ExposureArg::Manual) => { - println!("Setting the camera to manual exposure"); + println!("{}", t!("cli.exposure.response_to_manual")); camera .set_exposure_mode(tiny4linux::ExposureMode::Manual) .unwrap(); } Some(ExposureArg::Global) => { - println!("Setting the camera to global exposure"); + println!("{}", t!("cli.exposure.response_to_global")); camera .set_exposure_mode(tiny4linux::ExposureMode::Global) .unwrap(); } Some(ExposureArg::Face) => { - println!("Setting the camera to face exposure"); + println!("{}", t!("cli.exposure.response_to_face")); camera .set_exposure_mode(tiny4linux::ExposureMode::Face) .unwrap(); } None => { + let option_manual = t!("cli.exposure.option_manual"); + let option_global = t!("cli.exposure.option_global"); + let option_face = t!("cli.exposure.option_face"); + let options = [ SelectionOption { result: ExposureArg::Manual, - option: "Manual", + option: &option_manual, }, SelectionOption { result: ExposureArg::Global, - option: "Global", + option: &option_global, }, SelectionOption { result: ExposureArg::Face, - option: "Face", + option: &option_face, }, ]; let selection = FuzzySelect::new() - .with_prompt("Choose the exposure mode") + .with_prompt(t!("cli.exposure.request_should_be")) .default(0) .items( &options diff --git a/src/gui/main.rs b/src/gui/main.rs index 223df37..18a7594 100644 --- a/src/gui/main.rs +++ b/src/gui/main.rs @@ -10,8 +10,13 @@ use iced::widget::{Container, text}; use iced::window::Position; use iced::{Element, Point}; use iced::{Length, Size, Subscription, Task, time, window}; +use rust_i18n::{i18n, set_locale, t}; use std::time::Duration; -use tiny4linux::{AIMode, Camera, ExposureMode, SleepMode, Tiny2Camera, TrackingSpeed}; +use tiny4linux::{ + AIMode, Camera, ExposureMode, SleepMode, Tiny2Camera, TrackingSpeed, get_language, +}; + +i18n!("src/locales", fallback = "en"); #[derive(Debug, Clone, PartialEq)] enum Message { @@ -187,7 +192,7 @@ impl MainPanel { if self.camera.is_some() { get_current_ui_elements(self).into() } else { - text("Camera could not be found. Please check the connection of the camera.") + text(t!("shared.errors.no_camera")) .size(20) .align_x(Horizontal::Center) .align_y(Vertical::Center) @@ -215,7 +220,7 @@ enum WindowMode { fn get_size_for_window_mode(window_mode: WindowMode) -> Size { match window_mode { - WindowMode::Dashboard => Size::new(860.0, 720.0), // 43:36 + WindowMode::Dashboard => Size::new(860.0, 780.0), // 43:39 WindowMode::Widget => Size::new(300.0, 550.0), // 6:11 WindowMode::Invalid => Size::ZERO, } @@ -268,6 +273,9 @@ fn get_current_ui_elements(app: &MainPanel) -> Container<'static, Message> { } fn main() -> iced::Result { + let language = get_language(false); + set_locale(language.as_str()); + let start_mode = get_start_mode(); if start_mode == WindowMode::Invalid { diff --git a/src/gui/ui_modules/button_exposure_mode.rs b/src/gui/ui_modules/button_exposure_mode.rs index 9fd61c0..9bcbb16 100644 --- a/src/gui/ui_modules/button_exposure_mode.rs +++ b/src/gui/ui_modules/button_exposure_mode.rs @@ -5,6 +5,7 @@ use crate::styles::tooltip_style::tooltip_content; use iced::widget::button::secondary; use iced::widget::tooltip::Position; use iced::widget::{Container, button, container, text, tooltip}; +use rust_i18n::t; use tiny4linux::ExposureMode; pub fn button_exposure_mode(mode: ExposureMode) -> Container<'static, Message> { @@ -12,9 +13,9 @@ pub fn button_exposure_mode(mode: ExposureMode) -> Container<'static, Message> { button(text(format!("{}", mode))) .on_press(Message::ChangeExposure(mode)) .style(secondary), - tooltip_content(container(text(format!( - "Changes the exposure mode to {} exposure", - mode + tooltip_content(container(text(t!( + "gui.tooltips.changes_exposure", + mode = mode )))), Position::Bottom, )) diff --git a/src/gui/ui_modules/button_hdr.rs b/src/gui/ui_modules/button_hdr.rs index 4fc629b..49367f3 100644 --- a/src/gui/ui_modules/button_hdr.rs +++ b/src/gui/ui_modules/button_hdr.rs @@ -6,23 +6,28 @@ use iced::alignment::Vertical; use iced::widget::tooltip::Position; use iced::widget::{Container, button, container, row, text, tooltip}; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; pub fn button_hdr(current_mode: bool) -> Container<'static, Message> { container(tooltip( button( row![ fa_icon_solid(if current_mode { "palette" } else { "power-off" }), - text(if current_mode { "HDR on" } else { "HDR off" }) + text(if current_mode { + t!("shared.options.hdr.on") + } else { + t!("shared.options.hdr.off") + }) ] .align_y(Vertical::Center) .spacing(5), ) .on_press(Message::ChangeHDR(!current_mode)), - tooltip_content(container(if current_mode { - "Turns off HDR on click" + tooltip_content(container(text(if current_mode { + t!("gui.tooltips.hdr.turns_off") } else { - "Turns on HDR on click" - })), + t!("gui.tooltips.hdr.turns_on") + }))), Position::Bottom, )) } diff --git a/src/gui/ui_modules/button_sleep_wake.rs b/src/gui/ui_modules/button_sleep_wake.rs index a0188df..c364616 100644 --- a/src/gui/ui_modules/button_sleep_wake.rs +++ b/src/gui/ui_modules/button_sleep_wake.rs @@ -3,8 +3,9 @@ use crate::styles::tooltip_style::tooltip_content; use crate::{Message, WindowMode}; use iced::widget::tooltip::Position; -use iced::widget::{Container, button, container, row, tooltip}; +use iced::widget::{Container, button, container, row, text, tooltip}; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; use tiny4linux::SleepMode; pub fn button_sleep_wake( @@ -13,28 +14,28 @@ pub fn button_sleep_wake( ) -> Container<'static, Message> { let (text_element_text, icon, tooltip_text, message) = match sleep_mode { SleepMode::Awake => ( - "Set to Sleep", + t!("gui.buttons.sleep.set_sleep"), fa_icon_solid("moon"), - "Request the camera to go to sleep mode", + t!("gui.tooltips.sleep.request_to_sleep"), Message::ChangeSleeping(true), ), SleepMode::Sleep => ( - "Wake Up", + t!("gui.buttons.sleep.wake_up"), fa_icon_solid("sun"), - "Request the camera to wake up from sleep mode", + t!("gui.tooltips.sleep.request_to_wake"), Message::ChangeSleeping(false), ), SleepMode::Unknown => ( - "Sleep state unknown", + t!("gui.buttons.sleep.unknown"), fa_icon_solid("question"), - "The state can't be determined. Click the button to try setting the mode or check the connection to the camera.", + t!("gui.tooltips.sleep.request_to_sleep"), Message::ChangeSleeping(true), ), }; container(tooltip( - button(row![icon, text_element_text].spacing(5)).on_press(message), - tooltip_content(container(tooltip_text)), + button(row![icon, text(text_element_text)].spacing(5)).on_press(message), + tooltip_content(container(text(tooltip_text))), if window_mode == WindowMode::Widget { Position::Bottom } else { diff --git a/src/gui/ui_modules/button_tracking_mode.rs b/src/gui/ui_modules/button_tracking_mode.rs index 650960e..5ff0f69 100644 --- a/src/gui/ui_modules/button_tracking_mode.rs +++ b/src/gui/ui_modules/button_tracking_mode.rs @@ -5,6 +5,7 @@ use crate::styles::tooltip_style::tooltip_content; use iced::widget::button::{primary, secondary}; use iced::widget::tooltip::Position; use iced::widget::{Container, button, container, text, tooltip}; +use rust_i18n::t; use tiny4linux::{AIMode, TrackingSpeed}; pub fn button_tracking_mode(mode: AIMode, current_mode: AIMode) -> Container<'static, Message> { @@ -16,9 +17,9 @@ pub fn button_tracking_mode(mode: AIMode, current_mode: AIMode) -> Container<'st } else { secondary }), - tooltip_content(container(text(format!( - "Set the camera to {} tracking mode", - mode.to_string() + tooltip_content(container(text(t!( + "gui.tooltips.sets_tracking_mode", + mode = mode.to_string() )))), Position::Bottom, )) @@ -36,9 +37,9 @@ pub fn button_tracking_speed( } else { secondary }), - tooltip_content(container(text(format!( - "Set the camera's speed to {}", - speed.to_string() + tooltip_content(container(text(t!( + "gui.tooltips.sets_tracking_speed", + speed = speed.to_string() )))), Position::Bottom, )) diff --git a/src/gui/ui_modules/button_window_mode_change.rs b/src/gui/ui_modules/button_window_mode_change.rs index 78a2914..3ffbd73 100644 --- a/src/gui/ui_modules/button_window_mode_change.rs +++ b/src/gui/ui_modules/button_window_mode_change.rs @@ -3,21 +3,22 @@ use crate::styles::tooltip_style::tooltip_content; use crate::{Message, WindowMode}; use iced::widget::tooltip::Position; -use iced::widget::{Container, Space, button, container, tooltip}; +use iced::widget::{Container, Space, button, container, text, tooltip}; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; pub fn button_window_mode_change(window_mode: WindowMode) -> Container<'static, Message> { match window_mode { WindowMode::Dashboard => container(tooltip( button(fa_icon_solid("down-left-and-up-right-to-center")) .on_press(Message::RequestWindowModeChange(WindowMode::Widget)), - tooltip_content(container("Switch to Widget-Mode")), + tooltip_content(container(text(t!("gui.tooltips.window_mode.widget")))), Position::Bottom, )), WindowMode::Widget => container(tooltip( button(fa_icon_solid("up-right-and-down-left-from-center")) .on_press(Message::RequestWindowModeChange(WindowMode::Dashboard)), - tooltip_content(container("Switch to Dashboard-Mode")), + tooltip_content(container(text(t!("gui.tooltips.window_mode.dashboard")))), Position::Bottom, )), WindowMode::Invalid => container(Space::new(0, 0)), diff --git a/src/gui/ui_modules/current_stats.rs b/src/gui/ui_modules/current_stats.rs index 652f2ae..d4a26b2 100644 --- a/src/gui/ui_modules/current_stats.rs +++ b/src/gui/ui_modules/current_stats.rs @@ -4,6 +4,7 @@ use crate::{MainPanel, Message}; use iced::alignment::Horizontal; use iced::widget::{Container, column, container, horizontal_rule, row, text}; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; use tiny4linux::{AIMode, SleepMode, TrackingSpeed}; const TEXT_INDENT: &str = " "; @@ -12,62 +13,110 @@ const TEXT_INDENT_LONG: &str = " "; pub fn current_stats(app: &MainPanel) -> Container<'static, Message> { container( column![ - text("Camera status:"), + text(format!("{}:", t!("shared.info.camera_status"))), column![ row![ text(TEXT_INDENT), fa_icon_solid("moon"), - text("Sleep Mode:") + text(format!("{}:", t!("shared.info.sleep_mode"))) ] .spacing(10), row![ text(TEXT_INDENT_LONG), match app.awake { - SleepMode::Awake => row![fa_icon_solid("eye"), text("Awake")].spacing(10), - SleepMode::Sleep => - row![fa_icon_solid("eye-slash"), text("Sleeping")].spacing(10), - SleepMode::Unknown => - row![fa_icon_solid("question-circle"), text("Unknown")].spacing(10), + SleepMode::Awake => + row![fa_icon_solid("eye"), text(t!("display.sleep_mode.awake"))] + .spacing(10), + SleepMode::Sleep => row![ + fa_icon_solid("eye-slash"), + text(t!("display.sleep_mode.sleep")) + ] + .spacing(10), + SleepMode::Unknown => row![ + fa_icon_solid("question-circle"), + text(t!("display.sleep_mode.unknown")) + ] + .spacing(10), } ] .spacing(10), horizontal_rule(1), - row![text(TEXT_INDENT), fa_icon_solid("robot"), text("AI Mode:"),].spacing(10), + row![ + text(TEXT_INDENT), + fa_icon_solid("robot"), + text(format!("{}:", t!("shared.info.ai_mode"))), + ] + .spacing(10), row![ text(TEXT_INDENT_LONG), match app.tracking { AIMode::NoTracking => { - row![fa_icon_solid("tape"), text("Static")].spacing(10) + row![fa_icon_solid("tape"), text(t!("display.ai_mode.static"))] + .spacing(10) } AIMode::NormalTracking => { - row![fa_icon_solid("user"), text("Normal")].spacing(10) + row![ + fa_icon_solid("user"), + text(t!("display.ai_mode.normal_short")) + ] + .spacing(10) } AIMode::UpperBody => { - row![fa_icon_solid("user-plus"), text("Upper Body")].spacing(10) + row![ + fa_icon_solid("user-plus"), + text(t!("display.ai_mode.upper_body")) + ] + .spacing(10) } AIMode::CloseUp => { - row![fa_icon_solid("face-smile"), text("Close Up")].spacing(10) + row![ + fa_icon_solid("face-smile"), + text(t!("display.ai_mode.close_up")) + ] + .spacing(10) } AIMode::Headless => { - row![fa_icon_solid("circle-xmark"), text("Headless Body")].spacing(10) + row![ + fa_icon_solid("circle-xmark"), + text(t!("display.ai_mode.headless")) + ] + .spacing(10) } AIMode::LowerBody => { - row![fa_icon_solid("down-long"), text("Lower Body")].spacing(10) + row![ + fa_icon_solid("down-long"), + text(t!("display.ai_mode.lower_body")) + ] + .spacing(10) } AIMode::DeskMode => { - row![fa_icon_solid("stapler"), text("Desk")].spacing(10) + row![fa_icon_solid("stapler"), text(t!("display.ai_mode.desk"))] + .spacing(10) } AIMode::Whiteboard => { - row![fa_icon_solid("chalkboard"), text("Whiteboard")].spacing(10) + row![ + fa_icon_solid("chalkboard"), + text(t!("display.ai_mode.whiteboard")) + ] + .spacing(10) } AIMode::Hand => { - row![fa_icon_solid("hand"), text("Hand Tracking")].spacing(10) + row![fa_icon_solid("hand"), text(t!("display.ai_mode.hand"))] + .spacing(10) } AIMode::Group => { - row![fa_icon_solid("users-viewfinder"), text("Group")].spacing(10) + row![ + fa_icon_solid("users-viewfinder"), + text(t!("display.ai_mode.group")) + ] + .spacing(10) } AIMode::Unknown => { - row![fa_icon_solid("question-circle"), text("Unknown")].spacing(10) + row![ + fa_icon_solid("question-circle"), + text(t!("display.ai_mode.unknown")) + ] + .spacing(10) } } ] @@ -76,27 +125,39 @@ pub fn current_stats(app: &MainPanel) -> Container<'static, Message> { row![ text(TEXT_INDENT), fa_icon_solid("gauge"), - text("Tracking Speed:"), + text(format!("{}:", t!("shared.info.tracking_speed"))), ] .spacing(10), row![ text(TEXT_INDENT_LONG), match app.tracking_speed { - TrackingSpeed::Standard => - row![fa_icon_solid("gauge-simple"), text("Standard")].spacing(10), - TrackingSpeed::Sport => - row![fa_icon_solid("gauge-simple-high"), text("Sport")].spacing(10), + TrackingSpeed::Standard => row![ + fa_icon_solid("gauge-simple"), + text(t!("display.tracking_speed.standard")) + ] + .spacing(10), + TrackingSpeed::Sport => row![ + fa_icon_solid("gauge-simple-high"), + text(t!("display.tracking_speed.sport")) + ] + .spacing(10), } ] .spacing(10), horizontal_rule(1), - row![text(TEXT_INDENT), fa_icon_solid("palette"), text("HDR:"),].spacing(10), + row![ + text(TEXT_INDENT), + fa_icon_solid("palette"), + text(format!("{}:", t!("shared.info.hdr"))), + ] + .spacing(10), row![ text(TEXT_INDENT_LONG), if app.hdr_on { - row![fa_icon_solid("toggle-on"), text("On")].spacing(10) + row![fa_icon_solid("toggle-on"), text(t!("display.states.on"))].spacing(10) } else { - row![fa_icon_solid("toggle-off"), text("Off")].spacing(10) + row![fa_icon_solid("toggle-off"), text(t!("display.states.off"))] + .spacing(10) } ] .spacing(10), @@ -104,7 +165,7 @@ pub fn current_stats(app: &MainPanel) -> Container<'static, Message> { row![ text(TEXT_INDENT), fa_icon_solid("code-commit"), - text("T4L-Version:"), + text(format!("{}:", t!("shared.info.t4l_version"))), ] .spacing(10), row![text(TEXT_INDENT_LONG), text(env!("CARGO_PKG_VERSION"))].spacing(10) diff --git a/src/gui/ui_modules/debug_area.rs b/src/gui/ui_modules/debug_area.rs index 69be39c..5129f7b 100644 --- a/src/gui/ui_modules/debug_area.rs +++ b/src/gui/ui_modules/debug_area.rs @@ -7,6 +7,7 @@ use iced::alignment::Horizontal; use iced::widget::button::{primary, secondary}; use iced::widget::{Container, button, column, container, horizontal_space, row, text, text_input}; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; const DEBUG_BUTTON_WIDTH: f32 = 100.0; const DEBUG_INPUT_WIDTH: f32 = 250.0; @@ -17,40 +18,58 @@ pub fn debug_area(app: &MainPanel) -> Container<'static, Message> { container( column![ button(if debugging_active { - row![fa_icon_solid("bug"), text("Turn off debugging")].spacing(5) + row![ + fa_icon_solid("bug"), + text(t!("gui.buttons.debugging.turn_off")) + ] + .spacing(5) } else { - row![fa_icon_solid("bug-slash"), text("Turn on debugging")].spacing(5) + row![ + fa_icon_solid("bug-slash"), + text(t!("gui.buttons.debugging.turn_on")) + ] + .spacing(5) }) .on_press(Message::ChangeDebugging(!debugging_active)) .style(if debugging_active { primary } else { secondary }), if debugging_active { column![ row![ - row![fa_icon_solid("paper-plane"), text("Send")].spacing(5), + row![ + fa_icon_solid("paper-plane"), + text(t!("gui.text.debugging.send")) + ] + .spacing(5), horizontal_space(), column![ row![ - text_input("0x06 hex string", &app.text_input) - .on_input(Message::TextInput) - .on_submit(Message::SendCommand) - .width(DEBUG_INPUT_WIDTH), - button("Send 0x06") + text_input( + t!("gui.text.debugging.0x06_hex_string").as_ref(), + &app.text_input + ) + .on_input(Message::TextInput) + .on_submit(Message::SendCommand) + .width(DEBUG_INPUT_WIDTH), + button(text(t!("gui.text.debugging.send_x", to_send = "0x06"))) .on_press(Message::SendCommand) .width(DEBUG_BUTTON_WIDTH), - button("Clear") + button(text(t!("gui.text.debugging.clear_x", to_clear = "0x06"))) .on_press(Message::TextInput("".parse().unwrap())) .width(DEBUG_BUTTON_WIDTH) ] .spacing(15), row![ - text_input("0x02 hex string", &app.text_input_02) - .on_input(Message::TextInput02) - .on_submit(Message::SendCommand02) - .width(DEBUG_INPUT_WIDTH), - button("Send 0x02") + text_input( + t!("gui.text.debugging.0x02_hex_string").as_ref(), + &app.text_input_02 + ) + .on_input(Message::TextInput02) + .on_submit(Message::SendCommand02) + .width(DEBUG_INPUT_WIDTH), + button(text(t!("gui.text.debugging.send_x", to_send = "0x02"))) .on_press(Message::SendCommand02) .width(DEBUG_BUTTON_WIDTH), - button("Clear") + button(text(t!("gui.text.debugging.clear_x", to_clear = "0x02"))) .on_press(Message::TextInput02("".parse().unwrap())) .width(DEBUG_BUTTON_WIDTH) ] @@ -59,7 +78,11 @@ pub fn debug_area(app: &MainPanel) -> Container<'static, Message> { .spacing(15), ], row![ - row![fa_icon_solid("satellite-dish"), text("Get & Dump")].spacing(5), + row![ + fa_icon_solid("satellite-dish"), + text(t!("gui.text.debugging.get_and_dump")) + ] + .spacing(5), horizontal_space(), button("0x06 hex") .width(DEBUG_BUTTON_WIDTH) diff --git a/src/gui/ui_modules/settings_area.rs b/src/gui/ui_modules/settings_area.rs index 5349f3d..d67689f 100644 --- a/src/gui/ui_modules/settings_area.rs +++ b/src/gui/ui_modules/settings_area.rs @@ -13,6 +13,7 @@ use iced::widget::{ tooltip, }; use iced_font_awesome::fa_icon_solid; +use rust_i18n::t; use tiny4linux::{AIMode, ExposureMode, TrackingSpeed}; pub fn settings_area(app: &MainPanel) -> Container<'static, Message> { @@ -23,7 +24,9 @@ pub fn settings_area(app: &MainPanel) -> Container<'static, Message> { tracking_modes(app.window_mode == WindowMode::Widget, app.tracking), tracking_speed(app.tracking_speed), horizontal_rule(8), - row![hdr(app.hdr_on), horizontal_space(), exposure_mode()].align_y(Vertical::Center), + row![hdr(app.hdr_on), exposure_mode()] + .spacing(10) + .align_y(Vertical::Center), ] .spacing(20), ) @@ -32,16 +35,16 @@ pub fn settings_area(app: &MainPanel) -> Container<'static, Message> { fn presets() -> Row<'static, Message> { row![ - text("Presets:"), + text(format!("{}:", t!("shared.info.presets"))), horizontal_space().width(Length::FillPortion(2)), (0..=2) .fold(row![], |r, n| { let r = r.push(tooltip( button(fa_icon_solid(&(n + 1).to_string())) .on_press(Message::ChangePresetPosition(n)), - tooltip_content(container(text(format!( - "Sets the cameras position to preset {}", - n + 1 + tooltip_content(container(text(t!( + "gui.tooltips.preset", + preset_number = n + 1 )))), Position::Bottom, )); @@ -55,7 +58,7 @@ fn presets() -> Row<'static, Message> { fn tracking_modes(reduced: bool, current_mode: AIMode) -> Container<'static, Message> { container( column![ - text("Tracking:"), + text(format!("{}:", t!("shared.info.tracking"))), if reduced { column![ row![ @@ -107,7 +110,7 @@ fn tracking_modes(reduced: bool, current_mode: AIMode) -> Container<'static, Mes fn tracking_speed(current_speed: TrackingSpeed) -> Container<'static, Message> { container( column![ - text("Tracking Speed:"), + text(format!("{}:", t!("shared.info.tracking_speed"))), column![ row![ button_tracking_speed(TrackingSpeed::Standard, current_speed), @@ -125,17 +128,20 @@ fn tracking_speed(current_speed: TrackingSpeed) -> Container<'static, Message> { fn hdr(current_mode: bool) -> Container<'static, Message> { container( - column![text("HDR:"), button_hdr(current_mode)] - .spacing(5) - .align_x(Horizontal::Center) - .width(Length::Fill), + column![ + text(format!("{}:", t!("shared.info.hdr"))), + button_hdr(current_mode) + ] + .spacing(5) + .align_x(Horizontal::Center) + .width(Length::Fill), ) } fn exposure_mode() -> Container<'static, Message> { container( column![ - text("Exposure:"), + text(format!("{}:", t!("shared.info.exposure"))), button_exposure_mode(ExposureMode::Manual), button_exposure_mode(ExposureMode::Global), button_exposure_mode(ExposureMode::Face), diff --git a/src/gui/ui_modules/window_layout.rs b/src/gui/ui_modules/window_layout.rs index 5c8f00e..7cf9bf1 100644 --- a/src/gui/ui_modules/window_layout.rs +++ b/src/gui/ui_modules/window_layout.rs @@ -14,6 +14,7 @@ use iced::widget::{ row, text, }; use iced::{Alignment, FillPortion, Length}; +use rust_i18n::t; use tiny4linux::SleepMode; use tiny4linux_assets::handle_t4l_asset; @@ -49,9 +50,9 @@ fn dashboard_general_area(app: &MainPanel) -> Container<'static, Message> { .align_y(Alignment::Center) .spacing(15), text(match app.awake { - SleepMode::Awake => "The camera is awake", - SleepMode::Sleep => "The camera is sleeping", - SleepMode::Unknown => "The camera state is unknown", + SleepMode::Awake => t!("gui.sleep.is_awake"), + SleepMode::Sleep => t!("gui.sleep.is_sleeping"), + SleepMode::Unknown => t!("gui.sleep.unknown"), }), button(image(if app.awake == SleepMode::Awake { handle_t4l_asset("generated/png/icons/inverted-camera.png") diff --git a/src/libs/camera/enums.rs b/src/libs/camera/enums.rs index 0ee4e87..4af36fe 100644 --- a/src/libs/camera/enums.rs +++ b/src/libs/camera/enums.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: EUPL-1.2 +use rust_i18n::t; use std::fmt::Display; #[derive(Debug, Clone, Copy, PartialEq)] @@ -12,9 +13,9 @@ pub enum SleepMode { impl Display for SleepMode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - SleepMode::Awake => write!(f, "Awake"), - SleepMode::Sleep => write!(f, "Sleeping"), - SleepMode::Unknown => write!(f, "Unknown"), + SleepMode::Awake => write!(f, "{}", t!("display.sleep_mode.awake")), + SleepMode::Sleep => write!(f, "{}", t!("display.sleep_mode.sleep")), + SleepMode::Unknown => write!(f, "{}", t!("display.sleep_mode.unknown")), } } } @@ -37,17 +38,17 @@ pub enum AIMode { impl Display for AIMode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AIMode::NoTracking => write!(f, "Static"), - AIMode::NormalTracking => write!(f, "Normal Tracking"), - AIMode::UpperBody => write!(f, "Upper Body"), - AIMode::CloseUp => write!(f, "Close-up"), - AIMode::Headless => write!(f, "Headless"), - AIMode::LowerBody => write!(f, "Lower Body"), - AIMode::DeskMode => write!(f, "Desk Mode"), - AIMode::Whiteboard => write!(f, "Whiteboard"), - AIMode::Hand => write!(f, "Hand"), - AIMode::Group => write!(f, "Group"), - AIMode::Unknown => write!(f, "Unknown"), + AIMode::NoTracking => write!(f, "{}", t!("display.ai_mode.static")), + AIMode::NormalTracking => write!(f, "{}", t!("display.ai_mode.normal")), + AIMode::UpperBody => write!(f, "{}", t!("display.ai_mode.upper_body")), + AIMode::CloseUp => write!(f, "{}", t!("display.ai_mode.close_up")), + AIMode::Headless => write!(f, "{}", t!("display.ai_mode.headless")), + AIMode::LowerBody => write!(f, "{}", t!("display.ai_mode.lower_body")), + AIMode::DeskMode => write!(f, "{}", t!("display.ai_mode.desk")), + AIMode::Whiteboard => write!(f, "{}", t!("display.ai_mode.whiteboard")), + AIMode::Hand => write!(f, "{}", t!("display.ai_mode.hand")), + AIMode::Group => write!(f, "{}", t!("display.ai_mode.group")), + AIMode::Unknown => write!(f, "{}", t!("display.ai_mode.unknown")), } } } @@ -61,8 +62,8 @@ pub enum TrackingSpeed { impl Display for TrackingSpeed { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - TrackingSpeed::Standard => write!(f, "Standard"), - TrackingSpeed::Sport => write!(f, "Sport"), + TrackingSpeed::Standard => write!(f, "{}", t!("display.tracking_speed.standard")), + TrackingSpeed::Sport => write!(f, "{}", t!("display.tracking_speed.sport")), } } } @@ -77,9 +78,9 @@ pub enum ExposureMode { impl Display for ExposureMode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ExposureMode::Manual => write!(f, "Manual"), - ExposureMode::Global => write!(f, "Global"), - ExposureMode::Face => write!(f, "Face"), + ExposureMode::Manual => write!(f, "{}", t!("display.exposure_mode.manual")), + ExposureMode::Global => write!(f, "{}", t!("display.exposure_mode.global")), + ExposureMode::Face => write!(f, "{}", t!("display.exposure_mode.face")), } } } diff --git a/src/libs/i18n.rs b/src/libs/i18n.rs new file mode 100644 index 0000000..4b56de8 --- /dev/null +++ b/src/libs/i18n.rs @@ -0,0 +1,20 @@ +use sys_locale::get_locale; + +pub fn get_language(debugging: bool) -> String { + let args: Vec = std::env::args().collect(); + + if let Some(language_flag_pos) = args.iter().position(|a| a == ("--lang")) { + if let Some(language_arg) = args.get(language_flag_pos + 1) { + if debugging { + println!("Trying to use flagged language {:?}", language_arg); + } + return language_arg.clone(); + } + } + + let system_lang = get_locale().unwrap_or("en".to_string()); + if debugging { + println!("Trying to use systems language {:?}", system_lang); + } + system_lang +} diff --git a/src/libs/mod.rs b/src/libs/mod.rs index 27efa74..4ef3744 100644 --- a/src/libs/mod.rs +++ b/src/libs/mod.rs @@ -1,7 +1,12 @@ // SPDX-License-Identifier: EUPL-1.2 +use rust_i18n::i18n; +i18n!("src/locales", fallback = "en"); mod camera; mod errors; + +mod i18n; mod usbio; pub use camera::*; +pub use i18n::*; diff --git a/src/locales/ar.json b/src/locales/ar.json new file mode 100644 index 0000000..c581d94 --- /dev/null +++ b/src/locales/ar.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "لم يتم العثور على كاميرا. يرجى التحقق من اتصال الكاميرا." + }, + "options": { + "hdr": { + "on": "HDR تشغيل", + "off": "HDR إيقاف" + } + }, + "info": { + "ai_mode": "وضع الذكاء الاصطناعي", + "camera_status": "حالة الكاميرا", + "exposure": "التعريض", + "hdr": "HDR", + "presets": "الإعدادات المسبقة", + "sleep_mode": "وضع السكون", + "tracking": "التتبع", + "tracking_speed": "سرعة التتبع", + "t4l_version": "إصدار T4L" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "وضع السكون", + "wake_up": "إيقاظ", + "unknown": "حالة السكون غير معروفة" + }, + "debugging": { + "turn_on": "تشغيل وضع التصحيح", + "turn_off": "إيقاف وضع التصحيح" + } + }, + "sleep": { + "is_awake": "الكاميرا مستيقظة", + "is_sleeping": "الكاميرا في وضع السكون", + "unknown": "حالة الكاميرا غير معروفة" + }, + "text": { + "debugging": { + "send": "إرسال", + "get_and_dump": "جلب وعرض", + "send_x": "إرسال %{to_send}", + "clear_x": "مسح %{to_clear}", + "0x02_hex_string": "0x02 سلسلة hex", + "0x06_hex_string": "0x06 سلسلة hex" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "طلب وضع الكاميرا في وضع السكون", + "request_to_wake": "طلب إيقاظ الكاميرا من وضع السكون", + "state_unknown": "لا يمكن تحديد الحالة. انقر لمحاولة التعيين أو تحقق من الاتصال." + }, + "sets_tracking_mode": "يضبط وضع التتبع إلى \"%{mode}\"", + "sets_tracking_speed": "يضبط سرعة التتبع إلى %{speed}", + "changes_exposure": "يغيّر وضع التعريض إلى %{mode}", + "hdr": { + "turns_on": "تشغيل HDR عند النقر", + "turns_off": "إيقاف HDR عند النقر" + }, + "preset": "يضبط موضع الكاميرا على الإعداد المسبق %{preset_number}", + "window_mode": { + "widget": "التحويل إلى وضع الويدجت", + "dashboard": "التحويل إلى وضع لوحة التحكم" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "يتم وضع الكاميرا في وضع السكون", + "response_to_awake": "يتم إيقاظ الكاميرا", + "request_should_be": "يجب أن تكون الكاميرا", + "option_on1": "مستيقظة", + "option_on2": "قيد التشغيل", + "option_off1": "نائمة", + "option_off2": "متوقفة", + "option_off3": "في وضع السكون" + }, + "tracking_mode": { + "response_setting_to": "تعيين الكاميرا إلى", + "request_should_be": "ما نوع التتبع المطلوب؟", + "static": "ثابت (بدون تتبع)", + "normal": "تتبع عادي", + "close_up": "تتبع قريب", + "upper_body": "تتبع الجزء العلوي", + "headless": "تتبع بدون رأس", + "lower_body": "تتبع الجزء السفلي", + "desk": "تتبع المكتب", + "whiteboard": "تتبع السبورة", + "hand": "تتبع اليد", + "group": "تتبع المجموعة" + }, + "tracking_speed": { + "response_to_standard": "تعيين سرعة التتبع القياسية", + "response_to_fast": "تعيين سرعة التتبع السريعة", + "request_should_be": "اختر سرعة التتبع!", + "option_standard": "قياسي (أبطأ)", + "option_sport": "سريع (رياضي)" + }, + "preset_position": { + "response_to_position": "تعيين الكاميرا إلى الإعداد المسبق %{position_id}", + "request_position_id": "اختر إعدادًا مسبقًا!", + "stopping_tracking": "إيقاف التتبع قبل تغيير الإعداد المسبق" + }, + "hdr": { + "response_to_hdr_on": "تفعيل HDR", + "response_to_hdr_off": "إيقاف HDR", + "request_should_be": "اختر حالة HDR!", + "option_on": "HDR تشغيل", + "option_off": "HDR إيقاف" + }, + "exposure": { + "response_to_manual": "تغيير التعريض إلى يدوي", + "response_to_global": "تغيير التعريض إلى شامل", + "response_to_face": "تغيير التعريض إلى الوجه", + "request_should_be": "اختر وضع التعريض!", + "option_manual": "يدوي", + "option_global": "شامل", + "option_face": "الوجه" + }, + "errors": { + "info_error": "تعذر العثور على الكاميرا أو أعادت معلومات غير صحيحة. يرجى التحقق من الاتصال." + }, + "help": { + "sleep": "يضع الكاميرا في وضع السكون", + "wake": "يوقظ الكاميرا", + "turn": "يشغّل أو يوقف الكاميرا", + "tracking": "يتحكم في وضع التتبع", + "speed": "يتحكم في سرعة التتبع", + "preset": "يضبط على إعداد مسبق محدد", + "hdr": "يتحكم في وضع HDR", + "exposure": "يتحكم في وضع التعريض", + "info": "يعرض حالة الكاميرا", + "version": "يعرض إصدار أداة CLI", + "completions": "ينشئ سكربتات الإكمال التلقائي" + } + }, + "display": { + "sleep_mode": { + "awake": "مستيقظة", + "sleep": "نائمة", + "unknown": "غير معروف" + }, + "ai_mode": { + "static": "ثابت", + "normal": "تتبع عادي", + "normal_short": "عادي", + "upper_body": "الجزء العلوي", + "close_up": "قريب", + "headless": "بدون رأس", + "lower_body": "الجزء السفلي", + "desk": "وضع المكتب", + "whiteboard": "السبورة", + "hand": "اليد", + "group": "المجموعة", + "unknown": "غير معروف" + }, + "tracking_speed": { + "standard": "قياسي", + "sport": "رياضي" + }, + "exposure_mode": { + "manual": "يدوي", + "global": "شامل", + "face": "الوجه" + }, + "states": { + "on": "تشغيل", + "off": "إيقاف" + } + }, + "errors": { + "unsupported_int_value": "القيمة {1} غير مدعومة لـ {0}" + } +} diff --git a/src/locales/de.json b/src/locales/de.json new file mode 100644 index 0000000..f7738cd --- /dev/null +++ b/src/locales/de.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "Keine Kamera gefunden. Bitte überprüfen Sie die Verbindung der Kamera." + }, + "options": { + "hdr": { + "on": "HDR ein", + "off": "HDR aus" + } + }, + "info": { + "ai_mode": "KI-Modus", + "camera_status": "Kamerastatus", + "exposure": "Belichtung", + "hdr": "HDR", + "presets": "Presets", + "sleep_mode": "Schlafmodus", + "tracking": "Tracking", + "tracking_speed": "Tempo", + "t4l_version": "T4L-Version" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Schlafen legen", + "wake_up": "Aufwecken", + "unknown": "Schlafzustand unbekannt" + }, + "debugging": { + "turn_on": "Debugging einschalten", + "turn_off": "Debugging ausschalten" + } + }, + "sleep": { + "is_awake": "Die Kamera ist wach", + "is_sleeping": "Die Kamera schläft", + "unknown": "Der Kamerazustand ist unbekannt" + }, + "text": { + "debugging": { + "send": "Senden", + "get_and_dump": "Abrufen & Ausgeben", + "send_x": "Sende %{to_send}", + "clear_x": "Lösche %{to_clear}", + "0x02_hex_string": "0x02-Hex-String", + "0x06_hex_string": "0x06-Hex-String" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Die Kamera in den Schlafmodus versetzen", + "request_to_wake": "Die Kamera aus dem Schlafmodus aufwecken", + "state_unknown": "Der Zustand kann nicht bestimmt werden. Klicken Sie den Button, um einen Modus zu setzen, oder überprüfen Sie die Verbindung zur Kamera." + }, + "sets_tracking_mode": "Setzt die Kamera auf Tracking-Modus „%{mode}“", + "sets_tracking_speed": "Setzt die Tracking-Geschwindigkeit der Kamera auf %{speed}", + "changes_exposure": "Ändert den Belichtungsmodus auf %{mode}", + "hdr": { + "turns_on": "Aktiviert HDR beim Klicken", + "turns_off": "Deaktiviert HDR beim Klicken" + }, + "preset": "Setzt die Kameraposition auf Preset %{preset_number}", + "window_mode": { + "widget": "In den Widget-Modus wechseln", + "dashboard": "In den Dashboard-Modus wechseln" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Versetze die Kamera in den Schlafmodus", + "response_to_awake": "Wecke die Kamera auf", + "request_should_be": "Die Kamera sollte", + "option_on1": "wach sein", + "option_on2": "an sein", + "option_off1": "schlafen", + "option_off2": "aus sein", + "option_off3": "im Schlafmodus sein" + }, + "tracking_mode": { + "response_setting_to": "Setze die Kamera auf", + "request_should_be": "Welcher Tracking-Typ soll gesetzt werden?", + "static": "statisch (kein Tracking)", + "normal": "normales Tracking", + "close_up": "Nahaufnahme-Tracking", + "upper_body": "Oberkörper-Tracking", + "headless": "Headless-Tracking", + "lower_body": "Unterkörper-Tracking", + "desk": "Schreibtisch-Tracking", + "whiteboard": "Whiteboard-Tracking", + "hand": "Hand-Tracking", + "group": "Gruppen-Tracking" + }, + "tracking_speed": { + "response_to_standard": "Setze die Kamera auf die standard Tracking-Geschwindigkeit", + "response_to_fast": "Setze die Kamera auf die schnelle Tracking-Geschwindigkeit", + "request_should_be": "Wählen Sie die Tracking-Geschwindigkeit der Kamera!", + "option_standard": "Standard (langsamer)", + "option_sport": "Sport (schnell)" + }, + "preset_position": { + "response_to_position": "Setze die Kamera auf die Preset-Position %{position_id}", + "request_position_id": "Wählen Sie eine vordefinierte Preset-Position!", + "stopping_tracking": "Das Tracking wird gestoppt, bevor die Kamera auf eine Preset-Position gesetzt wird" + }, + "hdr": { + "response_to_hdr_on": "Aktiviere HDR", + "response_to_hdr_off": "Deaktiviere HDR", + "request_should_be": "Wählen Sie den HDR-Zustand!", + "option_on": "HDR ein", + "option_off": "HDR aus" + }, + "exposure": { + "response_to_manual": "Setze Belichtungsmodus auf manuell", + "response_to_global": "Setze Belichtungsmodus auf global", + "response_to_face": "Setze Belichtungsmodus auf Gesicht", + "request_should_be": "Wählen Sie den Belichtungsmodus!", + "option_manual": "Manuell", + "option_global": "Global", + "option_face": "Gesicht" + }, + "errors": { + "info_error": "Die Kamera konnte nicht gefunden werden oder lieferte fehlerhafte Informationen. Bitte überprüfen Sie die Verbindung der Kamera." + }, + "help": { + "sleep": "Versetzt die Kamera in den Schlafmodus", + "wake": "Weckt die Kamera auf", + "turn": "Schaltet die Kamera ein oder aus (Alias für `sleep` und `wake`)", + "tracking": "Steuert den KI-Tracking-Modus der Kamera", + "speed": "Steuert die Tracking-Geschwindigkeit der Kamera", + "preset": "Setzt die Kamera auf eine zuvor im OBSBOT Center definierte Preset-Position", + "hdr": "Steuert den HDR-Modus der Kamera", + "exposure": "Steuert den Belichtungsmodus der Kamera", + "info": "Zeigt Informationen über den aktuellen Zustand der Kamera", + "version": "Zeigt die Version des CLI-Tools", + "completions": "Erzeugt Shell-Vervollständigungs-Skripte für das CLI-Tool" + } + }, + "display": { + "sleep_mode": { + "awake": "Wach", + "sleep": "Schlafend", + "unknown": "Unbekannt" + }, + "ai_mode": { + "static": "Statisch", + "normal": "Normales Tracking", + "normal_short": "Normal", + "upper_body": "Oberkörper", + "close_up": "Porträt", + "headless": "Headless", + "lower_body": "Unterkörper", + "desk": "Schreibtischmodus", + "whiteboard": "Whiteboard", + "hand": "Hand", + "group": "Gruppe", + "unknown": "Unbekannt" + }, + "tracking_speed": { + "standard": "Standard", + "sport": "Sport" + }, + "exposure_mode": { + "manual": "Manuell", + "global": "Global", + "face": "Gesicht" + }, + "states": { + "on": "An", + "off": "Aus" + } + }, + "errors": { + "unsupported_int_value": "Der Wert {1} wird für {0} nicht unterstützt" + } +} diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..334b7b4 --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "No camera found. Please check the connection of the camera." + }, + "options": { + "hdr": { + "on": "HDR on", + "off": "HDR off" + } + }, + "info": { + "ai_mode": "AI Mode", + "camera_status": "Camera status", + "exposure": "Exposure", + "hdr": "HDR", + "presets": "Presets", + "sleep_mode": "Sleep Mode", + "tracking": "Tracking", + "tracking_speed": "Tracking Speed", + "t4l_version": "T4L Version" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Set to Sleep", + "wake_up": "Wake Up", + "unknown": "Sleep state unknown" + }, + "debugging": { + "turn_on": "Turn on debugging", + "turn_off": "Turn off debugging" + } + }, + "sleep": { + "is_awake": "The camera is awake", + "is_sleeping": "The camera is sleeping", + "unknown": "The camera state is unknown" + }, + "text": { + "debugging": { + "send": "Send", + "get_and_dump": "Get & Dump", + "send_x": "Send %{to_send}", + "clear_x": "Clear %{to_clear}", + "0x02_hex_string": "0x02 hex string", + "0x06_hex_string": "0x06 hex string" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Request the camera to go to sleep mode", + "request_to_wake": "Request the camera to wake up from sleep mode", + "state_unknown": "The state can't be determined. Click the button to try setting the mode or check the connection to the camera." + }, + "sets_tracking_mode": "Set the camera to \"%{mode}\" tracking mode", + "sets_tracking_speed": "Set the camera's speed to {%speed}", + "changes_exposure": "Changes the exposure mode to %{mode} exposure", + "hdr": { + "turns_on": "Turns on HDR on click", + "turns_off": "Turns off HDR on click" + }, + "preset": "Sets the cameras position to preset %{preset_number}", + "window_mode": { + "widget": "Switch to Widget-Mode", + "dashboard": "Switch to Dashboard-Mode" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Setting the camera to sleep", + "response_to_awake": "Waking up the camera", + "request_should_be": "The camera should be", + "option_on1": "awake", + "option_on2": "on", + "option_off1": "sleeping", + "option_off2": "off", + "option_off3": "asleep" + }, + "tracking_mode": { + "response_setting_to": "Setting the camera to", + "request_should_be": "What tracking type should be set?", + "static": "static (no tracking)", + "normal": "normal tracking", + "close_up": "close up tracking", + "upper_body": "upper body tracking", + "headless": "headless tracking", + "lower_body": "lower body tracking", + "desk": "desk tracking", + "whiteboard": "whiteboard tracking", + "hand": "hand tracking", + "group": "group tracking" + }, + "tracking_speed": { + "response_to_standard": "Setting the camera to standard tracking speed", + "response_to_fast": "Setting the camera to fast tracking speed", + "request_should_be": "Select the cameras tracking speed!", + "option_standard": "Standard (slower)", + "option_sport": "Sport (fast)" + }, + "preset_position": { + "response_to_position": "Setting the camera to preset position %{position_id}", + "request_position_id": "Select a predefined position preset!", + "stopping_tracking": "Stopping tracking before setting the camera to a preset position" + }, + "hdr": { + "response_to_hdr_on": "Enabling HDR", + "response_to_hdr_off": "Disabling HDR", + "request_should_be": "Select the HDR state!", + "option_on": "HDR on", + "option_off": "HDR off" + }, + "exposure": { + "response_to_manual": "Setting exposure mode to manual", + "response_to_global": "Setting exposure mode to global", + "response_to_face": "Setting exposure mode to face", + "request_should_be": "Select the exposure mode!", + "option_manual": "Manual", + "option_global": "Global", + "option_face": "Face" + }, + "errors": { + "info_error": "Camera could not be found or gave a faulty info. Please check the connection of the camera." + }, + "help": { + "sleep": "Sets the camera to sleep", + "wake": "Wakes the camera up", + "turn": "Turns the camera on or off (alias for `sleep` and `wake`)", + "tracking": "Controls the AI-tracking-mode of the camera", + "speed": "Controls the tracking speed of the camera", + "preset": "Sets the camera to a specific preset position previously defined in OBSBOT Center", + "hdr": "Controls the HDR-mode of the camera", + "exposure": "Controls the exposure-mode of the camera", + "info": "Displays information about the current state of the camera", + "version": "Displays the version of the CLI-tool", + "completions": "Generates shell-completion scripts for the CLI-tool" + } + }, + "display": { + "sleep_mode": { + "awake": "Awake", + "sleep": "Sleeping", + "unknown": "Unknown" + }, + "ai_mode": { + "static": "Static", + "normal": "Normal Tracking", + "normal_short": "Normal", + "upper_body": "Upper Body", + "close_up": "Close-up", + "headless": "Headless", + "lower_body": "Lower Body", + "desk": "Desk Mode", + "whiteboard": "Whiteboard", + "hand": "Hand", + "group": "Group", + "unknown": "Unknown" + }, + "tracking_speed": { + "standard": "Standard", + "sport": "Sport" + }, + "exposure_mode": { + "manual": "Manual", + "global": "Global", + "face": "Face" + }, + "states": { + "on": "On", + "off": "Off" + } + }, + "errors": { + "unsupported_int_value": "value of {1} is not supported for {0}" + } +} diff --git a/src/locales/es.json b/src/locales/es.json new file mode 100644 index 0000000..afd55e7 --- /dev/null +++ b/src/locales/es.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "No se encontró ninguna cámara. Por favor, compruebe la conexión de la cámara." + }, + "options": { + "hdr": { + "on": "HDR activado", + "off": "HDR desactivado" + } + }, + "info": { + "ai_mode": "Modo IA", + "camera_status": "Estado de la cámara", + "exposure": "Exposición", + "hdr": "HDR", + "presets": "Presets", + "sleep_mode": "Modo de reposo", + "tracking": "Seguimiento", + "tracking_speed": "Velocidad de seguimiento", + "t4l_version": "Versión T4L" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Poner en reposo", + "wake_up": "Despertar", + "unknown": "Estado de reposo desconocido" + }, + "debugging": { + "turn_on": "Activar depuración", + "turn_off": "Desactivar depuración" + } + }, + "sleep": { + "is_awake": "La cámara está activa", + "is_sleeping": "La cámara está en reposo", + "unknown": "El estado de la cámara es desconocido" + }, + "text": { + "debugging": { + "send": "Enviar", + "get_and_dump": "Obtener y volcar", + "send_x": "Enviar %{to_send}", + "clear_x": "Borrar %{to_clear}", + "0x02_hex_string": "Cadena hex 0x02", + "0x06_hex_string": "Cadena hex 0x06" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Solicitar que la cámara entre en modo de reposo", + "request_to_wake": "Solicitar que la cámara salga del modo de reposo", + "state_unknown": "No se puede determinar el estado. Haga clic para intentar establecer el modo o compruebe la conexión." + }, + "sets_tracking_mode": "Configura la cámara al modo de seguimiento \"%{mode}\"", + "sets_tracking_speed": "Configura la velocidad de seguimiento a %{speed}", + "changes_exposure": "Cambia el modo de exposición a %{mode}", + "hdr": { + "turns_on": "Activa HDR al hacer clic", + "turns_off": "Desactiva HDR al hacer clic" + }, + "preset": "Coloca la cámara en el preset %{preset_number}", + "window_mode": { + "widget": "Cambiar a modo widget", + "dashboard": "Cambiar a modo panel" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Poniendo la cámara en modo de reposo", + "response_to_awake": "Despertando la cámara", + "request_should_be": "La cámara debería estar", + "option_on1": "activa", + "option_on2": "encendida", + "option_off1": "durmiendo", + "option_off2": "apagada", + "option_off3": "en reposo" + }, + "tracking_mode": { + "response_setting_to": "Configurando la cámara a", + "request_should_be": "¿Qué tipo de seguimiento debe configurarse?", + "static": "estático (sin seguimiento)", + "normal": "seguimiento normal", + "close_up": "seguimiento de primer plano", + "upper_body": "seguimiento del torso superior", + "headless": "seguimiento sin cabeza", + "lower_body": "seguimiento del torso inferior", + "desk": "seguimiento de escritorio", + "whiteboard": "seguimiento de pizarra", + "hand": "seguimiento de mano", + "group": "seguimiento de grupo" + }, + "tracking_speed": { + "response_to_standard": "Configurando velocidad estándar de seguimiento", + "response_to_fast": "Configurando velocidad rápida de seguimiento", + "request_should_be": "Seleccione la velocidad de seguimiento", + "option_standard": "Estándar (más lento)", + "option_sport": "Deporte (rápido)" + }, + "preset_position": { + "response_to_position": "Colocando la cámara en la posición preset %{position_id}", + "request_position_id": "Seleccione un preset predefinido", + "stopping_tracking": "Deteniendo el seguimiento antes de mover la cámara a un preset" + }, + "hdr": { + "response_to_hdr_on": "Activando HDR", + "response_to_hdr_off": "Desactivando HDR", + "request_should_be": "Seleccione el estado HDR", + "option_on": "HDR activado", + "option_off": "HDR desactivado" + }, + "exposure": { + "response_to_manual": "Configurando exposición manual", + "response_to_global": "Configurando exposición global", + "response_to_face": "Configurando exposición facial", + "request_should_be": "Seleccione el modo de exposición", + "option_manual": "Manual", + "option_global": "Global", + "option_face": "Rostro" + }, + "errors": { + "info_error": "No se pudo encontrar la cámara o devolvió información incorrecta. Por favor, compruebe la conexión." + }, + "help": { + "sleep": "Pone la cámara en modo de reposo", + "wake": "Despierta la cámara", + "turn": "Enciende o apaga la cámara", + "tracking": "Controla el modo de seguimiento IA", + "speed": "Controla la velocidad de seguimiento", + "preset": "Selecciona un preset definido anteriormente", + "hdr": "Controla el modo HDR", + "exposure": "Controla el modo de exposición", + "info": "Muestra información del estado actual", + "version": "Muestra la versión de la herramienta CLI", + "completions": "Genera scripts de autocompletado" + } + }, + "display": { + "sleep_mode": { + "awake": "Activa", + "sleep": "Durmiendo", + "unknown": "Desconocido" + }, + "ai_mode": { + "static": "Estático", + "normal": "Seguimiento normal", + "normal_short": "Normal", + "upper_body": "Torso superior", + "close_up": "Primer plano", + "headless": "Sin cabeza", + "lower_body": "Torso inferior", + "desk": "Modo escritorio", + "whiteboard": "Pizarra", + "hand": "Mano", + "group": "Grupo", + "unknown": "Desconocido" + }, + "tracking_speed": { + "standard": "Estándar", + "sport": "Deporte" + }, + "exposure_mode": { + "manual": "Manual", + "global": "Global", + "face": "Rostro" + }, + "states": { + "on": "Encendido", + "off": "Apagado" + } + }, + "errors": { + "unsupported_int_value": "El valor {1} no es compatible para {0}" + } +} diff --git a/src/locales/fr.json b/src/locales/fr.json new file mode 100644 index 0000000..71f6c5f --- /dev/null +++ b/src/locales/fr.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "Aucune caméra trouvée. Veuillez vérifier la connexion de la caméra." + }, + "options": { + "hdr": { + "on": "HDR activé", + "off": "HDR désactivé" + } + }, + "info": { + "ai_mode": "Mode IA", + "camera_status": "État de la caméra", + "exposure": "Exposition", + "hdr": "HDR", + "presets": "Presets", + "sleep_mode": "Mode veille", + "tracking": "Suivi", + "tracking_speed": "Vitesse de suivi", + "t4l_version": "Version T4L" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Mettre en veille", + "wake_up": "Réveiller", + "unknown": "État de veille inconnu" + }, + "debugging": { + "turn_on": "Activer le débogage", + "turn_off": "Désactiver le débogage" + } + }, + "sleep": { + "is_awake": "La caméra est réveillée", + "is_sleeping": "La caméra est en veille", + "unknown": "L’état de la caméra est inconnu" + }, + "text": { + "debugging": { + "send": "Envoyer", + "get_and_dump": "Obtenir & Exporter", + "send_x": "Envoyer %{to_send}", + "clear_x": "Effacer %{to_clear}", + "0x02_hex_string": "Chaîne hex 0x02", + "0x06_hex_string": "Chaîne hex 0x06" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Demander à la caméra de passer en mode veille", + "request_to_wake": "Demander à la caméra de sortir de veille", + "state_unknown": "L’état ne peut pas être déterminé. Cliquez sur le bouton pour réessayer ou vérifiez la connexion." + }, + "sets_tracking_mode": "Définit le mode de suivi \"%{mode}\"", + "sets_tracking_speed": "Définit la vitesse de suivi de la caméra à %{speed}", + "changes_exposure": "Change le mode d'exposition pour %{mode}", + "hdr": { + "turns_on": "Active le HDR au clic", + "turns_off": "Désactive le HDR au clic" + }, + "preset": "Définit la caméra sur le preset %{preset_number}", + "window_mode": { + "widget": "Basculer en mode widget", + "dashboard": "Basculer en mode tableau de bord" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Mise en veille de la caméra", + "response_to_awake": "Réveil de la caméra", + "request_should_be": "La caméra doit être", + "option_on1": "réveillée", + "option_on2": "allumée", + "option_off1": "en veille", + "option_off2": "éteinte", + "option_off3": "endormie" + }, + "tracking_mode": { + "response_setting_to": "Configuration de la caméra en mode", + "request_should_be": "Quel type de suivi doit être défini ?", + "static": "statique (pas de suivi)", + "normal": "suivi normal", + "close_up": "suivi en gros plan", + "upper_body": "suivi du haut du corps", + "headless": "suivi sans tête", + "lower_body": "suivi du bas du corps", + "desk": "suivi de bureau", + "whiteboard": "suivi tableau blanc", + "hand": "suivi de la main", + "group": "suivi de groupe" + }, + "tracking_speed": { + "response_to_standard": "Définition de la vitesse de suivi standard", + "response_to_fast": "Définition de la vitesse de suivi rapide", + "request_should_be": "Sélectionnez la vitesse de suivi !", + "option_standard": "Standard (plus lent)", + "option_sport": "Sport (rapide)" + }, + "preset_position": { + "response_to_position": "Définition de la caméra sur le preset %{position_id}", + "request_position_id": "Sélectionnez un preset prédéfini !", + "stopping_tracking": "Arrêt du suivi avant d'appliquer le preset" + }, + "hdr": { + "response_to_hdr_on": "Activation du HDR", + "response_to_hdr_off": "Désactivation du HDR", + "request_should_be": "Sélectionnez l’état du HDR !", + "option_on": "HDR activé", + "option_off": "HDR désactivé" + }, + "exposure": { + "response_to_manual": "Réglage de l’exposition sur manuel", + "response_to_global": "Réglage de l’exposition sur global", + "response_to_face": "Réglage de l’exposition sur visage", + "request_should_be": "Sélectionnez le mode d’exposition !", + "option_manual": "Manuel", + "option_global": "Global", + "option_face": "Visage" + }, + "errors": { + "info_error": "La caméra est introuvable ou renvoie des informations incorrectes. Vérifiez la connexion." + }, + "help": { + "sleep": "Met la caméra en veille", + "wake": "Réveille la caméra", + "turn": "Allume ou éteint la caméra (alias de `sleep` et `wake`)", + "tracking": "Contrôle le mode de suivi IA", + "speed": "Contrôle la vitesse de suivi", + "preset": "Définit un preset prédéfini", + "hdr": "Contrôle le mode HDR", + "exposure": "Contrôle le mode d’exposition", + "info": "Affiche les informations de la caméra", + "version": "Affiche la version de l’outil CLI", + "completions": "Génère des scripts d’auto-complétion" + } + }, + "display": { + "sleep_mode": { + "awake": "Réveillée", + "sleep": "En veille", + "unknown": "Inconnu" + }, + "ai_mode": { + "static": "Statique", + "normal": "Suivi normal", + "normal_short": "Normal", + "upper_body": "Haut du corps", + "close_up": "Gros plan", + "headless": "Sans tête", + "lower_body": "Bas du corps", + "desk": "Mode bureau", + "whiteboard": "Tableau blanc", + "hand": "Main", + "group": "Groupe", + "unknown": "Inconnu" + }, + "tracking_speed": { + "standard": "Standard", + "sport": "Sport" + }, + "exposure_mode": { + "manual": "Manuel", + "global": "Global", + "face": "Visage" + }, + "states": { + "on": "Activé", + "off": "Désactivé" + } + }, + "errors": { + "unsupported_int_value": "La valeur {1} n’est pas prise en charge pour {0}" + } +} diff --git a/src/locales/hi.json b/src/locales/hi.json new file mode 100644 index 0000000..48a3981 --- /dev/null +++ b/src/locales/hi.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "कोई कैमरा नहीं मिला। कृपया कैमरे के कनेक्शन की जाँच करें।" + }, + "options": { + "hdr": { + "on": "HDR चालू", + "off": "HDR बंद" + } + }, + "info": { + "ai_mode": "AI मोड", + "camera_status": "कैमरा स्थिति", + "exposure": "एक्सपोज़र", + "hdr": "HDR", + "presets": "प्रीसेट्स", + "sleep_mode": "स्लीप मोड", + "tracking": "ट्रैकिंग", + "tracking_speed": "ट्रैकिंग गति", + "t4l_version": "T4L संस्करण" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "स्लीप पर सेट करें", + "wake_up": "जगाएँ", + "unknown": "स्लीप स्थिति अज्ञात" + }, + "debugging": { + "turn_on": "डिबगिंग चालू करें", + "turn_off": "डिबगिंग बंद करें" + } + }, + "sleep": { + "is_awake": "कैमरा जाग रहा है", + "is_sleeping": "कैमरा सो रहा है", + "unknown": "कैमरा स्थिति अज्ञात है" + }, + "text": { + "debugging": { + "send": "भेजें", + "get_and_dump": "प्राप्त करें और डंप करें", + "send_x": "%{to_send} भेजें", + "clear_x": "%{to_clear} साफ़ करें", + "0x02_hex_string": "0x02 हेक्स स्ट्रिंग", + "0x06_hex_string": "0x06 हेक्स स्ट्रिंग" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "कैमरे को स्लीप मोड में भेजें", + "request_to_wake": "कैमरे को स्लीप मोड से जगाएँ", + "state_unknown": "स्थिति निर्धारित नहीं की जा सकती। मोड सेट करने के लिए बटन पर क्लिक करें या कैमरे के कनेक्शन की जाँच करें।" + }, + "sets_tracking_mode": "कैमरे को \"%{mode}\" ट्रैकिंग मोड में सेट करें", + "sets_tracking_speed": "कैमरे की ट्रैकिंग गति %{speed} पर सेट करें", + "changes_exposure": "एक्सपोज़र मोड को %{mode} में बदलें", + "hdr": { + "turns_on": "क्लिक करने पर HDR चालू करता है", + "turns_off": "क्लिक करने पर HDR बंद करता है" + }, + "preset": "कैमरे की स्थिति को प्रीसेट %{preset_number} पर सेट करता है", + "window_mode": { + "widget": "विजेट मोड पर स्विच करें", + "dashboard": "डैशबोर्ड मोड पर स्विच करें" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "कैमरे को स्लीप मोड पर सेट किया जा रहा है", + "response_to_awake": "कैमरे को जगाया जा रहा है", + "request_should_be": "कैमरा होना चाहिए", + "option_on1": "जगा हुआ", + "option_on2": "चालू", + "option_off1": "सो रहा", + "option_off2": "बंद", + "option_off3": "स्लीप में" + }, + "tracking_mode": { + "response_setting_to": "कैमरे को सेट किया जा रहा है", + "request_should_be": "कौन सा ट्रैकिंग प्रकार सेट किया जाए?", + "static": "स्थिर (कोई ट्रैकिंग नहीं)", + "normal": "सामान्य ट्रैकिंग", + "close_up": "क्लोज़-अप ट्रैकिंग", + "upper_body": "ऊपरी शरीर ट्रैकिंग", + "headless": "हेडलैस ट्रैकिंग", + "lower_body": "निचले शरीर की ट्रैकिंग", + "desk": "डेस्क ट्रैकिंग", + "whiteboard": "व्हाइटबोर्ड ट्रैकिंग", + "hand": "हाथ ट्रैकिंग", + "group": "समूह ट्रैकिंग" + }, + "tracking_speed": { + "response_to_standard": "कैमरे को मानक ट्रैकिंग गति पर सेट किया जा रहा है", + "response_to_fast": "कैमरे को तेज ट्रैकिंग गति पर सेट किया जा रहा है", + "request_should_be": "कैमरे की ट्रैकिंग गति चुनें!", + "option_standard": "मानक (धीमा)", + "option_sport": "स्पोर्ट (तेज)" + }, + "preset_position": { + "response_to_position": "कैमरे को प्रीसेट स्थिति %{position_id} पर सेट किया जा रहा है", + "request_position_id": "एक प्रीसेट स्थिति चुनें!", + "stopping_tracking": "प्रीसेट सेट करने से पहले ट्रैकिंग बंद की जा रही है" + }, + "hdr": { + "response_to_hdr_on": "HDR सक्षम किया जा रहा है", + "response_to_hdr_off": "HDR अक्षम किया जा रहा है", + "request_should_be": "HDR स्थिति चुनें!", + "option_on": "HDR चालू", + "option_off": "HDR बंद" + }, + "exposure": { + "response_to_manual": "एक्सपोज़र मोड को मैनुअल पर सेट किया जा रहा है", + "response_to_global": "एक्सपोज़र मोड को ग्लोबल पर सेट किया जा रहा है", + "response_to_face": "एक्सपोज़र मोड को फेस पर सेट किया जा रहा है", + "request_should_be": "एक्सपोज़र मोड चुनें!", + "option_manual": "मैनुअल", + "option_global": "ग्लोबल", + "option_face": "फेस" + }, + "errors": { + "info_error": "कैमरा नहीं मिला या गलत जानकारी दी है। कृपया कनेक्शन की जाँच करें।" + }, + "help": { + "sleep": "कैमरे को स्लीप मोड में सेट करता है", + "wake": "कैमरे को जगाता है", + "turn": "कैमरा चालू या बंद करता है (`sleep` और `wake` के लिए उपनाम)", + "tracking": "कैमरे के AI ट्रैकिंग मोड को नियंत्रित करता है", + "speed": "कैमरे की ट्रैकिंग गति को नियंत्रित करता है", + "preset": "कैमरे को OBSBOT Center में सेट किए गए प्रीसेट पर ले जाता है", + "hdr": "HDR मोड को नियंत्रित करता है", + "exposure": "एक्सपोज़र मोड नियंत्रित करता है", + "info": "कैमरे की वर्तमान स्थिति दिखाता है", + "version": "CLI टूल का संस्करण दिखाता है", + "completions": "CLI टूल के लिए शेल-कम्प्लीशन स्क्रिप्ट्स उत्पन्न करता है" + } + }, + "display": { + "sleep_mode": { + "awake": "जगा हुआ", + "sleep": "सो रहा", + "unknown": "अज्ञात" + }, + "ai_mode": { + "static": "स्थिर", + "normal": "सामान्य ट्रैकिंग", + "normal_short": "सामान्य", + "upper_body": "ऊपरी शरीर", + "close_up": "क्लोज़-अप", + "headless": "हेडलैस", + "lower_body": "निचला शरीर", + "desk": "डेस्क मोड", + "whiteboard": "व्हाइटबोर्ड", + "hand": "हाथ", + "group": "समूह", + "unknown": "अज्ञात" + }, + "tracking_speed": { + "standard": "मानक", + "sport": "स्पोर्ट" + }, + "exposure_mode": { + "manual": "मैनुअल", + "global": "ग्लोबल", + "face": "फेस" + }, + "states": { + "on": "चालू", + "off": "बंद" + } + }, + "errors": { + "unsupported_int_value": "{0} के लिए {1} मान समर्थित नहीं है" + } +} diff --git a/src/locales/it.json b/src/locales/it.json new file mode 100644 index 0000000..91c37c8 --- /dev/null +++ b/src/locales/it.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "Nessuna fotocamera trovata. Controllare la connessione della fotocamera." + }, + "options": { + "hdr": { + "on": "HDR attivo", + "off": "HDR disattivato" + } + }, + "info": { + "ai_mode": "Modalità IA", + "camera_status": "Stato della fotocamera", + "exposure": "Esposizione", + "hdr": "HDR", + "presets": "Preset", + "sleep_mode": "Modalità sospensione", + "tracking": "Tracking", + "tracking_speed": "Velocità", + "t4l_version": "Versione T4L" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Metti in sospensione", + "wake_up": "Riattiva", + "unknown": "Stato sospensione sconosciuto" + }, + "debugging": { + "turn_on": "Attiva debug", + "turn_off": "Disattiva debug" + } + }, + "sleep": { + "is_awake": "La fotocamera è attiva", + "is_sleeping": "La fotocamera è in sospensione", + "unknown": "Stato della fotocamera sconosciuto" + }, + "text": { + "debugging": { + "send": "Invia", + "get_and_dump": "Ottieni e stampa", + "send_x": "Invia %{to_send}", + "clear_x": "Cancella %{to_clear}", + "0x02_hex_string": "Stringa esadecimale 0x02", + "0x06_hex_string": "Stringa esadecimale 0x06" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Richiedi alla fotocamera di andare in sospensione", + "request_to_wake": "Richiedi alla fotocamera di riattivarsi", + "state_unknown": "Impossibile determinare lo stato. Clicca il pulsante o controlla la connessione." + }, + "sets_tracking_mode": "Imposta la fotocamera sulla modalità di tracking \"%{mode}\"", + "sets_tracking_speed": "Imposta la velocità di tracking su %{speed}", + "changes_exposure": "Cambia la modalità esposizione in %{mode}", + "hdr": { + "turns_on": "Attiva HDR al clic", + "turns_off": "Disattiva HDR al clic" + }, + "preset": "Imposta la fotocamera sul preset %{preset_number}", + "window_mode": { + "widget": "Passa alla modalità widget", + "dashboard": "Passa alla modalità dashboard" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Impostazione della fotocamera in sospensione", + "response_to_awake": "Riattivazione della fotocamera", + "request_should_be": "La fotocamera dovrebbe essere", + "option_on1": "attiva", + "option_on2": "accesa", + "option_off1": "in sospensione", + "option_off2": "spenta", + "option_off3": "addormentata" + }, + "tracking_mode": { + "response_setting_to": "Impostazione della fotocamera su", + "request_should_be": "Quale tipo di tracking impostare?", + "static": "statico (nessun tracking)", + "normal": "tracking normale", + "close_up": "tracking ravvicinato", + "upper_body": "tracking del busto", + "headless": "tracking headless", + "lower_body": "tracking parte inferiore", + "desk": "tracking scrivania", + "whiteboard": "tracking lavagna", + "hand": "tracking mano", + "group": "tracking di gruppo" + }, + "tracking_speed": { + "response_to_standard": "Impostazione velocità tracking standard", + "response_to_fast": "Impostazione velocità tracking veloce", + "request_should_be": "Seleziona la velocità di tracking!", + "option_standard": "Standard (più lento)", + "option_sport": "Sport (veloce)" + }, + "preset_position": { + "response_to_position": "Impostazione della fotocamera sul preset %{position_id}", + "request_position_id": "Seleziona un preset predefinito!", + "stopping_tracking": "Interruzione del tracking prima del preset" + }, + "hdr": { + "response_to_hdr_on": "Attivazione HDR", + "response_to_hdr_off": "Disattivazione HDR", + "request_should_be": "Seleziona lo stato HDR!", + "option_on": "HDR attivo", + "option_off": "HDR disattivo" + }, + "exposure": { + "response_to_manual": "Impostazione esposizione manuale", + "response_to_global": "Impostazione esposizione globale", + "response_to_face": "Impostazione esposizione volto", + "request_should_be": "Seleziona la modalità esposizione!", + "option_manual": "Manuale", + "option_global": "Globale", + "option_face": "Volto" + }, + "errors": { + "info_error": "La fotocamera non è stata trovata o ha dato informazioni errate. Controllare la connessione." + }, + "help": { + "sleep": "Mette la fotocamera in sospensione", + "wake": "Riattiva la fotocamera", + "turn": "Accende o spegne la fotocamera (alias di `sleep` e `wake`)", + "tracking": "Controlla la modalità tracking IA", + "speed": "Controlla la velocità di tracking", + "preset": "Imposta un preset definito", + "hdr": "Controlla la modalità HDR", + "exposure": "Controlla la modalità esposizione", + "info": "Mostra le informazioni della fotocamera", + "version": "Mostra la versione dello strumento CLI", + "completions": "Genera script di completamento" + } + }, + "display": { + "sleep_mode": { + "awake": "Attiva", + "sleep": "In sospensione", + "unknown": "Sconosciuto" + }, + "ai_mode": { + "static": "Statico", + "normal": "Tracking normale", + "normal_short": "Normale", + "upper_body": "Busto", + "close_up": "Primo piano", + "headless": "Headless", + "lower_body": "Parte inferiore", + "desk": "Modo scrivania", + "whiteboard": "Lavagna", + "hand": "Mano", + "group": "Gruppo", + "unknown": "Sconosciuto" + }, + "tracking_speed": { + "standard": "Standard", + "sport": "Sport" + }, + "exposure_mode": { + "manual": "Manuale", + "global": "Globale", + "face": "Volto" + }, + "states": { + "on": "Attivo", + "off": "Disattivo" + } + }, + "errors": { + "unsupported_int_value": "Il valore {1} non è supportato per {0}" + } +} diff --git a/src/locales/ja.json b/src/locales/ja.json new file mode 100644 index 0000000..ef74107 --- /dev/null +++ b/src/locales/ja.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "カメラが見つかりません。カメラの接続を確認してください。" + }, + "options": { + "hdr": { + "on": "HDR オン", + "off": "HDR オフ" + } + }, + "info": { + "ai_mode": "AI モード", + "camera_status": "カメラステータス", + "exposure": "露出", + "hdr": "HDR", + "presets": "プリセット", + "sleep_mode": "スリープモード", + "tracking": "トラッキング", + "tracking_speed": "トラッキング速度", + "t4l_version": "T4L バージョン" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "スリープにする", + "wake_up": "起動する", + "unknown": "スリープ状態は不明です" + }, + "debugging": { + "turn_on": "デバッグをオンにする", + "turn_off": "デバッグをオフにする" + } + }, + "sleep": { + "is_awake": "カメラは起動しています", + "is_sleeping": "カメラはスリープ中です", + "unknown": "カメラの状態は不明です" + }, + "text": { + "debugging": { + "send": "送信", + "get_and_dump": "取得して出力", + "send_x": "%{to_send} を送信", + "clear_x": "%{to_clear} をクリア", + "0x02_hex_string": "0x02 16 進数文字列", + "0x06_hex_string": "0x06 16 進数文字列" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "カメラをスリープモードにする", + "request_to_wake": "カメラをスリープモードから起動する", + "state_unknown": "状態を判定できません。ボタンをクリックしてモードを設定するか、カメラの接続を確認してください。" + }, + "sets_tracking_mode": "カメラを「%{mode}」トラッキングモードに設定します", + "sets_tracking_speed": "カメラのトラッキング速度を %{speed} に設定します", + "changes_exposure": "露出モードを %{mode} に変更します", + "hdr": { + "turns_on": "クリックで HDR をオンにします", + "turns_off": "クリックで HDR をオフにします" + }, + "preset": "カメラをプリセット %{preset_number} の位置に設定します", + "window_mode": { + "widget": "ウィジェットモードに切り替え", + "dashboard": "ダッシュボードモードに切り替え" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "カメラをスリープモードに設定します", + "response_to_awake": "カメラを起動します", + "request_should_be": "カメラは次の状態であるべきです", + "option_on1": "起動", + "option_on2": "オン", + "option_off1": "スリープ", + "option_off2": "オフ", + "option_off3": "スリープ中" + }, + "tracking_mode": { + "response_setting_to": "カメラを次に設定します:", + "request_should_be": "どのトラッキングタイプを設定しますか?", + "static": "静止(トラッキングなし)", + "normal": "通常トラッキング", + "close_up": "クローズアップトラッキング", + "upper_body": "上半身トラッキング", + "headless": "ヘッドレストラッキング", + "lower_body": "下半身トラッキング", + "desk": "デスクトラッキング", + "whiteboard": "ホワイトボードトラッキング", + "hand": "手のトラッキング", + "group": "グループトラッキング" + }, + "tracking_speed": { + "response_to_standard": "カメラを標準トラッキング速度に設定します", + "response_to_fast": "カメラを高速トラッキング速度に設定します", + "request_should_be": "トラッキング速度を選択してください!", + "option_standard": "標準(遅め)", + "option_sport": "スポーツ(速い)" + }, + "preset_position": { + "response_to_position": "カメラをプリセット位置 %{position_id} に設定します", + "request_position_id": "あらかじめ定義されたプリセット位置を選択してください!", + "stopping_tracking": "プリセット位置に移動する前にトラッキングを停止します" + }, + "hdr": { + "response_to_hdr_on": "HDR を有効化", + "response_to_hdr_off": "HDR を無効化", + "request_should_be": "HDR 状態を選択してください!", + "option_on": "HDR オン", + "option_off": "HDR オフ" + }, + "exposure": { + "response_to_manual": "露出モードをマニュアルに設定", + "response_to_global": "露出モードをグローバルに設定", + "response_to_face": "露出モードを顔に設定", + "request_should_be": "露出モードを選択してください!", + "option_manual": "マニュアル", + "option_global": "グローバル", + "option_face": "顔" + }, + "errors": { + "info_error": "カメラが見つからないか、情報が正しくありません。カメラの接続を確認してください。" + }, + "help": { + "sleep": "カメラをスリープモードに設定", + "wake": "カメラを起動", + "turn": "カメラをオン/オフにする(sleep / wake のエイリアス)", + "tracking": "カメラの AI トラッキングモードを制御", + "speed": "カメラのトラッキング速度を制御", + "preset": "OBSBOT Center で定義されたプリセット位置に設定", + "hdr": "カメラの HDR モードを制御", + "exposure": "カメラの露出モードを制御", + "info": "カメラの現在の状態を表示", + "version": "CLI ツールのバージョンを表示", + "completions": "CLI ツールのシェル補完スクリプトを生成" + } + }, + "display": { + "sleep_mode": { + "awake": "起動", + "sleep": "スリープ", + "unknown": "不明" + }, + "ai_mode": { + "static": "静止", + "normal": "通常トラッキング", + "normal_short": "通常", + "upper_body": "上半身", + "close_up": "クローズアップ", + "headless": "ヘッドレス", + "lower_body": "下半身", + "desk": "デスクモード", + "whiteboard": "ホワイトボード", + "hand": "手", + "group": "グループ", + "unknown": "不明" + }, + "tracking_speed": { + "standard": "標準", + "sport": "スポーツ" + }, + "exposure_mode": { + "manual": "マニュアル", + "global": "グローバル", + "face": "顔" + }, + "states": { + "on": "オン", + "off": "オフ" + } + }, + "errors": { + "unsupported_int_value": "{0} は値 {1} をサポートしていません" + } +} diff --git a/src/locales/tr.json b/src/locales/tr.json new file mode 100644 index 0000000..e7cc25d --- /dev/null +++ b/src/locales/tr.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "Kamera bulunamadı. Lütfen kameranın bağlantısını kontrol edin." + }, + "options": { + "hdr": { + "on": "HDR açık", + "off": "HDR kapalı" + } + }, + "info": { + "ai_mode": "Yapay Zekâ Modu", + "camera_status": "Kamera durumu", + "exposure": "Pozlama", + "hdr": "HDR", + "presets": "Önayarlar", + "sleep_mode": "Uyku modu", + "tracking": "Takip", + "tracking_speed": "Takip Hızı", + "t4l_version": "T4L Sürümü" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Uykuya al", + "wake_up": "Uyandır", + "unknown": "Uyku durumu bilinmiyor" + }, + "debugging": { + "turn_on": "Hata ayıklamayı aç", + "turn_off": "Hata ayıklamayı kapat" + } + }, + "sleep": { + "is_awake": "Kamera uyanık", + "is_sleeping": "Kamera uyuyor", + "unknown": "Kamera durumu bilinmiyor" + }, + "text": { + "debugging": { + "send": "Gönder", + "get_and_dump": "Al ve dök", + "send_x": "%{to_send} gönder", + "clear_x": "%{to_clear} temizle", + "0x02_hex_string": "0x02 hex dizesi", + "0x06_hex_string": "0x06 hex dizesi" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Kamerayı uyku moduna geçir", + "request_to_wake": "Kamerayı uyku modundan çıkar", + "state_unknown": "Durum belirlenemiyor. Modu ayarlamak için tıklayın veya bağlantıyı kontrol edin." + }, + "sets_tracking_mode": "Kamerayı \"%{mode}\" takip moduna ayarlar", + "sets_tracking_speed": "Kameranın takip hızını %{speed} olarak ayarlar", + "changes_exposure": "Pozlama modunu %{mode} olarak değiştirir", + "hdr": { + "turns_on": "Tıklandığında HDR açılır", + "turns_off": "Tıklandığında HDR kapanır" + }, + "preset": "Kamerayı %{preset_number} önayarına konumlandırır", + "window_mode": { + "widget": "Widget moduna geç", + "dashboard": "Pano moduna geç" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Kamera uyku moduna alınıyor", + "response_to_awake": "Kamera uyandırılıyor", + "request_should_be": "Kamera", + "option_on1": "uyanık olmalı", + "option_on2": "açık olmalı", + "option_off1": "uyuyor olmalı", + "option_off2": "kapalı olmalı", + "option_off3": "uyku modunda olmalı" + }, + "tracking_mode": { + "response_setting_to": "Kamera ayarlanıyor:", + "request_should_be": "Hangi takip modu ayarlanmalı?", + "static": "statik (takip yok)", + "normal": "normal takip", + "close_up": "yakın plan takip", + "upper_body": "üst vücut takibi", + "headless": "başsız takip", + "lower_body": "alt vücut takibi", + "desk": "masa takibi", + "whiteboard": "yazı tahtası takibi", + "hand": "el takibi", + "group": "grup takibi" + }, + "tracking_speed": { + "response_to_standard": "Kamera standart takip hızına ayarlanıyor", + "response_to_fast": "Kamera hızlı takip hızına ayarlanıyor", + "request_should_be": "Kameranın takip hızını seçin!", + "option_standard": "Standart (daha yavaş)", + "option_sport": "Spor (hızlı)" + }, + "preset_position": { + "response_to_position": "Kamera %{position_id} önayarına ayarlanıyor", + "request_position_id": "Önceden tanımlı bir önayarı seçin!", + "stopping_tracking": "Kamera bir önayara ayarlanmadan önce takip durduruluyor" + }, + "hdr": { + "response_to_hdr_on": "HDR etkinleştiriliyor", + "response_to_hdr_off": "HDR devre dışı bırakılıyor", + "request_should_be": "HDR durumunu seçin!", + "option_on": "HDR açık", + "option_off": "HDR kapalı" + }, + "exposure": { + "response_to_manual": "Pozlama modu manuel yapılıyor", + "response_to_global": "Pozlama modu global yapılıyor", + "response_to_face": "Pozlama modu yüz olarak ayarlanıyor", + "request_should_be": "Pozlama modunu seçin!", + "option_manual": "Manuel", + "option_global": "Global", + "option_face": "Yüz" + }, + "errors": { + "info_error": "Kamera bulunamadı veya hatalı bilgi verdi. Lütfen bağlantıyı kontrol edin." + }, + "help": { + "sleep": "Kamerayı uyku moduna alır", + "wake": "Kamerayı uyandırır", + "turn": "Kamerayı açar veya kapatır", + "tracking": "Yapay zekâ takip modunu kontrol eder", + "speed": "Takip hızını kontrol eder", + "preset": "Kamerayı bir önayara ayarlar", + "hdr": "HDR modunu kontrol eder", + "exposure": "Pozlama modunu kontrol eder", + "info": "Kameranın mevcut durumunu gösterir", + "version": "CLI aracının sürümünü gösterir", + "completions": "CLI için kabuk tamamlama betikleri oluşturur" + } + }, + "display": { + "sleep_mode": { + "awake": "Uyanık", + "sleep": "Uyuyor", + "unknown": "Bilinmiyor" + }, + "ai_mode": { + "static": "Statik", + "normal": "Normal takip", + "normal_short": "Normal", + "upper_body": "Üst vücut", + "close_up": "Yakın plan", + "headless": "Başsız", + "lower_body": "Alt vücut", + "desk": "Masa modu", + "whiteboard": "Yazı tahtası", + "hand": "El", + "group": "Grup", + "unknown": "Bilinmiyor" + }, + "tracking_speed": { + "standard": "Standart", + "sport": "Spor" + }, + "exposure_mode": { + "manual": "Manuel", + "global": "Global", + "face": "Yüz" + }, + "states": { + "on": "Açık", + "off": "Kapalı" + } + }, + "errors": { + "unsupported_int_value": "{0} için {1} değeri desteklenmiyor" + } +} diff --git a/src/locales/uk.json b/src/locales/uk.json new file mode 100644 index 0000000..37ed325 --- /dev/null +++ b/src/locales/uk.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "Камеру не знайдено. Будь ласка, перевірте підключення камери." + }, + "options": { + "hdr": { + "on": "HDR увімкнено", + "off": "HDR вимкнено" + } + }, + "info": { + "ai_mode": "Режим ШІ", + "camera_status": "Стан камери", + "exposure": "Експозиція", + "hdr": "HDR", + "presets": "Пресети", + "sleep_mode": "Режим сну", + "tracking": "Трекінг", + "tracking_speed": "Швидкість трекінгу", + "t4l_version": "Версія T4L" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "Перевести в сон", + "wake_up": "Пробудити", + "unknown": "Стан сну невідомий" + }, + "debugging": { + "turn_on": "Увімкнути налагодження", + "turn_off": "Вимкнути налагодження" + } + }, + "sleep": { + "is_awake": "Камера активна", + "is_sleeping": "Камера спить", + "unknown": "Стан камери невідомий" + }, + "text": { + "debugging": { + "send": "Надіслати", + "get_and_dump": "Отримати й вивести", + "send_x": "Надіслати %{to_send}", + "clear_x": "Очистити %{to_clear}", + "0x02_hex_string": "0x02 hex-рядок", + "0x06_hex_string": "0x06 hex-рядок" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "Запит на переведення камери в режим сну", + "request_to_wake": "Запит на пробудження камери", + "state_unknown": "Неможливо визначити стан. Натисніть кнопку або перевірте підключення." + }, + "sets_tracking_mode": "Установлює режим трекінгу \"%{mode}\"", + "sets_tracking_speed": "Встановлює швидкість трекінгу %{speed}", + "changes_exposure": "Змінює режим експозиції на %{mode}", + "hdr": { + "turns_on": "Увімкнути HDR при натисканні", + "turns_off": "Вимкнути HDR при натисканні" + }, + "preset": "Установлює позицію камери на пресет %{preset_number}", + "window_mode": { + "widget": "Переключити в режим віджета", + "dashboard": "Переключити в режим панелі" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "Переведення камери в режим сну", + "response_to_awake": "Пробудження камери", + "request_should_be": "Камера повинна бути", + "option_on1": "активною", + "option_on2": "увімкненою", + "option_off1": "спати", + "option_off2": "вимкненою", + "option_off3": "у стані сну" + }, + "tracking_mode": { + "response_setting_to": "Встановлення камери в режим", + "request_should_be": "Який тип трекінгу встановити?", + "static": "статичний (без трекінгу)", + "normal": "звичайний трекінг", + "close_up": "трекінг крупним планом", + "upper_body": "трекінг верхньої частини тіла", + "headless": "headless-трекінг", + "lower_body": "трекінг нижньої частини тіла", + "desk": "трекінг робочого столу", + "whiteboard": "трекінг дошки", + "hand": "трекінг руки", + "group": "груповий трекінг" + }, + "tracking_speed": { + "response_to_standard": "Установлення стандартної швидкості трекінгу", + "response_to_fast": "Установлення швидкого трекінгу", + "request_should_be": "Виберіть швидкість трекінгу!", + "option_standard": "Стандарт (повільніший)", + "option_sport": "Спорт (швидкий)" + }, + "preset_position": { + "response_to_position": "Установлення камери на пресет %{position_id}", + "request_position_id": "Виберіть пресет позиції!", + "stopping_tracking": "Зупинка трекінгу перед установленням пресету" + }, + "hdr": { + "response_to_hdr_on": "Увімкнення HDR", + "response_to_hdr_off": "Вимкнення HDR", + "request_should_be": "Виберіть стан HDR!", + "option_on": "HDR увімкнено", + "option_off": "HDR вимкнено" + }, + "exposure": { + "response_to_manual": "Експозиція встановлена на ручну", + "response_to_global": "Експозиція встановлена на глобальну", + "response_to_face": "Експозиція встановлена на обличчя", + "request_should_be": "Виберіть режим експозиції!", + "option_manual": "Ручний", + "option_global": "Глобальний", + "option_face": "Обличчя" + }, + "errors": { + "info_error": "Камера не знайдена або дала некоректну інформацію. Перевірте підключення." + }, + "help": { + "sleep": "Переводить камеру в режим сну", + "wake": "Пробуджує камеру", + "turn": "Увімкнути або вимкнути камеру (аналог `sleep` та `wake`)", + "tracking": "Керує режимом ШІ-трекінгу", + "speed": "Керує швидкістю трекінгу", + "preset": "Установлює камеру на пресет", + "hdr": "Керує режимом HDR", + "exposure": "Керує режимом експозиції", + "info": "Показує інформацію про стан камери", + "version": "Показує версію CLI", + "completions": "Генерує скрипти автодоповнення" + } + }, + "display": { + "sleep_mode": { + "awake": "Активна", + "sleep": "Спить", + "unknown": "Невідомо" + }, + "ai_mode": { + "static": "Статичний", + "normal": "Звичайний трекінг", + "normal_short": "Звичайний", + "upper_body": "Верхня частина", + "close_up": "Крупний план", + "headless": "Headless", + "lower_body": "Нижня частина", + "desk": "Режим столу", + "whiteboard": "Дошка", + "hand": "Рука", + "group": "Група", + "unknown": "Невідомо" + }, + "tracking_speed": { + "standard": "Стандарт", + "sport": "Спорт" + }, + "exposure_mode": { + "manual": "Ручний", + "global": "Глобальний", + "face": "Обличчя" + }, + "states": { + "on": "Увімкнено", + "off": "Вимкнено" + } + }, + "errors": { + "unsupported_int_value": "Значення {1} не підтримується для {0}" + } +} diff --git a/src/locales/zh-TW.json b/src/locales/zh-TW.json new file mode 100644 index 0000000..62bfe58 --- /dev/null +++ b/src/locales/zh-TW.json @@ -0,0 +1,178 @@ +{ + "shared": { + "errors": { + "no_camera": "未找到相機。請檢查相機的連線。" + }, + "options": { + "hdr": { + "on": "HDR 開啟", + "off": "HDR 關閉" + } + }, + "info": { + "ai_mode": "AI 模式", + "camera_status": "相機狀態", + "exposure": "曝光", + "hdr": "HDR", + "presets": "預設位置", + "sleep_mode": "睡眠模式", + "tracking": "追蹤", + "tracking_speed": "追蹤速度", + "t4l_version": "T4L 版本" + } + }, + "gui": { + "buttons": { + "sleep": { + "set_sleep": "進入睡眠", + "wake_up": "喚醒", + "unknown": "睡眠狀態未知" + }, + "debugging": { + "turn_on": "開啟除錯", + "turn_off": "關閉除錯" + } + }, + "sleep": { + "is_awake": "相機已喚醒", + "is_sleeping": "相機正在睡眠", + "unknown": "相機狀態未知" + }, + "text": { + "debugging": { + "send": "送出", + "get_and_dump": "取得並輸出", + "send_x": "送出 %{to_send}", + "clear_x": "清除 %{to_clear}", + "0x02_hex_string": "0x02 十六進位字串", + "0x06_hex_string": "0x06 十六進位字串" + } + }, + "tooltips": { + "sleep": { + "request_to_sleep": "要求相機進入睡眠模式", + "request_to_wake": "要求相機從睡眠模式喚醒", + "state_unknown": "無法判斷狀態。請點擊按鈕嘗試設定模式,或檢查相機連線。" + }, + "sets_tracking_mode": "將相機設定為「%{mode}」追蹤模式", + "sets_tracking_speed": "將相機的追蹤速度設定為 %{speed}", + "changes_exposure": "將曝光模式變更為 %{mode}", + "hdr": { + "turns_on": "點擊時開啟 HDR", + "turns_off": "點擊時關閉 HDR" + }, + "preset": "將相機移動至預設位置 %{preset_number}", + "window_mode": { + "widget": "切換至小工具模式", + "dashboard": "切換至儀表板模式" + } + } + }, + "cli": { + "sleep": { + "response_to_sleep": "將相機設為睡眠模式", + "response_to_awake": "喚醒相機", + "request_should_be": "相機應該", + "option_on1": "醒著", + "option_on2": "開啟", + "option_off1": "睡眠", + "option_off2": "關閉", + "option_off3": "進入睡眠" + }, + "tracking_mode": { + "response_setting_to": "將相機設定為", + "request_should_be": "要設定哪種追蹤模式?", + "static": "靜態(無追蹤)", + "normal": "一般追蹤", + "close_up": "特寫追蹤", + "upper_body": "上半身追蹤", + "headless": "無頭追蹤", + "lower_body": "下半身追蹤", + "desk": "桌面追蹤", + "whiteboard": "白板追蹤", + "hand": "手部追蹤", + "group": "群組追蹤" + }, + "tracking_speed": { + "response_to_standard": "設定相機為標準追蹤速度", + "response_to_fast": "設定相機為快速追蹤速度", + "request_should_be": "請選擇追蹤速度!", + "option_standard": "標準(較慢)", + "option_sport": "運動(快速)" + }, + "preset_position": { + "response_to_position": "將相機設定到預設位置 %{position_id}", + "request_position_id": "請選擇預設位置!", + "stopping_tracking": "在移動至預設位置前停止追蹤" + }, + "hdr": { + "response_to_hdr_on": "啟用 HDR", + "response_to_hdr_off": "停用 HDR", + "request_should_be": "請選擇 HDR 狀態!", + "option_on": "HDR 開啟", + "option_off": "HDR 關閉" + }, + "exposure": { + "response_to_manual": "將曝光模式設為手動", + "response_to_global": "將曝光模式設為全局", + "response_to_face": "將曝光模式設為臉部", + "request_should_be": "請選擇曝光模式!", + "option_manual": "手動", + "option_global": "全局", + "option_face": "臉部" + }, + "errors": { + "info_error": "找不到相機或相機資訊異常。請檢查相機連線。" + }, + "help": { + "sleep": "將相機設為睡眠模式", + "wake": "喚醒相機", + "turn": "開啟或關閉相機(sleep/wake 的別名)", + "tracking": "控制相機的 AI 追蹤模式", + "speed": "控制相機的追蹤速度", + "preset": "將相機設為 OBSBOT Center 中預先定義的預設位置", + "hdr": "控制相機的 HDR 模式", + "exposure": "控制相機的曝光模式", + "info": "顯示相機目前狀態資訊", + "version": "顯示 CLI 工具版本", + "completions": "產生 CLI 工具的 shell 自動補全腳本" + } + }, + "display": { + "sleep_mode": { + "awake": "醒著", + "sleep": "睡眠", + "unknown": "未知" + }, + "ai_mode": { + "static": "靜態", + "normal": "一般追蹤", + "normal_short": "一般", + "upper_body": "上半身", + "close_up": "特寫", + "headless": "無頭", + "lower_body": "下半身", + "desk": "桌面模式", + "whiteboard": "白板", + "hand": "手部", + "group": "群組", + "unknown": "未知" + }, + "tracking_speed": { + "standard": "標準", + "sport": "運動" + }, + "exposure_mode": { + "manual": "手動", + "global": "全局", + "face": "臉部" + }, + "states": { + "on": "開", + "off": "關" + } + }, + "errors": { + "unsupported_int_value": "{0} 不支援值 {1}" + } +}