fix(app-iced): M93 r3 —— 复审 r1 四条返工(Canvas 不吃 α / 平铺补缝 / 诊断上移 / 文档)
先 `git rebase main`(M92 `eae7ae0` 已在主线;`Cargo.lock` 与 `crates/app-iced/Cargo.toml`
自动合并,`image-without-codecs` 与 M92 的 `unlucky-i18n` 两段都在)。
P2-2(口径违约)Canvas 层不许吃面板 α
- `Ui::layer()` 改成按令牌 `MaterialLayer::allows_translucency()` 判定:Canvas 恒不透明,
只有 Card / Overlay 乘 `panel_alpha`。判据取令牌的不变量,三个调用点(标题栏 / 导航轨 /
页头带)没有各自特判。
- 守门:`the_canvas_layer_stays_opaque_while_panels_take_the_alpha`(α=0.55 时 Canvas.a==1.0、
Card/Overlay.a==0.55;CPU 档连卡片都是 1.0)。
P2-1 平铺不许留缝
- `background::tiles()` 超 `MAX_TILES` 时改成**放大图块步长**(`Tiles { cols, rows, scale }`,
按 1.15 逐级放大到块数进预算),而不是减列/减行;`MAX_TILE_SCALE` 提到 1024 只是安全阀
(1×1 的图在 1180×760 上需要 ~118 倍才能用 64 块盖满)。
- `picture::tiled()` 用 `ContentFit::Fill` + 格子尺寸 = `源尺寸 × scale`(同比例,不变形):
`None` 会按图片原生尺寸画、比格子小就留空,正是那道缝。
- 守门:`tile_grid_always_covers_the_viewport_within_budget`(6 组尺寸,含 120×120 与 1×1,
断言 `covered >= viewport` 且 `count <= MAX_TILES`);背景层底下本来就有不透明画布底色兜底。
P2-3 诊断上移到首屏
- 诊断块(读盘失败红字 / CPU 降级 / 配色回落 / 当前配色层级)从卡片末尾移到「背景图路径」
紧下方:1180×760 首屏可见(截图 `r4-broken-path.png` 里红字在 y≈594)。
P2-4 文档对齐
- `transparency.rs`:`WS_EX_LAYERED` 的归属改成「本文件的 `ensure_layered` 负责」,
窗口创建侧只拿句柄;`platform/mod.rs` / `lib.rs` 的模块表同步。
- 删掉「马赛克取样」这类已删实现的现在时描述(`background` / `picture` / `app` 的注释),
保留一句 r1→r2 的历史说明;`app/tests/appearance.rs` 的测试意图跟着改。
门禁(工作区级,最终树):`cargo fmt --all --check` 干净;
`cargo clippy --workspace --all-targets -- -D warnings` 无输出;
`cargo test --workspace` 全绿(app-iced 299 lib + 6 集成守门、presenter 126、其余 crate 全过)。
出图:`r4-canvas-opaque-panel55{,-dark}.png`(Canvas 不透明 + 面板透底)、
`r4-tile-120.png`(120×120 平铺右缘无裸白)、`r4-broken-path.png`(诊断首屏可见)。
This commit is contained in:
1 parent
22e4c423fa
commit
5c40c64b5f
13 files changed
+181
-85
No files matched your search
@@ -1,18 +1,13 @@
|
||||
//! 令牌 → iced 类型(`Color` / `Font` / `Border` / `Radius` / `Theme`)。
|
||||
//!
|
||||
//! ## 边界(M61 `design-令牌约定.md` §0)
|
||||
//!
|
||||
//! 本模块是**唯一**允许把 `unlucky-design` 的值翻成 iced 类型的地方:组件层只调 [`Ui`],
|
||||
//! 绝不出现色值/字号/半径/间距字面量(`tests/no_hardcoded_tokens.rs` 扫 `src/**` 守门)。
|
||||
//! 本模块是**唯一**允许把 `unlucky-design` 的值翻成 iced 类型的地方(M61 §0):组件层只调
|
||||
//! [`Ui`],绝不出现色值/字号/半径/间距字面量(`tests/no_hardcoded_tokens.rs` 扫 `src/**`)。
|
||||
//!
|
||||
//! ## 为什么不用 `iced::theme::Base` 承载 49 个角色
|
||||
//!
|
||||
//! iced 的 `Palette` 只有 6 个颜色,M3 有 49 个角色(M60 Q5 + M61 §9-0)。所以真源是本模块持有
|
||||
//! 的 [`Scheme`],iced 的 `Theme` 只用来「换名字」——名字变了 iced 才重算受主题影响的缓存,
|
||||
//! `palette()` 只给 devtools 看,控件外观由各自的 `Style` 注入。
|
||||
//!
|
||||
//! `success`/`warning` 在 M3 里没有对应角色,按语义最近的现成角色映射
|
||||
//! (`success → Secondary`、`warning → Tertiary`),任何控件都不要读这两个槽位。
|
||||
//! iced 的 `Palette` 只有 6 色,M3 有 49 个角色(M60 Q5):真源是本模块的 [`Scheme`],`Theme`
|
||||
//! 只用来「换名字」(名字变了 iced 才重算缓存),控件外观由各自的 `Style` 注入。
|
||||
//! `success`/`warning` 没有对应角色,按邻近语义映射(→ `Secondary` / `Tertiary`),不许读。
|
||||
|
||||
use iced::border::Radius;
|
||||
use iced::theme::Palette;
|
||||
@@ -113,14 +108,19 @@ impl Ui {
|
||||
to_iced(self.scheme.get(role))
|
||||
}
|
||||
|
||||
/// 材质层(Canvas/Card/Overlay)→ 容器色,**已乘上面板 α**(M93 的唯一来源)。
|
||||
/// 材质层(Canvas/Card/Overlay)→ 容器色;**只有令牌允许半透明的层才乘面板 α**(M93 唯一来源)。
|
||||
///
|
||||
/// 为什么 α 施加在这里:面板 α 是**表面色**的属性,而全仓所有表面色都从这个函数出去
|
||||
/// (外壳的根容器/标题栏/导航轨、`pages::frame::card`、空态图标块……),乘一次就让
|
||||
/// 四页 + 外壳自动同源,调用点没有机会「各处自乘」。`α = 1.0` 时逐字节等于原色。
|
||||
/// α 乘在这里而不是调用点:所有表面色都从这里出去(根容器/标题栏/导航轨/页头带/卡片),
|
||||
/// 一次同源、调用点无从「各自自乘」。Canvas 层恒不透明(r1 P2-2):令牌
|
||||
/// [`MaterialLayer::allows_translucency`] 写死 `Canvas => false`(窗口底),而三个窗口键与
|
||||
/// 导航轨、页头带都取 Canvas——给它们乘 α 会让文字直接压在背景照片上(α=0.55 实测不可读)。
|
||||
pub fn layer(&self, layer: MaterialLayer) -> Color {
|
||||
self.color(layer.surface_role())
|
||||
.scale_alpha(self.panel_alpha)
|
||||
let base = self.color(layer.surface_role());
|
||||
if layer.allows_translucency() {
|
||||
base.scale_alpha(self.panel_alpha)
|
||||
} else {
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前面板 α(CPU 档由 `app` 侧强制成 1.0)。
|
||||
|
||||
Reference in new issue
Block a user