fix(app-iced): M68 r1 —— M69 迁移 + 守门补洞 + 药丸 56×32 + caption 图标 24 + 东侧热区回 1180
代码复审 p2-2items / 视觉复审 p2-2items 的修复轮(配色重拍等 M70 定案)。
M69 迁移(2 行)
- nav 轨宽:nav_rail_width(metrics) 函数体改用 metrics.nav_rail_width
- theme::STROKE_PX 改为 pub use unlucky_design::stroke::HAIRLINE as STROKE_PX
P2-1 零硬编码守门补洞(reviewer 造样 5 个漏网样本全部补上,并进自检正向断言)
- COLOR 调用表补 from_rgb8 / rgb8 / rgba(`from_rgb(` 子串匹配不到 `from_rgb8(` 是根因)
- 新增 `Color { r: .., g: .. }` 结构体字面量检查
- 尺寸规则遇到 Length::Fixed( / Padding::from( / Size::new( 往里剥一层再判数字
- 新增渲染层回归守门 pill_never_overrides_its_size_with_fill(禁 nav.rs 出现 center_*( ):
视觉复审 P2-1 的病根就是 center_*(Length::Fill) 把容器尺寸覆盖成 Fill
视觉 P2-1 药丸 88×32 → 56×32(实测 x=16..71)
- 去掉 center_x/center_y(Fill);居中改由父 column 的 align_x + 显式 width(轨宽) 完成
(只去掉 center_* 还不够:column 会 shrink 到 56,药丸贴左缘 x=0..55,是同一个坑的第二层)
视觉 P2-2 / 用户点名 caption 图标 46 → 24(按钮容器保持 46×48)
- button 内包 container(...).width(24).height(24).center(Length::Fill):
只设 width/height 会让容器缩到 24 并贴 button 内容左上角;center(Fill) 才既撑满又居中
视觉 P3-1 东侧/南侧缩放热区改成叠层
- 原来是 row 的兄弟列,吃掉 4px 布局宽(右留白 28、关闭键离窗角 4px);
现在用 stack! + 对齐容器叠在工作区上,布局宽回到 1180(卡片右缘 x=1155 = 右留白 24)
P3 清单
1. --data-dir 接受并忽略(翻牌前 CI 兼容;现役 smoke 命令行可原样跑,exit 0)+ 单测
2. --diff 内建 ±N px 平移扫描(--diff-scan),CI 不再依赖 numpy
3. 截图模式等 SystemTheme 到达才出图(否则暗色系统上会拍到浅色)
4. (Auto, 未编入 wgpu) 返回 tiny-skia,不再把 wgpu 写进候选列表
5. --renderer=gpu 也跳过适配器枚举(决策与探测无关,省 ~0.6~1.2s)
6. icons::handle 加 debug_assert_eq!(IconKind::ALL[kind as usize], kind)
7. 轨顶留白改 container padding-top,实测 24(原来 spacer + column spacing = 28)
顺带:shot.rs 拆成 shot/mod.rs + shot/diff.rs(≤400 行门禁)
门禁:fmt OK / clippy -D warnings 干净 / 46+5 测试全过 / cargo check --workspace --all-targets OK
体积:双后端 6,769,664 B(6.46 MiB)、仅 CPU 3,955,712 B(3.77 MiB)
截图:r1 代码验证图(r1-verify / hover / pressed / compare-nav-rail)已出;4 张交付主图待 M70 定案后重拍
This commit is contained in:
1 parent
14da7b3dec
commit
a1adf024ba
11 files changed
+599
-200
No files matched your search
@@ -45,6 +45,34 @@ pub struct Options {
|
||||
pub scale_factor: Option<f32>,
|
||||
/// `--diff <left> <right>`:只做两图逐像素对比,不开窗。
|
||||
pub diff: Option<(PathBuf, PathBuf)>,
|
||||
/// `--diff-scan <n>`:对比时额外做 ±n px 的平移扫描(找最佳对齐,默认 0 = 不扫)。
|
||||
pub diff_scan: u32,
|
||||
/// `--force-state=hover|pressed`:把按钮强制成某个状态便于截图取证(D30 的状态图)。
|
||||
pub force_state: Option<ForcedState>,
|
||||
/// `--data-dir <dir>`:当前**接受并忽略**。
|
||||
///
|
||||
/// 现役 Slint 版的 CI 冒烟用 `--software-renderer --screenshot <png> --data-dir <dir>`,
|
||||
/// 翻牌后同一套脚本要能直接跑 iced 版;真正的数据目录消费由后续页面 mission 接 `host`/`state` 时做。
|
||||
pub data_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// 截图取证用的强制交互状态(只影响观感,不改变任何状态机)。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ForcedState {
|
||||
/// 所有可交互控件按 hover 画。
|
||||
Hover,
|
||||
/// 所有可交互控件按 pressed 画。
|
||||
Pressed,
|
||||
}
|
||||
|
||||
impl ForcedState {
|
||||
/// 稳定名字(日志用)。
|
||||
pub const fn name(self) -> &'static str {
|
||||
match self {
|
||||
ForcedState::Hover => "hover",
|
||||
ForcedState::Pressed => "pressed",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Options {
|
||||
@@ -56,6 +84,9 @@ impl Default for Options {
|
||||
screenshot_theme: None,
|
||||
scale_factor: None,
|
||||
diff: None,
|
||||
diff_scan: 0,
|
||||
force_state: None,
|
||||
data_dir: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,6 +155,28 @@ impl Options {
|
||||
.ok_or_else(|| "--diff 需要两张图的路径".to_owned())?;
|
||||
options.diff = Some((PathBuf::from(left), PathBuf::from(right)));
|
||||
}
|
||||
"--diff-scan" => {
|
||||
let raw = take(&mut args, inline, "--diff-scan")?;
|
||||
options.diff_scan = raw
|
||||
.parse()
|
||||
.map_err(|_| format!("--diff-scan 需要非负整数,收到 {raw:?}"))?;
|
||||
}
|
||||
"--force-state" => {
|
||||
let raw = take(&mut args, inline, "--force-state")?;
|
||||
options.force_state = Some(match raw.as_str() {
|
||||
"hover" => ForcedState::Hover,
|
||||
"pressed" => ForcedState::Pressed,
|
||||
other => {
|
||||
return Err(format!(
|
||||
"--force-state 只认 hover|pressed,收到 {other:?}"
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
// 翻牌前的兼容参数:接受并忽略(见字段文档)
|
||||
"--data-dir" => {
|
||||
options.data_dir = Some(PathBuf::from(take(&mut args, inline, "--data-dir")?));
|
||||
}
|
||||
other => return Err(format!("未知参数 {other:?}")),
|
||||
}
|
||||
}
|
||||
@@ -207,6 +260,33 @@ mod tests {
|
||||
assert!(parse(&["--nope"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn data_dir_is_accepted_and_ignored_for_the_flip() {
|
||||
// 现役 CI 冒烟:--software-renderer --screenshot <png> --data-dir <dir>
|
||||
let options = parse(&[
|
||||
"--software-renderer",
|
||||
"--screenshot",
|
||||
"shot.png",
|
||||
"--data-dir",
|
||||
"/d/tmp/x",
|
||||
])
|
||||
.expect("翻牌前必须兼容 --data-dir");
|
||||
assert_eq!(options.backend, Backend::Cpu);
|
||||
assert_eq!(options.screenshot, Some(PathBuf::from("shot.png")));
|
||||
assert_eq!(options.data_dir, Some(PathBuf::from("/d/tmp/x")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diff_scan_and_force_state_parse() {
|
||||
assert_eq!(parse(&["--diff-scan=2"]).unwrap().diff_scan, 2);
|
||||
assert_eq!(
|
||||
parse(&["--force-state", "hover"]).unwrap().force_state,
|
||||
Some(ForcedState::Hover)
|
||||
);
|
||||
assert!(parse(&["--force-state=focus"]).is_err());
|
||||
assert!(parse(&["--diff-scan=-1"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diff_takes_two_paths() {
|
||||
let options = parse(&["--diff", "a.png", "b.png"]).unwrap();
|
||||
|
||||
Reference in new issue
Block a user