fix(app-iced): M77 r1 —— 菜单项 trailing 槽位靠右(视觉 r5 P1)
`item_row` 的 Row 早先是 `leading → label → trailing`,中间没有撑开的空间,于是
trailing(快捷键 / 子菜单箭头 / 勾)**紧贴 label 右边**,一列菜单里读不出一条竖线,
也与 M3「trailing 落在行右内边距上」不符。
改法(只动 `menu.rs` 的行装配):
- label 与 trailing 之间插一个 `space::horizontal()`(宽度 Fill),**只在有 trailing 时插**——
没有 trailing 的项仍然左边起排,不被居中/右对齐;
- 把 Row 包进 `container(..).width(Fill).height(Fill).align_y(Center)`:Fill 空间要有宽度可撑
(Q8 的教训:撑开靠容器,不靠子元素),顺带把内容垂直居中(`button` 只把内容放左上角);
- trailing 的右缘现在落在 item 右内边距上,与 leading 左内边距对称(12 = 4 内缩 + 8 button pad);
- 分组分隔线 / 禁用项的行为未动(同一函数的其它分支没改)。
渲染层断言(`probe/menu.rs`):带 trailing 的项,其 trailing 墨迹右缘 = `menu_right − 17`
(= 4 指示器内缩 + 12 内边距 + `Check` 字形在 24 viewBox 里约 5 的边界)±1。
变异(删掉那行 `space::horizontal()`)后实测 `menu_right=559、墨迹右缘=438 ⇒ 偏 121`,断言红;
修复后偏 **17**。重出 `menu-{light,dark}.png`,勾已贴行右缘成一条竖线。
This commit is contained in:
1 parent
21f2734981
commit
05fefc8a7b
2 files changed
+35
-1
No files matched your search
@@ -287,6 +287,10 @@ fn item_row<'a, M: Clone + 'a>(
|
||||
}
|
||||
row = row.push(label);
|
||||
if let Some(kind) = item.trailing {
|
||||
// **撑开**:label 与 trailing 之间插一个水平 Fill,trailing 才会被推到行右内边距上
|
||||
// (M3 里 trailing 是「快捷键 / 子菜单箭头 / 勾」,必须在一列菜单里成一条竖线)。
|
||||
// 没有 trailing 时**不插**:label 仍在左边,不会被居中或右对齐。
|
||||
row = row.push(iced::widget::space::horizontal());
|
||||
row = row.push(layout::fixed(
|
||||
geometry.icon,
|
||||
geometry.icon,
|
||||
@@ -294,6 +298,13 @@ fn item_row<'a, M: Clone + 'a>(
|
||||
));
|
||||
}
|
||||
|
||||
// 行必须撑满 item 宽度:上面的 Fill 空间要有宽度可撑(Q8 的教训:撑开靠容器,不靠子元素)。
|
||||
// 顺带把内容垂直居中——`button` 只把内容放在 padding-box 的左上角。
|
||||
let content = iced::widget::container(row)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.align_y(Alignment::Center);
|
||||
|
||||
let selected = item.selected;
|
||||
let style = move |_theme: &iced::Theme, status: button::Status| {
|
||||
let state = forced.unwrap_or_else(|| Interaction::from_status(status));
|
||||
@@ -311,7 +322,7 @@ fn item_row<'a, M: Clone + 'a>(
|
||||
};
|
||||
|
||||
let inset = ui.space(Space::X1);
|
||||
let button = button(row)
|
||||
let button = button(content)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(geometry.item_height))
|
||||
.padding(Padding {
|
||||
|
||||
@@ -75,5 +75,28 @@ fn menu_container_items_and_divider() {
|
||||
(0.6..=1.4).contains(&ink),
|
||||
"8.x 分组分隔线应 1dp `OutlineVariant`:实测墨量 {ink:.2}"
|
||||
);
|
||||
|
||||
// trailing 槽位必须靠到**行右内边距**上(视觉 r5 P1:早先它紧贴 label 右边)。
|
||||
//
|
||||
// 位置公式:item 右缘 = menu_right − 4(选中指示器内缩);button 内容右缘 = item 右缘 −
|
||||
// (pad_h − inset) = menu_right − 12;trailing 图标盒 24 的**墨迹**再内缩 k(`Check` 字形
|
||||
// 在 24 viewBox 里右边界 ≈ 5,与 leading 图标「可视边 12、墨迹 16」同一口径)。
|
||||
// 所以墨迹右缘 ≈ menu_right − 17。变异(去掉撑开的 Fill)会让它贴着 label ⇒ 差 ~120。
|
||||
let trailing_ink_color = rgb(ui.color(Role::OnSecondaryContainer));
|
||||
let mut trailing_right = 0usize;
|
||||
for y in selected_box.top..=selected_box.bottom {
|
||||
for x in selected_box.left..=selected_box.right {
|
||||
if matches(shot.at(x, y), trailing_ink_color) {
|
||||
trailing_right = trailing_right.max(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
let trailing_offset = menu_right - trailing_right;
|
||||
assert!(
|
||||
(16..=18).contains(&trailing_offset),
|
||||
"8.6/trailing:带 trailing 的项,其 trailing 墨迹右缘应在 item 右内边距上\
|
||||
(menu_right − 17,允许 ±1):实测 menu_right={menu_right}、墨迹右缘={trailing_right}\
|
||||
⇒ 偏 {trailing_offset}(贴 label 时会是 ~120)"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user