fix(app-iced): M75 r5 —— 禁用内容角色按变体(A1)+ 删 probe 重复块 + 逐行护栏
1) A1 逐变体(AAR javap):Filled/Elevated/Outlined/Text = OnSurfaceVariant@0.38; FilledTonal = OnSurface@0.38(FilledTonalButtonTokens.DisabledLabelTextColor); Standard/Filled IconButton = OnSurface@0.38(*IconButtonTokens.DisabledColor)。 新增 Variant::disabled_content() / IconVariant::disabled_content(), interaction::disabled_content_over_role(ui, role, on_container) 成唯一入口。 2) probe.rs 删掉被两个 reviewer 点名的重复块(disabled_colors 调用两次、 disabled_container 绑定两次),并补 grep 证据。 3) 护栏改成**逐行**:矩阵 7 个有内容的变体行各自断言 disabled 列的 38% 墨迹 > 40 px (浅/深同一套阈值,单行回退就会红),取代原来按浅色标定的全局 500 阈值。 6) 删掉 interaction/mod.rs 里挂在 mod tests 头上的悬挂文档。
This commit is contained in:
1 parent
b31a758cda
commit
eed1c9d3f7
5 files changed
+99
-51
No files matched your search
@@ -23,6 +23,8 @@ use unlucky_design::typography::Platform;
|
||||
|
||||
use crate::theme::{Families, Ui};
|
||||
|
||||
use crate::app::components::interaction;
|
||||
|
||||
use super::scan::{matches, nearer, rgb, Shot};
|
||||
|
||||
const FAMILIES: Families = Families {
|
||||
@@ -312,9 +314,12 @@ fn gallery_geometry_matches_the_tokens() {
|
||||
"单条分隔线墨量覆盖率应 ≈1.0(= 1dp),实测 {coverage:.2}(1.5dp 会到 ~1.5)"
|
||||
);
|
||||
|
||||
// ---- 12b 1.8:禁用格必须与静息格不同 ------------------------------------
|
||||
let disabled_container =
|
||||
crate::app::components::interaction::disabled_colors(&ui, Role::Surface).0;
|
||||
// ---- 12b 1.8 禁用态:容器 + **每一行**的内容色(A1 逐变体不同)----------------
|
||||
//
|
||||
// 上一版把两个 reviewer 都指出的重复块留在这里(`disabled_colors` 被调两次、
|
||||
// `disabled_container` 被绑定两次),且只有一条「全图数墨迹」的护栏 —— 深色下阈值失效、
|
||||
// 单行回退也抓不住。现在按矩阵的行逐条断言。
|
||||
let (disabled_container, _) = interaction::disabled_colors(&ui, Role::Surface);
|
||||
assert!(
|
||||
shot.bbox_of(rgb(disabled_container))
|
||||
.iter()
|
||||
@@ -322,37 +327,36 @@ fn gallery_geometry_matches_the_tokens() {
|
||||
"没找到禁用态实心按钮(12b 1.8:容器 = on-surface@12%)"
|
||||
);
|
||||
|
||||
// ---- 12b 1.8(视觉 reviewer 的 P1-A):禁用态的内容色必须真的下发 ----
|
||||
let (disabled_container, disabled_ink) =
|
||||
crate::app::components::interaction::disabled_colors(&ui, Role::Surface);
|
||||
let ink_px = count_pixels(&shot, rgb(disabled_ink));
|
||||
assert!(
|
||||
ink_px > 200,
|
||||
"**有容器**四式的禁用内容(OnSurfaceVariant@38% 叠 12% 容器)只出现 {ink_px} 像素: 说明 Filled/Tonal/Elevated 的字形没走 38%"
|
||||
);
|
||||
// 矩阵行序(gallery/buttons.rs 的 Variant::ALL + IconVariant::ALL),行距 48 = 40 + 8
|
||||
let row_step = 48usize;
|
||||
let rows: [(usize, Role, bool, &str); 7] = [
|
||||
(0, Role::OnSurfaceVariant, true, "filled"),
|
||||
(1, Role::OnSurface, true, "tonal"), // A1:FilledTonal 是例外
|
||||
(2, Role::OnSurfaceVariant, true, "elevated"),
|
||||
(3, Role::OnSurfaceVariant, false, "outlined"),
|
||||
(4, Role::OnSurfaceVariant, false, "text"),
|
||||
(5, Role::OnSurface, false, "icon·standard"), // A1:IconButton 全是 OnSurface
|
||||
(6, Role::OnSurface, false, "icon·filled"),
|
||||
];
|
||||
let column_from = shot.width * 2 / 3; // 矩阵最右列 = disabled 列
|
||||
for (index, role, on_container, name) in rows {
|
||||
let y0 = label_button.top + index * row_step;
|
||||
let y1 = y0 + 44;
|
||||
let ink = interaction::disabled_content_over_role(&ui, role, on_container);
|
||||
let count = shot.count_in(rgb(ink), column_from, shot.width, y0, y1);
|
||||
assert!(
|
||||
count > 40,
|
||||
"{name} 行的禁用内容({role:?}@38%)在 disabled 列里只有 {count} px —— 说明这一行没走 A1 的禁用角色"
|
||||
);
|
||||
}
|
||||
|
||||
// **无容器**三式(Text / Outlined / standard IconButton)的禁用内容叠在 surface 上,
|
||||
// 是另一个色值;单查上面那个只会覆盖到有容器的四式(reviewer code-r2 p2-1:护栏漏一半)。
|
||||
let bare_ink = crate::app::components::interaction::disabled_content_over(&ui, Role::Surface);
|
||||
// **只数 disabled 列**(矩阵最右那一列,x ≥ 全宽 2/3):整图计数会被别处的抗锯齿像素
|
||||
// 抬到 1000+,把该列涂回满档色也降不到阈值以下 —— 那正是「护栏拦不住」的成因。
|
||||
let bare_px = shot.count_pixels_in(rgb(bare_ink), shot.width * 2 / 3, shot.width);
|
||||
// 阈值 500 的来历(实测,矩阵 8 行 × 5 列):
|
||||
// 浅色正常 800 px、深色正常 1966 px;把 disabled 列的 38% 墨迹涂回满档色后只剩 348 px
|
||||
// (剩下的都是别处抗锯齿像素恰好落进容差)——所以 500 是「真墨迹在 / 不在」的分界。
|
||||
assert!(
|
||||
bare_px > 500,
|
||||
"**无容器**三式在 disabled 列里的 38% 墨迹只出现 {bare_px} 像素: 说明 Text/Outlined/standard 的字形没走 38%"
|
||||
);
|
||||
|
||||
// filled 禁用容器里不许出现满档 OnPrimary(旧实现是 #FFFFFF 压在 12% 容器上 = 1.23:1)
|
||||
// filled 禁用容器里不许出现满档 OnPrimary(旧实现是白字压在 12% 容器上 = 1.23:1)
|
||||
let full_content = rgb(ui.color(Role::OnPrimary));
|
||||
for bbox in shot.bbox_of(rgb(disabled_container)) {
|
||||
if bbox.width() < 60 {
|
||||
continue;
|
||||
}
|
||||
// 只扫**内带**:圆角外的页面底色 (246,250,255) 与 OnPrimary(255,255,255) 在容差内,
|
||||
// 贴边扫描会把圆角透出的底色当成「满档内容」(首版就在 (866,162) 误报)。
|
||||
// 只扫**内带**:圆角外的页面底色与 OnPrimary 在容差内,贴边扫描会误报。
|
||||
for y in (bbox.top + 12)..=(bbox.bottom - 12) {
|
||||
for x in (bbox.left + 12)..=(bbox.right - 12) {
|
||||
assert!(
|
||||
@@ -369,7 +373,7 @@ fn gallery_geometry_matches_the_tokens() {
|
||||
顶行左内缩 {}(r=20 应 ≈14;8 圆角 ≈4;直角 0)
|
||||
实心块 {} 个(含 40×40 IconButton)
|
||||
分隔线长行 {} 行(每条 1px)
|
||||
禁用容器 (on-surface@12%) 命中 · 禁用内容 38% 墨迹 {} px(有容器)/ {} px(无容器)
|
||||
禁用容器 (on-surface@12%) 命中 · 逐行禁用内容断言 {} 行通过
|
||||
分隔线墨量覆盖率 {:.2}(1dp 应 ≈1.0)
|
||||
字形墨迹 {}px(24 盒应 16~26)",
|
||||
flavor,
|
||||
@@ -378,8 +382,7 @@ fn gallery_geometry_matches_the_tokens() {
|
||||
top_inset,
|
||||
primary.len(),
|
||||
runs,
|
||||
ink_px,
|
||||
bare_px,
|
||||
rows.len(),
|
||||
coverage,
|
||||
glyph_width
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user