fix(i18n): 复审 r1 —— 两句近义软件渲染说明合一,生效层级码翻成译文(M180)
P2-1(一屏两句重复):
- 留面板那一句(就在被禁用的滑块旁边,正好回答「为什么拖不动」),措辞同时点名面板与玻璃
- 删 `SettingsAppearanceSoftwareRendererNote`(catalog 一条 + 金表一行,两边同时删)
- 删 `bg_image.rs` 的 `backend_note` 渲染块与 `State::backend_note()`;state.rs 391 → 382 行
P2-2(配色:preset 的机器码):
- `palette::level_key(code)` 把 `preset`/`wallpaper`/其余 映射到已有的三条档位 key,不新增平行词表
- `bg_image.rs` 用 `tr(PaletteLevel, {level})` 传译文,中文界面显示「配色:内置色卡」
- 补 `every_level_code_maps_to_its_own_sentence`:三个码值一一对应 + 三条译文互不相同
顺手(复审 L-1/L-2/L-4,全在本 scope 内):
- `appearance_texts` 加「渲染后不许残留 `{`」断言(参数名写错当场红)
- `section/mod.rs` 文档:取词口 t/tr、填充措辞、清掉孤立 `//!`、把「没有一句英文」改成
写明两处例外(`{reason}` 原文串、专名)
This commit is contained in:
1 parent
c4c3c15285
commit
1d240ff1f2
7 files changed
+88
-32
No files matched your search
@@ -130,6 +130,24 @@ pub fn note(provenance: &Provenance) -> Option<Key> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 生效层级**码值** → 已有的那三条档位 key(M180 复审 P2-2:中文界面里不许留机器码)。
|
||||||
|
///
|
||||||
|
/// 码值的全部来源只有两处,取值集合相同:`Level::code()`(`background-image` / `wallpaper` /
|
||||||
|
/// `preset`)与 `PaletteSource::as_str()`(同三个词)。所以三条 key 就够,**不新增平行词表**——
|
||||||
|
/// 卡片底部「配色来源」用它们表示**用户选的**档,这一行用它们表示**回落之后真正生效**的档。
|
||||||
|
///
|
||||||
|
/// 未识别的码值落到 `background-image` 那条(宁可显示一个偏保守的档名,也不许把机器码漏进
|
||||||
|
/// 中文界面——这条兜底本身由 `tests` 里的 `every_level_code_maps_to_its_own_sentence` 钉住)。
|
||||||
|
/// `state.rs` 已贴 400 行线,所以这个映射住在本文件。
|
||||||
|
#[must_use]
|
||||||
|
pub fn level_key(code: &str) -> Key {
|
||||||
|
match code {
|
||||||
|
"preset" => Key::SettingsAppearancePalettePreset,
|
||||||
|
"wallpaper" => Key::SettingsAppearancePaletteWallpaper,
|
||||||
|
_ => Key::SettingsAppearancePaletteBackground,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{note, resolve, Source};
|
use super::{note, resolve, Source};
|
||||||
@@ -273,4 +291,40 @@ mod tests {
|
|||||||
None
|
None
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **M180 复审 P2-2 的守门**:生效层级的**每一个码值**都必须映射到它自己那条中文句子。
|
||||||
|
///
|
||||||
|
/// 抓得住:① 三个码值被映射到同一条 key(界面上分不出到底生效的是哪一级);
|
||||||
|
/// ② 某条映射被删掉 / 写错(`preset` 落到 background 那条 ⇒ 中文界面说「取自背景图」);
|
||||||
|
/// ③ 有人再加一级却忘了扩映射。
|
||||||
|
/// 抓不住:译文本身的措辞(那是 `catalog/settings/appearance.rs` 的译文守卫的事)。
|
||||||
|
///
|
||||||
|
/// 变异证明:把 `"preset"` 那行删掉(落进兜底)⇒ 本条红,且 `assert_ne!` 直接点名码值。
|
||||||
|
///
|
||||||
|
/// 为什么这条必须有:`the_appearance_card_speaks_chinese` 断的是**整句**非 ASCII,
|
||||||
|
/// 而「配色:preset」里有汉字 ⇒ 整句非 ASCII ⇒ 那个守卫放过它。这个口子只能在这里堵。
|
||||||
|
#[test]
|
||||||
|
fn every_level_code_maps_to_its_own_sentence() {
|
||||||
|
use super::level_key;
|
||||||
|
|
||||||
|
let codes = ["background-image", "wallpaper", "preset"];
|
||||||
|
let keys: Vec<Key> = codes.iter().copied().map(level_key).collect();
|
||||||
|
assert_eq!(
|
||||||
|
keys,
|
||||||
|
vec![
|
||||||
|
Key::SettingsAppearancePaletteBackground,
|
||||||
|
Key::SettingsAppearancePaletteWallpaper,
|
||||||
|
Key::SettingsAppearancePalettePreset,
|
||||||
|
],
|
||||||
|
"码值与档位 key 必须一一对应"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 三条中文句子互不相同(否则「映射对了」但界面上仍分不出层级)。
|
||||||
|
let zh = unlucky_i18n::Lang::ZhCn.catalog();
|
||||||
|
let mut texts: Vec<&str> = keys.iter().map(|key| zh.text(*key)).collect();
|
||||||
|
let total = texts.len();
|
||||||
|
texts.sort_unstable();
|
||||||
|
texts.dedup();
|
||||||
|
assert_eq!(texts.len(), total, "三条档位译文有重复:{texts:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@ use crate::pages::Message;
|
|||||||
use crate::theme::Ui;
|
use crate::theme::Ui;
|
||||||
|
|
||||||
use super::super::background::{self, BG_DIM_MAX};
|
use super::super::background::{self, BG_DIM_MAX};
|
||||||
|
use super::super::palette;
|
||||||
use super::super::state::State;
|
use super::super::state::State;
|
||||||
use super::super::Change;
|
use super::super::Change;
|
||||||
use super::{choice, choice_row, fixed2, label, note_line, slider_row, t, tr, tr_note};
|
use super::{choice, choice_row, fixed2, label, note_line, slider_row, t, tr, tr_note};
|
||||||
@@ -66,19 +67,15 @@ pub(super) fn push<'a>(
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// ⑥ 诊断(读盘失败 / CPU 降级 / 配色回落)——**不许静默**,且必须在**首屏可见处**
|
// ⑥ 诊断(读盘失败 / 配色回落)——**不许静默**,且必须在**首屏可见处**
|
||||||
// (复审 r1 P2-3:文案落在折叠线以下等于没提示)。位置就在背景图那两行的紧下方。
|
// (复审 r1 P2-3:文案落在折叠线以下等于没提示)。位置就在背景图那两行的紧下方。
|
||||||
|
//
|
||||||
|
// CPU 档的「面板/玻璃被强制」那句**不在这里**:它是张卡级状态,挂在被禁用的面板滑块旁边
|
||||||
|
// (`panel.rs` 的 `PanelOpacityForcedHint`),一屏只出现一次(M180 复审 P2-1)。
|
||||||
for note in state.diagnostics() {
|
for note in state.diagnostics() {
|
||||||
let text = tr_note(lang, note);
|
let text = tr_note(lang, note);
|
||||||
rows.push(note_line(ui, &text, ui.color(Role::Error)));
|
rows.push(note_line(ui, &text, ui.color(Role::Error)));
|
||||||
}
|
}
|
||||||
if let Some(key) = state.backend_note() {
|
|
||||||
rows.push(note_line(
|
|
||||||
ui,
|
|
||||||
t(key, lang),
|
|
||||||
ui.color(Role::OnSurfaceVariant),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if let Some(note) = state
|
if let Some(note) = state
|
||||||
.image()
|
.image()
|
||||||
.and_then(|image| background::small_tile_note(image, state.bg_fill))
|
.and_then(|image| background::small_tile_note(image, state.bg_fill))
|
||||||
@@ -93,10 +90,12 @@ pub(super) fn push<'a>(
|
|||||||
ui.color(Role::OnSurfaceVariant),
|
ui.color(Role::OnSurfaceVariant),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
// 生效的配色层级:显示的是**回落之后真正生效**的那一级(与底部「配色来源」里用户选的那一档
|
||||||
|
// 不一定相同)。码值 → 已有的三条档位 key(不新增平行词表),所以中文界面也读得懂。
|
||||||
let level = tr(
|
let level = tr(
|
||||||
lang,
|
lang,
|
||||||
Key::SettingsAppearancePaletteLevel,
|
Key::SettingsAppearancePaletteLevel,
|
||||||
&[("level", state.palette_level())],
|
&[("level", t(palette::level_key(state.palette_level()), lang))],
|
||||||
);
|
);
|
||||||
rows.push(note_line(ui, &level, ui.color(Role::OnSurfaceVariant)));
|
rows.push(note_line(ui, &level, ui.color(Role::OnSurfaceVariant)));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
//! | 面板透明度滑块(下限 0.4,CPU 档禁用) | `appearance.panel_alpha` | [`Change::PanelAlpha`] |
|
//! | 面板透明度滑块(下限 0.4,CPU 档禁用) | `appearance.panel_alpha` | [`Change::PanelAlpha`] |
|
||||||
//! | 背景图开关 | `appearance.bg_image_enabled` | [`Change::BgEnabled`] |
|
//! | 背景图开关 | `appearance.bg_image_enabled` | [`Change::BgEnabled`] |
|
||||||
//! | 背景图路径(文本框) | `appearance.bg_image` | [`Change::BgImage`] |
|
//! | 背景图路径(文本框) | `appearance.bg_image` | [`Change::BgImage`] |
|
||||||
//! | 填充(封面 / 拉伸 / 平铺) | `appearance.bg_fill` | [`Change::BgFill`] |
|
//! | 填充(铺满 / 完整显示 / 平铺) | `appearance.bg_fill` | [`Change::BgFill`] |
|
||||||
//! | 暗化强度(0~0.95) | `appearance.bg_dim` | [`Change::BgDim`] |
|
//! | 暗化强度(0~0.95) | `appearance.bg_dim` | [`Change::BgDim`] |
|
||||||
//! | 配色来源(三档) | `appearance.palette_source` | [`Change::PaletteSource`] |
|
//! | 配色来源(三档) | `appearance.palette_source` | [`Change::PaletteSource`] |
|
||||||
//!
|
//!
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
//!
|
//!
|
||||||
//! | 文件 | 是什么 |
|
//! | 文件 | 是什么 |
|
||||||
//! |---|---|
|
//! |---|---|
|
||||||
//! | 本文件(`section/mod.rs`) | **壳**:[`section`] 按顺序拼各段 + [`card`] 卡片 + 行控件([`label`] / [`slider_row`] / [`choice_row`] / [`choice`] / [`note_line`])+ 取词口 [`t`] |
|
//! | 本文件(`section/mod.rs`) | **壳**:[`section`] 按顺序拼各段 + [`card`] 卡片 + 行控件([`label`] / [`slider_row`] / [`choice_row`] / [`choice`] / [`note_line`])+ 两个取词口 [`t`] / [`tr`] |
|
||||||
//! | [`window`] | ① 整窗透明度 + ② 窗口圆角(含「因整窗 α 不生效」的 notice 与说明段) |
|
//! | [`window`] | ① 整窗透明度 + ② 窗口圆角(含「因整窗 α 不生效」的 notice 与说明段) |
|
||||||
//! | [`panel`] | ③ 面板透明度(CPU 档强制 1.0,值 / 生效值分开显示) |
|
//! | [`panel`] | ③ 面板透明度(CPU 档强制 1.0,值 / 生效值分开显示) |
|
||||||
//! | [`bg_image`] | ④ 背景图开关 + ⑤ 路径 + ⑥ 诊断 + ⑦ 填充 + ⑧ 暗化 |
|
//! | [`bg_image`] | ④ 背景图开关 + ⑤ 路径 + ⑥ 诊断 + ⑦ 填充 + ⑧ 暗化 |
|
||||||
@@ -41,8 +41,12 @@
|
|||||||
//! `lang` 从 `settings::view` 的 `Language.effective` → `Group.body` → [`section`] 一路递进来。
|
//! `lang` 从 `settings::view` 的 `Language.effective` → `Group.body` → [`section`] 一路递进来。
|
||||||
//! M179 只把管子接通(当时本组 27 条文案里真正本地化的只有圆角那 5 条);M180 `I18NAPPEAR` 把
|
//! M179 只把管子接通(当时本组 27 条文案里真正本地化的只有圆角那 5 条);M180 `I18NAPPEAR` 把
|
||||||
//! 剩下 22 条字面量与 `state.rs` / `background.rs` / `palette.rs` 的运行时诊断全部搬进
|
//! 剩下 22 条字面量与 `state.rs` / `background.rs` / `palette.rs` 的运行时诊断全部搬进
|
||||||
//! `catalog/settings/appearance.rs`,于是中文界面上这一页**没有一句是英文**。
|
//! `catalog/settings/appearance.rs`,于是中文界面上这一页的**卡片文案**没有一句是英文。
|
||||||
|
//!
|
||||||
|
//! 两处例外(M180 复审 L-1 记下的口径):① 写进 `{reason}` 的**原因串**里,来自本仓库自写的
|
||||||
|
//! 两条(`"no path configured"`、`"unknown image format …"`)与 OS / 解码库给出的文本仍是英文——
|
||||||
|
//! 它们是不可翻译的第三方或诊断原文;② `Windows 11` / `macOS` / `Linux` / `PNG` / `JPEG` / `BMP`
|
||||||
|
//! 这些专名。除此之外这一页不出现英文。
|
||||||
//!
|
//!
|
||||||
//! ## 为什么「值」与「生效值」分开显示
|
//! ## 为什么「值」与「生效值」分开显示
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -203,15 +203,6 @@ impl State {
|
|||||||
&self.diagnostics
|
&self.diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CPU 档降级的说明 key(`None` = 没有降级)。
|
|
||||||
///
|
|
||||||
/// M180:返回 key 而不是英文句子——本文件已 390 行、贴着 400 行硬线,**不放文案表**。
|
|
||||||
#[must_use]
|
|
||||||
pub fn backend_note(&self) -> Option<Key> {
|
|
||||||
self.panel_is_forced()
|
|
||||||
.then_some(Key::SettingsAppearanceSoftwareRendererNote)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 配色来源的提示 key(`None` = 一级成功)。
|
/// 配色来源的提示 key(`None` = 一级成功)。
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn palette_note(&self) -> Option<Key> {
|
pub fn palette_note(&self) -> Option<Key> {
|
||||||
|
|||||||
@@ -119,6 +119,17 @@ fn appearance_texts(lang: Lang, case: Case) -> Vec<(Key, String)> {
|
|||||||
.map(|(key, text)| (key, text.to_owned()))
|
.map(|(key, text)| (key, text.to_owned()))
|
||||||
.collect();
|
.collect();
|
||||||
texts.extend(probe::take_rendered());
|
texts.extend(probe::take_rendered());
|
||||||
|
|
||||||
|
// 复审 L-2:`{name}` 换完还留着花括号 ⇒ 某处参数名与模板不一致(`("floor", …)` 写成
|
||||||
|
// `("flor", …)` 时句子会原样显示「下限 {floor}」,而「整句非 ASCII」的守卫看不出来)。
|
||||||
|
// 三档状态合起来覆盖本页全部 `tr()` 调用,所以这条断言是全覆盖的。
|
||||||
|
for (key, text) in &texts {
|
||||||
|
assert!(
|
||||||
|
!text.contains('{'),
|
||||||
|
"{case:?}:{} 渲染后还留着占位符「{text}」——`tr()` 的参数名与模板对不上",
|
||||||
|
key.name()
|
||||||
|
);
|
||||||
|
}
|
||||||
texts
|
texts
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +161,6 @@ const CARD_KEYS: &[Key] = &[
|
|||||||
Key::SettingsAppearancePanelOpacityHint,
|
Key::SettingsAppearancePanelOpacityHint,
|
||||||
Key::SettingsAppearancePanelOpacityForcedValue,
|
Key::SettingsAppearancePanelOpacityForcedValue,
|
||||||
Key::SettingsAppearancePanelOpacityForcedHint,
|
Key::SettingsAppearancePanelOpacityForcedHint,
|
||||||
Key::SettingsAppearanceSoftwareRendererNote,
|
|
||||||
Key::SettingsAppearanceBackgroundImage,
|
Key::SettingsAppearanceBackgroundImage,
|
||||||
Key::SettingsAppearanceOff,
|
Key::SettingsAppearanceOff,
|
||||||
Key::SettingsAppearanceOn,
|
Key::SettingsAppearanceOn,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ pub(super) const ROWS: &[(&str, &str, &str)] = &[
|
|||||||
("SettingsAppearancePanelOpacity", "Panel transparency", "面板透明度"),
|
("SettingsAppearancePanelOpacity", "Panel transparency", "面板透明度"),
|
||||||
("SettingsAppearancePanelOpacityHint", "Only the panel/card layer. Floor {floor}; independent of window transparency.", "只作用于面板 / 卡片这一层。下限 {floor};与整窗透明度互不影响。"),
|
("SettingsAppearancePanelOpacityHint", "Only the panel/card layer. Floor {floor}; independent of window transparency.", "只作用于面板 / 卡片这一层。下限 {floor};与整窗透明度互不影响。"),
|
||||||
("SettingsAppearancePanelOpacityForcedValue", "100% (forced from {requested})", "100%(强制,原请求值 {requested})"),
|
("SettingsAppearancePanelOpacityForcedValue", "100% (forced from {requested})", "100%(强制,原请求值 {requested})"),
|
||||||
("SettingsAppearancePanelOpacityForcedHint", "Software renderer: panels stay fully opaque (window transparency still works).", "软件渲染:面板恒为不透明(整窗透明度仍然有效)。"),
|
("SettingsAppearancePanelOpacityForcedHint", "Software renderer: panels and glass stay fully opaque (window transparency still works).", "软件渲染:面板与玻璃效果恒为不透明(整窗透明度仍然有效)。"),
|
||||||
("SettingsAppearanceBackgroundImage", "Background image", "背景图"),
|
("SettingsAppearanceBackgroundImage", "Background image", "背景图"),
|
||||||
("SettingsAppearanceOff", "Off", "关"),
|
("SettingsAppearanceOff", "Off", "关"),
|
||||||
("SettingsAppearanceOn", "On", "开"),
|
("SettingsAppearanceOn", "On", "开"),
|
||||||
@@ -54,7 +54,6 @@ pub(super) const ROWS: &[(&str, &str, &str)] = &[
|
|||||||
("SettingsAppearancePaletteBackground", "Background", "取自背景图"),
|
("SettingsAppearancePaletteBackground", "Background", "取自背景图"),
|
||||||
("SettingsAppearancePaletteWallpaper", "Wallpaper", "取自壁纸"),
|
("SettingsAppearancePaletteWallpaper", "Wallpaper", "取自壁纸"),
|
||||||
("SettingsAppearancePalettePreset", "Preset", "内置色卡"),
|
("SettingsAppearancePalettePreset", "Preset", "内置色卡"),
|
||||||
("SettingsAppearanceSoftwareRendererNote", "Software renderer: panel transparency and glass stay fully opaque (window transparency still works).", "软件渲染:面板透明度与玻璃效果恒为不透明(整窗透明度仍然有效)。"),
|
|
||||||
("SettingsAppearanceBgReadFailed", "Background image could not be read: {reason}", "背景图读不出来:{reason}"),
|
("SettingsAppearanceBgReadFailed", "Background image could not be read: {reason}", "背景图读不出来:{reason}"),
|
||||||
("SettingsAppearanceBgDecodeFailed", "Background image could not be decoded ({reason}; this build decodes PNG, JPEG and BMP)", "背景图解不开({reason};这个构建只支持 PNG、JPEG 与 BMP)"),
|
("SettingsAppearanceBgDecodeFailed", "Background image could not be decoded ({reason}; this build decodes PNG, JPEG and BMP)", "背景图解不开({reason};这个构建只支持 PNG、JPEG 与 BMP)"),
|
||||||
("SettingsAppearanceBgTooLarge", "Background image is too large to decode: {width}×{height} (limit {limit} px per edge)", "背景图太大,解不开:{width}×{height}(每边上限 {limit} 像素)"),
|
("SettingsAppearanceBgTooLarge", "Background image is too large to decode: {width}×{height} (limit {limit} px per edge)", "背景图太大,解不开:{width}×{height}(每边上限 {limit} 像素)"),
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ macro_rules! settings_appearance_entries {
|
|||||||
"100%(强制,原请求值 {requested})"
|
"100%(强制,原请求值 {requested})"
|
||||||
),
|
),
|
||||||
SettingsAppearancePanelOpacityForcedHint => (
|
SettingsAppearancePanelOpacityForcedHint => (
|
||||||
"Software renderer: panels stay fully opaque (window transparency still works).",
|
"Software renderer: panels and glass stay fully opaque (window transparency still works).",
|
||||||
"软件渲染:面板恒为不透明(整窗透明度仍然有效)。"
|
"软件渲染:面板与玻璃效果恒为不透明(整窗透明度仍然有效)。"
|
||||||
),
|
),
|
||||||
SettingsAppearanceBackgroundImage => ("Background image", "背景图"),
|
SettingsAppearanceBackgroundImage => ("Background image", "背景图"),
|
||||||
SettingsAppearanceOff => ("Off", "关"),
|
SettingsAppearanceOff => ("Off", "关"),
|
||||||
@@ -91,11 +91,10 @@ macro_rules! settings_appearance_entries {
|
|||||||
SettingsAppearancePaletteBackground => ("Background", "取自背景图"),
|
SettingsAppearancePaletteBackground => ("Background", "取自背景图"),
|
||||||
SettingsAppearancePaletteWallpaper => ("Wallpaper", "取自壁纸"),
|
SettingsAppearancePaletteWallpaper => ("Wallpaper", "取自壁纸"),
|
||||||
SettingsAppearancePalettePreset => ("Preset", "内置色卡"),
|
SettingsAppearancePalettePreset => ("Preset", "内置色卡"),
|
||||||
// ---- M180:运行时诊断(`state.rs` 的 backend_note + `background.rs` 的三种读盘失败 + 小图平铺)
|
// ---- M180:运行时诊断(`background.rs` 的三种读盘失败 + 小图平铺)。
|
||||||
SettingsAppearanceSoftwareRendererNote => (
|
//
|
||||||
"Software renderer: panel transparency and glass stay fully opaque (window transparency still works).",
|
// M180 r1 复审 P2-1:软件渲染那句**只有一条**,就挂在面板那一行(`PanelOpacityForcedHint`)
|
||||||
"软件渲染:面板透明度与玻璃效果恒为不透明(整窗透明度仍然有效)。"
|
// 上——它挨着被禁用的滑块,正好回答「为什么拖不动」;这里不再有第二句。
|
||||||
),
|
|
||||||
SettingsAppearanceBgReadFailed => (
|
SettingsAppearanceBgReadFailed => (
|
||||||
"Background image could not be read: {reason}",
|
"Background image could not be read: {reason}",
|
||||||
"背景图读不出来:{reason}"
|
"背景图读不出来:{reason}"
|
||||||
|
|||||||
Reference in new issue
Block a user