From 5d7426b6c9fefef98878fa12f692c83db172acb5 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Mon, 2 Nov 2026 13:17:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(iced/feedback):=20=E7=A9=BA=E6=80=81?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E6=94=B9=E7=94=A8=20M86=20=E7=9A=84=20view?= =?UTF-8?q?=5Fat=20=E6=B8=B2=E6=9F=93=2032=EF=BC=88=E5=A4=8D=E5=AE=A1=20C?= =?UTF-8?q?=20=E4=BF=AE=E6=AD=A3=E7=89=88=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tower 修正指令:M86(e377989)把 `icons::view_at(kind, ink, px)` 并进 main 了,所以 C 项 从「登记值改成 24」改为「登记值保持 32 + 用 view_at 真渲 32」: - `empty_state.rs`:`icons::view(..)` → `icons::view_at(.., geometry.icon)`,盒仍 96、 图标 32;`view_at` 按 32 **重新烘焙 stroke**,视觉线宽仍是 1.5px(不会把描边拉粗)。 早先 `view` 把 svg 钉成 `Fixed(24)`,32 的盒子只居中不拉伸 —— 实渲 24、墨迹 20×20。 - `panel.rs`:`EMPTY_ICON = 32.0`(`IconSize::Empty`),删掉 G18-h 欠账说明(已消解)。 - `probe/panels.rs`:图标墨迹判据 16..26 → **22..34**(32 盒)。 - `tests.rs`:`geometry.icon == 32` 保留,并写明它守的是「登记值 = 交给 view_at 的 px」, 抓不住「盒子 32 而 svg 仍钉 24」那类(渲染层由 probe 的墨迹断言兜)。 - 顺带清掉 `panels.rs` 里两个未用 import(`-D warnings` 会红)。 已 `git rebase main`(1f4bc1b,含 M86),无冲突。 --- .../src/components/feedback/empty_state.rs | 6 ++++-- crates/app-iced/src/components/feedback/panel.rs | 15 ++++++--------- .../src/components/feedback/probe/panels.rs | 10 ++++------ crates/app-iced/src/components/feedback/tests.rs | 8 ++++++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/crates/app-iced/src/components/feedback/empty_state.rs b/crates/app-iced/src/components/feedback/empty_state.rs index d173cc0..62f538f 100644 --- a/crates/app-iced/src/components/feedback/empty_state.rs +++ b/crates/app-iced/src/components/feedback/empty_state.rs @@ -69,11 +69,13 @@ pub fn empty_state<'a, M: Clone + 'a>(ui: &'a Ui, spec: EmptyState<'a, M>) -> El let title_style = ui.style(TypeRole::HeadlineSmall); let body_style = ui.style(TypeRole::BodySmall); - // Q9:图标必须落在固定尺寸的盒子里,否则 fill 约束会让 usvg 按 Contain 撑满 96 块。 + // Q9(两层):①`view_at` 自己按 32 烘焙(stroke 也按 32 重算,视觉仍是 1.5px); + // ②外面再套 32 的固定盒,确保内容拿到的约束就是 32,不会被 96 块的 Fill 撑成 Contain。 + // 早先写的是 `view(..)`:它把 svg 钉成 24,32 的盒子只起居中作用,实渲 24(复审 C)。 let glyph = layout::centered_fixed( geometry.icon, geometry.icon, - icons::view::(spec.icon, ui.color(Role::OnSurfaceVariant)), + icons::view_at::(spec.icon, ui.color(Role::OnSurfaceVariant), geometry.icon), ); let block_radius = iced::border::Radius::new(geometry.block_radius); // 块底色 `[估]`:`SurfaceContainerHigh`(材质层 `Overlay`)。早先取 `Card` diff --git a/crates/app-iced/src/components/feedback/panel.rs b/crates/app-iced/src/components/feedback/panel.rs index 72d5bc3..08b537d 100644 --- a/crates/app-iced/src/components/feedback/panel.rs +++ b/crates/app-iced/src/components/feedback/panel.rs @@ -107,8 +107,11 @@ impl DialogGeometry { } } -/// 空态图标边长 = `icons::view` 的实际渲染尺寸(24),见 [`EmptyStateGeometry::icon`] 的 G18-h。 -pub const EMPTY_ICON: f32 = 24.0; +/// 空态图标边长(`IconSize::Empty` = 32)。 +/// +/// M86 起 `icons::view_at` 会按请求尺寸**重新烘焙 stroke**,所以 32 渲染仍是视觉 1.5px 线宽 +/// (早先 `view` 把 svg 钉成 24,32 的盒子只是居中不拉伸,实渲 24 —— 那个欠账已随 M86 消解)。 +pub const EMPTY_ICON: f32 = 32.0; /// 空态的几何(**项目自定**:官方没有这个组件;`[估]` 几何 + `[规格]` 排版 + `[源]` CTA)。 #[derive(Debug, Clone, Copy, PartialEq)] @@ -117,13 +120,7 @@ pub struct EmptyStateGeometry { pub block: f32, /// 图标块圆角(16,`ShapeScale::Large`)。 pub block_radius: f32, - /// 块内图标(**24**,实渲染值)。 - /// - /// 欠账 **G18-h**:早先登记的是 `IconSize::Empty`(32),但 `icons::view` 内部把 svg 钉成 - /// `Length::Fixed(24)`(Q9 的同一处),外面套 32 的盒子只是**居中**、不拉伸子件 —— - /// 实测墨迹 20×20、字形 24。所以登记值改成 24,与 `view` 一致。 - /// 真要 32:需要 `view_at(px)`(把 `icons::RENDER_PX` 也传进去,按 32 重算 - /// `stroke_width(32)`,否则 1.5px 视觉线宽会变成 2.0px)——那是 **M86** 的 scope,本线不自造。 + /// 块内图标(**32**,`IconSize::Empty`;由 `icons::view_at` 按 32 烘焙,stroke 同步重算)。 pub icon: f32, /// 块 ↔ 标题(16)。 pub gap_title: f32, diff --git a/crates/app-iced/src/components/feedback/probe/panels.rs b/crates/app-iced/src/components/feedback/probe/panels.rs index 89aa0ab..e6e996a 100644 --- a/crates/app-iced/src/components/feedback/probe/panels.rs +++ b/crates/app-iced/src/components/feedback/probe/panels.rs @@ -22,9 +22,7 @@ use unlucky_design::elevation::MaterialLayer; use super::super::dialog::scrim; use super::super::empty_state::BLOCK_LAYER; -use super::super::pixel::{ - band_width, bands, ink_inside, matches, near, rgb, row_ink, runs, BBox, Shot, -}; +use super::super::pixel::{band_width, bands, ink_inside, matches, near, rgb, BBox, Shot}; use crate::theme::Ui; /// Dialog 宽(本项目取值,官方区间 280..560 内)。 @@ -218,7 +216,7 @@ pub(super) fn check_empty(shot: &Shot, ui: &Ui) { "15.1:图标块必须 {BLOCK}(±2,1px 描边)宽,实测 {width}" ); - // 图标本身:`icons::view` 钉成 24(G18-h 的登记值),墨迹 ≈20×20。 + // 图标本身:`view_at` 按 32 烘焙(stroke 同步重算),墨迹 ≈26~28。 let glyph = ink_inside( shot, &BBox { @@ -233,8 +231,8 @@ pub(super) fn check_empty(shot: &Shot, ui: &Ui) { ) .expect("块里必须有图标墨迹"); assert!( - (16..=26).contains(&glyph.width()) && (16..=26).contains(&glyph.height()), - "15.1:图标墨迹应在 16..26(24 盒;G18-h 登记 24,不是 32),实测 {}×{}", + (22..=34).contains(&glyph.width()) && (22..=34).contains(&glyph.height()), + "15.1:图标墨迹应在 22..34(32 盒;`view` 时代只有 20×20),实测 {}×{}", glyph.width(), glyph.height() ); diff --git a/crates/app-iced/src/components/feedback/tests.rs b/crates/app-iced/src/components/feedback/tests.rs index a39c264..fafa87d 100644 --- a/crates/app-iced/src/components/feedback/tests.rs +++ b/crates/app-iced/src/components/feedback/tests.rs @@ -109,8 +109,12 @@ fn empty_state_geometry_is_the_project_defined_set() { let geometry = EmptyStateGeometry::of(&ui(SchemeFlavor::Light)); assert_eq!(geometry.block, 96.0); assert_eq!(geometry.block_radius, 16.0, "ShapeScale::Large"); - // 复审 C:登记值是 **24**(`icons::view` 的实渲染尺寸),不是 32;见欠账 G18-h。 - assert_eq!(geometry.icon, 24.0, "图标实渲染 24(G18-h)"); + // 复审 C:登记值 32(`IconSize::Empty`)。这条守「登记值 = 交给 `view_at` 的 px」—— + // 它抓不住「盒子 32 而 svg 仍钉 24」那种情况(那是渲染层的事,probe 量墨迹 22..34 兜)。 + assert_eq!( + geometry.icon, 32.0, + "盒内图标 32(`view_at` 按 32 烘焙 stroke)" + ); // **复审 P2-1 的回归断言**:三个间距必须精确等于令牌档位。 // 早先这里只写 `> 0.0`,所以「Column::spacing(8) 与显式 gap(16/24) 双算成 32/40」 // 完全藏得住(渲染实测 264 vs 登记 232)。