feat(app-iced): Ink Cat / Silver Cat 换肤 —— 双色板默认 + 规格卡组件几何(M229)
产品出厂外观从 tone 派生的 `Scheme::baseline` 切到品牌色板:深色 = Ink(淡绿)、 浅色 = Silver(钢蓝),D38 取色链(背景图 / 壁纸)仍然优先,取色失败回落到色板。 主题三档接进设置页「通用 → 主题」:Ink / Silver / 跟随系统(落盘仍是 `appearance.theme_mode` 的 dark / light / auto,不新增配置键)。 组件几何按规格卡对齐(M228 的 `inkcat` 登记项逐条落地): - 卡片圆角 12 → 16;实例元信息卡改用新的 ELEVATED CARD(无描边、SurfaceContainer 底、内距 24、上标注 11/600) - Snackbar 48/4 → 52/16(双行 72) - Checkbox 20/rx2 → 18/rx4;Radio 20 → 18 Ø(内点仍 10) - 按钮加 XS~XL 五档(产品仍只用 S=40),内距改走 ControlSize::pad_x - 新增 FAB 四态(40/56/80/160×56)与图标按钮第四式 outlined - 语言与主题两行 chips 统一成规格卡 chip(32 高 / rx8) `theme.rs` 原本正好 400 行,先把单测纯搬移到 `theme/tests.rs` 再加色板字段; `app/tests.rs`、`settings/general.rs` 同样按纯搬移拆分守 400 行硬线。 验证:cargo fmt --all --check、cargo check -p unlucky-app-iced --all-targets、 cargo test --workspace(除 clippy 前的一轮 flake,见报告)、cargo clippy --workspace --all-targets -- -D warnings、全仓 400 行扫描。视觉矩阵 42 张在 DevDocs/artifacts/m229/(gitignored,不进提交)。
This commit is contained in:
1 parent
a06b7ff4ec
commit
db541c820e
44 files changed
+1439
-300
No files matched your search
@@ -6,6 +6,8 @@
|
||||
//! 截图通道的判据 [`App::has_screenshot`] 也放在这儿:上面三条里两条都要「截图不读用户配置」。
|
||||
|
||||
use crate::app::diag::diag;
|
||||
use crate::app::message::Message;
|
||||
use iced::Task;
|
||||
use unlucky_design::color::SchemeFlavor;
|
||||
use unlucky_presenter::prefs::ThemeMode;
|
||||
|
||||
@@ -73,6 +75,8 @@ impl App {
|
||||
}
|
||||
let mode = self.bridge.load().1;
|
||||
self.theme_mode = mode;
|
||||
// M229:设置页那一行画的是这个字段(唯一写者见 [`App::set_theme_mode`])。
|
||||
self.settings.language_appearance.theme = mode;
|
||||
match mode {
|
||||
ThemeMode::Light => self.set_flavor(SchemeFlavor::Light),
|
||||
ThemeMode::Dark => self.set_flavor(SchemeFlavor::Dark),
|
||||
@@ -80,6 +84,68 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
/// 换主题档(M229:设置页「通用 → 主题」→ `pages::Message::Theme`)。
|
||||
///
|
||||
/// 四件事:①改 `theme_mode`(唯一真相)②同步设置页那一行的档位 ③重建 `Ui`(色板换了,
|
||||
/// `Theme::name` 与 49 个角色一起变,iced 才会重算缓存)④落盘 `appearance.theme_mode`。
|
||||
/// `Auto` 自己没有颜色,要等系统回答——所以返回 `iced::system::theme()` 那个 Task,
|
||||
/// 由既有的 `Message::SystemTheme` 分支落地(它只在 `theme_mode == Auto` 时吃这条消息)。
|
||||
pub(in crate::app) fn set_theme_mode(&mut self, mode: ThemeMode) -> Task<Message> {
|
||||
self.settings.language_appearance.theme = mode;
|
||||
if mode == self.theme_mode {
|
||||
return Task::none();
|
||||
}
|
||||
self.theme_mode = mode;
|
||||
|
||||
let prefs = self.appearance_prefs.clone();
|
||||
self.bridge.persist(&prefs, mode);
|
||||
match self.bridge.path() {
|
||||
Some(path) => diag!("[theme] mode={} 已写回 {}", mode.as_str(), path.display()),
|
||||
None => diag!(
|
||||
"[theme] mode={} 未落盘(数据根解析不出来,内存态运行):重启会回到旧值",
|
||||
mode.as_str()
|
||||
),
|
||||
}
|
||||
|
||||
match mode {
|
||||
ThemeMode::Light => {
|
||||
self.set_flavor(SchemeFlavor::Light);
|
||||
self.after_theme_switch();
|
||||
Task::none()
|
||||
}
|
||||
ThemeMode::Dark => {
|
||||
self.set_flavor(SchemeFlavor::Dark);
|
||||
self.after_theme_switch();
|
||||
Task::none()
|
||||
}
|
||||
// 跟随系统:当前先按已有深浅画,紧接着由系统主题回答覆盖
|
||||
// (`set_flavor` 有「同档不重建」的保护,所以这里不必先猜一次)。
|
||||
ThemeMode::Auto => iced::system::theme().map(Message::SystemTheme),
|
||||
}
|
||||
}
|
||||
|
||||
/// 换档之后重建视图模型 + 记一行取证日志(色板名就是证据:`ink` / `silver`)。
|
||||
fn after_theme_switch(&mut self) {
|
||||
self.view_dirty = true;
|
||||
self.refresh_view();
|
||||
diag!(
|
||||
"[theme] mode={} board={} Theme::name={}",
|
||||
self.theme_mode().as_str(),
|
||||
self.board_name(),
|
||||
self.ui.name()
|
||||
);
|
||||
}
|
||||
|
||||
/// 当前主题档(设置页那一行的选中态来自 `settings.groups`,这里是取证与测试的读数口)。
|
||||
pub(in crate::app) fn theme_mode(&self) -> ThemeMode {
|
||||
self.theme_mode
|
||||
}
|
||||
|
||||
/// 当前色板名(日志与测试用:`ink` / `silver`;取色方案接管时仍报它所属深浅的那块)。
|
||||
pub(in crate::app) fn board_name(&self) -> &'static str {
|
||||
self.ui.board().name()
|
||||
}
|
||||
|
||||
/// 当前令牌求值器(测试与截图日志用)。
|
||||
pub(in crate::app) fn ui(&self) -> &Ui {
|
||||
&self.ui
|
||||
|
||||
Reference in new issue
Block a user