Files
Unlucky-Launcher/crates/app-iced/src/components/feedback/mod.rs
T
AskaEth 9bb3c33b8c fix(app-iced): 复审 r1 四条 P2 收口(M234)
- P2-1 判据恒绿:`gallery/probe/bases.rs` 的「反向检查」把字段档计数(`:172` 遮蔽后的
  `hits`)拿去比按钮档 stray ⇒ 恒绿。改成 `button_hits` / `field_hits` 两个计数,各比各的
  stray,失败信息的数值与单位对齐量测对象。变异自证:卡列里留一颗忘了 `.base(..)` 的按钮
  ⇒ 该断言单独红(2137 px vs 3178 px,退出码 101)。
- P2-2 FAB 的底错了:禁用态背景仍是满档 `PrimaryContainer`(`Disabled.layer() == None`),
  38% 内容却合在画布上。改成 `Base::of(PrimaryContainer)` + `on_container = false`
  (那一层 10% 在 FAB 身上不存在),两处调用收进一个 `content_color()`;新增值判据
  `disabled_fab_ink_composites_over_its_own_container`(修前 #8CA0AA / 修后 #548FBC 量级)。
- P2-3 漏改:`selection::paint::state_layer()`(hover/focus/pressed)与 `list_item` 的
  状态层叠底仍写死 `Role::Surface`,改成跟 `base`;同类两处(`assemble::transparent_state_color`
  的 Outlined/Text hover、drawer 项药丸)一并跟上。
- P2-4 文档失真:`feedback/{action,mod}.rs` 删掉「本地 α 合成 / 规则只认两档」的旧描述
  与失效链接;`list_item` 的旧签名;三处 `probe/base.rs` → `probe/bases.rs`;
  新增 `surfaces::elevated::tests::the_card_base_constant_is_the_role_the_card_paints`
  真断言(原来只在文档里声称那条测试守 `BASE`),并把这句描述改准。
- nit:`disabledbase.rs` 字符串里塌成一行的续行空格、probe 汇总行把列左缘横坐标说成
  「像素计数」的措辞。

门禁(CARGO_TARGET_DIR=C:/Temp/ull-target/wt-234):fmt / check --all-targets /
test -p unlucky-app-iced(896 + 6 通过,0 失败)/ clippy --workspace --all-targets -D warnings /
文件 ≤400 全绿;probe 浅色与深色都过。
2026-11-11 06:34:24 +08:00

92 lines
6.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! **反馈类家族**:Progress(§12)/ Snackbar(§14)/ Dialog(§7)/ EmptyState(§15)。
//!
//! ## 接口(契约 §2 + §8:官方名的小写形式,对消息类型泛型,不 import `app::Message`)
//!
//! | 组件 | 入口 | 消息要求 |
//! |---|---|---|
//! | 线性进度 | [`linear(ui, Progress::determinate(0.5))`](linear) | **无消息**(进度不可点) |
//! | 环形进度 | [`circular(ui, Progress::indeterminate(phase))`](circular) | **无消息** |
//! | 提示条 | [`snackbar(ui, Snackbar::new("…").action("撤销", msg))`](snackbar) | 有动作/关闭时才要 `M` |
//! | 对话框 | [`dialog(ui, Dialog::new("标题", "正文").double(..))`](dialog) | 有动作时要 `M` |
//! | 空态 | [`empty_state(ui, EmptyState::new(icon, "标题", "说明"))`](empty_state) | 有 CTA 时要 `M` |
//!
//! 全部 `M: Clone + 'a`(与按钮家族同一口径),`Ui` 一律 `&'a Ui` 传入、组件内不 `Ui::new`。
//!
//! ## 三条硬口径(每个组件文件开头各有一套细则表)
//!
//! 1. **数值来自哪里**:颜色/字级/圆角/内距走令牌(`Role` / `TypeRole` / `ShapeScale` / `Space`),
//! 进度厚度、Snackbar 宽高、Dialog 宽、空态块这四组令牌层没有 → 登记 **G17**([`geometry`])。
//! 2. **状态层只有一处**:hover/pressed 的叠色一律经 [`interaction::overlay_color`];
//! 禁用内容一律经 [`interaction::disabled_content_over_role`],**底由容器给**
//! ([`interaction::Base`]):`action.rs` 传的是这两个动作件自己的容器角色
//! (`InverseSurface` / `SurfaceContainerHigh`),其余组件传 `Base::CANVAS`;
//! 禁用是**状态**(`on_press: Option<M>` 为 `None`),不是另一个构造器(M77 之前 Chip 踩过)。
//! 3. **精确尺寸经 `layout`**:图标/几何图元一律 `layout::fixed` / `layout::centered_fixed`(Q9),
//! 居中一律父级 `align_x/align_y`(Q8,不许 `center_*`)。
//!
//! ## CPU 降级(D27)与「不画阴影」
//!
//! 本家族零模糊、零运行时半透明:进度条是实色、Dialog 的 scrim 是**预合成实色**
//! ([`scrim`]),两个浮层都不画阴影(`ShadowSpec` 还是 M63 占位值 + D27 禁模糊)。
//! 四条偏离逐条登记在报告里(D-1 无阴影 / D-2 scrim 预合成 / D-3 波浪未实现 / D-4 Snackbar 无阴影),
//! 另有一条**观察项** D-5(深色档 scrim 只压暗 4%,见 `dialog.rs` 的 scrim 一节)。
//!
//! ## 逐项偏离登记(提交报告里同一份表)
//!
//! | 编号 | 参考 | 我们 | 理由 | 可修 |
//! |---|---|---|---|---|
//! | D-1 | Dialog L3 阴影 | 无阴影 | D27 CPU 禁模糊 + `ShadowSpec` 为 M63 占位 | 是(等 M63 阴影表 + 双档渲染) |
//! | D-2 | scrim 真半透明 @0.32 | 预合成实色 | D27 CPU 零半透明;遮罩下是底色时逐像素等价 | 是(GPU 档可切真 α) |
//! | D-3 | 线性波浪 3/40、环形 1.6/15 | 直线段 / 等弧长 | `12b §12.4` 明确允许,登记后用匀速替代 | 是 |
//! | D-4 | Snackbar L3 阴影 | 无阴影 | 同 D-1 | 是 |
//! | G17-d | Snackbar 最小宽 344 | 组件不强制(宿主保证) | iced `Length` 无 min-width(同按钮 G15) | 是(自定义 Widget) |
//! | D-5 | 深色档 scrim 压暗 32% | 保持 0.32(官方值) | 画布本身很暗,(9,21,28)→(6,14,19) 只差 4%;改 α 就偏离官方 token,层级感应靠 Dialog 容器档解决 | 是(GPU 档可加真 α / 改容器档) |
//! | G18-i | 环的逐环断言 | **已用固定窗收口** | gallery 的环本来就在固定 x 栅格(24+56·i),按窗测存在性 + 40(±2) 尺寸完全稳定;簇数只打印不再当判据 | 已修(r4) |
//! | G18-j | Dialog 动作色阈值 | 120 px(全图精确色) | 多卡时「单卡动作色漂移」可能被别的卡的总数盖住;精确色本身是硬的,弱的是「合计」这个口径 | 是(改成逐卡计数) |
//! | G18-k | 文档残留 | 本轮只改了能确证的行 | 复审又找出 4 处同类残留;不为凑数扩大 diff,留待下次触碰该文件时顺手改 | 是 |
//! | G18-l | snackbar 取景框判据 | 「更靠近框色而不是画布」 | 条自身的抗锯齿底行覆盖率实测 0.5008(余量 0.0008),可能被算成框 ⇒ **误报方向**(不是假绿);加了「框高 96」之后触发概率下降 | 是(改用精确色 + 容差,或自绘取景框) |
//!
//! ## 文件地图
//!
//! ```text
//! geometry.rs G17 常量 + 五组几何(含不定态 keyframes)
//! keyframes.rs 相位 → 进度 的纯函数求值器(组件不计时)
//! progress.rs linear / circular(含环形 SVG 图元)
//! snackbar.rs 提示条 + 贴顶/贴底
//! dialog.rs 对话框 + scrim
//! empty_state.rs 空态(项目自定:`[估]` 几何 + `[规格]` 排版 + 一条 `[源]` CTA)
//! action.rs 文字动作 / 图标动作(Dialog 与 Snackbar 共用)
//! gallery_parts.rs 家族自己的 gallery 段落开关(`ULL_FEEDBACK_PART`)
//! probe.rs 渲染层像素断言(对着 gallery 截图量,见其模块文档)
//! ```
//!
//! ## 桩期的 `demo()` 已删除(不是签名被改)
//!
//! M75 的占位 `demo()` 只画一行「pending」文字,没有任何验收价值;真组件的验收画面就是
//! `gallery/feedback.rs` 的四段矩阵。契约 §9.3「家族 `demo()` 签名是共享契约」约束的是
//! **别改别人的调用点**——`feedback::demo` 自始至终只有 `gallery/feedback.rs` 一个调用点,
//! 而那个文件就在本 mission 的 scope 内,所以这里连同调用点一起换成了真组件(不留死代码:
//! 一个没人调用的 `pub fn` 会直接触发 `dead_code`,`-D warnings` 门禁会红)。
mod action;
pub mod dialog;
pub mod empty_state;
pub mod gallery_parts;
pub mod geometry;
pub mod keyframes;
pub mod panel;
pub mod progress;
pub mod snackbar;
#[cfg(test)]
mod pixel;
#[cfg(test)]
mod probe;
#[cfg(test)]
mod tests;
pub use dialog::{dialog, scrimmed, Dialog};
pub use empty_state::{empty_state, EmptyState};
pub use progress::{circular, linear, Progress};
pub use snackbar::{snackbar, Placement, Snackbar};