D30 视觉审 hold 的必改项:滚动视口在 y=660 硬裁,把版本菜单的容器上沿切成 639–659 = 21px、 **零字形墨迹**的一条色块(深色下 (22,33,41) vs 画布 (9,21,28),CR 1.99),读起来像渲染错 而不是「下面还有内容可滚」。 改法(reviewer 推荐方案①,保留发现性): - 新增 `options/fade.rs::viewport_fade` + `VIEWPORT_FADE_PX = 12`:12 条 1px、α 单调上升的 **画布色**实色块拼成的斜坡(iced 0.14 没有渐变原语;1px 步进的差别在 1/255 量级); - `options::section` 的窄档分支把滚动区包一层 `stack![滚动区, 底部对齐的遮罩]`,遮罩贴着 视口内沿(≤660),压不到钉死区的实例名(≥668); - 颜色取 `ui.layer(MaterialLayer::Canvas)`:浅色淡出到纸面、**深色淡出到墨底**(不是白雾), 与它下方那块背景同色,所以两档都不新增颜色; - 三栏档不铺这条遮罩:那里滚动区内容恒 76px < 视口 ≈118px,不会出现半截内容,铺了只是 「画布盖画布」,反而会动 M222 已验的 1180 像素; - `options/view.rs` 已 422 行、撞 400 行硬线,遮罩拆成 `options/fade.rs`(含一条几何自检单测)。 实测(720×760): - 浅色 x=600 竖列 648 (211,229,245) → 659 (246,250,255) 单调升到画布色;深色 648 (55,72,85) → 659 (9,21,28),无白雾;中文与浅色逐值同串; - 可见带 21px → 墨迹口径 18px + 底 12px 连续渐变(硬裁边消失,右侧滚动条仍在); - 逐像素零回退:`77d675b`(遮罩前)vs 本轮 720 浅/深/中 + 700 守门,差异 bbox 只有 (112,648)–(696,660) 这 12 行,其余像素一个都没动;1180×760 浅/深/中 与 1180×900 对 M222 基线仍 **IDENTICAL**。 门禁:fmt ✓ / check ✓ / test --workspace(喂四张守门图)exit 0(app-iced lib 860 passed、 四条像素守门 + 400 行门全绿)/ clippy --workspace --all-targets -D warnings exit 0 / .rs 全仓扫描 >400 行 0 个、<2 字节 0 个。 已知残留(本轮不动,按债务台账口径登记):menu 的 L2 阴影不随滚动视口裁切(压在实例名输入框上 约 6.9%,三栏档 fabric 同样存在)——根因在 `components::inputs::menu`,不在 M227 scope, 待专门 mission;finding `.tower/comms/findings/20261110-worker-m227-bug-l2.md`。
40 lines
1.9 KiB
Rust
40 lines
1.9 KiB
Rust
//! 安装选项区(M105):**选中版本之后先给选项,点「安装」才开工**。
|
||
//!
|
||
//! ## 为什么要有这一步
|
||
//!
|
||
//! 用户实跑反馈的原话是「点击下载之后它就直接下载了,没有选择前置加载器(版本选择)选项」。
|
||
//! 这不是画得不好,是**功能没做**:`Message::InstallVersion` 直接派 `InstallVersion`,
|
||
//! 而 core 早就会装四家加载器(M32/M35/M45 已合)。于是「能装什么」与「UI 让你装什么」
|
||
//! 之间差着一整个加载器维度。
|
||
//!
|
||
//! ## 文件分工
|
||
//!
|
||
//! | 文件 | 内容 |
|
||
//! |---|---|
|
||
//! | [`model`] | **决策**(无 iced):加载器词表、兼容性静态规则、选项视图、确认键判据 |
|
||
//! | [`view`] | 控件树:加载器 chip ×2 行 + 加载器版本列表 + 实例名 + 不兼容提示 |
|
||
//! | `tests`(`options/tests.rs`) | 兼容性真值表 + 确认键门(纯函数,不开图形环境) |
|
||
//!
|
||
//! ## 一条纪律:页面只发意图
|
||
//!
|
||
//! | 控件 | 消息 | app 层落点 |
|
||
//! |---|---|---|
|
||
//! | 加载器 chip | [`Message::SetLoader`](super::Message::SetLoader) | 改草稿 + 按需派 `ListLoaderVersions` |
|
||
//! | 加载器版本一行 | [`Message::SetLoaderVersion`](super::Message::SetLoaderVersion) | 改草稿 |
|
||
//! | 实例名输入 | [`Message::SetInstanceName`](super::Message::SetInstanceName) | 改草稿 |
|
||
//! | 「安装」 | [`Message::InstallVersion`](super::Message::InstallVersion) | `AppCommand::CreateInstance(草稿)` |
|
||
//!
|
||
//! 草稿(选中版本 + 三个选项)住在 `App`,由 `refresh_view` 带进页面模型——与分类筛选同一个做法,
|
||
//! 因为 `refresh_view` 每次事件都会把整棵模型重建,页面自己存不住任何东西。
|
||
|
||
mod fade;
|
||
mod model;
|
||
#[cfg(test)]
|
||
mod s1_tests;
|
||
#[cfg(test)]
|
||
mod tests;
|
||
mod view;
|
||
|
||
pub use model::{InstallDraft, Loader, OptionsView};
|
||
pub(crate) use view::section;
|