新增 crates/app-iced(package `unlucky-app-iced`,bin `unlucky-launcher-iced`),与 Slint 版并存, 为 D26「UI 从头写」打地基。本 mission 只做骨架:能开窗、颜色/字体对、层级在,不做业务页面。 - 后端(D27):启动探测 wgpu 适配器(只看 device_type,避开 WARP 误判)→ 写 ICED_BACKEND; auto/gpu/cpu 三条路径都保留 tiny-skia 兜底,绝不硬失败;`--renderer=cpu` 跳过探测(省 ~0.85s) - 字体(D28 前半):令牌三平台字体栈 → 用 iced 全局 FontSystem 查装机情况 → 族名与 400/500/700 字重落点(缺档按 Nearest/Synthetic 记录)打一行启动日志 - 令牌适配层 theme::Ui:唯一把 unlucky-design 的值翻成 iced Color/Font/Border/Radius/Theme 的地方; 49 个 M3 角色留在自己的 Scheme 里,iced 的 6 色 Palette 只给 devtools - 骨架:1180×760 无边框窗口、48 高自绘标题栏(drag + 东/南 drag_resize + 最小化/最大化/关闭)、 88 宽导航轨(56×32 SecondaryContainer 药丸,由令牌推导)、页头 56 + 一张 OutlinedCard - 主题:系统主题探测 + --theme,切主题只重建 Ui(Theme::name 变化触发重算),不动 UI 状态 - 截图通道:`--screenshot <png>` + `--screenshot-theme`(真开窗第 3 帧出图),以及 `--diff <a> <b>` 自带逐像素对比(CI 不依赖 Python/ImageMagick) - 图标:令牌 SVG path → iced svg 控件(颜色走 alpha 蒙版,深浅共用一份位图缓存) - 门禁:tests/no_hardcoded_tokens.rs 扫源码挡色值/尺寸字面量 + 挡 slint 依赖(自检也算过) 实测(Windows Server 2025 / 96 DPI / RX 6600 XT):浅/深 × GPU/CPU 四张真开窗截图;GPU vs CPU 差异 0.72% 像素、全部落在字形/图标抗锯齿与 1px 圆角描边、最佳对齐 (0,0)、平坦区颜色逐字节相同; release 体积双后端 6.44 MiB / 仅 CPU 3.75 MiB;首帧 GPU 1.18~1.31s、CPU 33~37ms。 未做/未验证:macOS 与 Wayland 全链路、西/北边缩放热区、letter spacing(iced 0.14 无此属性)、 中文 CDN 字体、玻璃;翻牌步骤写在 DevDocs/SubAgentsTalk/app-iced-骨架与翻牌.md(不入库)。
56 lines
2.3 KiB
Rust
56 lines
2.3 KiB
Rust
//! # unlucky-app-iced · iced 版桌面壳(P4 / D26)
|
||
//!
|
||
//! 本 crate 是「UI 从头写」的第一步:**只做骨架**(能开窗、颜色/字体对、层级在),
|
||
//! 业务页面、组件库、i18n 全文案、玻璃 shader 都是后续 mission。
|
||
//!
|
||
//! | 模块 | 职责 | 不负责 |
|
||
//! |---|---|---|
|
||
//! | [`theme`] | 令牌(`unlucky-design`)→ iced 类型:`Color` / `Font` / `Radius` / `Theme` | 发明令牌值 |
|
||
//! | `cli` | `--renderer` / `--software-renderer` / `--theme` / `--screenshot*` 参数 | 业务开关 |
|
||
//! | `probe` | 渲染后端探测(D27)+ 写 `ICED_BACKEND`,失败自动降级 CPU | 绘制 |
|
||
//! | `fonts` | 字体栈求值(D28 前半):平台族名 → 系统字体库校验 → 启动日志 | 中文字体下载 |
|
||
//! | `app` / `shell` | Elm 三件套 + 自绘标题栏 / 导航轨 / 内容骨架 | 业务逻辑 |
|
||
//! | `shot` | `window::screenshot` → PNG(验收通道) | 图像比对 |
|
||
//! | `icons` | 令牌里的 SVG path → iced `svg` 控件 | 画新图标 |
|
||
//!
|
||
//! ## 消费纪律
|
||
//!
|
||
//! **组件层零硬编码色值/字号/半径/间距**:一律走 [`theme::Ui`]。守门测试在
|
||
//! `tests/no_hardcoded_tokens.rs`(扫 `src/**`,出现 `#RRGGBB` / `Color::from_rgb(` 即红)。
|
||
//!
|
||
//! ## 与 Slint 版的关系
|
||
//!
|
||
//! 并存期:`crates/app` 仍出 `unlucky-launcher`,本 crate 出 `unlucky-launcher-iced`。
|
||
//! 等价验收后翻牌(bin 改名 + 旧 crate 降级),步骤写在
|
||
//! `DevDocs/SubAgentsTalk/app-iced-骨架与翻牌.md`。
|
||
|
||
pub mod shot;
|
||
pub mod theme;
|
||
|
||
mod app;
|
||
mod cli;
|
||
mod fonts;
|
||
mod icons;
|
||
mod probe;
|
||
mod shell;
|
||
|
||
pub use cli::{Backend, Options};
|
||
pub use probe::Probe;
|
||
|
||
/// 启动 UI(阻塞到窗口关闭)。渲染后端由 `probe` 在 `run()` 之前写进 `ICED_BACKEND`。
|
||
pub fn run(options: Options) -> iced::Result {
|
||
app::run(options)
|
||
}
|
||
|
||
/// 与 [`run`] 同义,但把命令行做成最终结论:`Options::from_env()` + 启动日志。
|
||
///
|
||
/// 二进制入口用 [`Options::from_env`] + [`run`] 自己拼(要额外处理 `--diff`),这个函数留给
|
||
/// 集成测试与将来的 CLI 复用。
|
||
///
|
||
/// # Errors
|
||
/// 参数不合法时返回人话(不 panic、不 `exit`)。
|
||
pub fn run_from_env() -> Result<iced::Result, String> {
|
||
let options = Options::from_env()?;
|
||
Ok(run(options))
|
||
}
|