Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions configurator/src/models/color/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ impl NamedColorOption {

pub fn as_value(&self) -> &'static str {
match self {
Self::Red => tr("red"),
Self::Green => tr("green"),
Self::Blue => tr("blue"),
Self::Yellow => tr("yellow"),
Self::Orange => tr("orange"),
Self::Pink => tr("pink"),
Self::White => tr("white"),
Self::Black => tr("black"),
Self::Red => "red",
Self::Green => "green",
Self::Blue => "blue",
Self::Yellow => "yellow",
Self::Orange => "orange",
Self::Pink => "pink",
Self::White => "white",
Self::Black => "black",
Self::Custom => "",
}
}
Expand Down
42 changes: 42 additions & 0 deletions configurator/src/models/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,48 @@ fn config_draft_round_trips_quick_colors() {
);
}

/// A save rebuilds the draft in the window's language, so a translated value
/// would come back on the next save.
#[test]
fn a_config_saved_in_chinese_keeps_its_font_and_color_names() {
crate::test_env::in_language_child(
concat!(
module_path!(),
"::a_config_saved_in_chinese_keeps_its_font_and_color_names"
),
|| {
wayscriber::i18n::set_language(wayscriber::domain::Language::SimplifiedChinese);
let mut config = Config::default();
config.drawing.font_style = "italic".to_string();
config.drawing.font_weight = "light".to_string();
config.drawing.default_color = ColorSpec::Name("blue".to_string());
config.drawing.quick_colors.entries = vec![QuickColorConfig {
label: "Leaf".to_string(),
color: ColorSpec::Name("green".to_string()),
}];

let draft = ConfigDraft::from_config(&config);
assert_eq!(draft.drawing_font_style, "italic");
assert_eq!(draft.drawing_font_weight, "light");
let saved = draft.to_config(&config).expect("unchanged draft");

assert_eq!(saved.drawing.font_style, "italic");
assert_eq!(saved.drawing.font_weight, "light");
assert_eq!(
saved.drawing.default_color,
ColorSpec::Name("blue".to_string())
);
assert_eq!(
saved.drawing.quick_colors.entries[0].color,
ColorSpec::Name("green".to_string())
);
if let Err(error) = saved.validate_for_save() {
panic!("{error}");
}
},
);
}

#[test]
fn config_draft_preserves_implicit_quick_color_defaults() {
let config = Config::default();
Expand Down
36 changes: 18 additions & 18 deletions configurator/src/models/fields/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ impl FontStyleOption {

pub fn canonical_value(&self) -> &'static str {
match self {
Self::Normal => tr("normal"),
Self::Italic => tr("italic"),
Self::Oblique => tr("oblique"),
Self::Normal => "normal",
Self::Italic => "italic",
Self::Oblique => "oblique",
Self::Custom => "",
}
}

pub fn from_value(value: &str) -> (Self, String) {
let lower = value.trim().to_lowercase();
match lower.as_str() {
"normal" => (Self::Normal, tr("normal").to_string()),
"italic" => (Self::Italic, tr("italic").to_string()),
"oblique" => (Self::Oblique, tr("oblique").to_string()),
"normal" => (Self::Normal, "normal".to_string()),
"italic" => (Self::Italic, "italic".to_string()),
"oblique" => (Self::Oblique, "oblique".to_string()),
_ => (Self::Custom, value.to_string()),
}
}
Expand Down Expand Up @@ -86,25 +86,25 @@ impl FontWeightOption {

pub fn canonical_value(&self) -> &'static str {
match self {
Self::Normal => tr("normal"),
Self::Bold => tr("bold"),
Self::Light => tr("light"),
Self::Ultralight => tr("ultralight"),
Self::Heavy => tr("heavy"),
Self::Ultrabold => tr("ultrabold"),
Self::Normal => "normal",
Self::Bold => "bold",
Self::Light => "light",
Self::Ultralight => "ultralight",
Self::Heavy => "heavy",
Self::Ultrabold => "ultrabold",
Self::Custom => "",
}
}

pub fn from_value(value: &str) -> (Self, String) {
let lower = value.trim().to_lowercase();
match lower.as_str() {
"normal" => (Self::Normal, tr("normal").to_string()),
"bold" => (Self::Bold, tr("bold").to_string()),
"light" => (Self::Light, tr("light").to_string()),
"ultralight" => (Self::Ultralight, tr("ultralight").to_string()),
"heavy" => (Self::Heavy, tr("heavy").to_string()),
"ultrabold" => (Self::Ultrabold, tr("ultrabold").to_string()),
"normal" => (Self::Normal, "normal".to_string()),
"bold" => (Self::Bold, "bold".to_string()),
"light" => (Self::Light, "light".to_string()),
"ultralight" => (Self::Ultralight, "ultralight".to_string()),
"heavy" => (Self::Heavy, "heavy".to_string()),
"ultrabold" => (Self::Ultrabold, "ultrabold".to_string()),
_ => (Self::Custom, value.to_string()),
}
}
Expand Down
66 changes: 66 additions & 0 deletions configurator/src/models/fields/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,72 @@ fn font_weight_option_handles_custom_values() {
assert_eq!(value, "UltraHeavy");
}

#[test]
fn config_values_do_not_follow_the_interface_language() {
crate::test_env::in_language_child(
concat!(
module_path!(),
"::config_values_do_not_follow_the_interface_language"
),
|| {
use wayscriber::config::ColorSpec;
use wayscriber::domain::Language;

const STYLES: [&str; 4] = ["normal", "italic", "oblique", ""];
const WEIGHTS: [&str; 7] = [
"normal",
"bold",
"light",
"ultralight",
"heavy",
"ultrabold",
"",
];
const COLORS: [&str; 8] = [
"red", "green", "blue", "yellow", "orange", "pink", "white", "black",
];
for language in [Language::English, Language::SimplifiedChinese] {
wayscriber::i18n::set_language(language);
// The overlay parses these words; a translated one is an
// invalid font value or an unknown color.
let styles: Vec<_> = FontStyleOption::list()
.iter()
.map(FontStyleOption::canonical_value)
.collect();
assert_eq!(styles, STYLES, "{language:?}");
let weights: Vec<_> = FontWeightOption::list()
.iter()
.map(FontWeightOption::canonical_value)
.collect();
assert_eq!(weights, WEIGHTS, "{language:?}");
for option in FontStyleOption::list() {
let value = option.canonical_value();
assert_eq!(FontStyleOption::from_value(value).1, value, "{language:?}");
}
for option in FontWeightOption::list() {
let value = option.canonical_value();
assert_eq!(FontWeightOption::from_value(value).1, value, "{language:?}");
}

let named: Vec<_> = crate::models::NamedColorOption::list()
.iter()
.map(|option| option.as_value())
.collect();
assert_eq!(named[..COLORS.len()], COLORS, "{language:?}");
let drag: Vec<_> = DragColorOption::list()
.into_iter()
.filter_map(|option| option.to_color_spec(None))
.collect();
assert_eq!(
drag,
COLORS.map(|name| ColorSpec::Name(name.to_string())),
"{language:?}"
);
}
},
);
}

#[test]
fn status_position_option_round_trips() {
let option = StatusPositionOption::from_status_position(StatusPosition::BottomRight);
Expand Down
16 changes: 8 additions & 8 deletions configurator/src/models/fields/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,14 @@ impl DragColorOption {
let name = match self {
Self::Current => return None,
Self::Custom => return existing,
Self::Red => tr("red"),
Self::Green => tr("green"),
Self::Blue => tr("blue"),
Self::Yellow => tr("yellow"),
Self::Orange => tr("orange"),
Self::Pink => tr("pink"),
Self::White => tr("white"),
Self::Black => tr("black"),
Self::Red => "red",
Self::Green => "green",
Self::Blue => "blue",
Self::Yellow => "yellow",
Self::Orange => "orange",
Self::Pink => "pink",
Self::White => "white",
Self::Black => "black",
};
Some(ColorSpec::Name(name.to_string()))
}
Expand Down
6 changes: 3 additions & 3 deletions docs/I18N.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ name, a file name — is never translated. Canvas content (typed text, sticky
notes, board and page names) is user data and stays as the user wrote it.

Displayed text is never an identifier. Widget IDs, stack page names, CSS names,
config keys and action IDs are fixed English spellings derived from typed
values, never from a label, and no code compares a label with translated text
to decide what to do.
config keys, config values such as `bold` or `blue`, and action IDs are fixed
English spellings derived from typed values, never from a label, and no code
compares a label with translated text to decide what to do.

### What is not translated

Expand Down
16 changes: 0 additions & 16 deletions locales/zh-CN.toml
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,10 @@
"Balanced" = "均衡"
"Bend" = "弯曲"
"Black" = "黑色"
"black" = "黑色"
"Black out" = "涂黑"
"Blackboard" = "黑板"
"Blackboard Mode" = "黑板模式"
"Blue" = "蓝色"
"blue" = "蓝色"
"Blue (0-255)" = "蓝 (0-255)"
"Blur" = "模糊"
"Blur sensitive regions on captured backgrounds" = "模糊截图背景中的敏感区域"
Expand Down Expand Up @@ -256,7 +254,6 @@
"Boards: click to switch or add one" = "画板:点击可切换或新建"
"Boards: prev/next/new/del." = "画板:上一个/下一个/新建/删除。"
"Bold" = "加粗"
"bold" = "粗体"
"Bold. Applies to selected text, or to the next label you type." = "加粗。应用于选中的文字或下一个输入的标签"
"Border (hex)" = "边框(十六进制)"
"Border width" = "边框宽度"
Expand Down Expand Up @@ -859,12 +856,10 @@
"Go to previous page" = "转到上一页"
"Got it" = "知道了"
"Green" = "绿色"
"green" = "绿色"
"Green (0-255)" = "绿 (0-255)"
"Grid spacing (8–200 logical pixels)" = "网格间距(8–200 逻辑像素)"
"gsettings is not available in {}." = "{} 中找不到 gsettings。"
"Heavy" = "粗体"
"heavy" = "粗"
"Help" = "帮助"
"Help Overlay" = "帮助叠层"
"Help Overlay Style" = "帮助叠层样式"
Expand Down Expand Up @@ -960,7 +955,6 @@
"Invalid user service path" = "无效的用户服务路径"
"Irons out the finest jitter" = "消除最细微的抖动"
"Italic" = "斜体"
"italic" = "斜体"
"Jump to Conflict" = "跳转到冲突"
"Jump to conflicting action" = "跳转到冲突的操作"
"just now" = "刚刚"
Expand Down Expand Up @@ -1008,7 +1002,6 @@
"Less smoothing" = "减少平滑"
"Letter" = "信纸"
"Light" = "灯光"
"light" = "细"
"Light controls include: {}" = "灯光控制包含文件:{}"
"Light controls setup available via Hyprland native bindings" = "灯光控制可通过 Hyprland 原生绑定设置"
"Light controls setup requires manual compositor bindings" = "灯光控制需要手动添加合成器绑定"
Expand Down Expand Up @@ -1211,7 +1204,6 @@
"none" = "无"
"None" = "无"
"Normal" = "常规"
"normal" = "常规"
"Not a hex color" = "不是十六进制颜色"
"Not configured" = "未配置"
"Not installed" = "未安装"
Expand All @@ -1229,7 +1221,6 @@
"Nudge Selection Up" = "选区上移"
"Nudge Selection Up (Large)" = "选区上移(大幅)"
"Oblique" = "倾斜"
"oblique" = "倾斜"
"OCR is already running" = "文字识别已在运行"
"OCR languages (e.g. eng, eng+deu; needs the matching Tesseract packages)" = "文字识别语言(例如 eng、eng+deu;需要对应的 Tesseract 语言包)"
"OCR languages: {}." = "文字识别语言:{}。"
Expand Down Expand Up @@ -1285,7 +1276,6 @@
"Opening session folder..." = "正在打开会话文件夹..."
"Opens wayscriber.com · your app details come along" = "打开 wayscriber.com · 会附带应用信息"
"Orange" = "橙色"
"orange" = "橙色"
"Order" = "顺序"
"Orientation" = "方向"
"Outline (hex)" = "描边(十六进制)"
Expand Down Expand Up @@ -1387,7 +1377,6 @@
"Pin top toolbar" = "固定顶部工具栏"
"Pin: click to open at startup" = "固定:点击以在启动时打开"
"Pink" = "粉色"
"pink" = "粉色"
"Pinned" = "已固定"
"Pinned: opens at startup (click to disable)" = "已固定:启动时打开(点击禁用)"
"Pixelate" = "像素化"
Expand Down Expand Up @@ -1514,7 +1503,6 @@
"Rectangle" = "矩形"
"Rectangle Tool" = "矩形工具"
"Red" = "红色"
"red" = "红色"
"Red (0-255)" = "红 (0-255)"
"Redo" = "重做"
"Redo All" = "全部重做"
Expand Down Expand Up @@ -2192,9 +2180,7 @@
"Type to search... (Esc clears)" = "输入以搜索…(Esc 清除)"
"UI & Modes" = "界面与模式"
"Ultrabold" = "特粗"
"ultrabold" = "特粗"
"Ultralight" = "特细"
"ultralight" = "特细"
"Unable to locate `wayscriber` binary. Set {} or install `wayscriber` in {}." = "找不到 `wayscriber` 可执行文件。请设置 {} 或将 `wayscriber` 安装到 {} 中。"
"Unable to resolve config path." = "无法解析配置路径。"
"Unavailable" = "不可用"
Expand Down Expand Up @@ -2285,14 +2271,12 @@
"were saved to {} instead, in its recovery file {} because they exceed the session size limit" = "已改为保存到 {},即其恢复文件 {},因为它们超出了会话大小限制"
"What changed in each version" = "各版本的变化"
"White" = "白色"
"white" = "白色"
"Whiteboard" = "白板"
"Whiteboard Mode" = "白板模式"
"Width (px)" = "宽度(像素)"
"Working..." = "处理中..."
"Wrote Hyprland light controls to {}" = "已将 Hyprland 灯光控制写入 {}"
"Yellow" = "黄色"
"yellow" = "黄色"
"You are running {}. Wayscriber does not install updates itself. See {}" = "您正在运行 {}。Wayscriber 不会自行安装更新。请参阅 {}"
"You can change this later in the configurator." = "您可以稍后在配置器中更改。"
"You have unsaved changes. Save them, discard them, or cancel to keep editing." = "你有未保存的更改。保存、放弃,或取消以继续编辑。"
Expand Down
Loading