test(app-iced): M102 r2 护栏改成「抓得住页面换摆法」——块偏移/行距/散文接线全部有源码结构断言
r1 复审的两条 P1 都是假护栏:把修复原样回滚(A:frame::body 换回居中 424; C:内缩 X2→X1;D:行距加回 4px)后测试仍全绿,因为断言只喂 frame_metrics() 与常量重算, 既不观察 frame::body,也不引用页面常量。本轮把「摆法」做成可断言的东西: - 新增 `pages/layout/block.rs`:body_width(pane 宽封顶 1440)、body_offset(恒 0 = 贴左)、 prose_width(= metrics.column ≤424)三个纯量 + 单测。frame::body / frame::prose 从它们建盒, frame::body_width 改成 pub use(不另算一份)。 - 新增 `pages/layout/source.rs`(cfg(test)):把某个函数的实现文本切出来。iced 的 Element 没有几何内省,量不到「块摆在哪」,只能断言「照哪个数建的」;仓里已有 no_hardcoded_tokens 扫源码、download/tests 用 include_str! 扫 key 的先例。 - 新护栏(每条都做过变异实测,见报告): · frame_body_is_built_from_the_block_quantities(A 变异红) · frame_prose_is_built_from_the_prose_width(E 变异红) · list_column_spaces_rows_only_from_the_shared_constant(D 变异红) · instances 几何断言改用页面真源 LIST_BOTTOM_INSET.dp() / ROW_SPACING(C 变异红) · the_detail_note_goes_through_the_prose_box(散文接线) - P2:wrap::strip 的「会删原文自带 U+200B」写成限界 + 一条断言;docs 口径从 layout.rs 挪到 layout/block.rs(layout.rs 399 → 389)。 零像素变化:改后 9 张图与 r1 的 m102-after 逐张 cmp 完全相同;2560×760 新出三张证明块宽封顶 1440(112..1551)且仍贴左。
This commit is contained in:
1 parent
89d98184c1
commit
824bb36f8e
11 files changed
+469
-67
No files matched your search
@@ -12,13 +12,17 @@
|
||||
//! 页头带与内容区共用同一个 `gutter`(`Padding::from([0.0, metrics.gutter])` / `padding(gutter)`),
|
||||
//! 所以页头标题的左缘 = `rail 88 + gutter 24 = 112`。正文块必须从**同一条线**起:
|
||||
//!
|
||||
//! - 单列页用 [`body`](贴左 + 吃满 `layout::available`);
|
||||
//! - 成段散文再套一层 [`prose`](宽度 ≤424,保证一行 ≤72 字符);
|
||||
//! - 单列页用 [`body`](贴左 + 宽 `layout::block::body_width` = pane 宽,封顶 1440);
|
||||
//! - 成段散文再套一层 [`prose`](宽 `layout::block::prose_width` ≤424,保证一行 ≤72 字符);
|
||||
//! - 两列页的正文在 [`panes`] 的主列里,左缘 = `112 + 列表列 336 + 间隙 24 = 472`(有据的分栏,不是错位)。
|
||||
//!
|
||||
//! 旧 [`single_column`] 把 424 的块**居中**摆进 1044,于是左缘 422、标题 112——视觉复审的 ① 就是这个。
|
||||
//! 它保留给设置页(`pages/settings/**`,几何归设置页线)。
|
||||
//!
|
||||
//! **这三个量都在 [`super::layout::block`](纯函数 + 单测)**;[`body`] / [`prose`] 只是把
|
||||
//! 「从哪个数建盒」写死在一处,`pages/tests.rs` 有两条**源码结构断言**盯着这两个盒子
|
||||
//! (iced 的 Element 没有几何内省,量不到摆法,只能断言「照哪个数建的」)。
|
||||
//!
|
||||
//! ## 判据落点(`research/12b`)
|
||||
//!
|
||||
//! | 部件 | 参考 | 落点 |
|
||||
@@ -50,7 +54,7 @@ use unlucky_design::typography::TypeRole;
|
||||
|
||||
use crate::theme::Ui;
|
||||
|
||||
use super::layout::{self, FrameMetrics, PageLayout};
|
||||
use super::layout::{self, block, FrameMetrics};
|
||||
use super::Message;
|
||||
|
||||
/// 页头操作区之间的间隔(`Space::X2`)。
|
||||
@@ -162,22 +166,18 @@ pub fn single_column<'a>(
|
||||
centered(metrics.column, content)
|
||||
}
|
||||
|
||||
/// **页面块宽度**:单列版面 = 整条可用宽度;两列版面 = 主列 pane 宽度。
|
||||
/// **页面块宽度**:pane 宽(单列 = 可用宽度 / 两列 = 主列 pane)封顶 1440。
|
||||
///
|
||||
/// 这是「表格 / 卡片 / 列表能有多宽」的答案,与 [`FrameMetrics::column`](一句话能有多宽,
|
||||
/// ≤424)是**两个量**。M102 的根因就是把后者当成了前者:424 的块在 1044 里居中,
|
||||
/// 于是正文左缘比页头标题右移了 310px(1180 窗宽下)。
|
||||
pub fn body_width(metrics: FrameMetrics) -> f32 {
|
||||
match metrics.layout {
|
||||
PageLayout::SingleColumn => metrics.available,
|
||||
PageLayout::SupportingPane | PageLayout::ListDetail => metrics.main_pane,
|
||||
}
|
||||
}
|
||||
/// 真源在 [`super::layout::block::body_width`](纯量 + 单测);这里只是转发,**不另算一份**。
|
||||
/// 与 [`FrameMetrics::column`](一句话多宽,≤424)是两个量。
|
||||
pub use super::layout::block::body_width;
|
||||
|
||||
/// **正文块**:从页边距起(= 页头标题那条左缘)、铺满 [`body_width`]。
|
||||
/// **正文块**:从页边距起(= 页头标题那条左缘)、宽 [`body_width`]、左内边距 [`body_offset`]。
|
||||
///
|
||||
/// 与旧 `single_column` 的差别只有两点,但都是判据本身:**贴左**而不是居中,
|
||||
/// 宽度取 pane 而不是行宽上限。散文仍要自己套 [`prose`],别把整页块拉回 424。
|
||||
/// 盒子**从纯量建**:宽度取 [`body_width`]、左内边距取 [`super::layout::block::body_offset`]
|
||||
/// (恒 0)、对齐 `Start`。这三件事的顺序就是契约,`pages/tests.rs` 的
|
||||
/// `frame_body_is_built_from_the_block_quantities` 逐条扫这段源码(iced 的 Element 没有几何
|
||||
/// 内省,量不到「摆在哪」,只能断言「照哪个数建的」)。
|
||||
pub fn body<'a>(
|
||||
metrics: FrameMetrics,
|
||||
content: impl Into<Element<'a, Message>>,
|
||||
@@ -187,10 +187,11 @@ pub fn body<'a>(
|
||||
.height(Length::Fill)
|
||||
.align_x(Alignment::Start)
|
||||
.align_y(Alignment::Start)
|
||||
.padding(Padding::default().left(block::body_offset(metrics)))
|
||||
.into()
|
||||
}
|
||||
|
||||
/// **散文块**:宽度锁在 [`FrameMetrics::column`](≤424 = 逐行 ≤72 字符)。
|
||||
/// **散文块**:宽度锁在 [`super::layout::block::prose_width`](= `metrics.column`,≤424 ⇒ 一行 ≤72 字符)。
|
||||
///
|
||||
/// 只包「成段读的文字」(实例详情正文那样的 prose);卡片、列表、Tabs 吃的是 [`body_width`],
|
||||
/// 它们的宽度不承担行宽承诺(列宽只影响每行放几个字段,不影响读一句话的舒适度)。
|
||||
@@ -199,7 +200,7 @@ pub fn prose<'a>(
|
||||
content: impl Into<Element<'a, Message>>,
|
||||
) -> Element<'a, Message> {
|
||||
container(content)
|
||||
.width(Length::Fixed(metrics.column))
|
||||
.width(Length::Fixed(block::prose_width(metrics)))
|
||||
.into()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user