docs(download): r2 复审返工——改名后的旧注释三处、视口高度口径如实分档、fade 单测改成对生产值断言(M227)
P2-1(三处改名后旧注释 + 一处口径,纯文档/注释,无像素变化,未重出图): - `install.rs` 段标题「两个 Shared 分支」→「两支「面板先保预算」的分支(Shared / Narrow)」, 两条子项分别标注 `(Shared)` / `(Narrow)`(改名后只剩一个 Shared,另一支已是 Narrow)。 - `options/view.rs` 的 `Shared` 条目删掉「(chips 档还可能有错误行)」——chips 档被 arm 1 接走 给 `Narrow`,`Shared` 走不到错误行;`Narrow` 条目本来就写对。 - `tests/options_shot/chips.rs` 断言③ 的注释:实测这条断言在窗口 518–610 里命中的是 y=550、宽 94px 的**实心「安装」药丸**,版本菜单容器上沿在 636–639(窗口外)——删掉 「菜单容器的满宽底边」这个错误替代项,并把实测值写进注释。 - 滚动区高度口径:八审原文恢复为「1180×760 ≈96–104px」(署名真实性),另起一句写 M227 在 tip 上的复量:1180×760 = 101px、1180×900 = 109px、窄档 = 120px,并注明 r2 量的 116px 与 109px 只差「钉死区从哪一行算起」。`DevDocs/artifacts/m227/README.md` 同句一并改。 P2-2(fade 单测空转,r2 实测变异 STEPS=6 仍绿): - 步数与 α 曲线提成 `pub(super) const VIEWPORT_FADE_STEPS` + `pub(super) fn step_alpha(i)`, `viewport_fade` 用它们;单测改成对**生产值**断言四条:步数 = 高度像素数(1px/条)、 α 严格递增且除末条外 <1、相邻增量非递减(曲线要凸)、末条 = 1.0。 变异验证(自己跑,红过再还原): - `VIEWPORT_FADE_STEPS` 12 → 6:`panicked … 步数必须等于高度像素数:12px 要 1px 一条, 现在 6 条 ⇒ 2px/条`,MUTATION_EXIT=101;还原 12 后 GREEN_EXIT=0。 - `t.powf(1.6)` → `t.powf(1.0)`:`panicked … 第 2 条比前一条浓得更少…曲线要凸(t^1.6)`, MUTATION2_EXIT=101;还原后绿。 门禁(真实退出码,CARGO_TARGET_DIR=C:/Temp/ull-target/wt-227,-j 4): fmt 0 / check -p unlucky-app-iced --all-targets 0 / test --workspace 0(67 个 ok, app-iced lib 875 passed,四条像素守门 + fade 单测全绿)/ clippy --workspace --all-targets -D warnings 0 / .rs 扫描 >400 行 0 个、<2 字节 0 个。
This commit is contained in:
1 parent
122accdd02
commit
4f5a76f238
4 files changed
+81
-31
No files matched your search
@@ -129,13 +129,15 @@ pub(super) fn panel_state(model: &Download) -> PanelState<'_> {
|
|||||||
/// 落在切线上),在 `Narrow` 档则**在滚动区里**——窄档没有多余高度同时钉住「菜单 + 3 整行列表」,
|
/// 落在切线上),在 `Narrow` 档则**在滚动区里**——窄档没有多余高度同时钉住「菜单 + 3 整行列表」,
|
||||||
/// 而列表那 3 整行是 M125 像素守门的下限。两支的取舍都写在 `rows/tail.rs`。
|
/// 而列表那 3 整行是 M125 像素守门的下限。两支的取舍都写在 `rows/tail.rs`。
|
||||||
///
|
///
|
||||||
/// **两个 Shared 分支的现实不同,别一概而论**(`rows/tail.rs::TailShare::of`):
|
/// **两支「面板先保预算」的分支(`Shared` / `Narrow`)的现实不同,别一概而论**
|
||||||
|
/// (`rows/tail.rs::TailShare::of`):
|
||||||
///
|
///
|
||||||
/// - **三栏档 + 带加载器版本列表**:`has_loader_versions()` 要求 `problem.is_none()`,所以这一支
|
/// - **三栏档 + 带加载器版本列表**(`Shared`):`has_loader_versions()` 要求 `problem.is_none()`,
|
||||||
/// 滚动区里**只会有 head + chips**,错误行与它不可达;
|
/// 所以这一支滚动区里**只会有 head + chips**,错误行与它不可达;
|
||||||
/// - **chips 档**:`TailShare::of` 对 `Options`/`Install` 无条件 `Narrow`,`problem` **可以是**
|
/// - **chips 档**(`Narrow`):`TailShare::of` 对 `Options`/`Install` 无条件 `Narrow`,
|
||||||
/// `Some`(静态不兼容 / 版本列表取不到 / 空表三种),那时错误行**在滚动区里**、可能被滚走;
|
/// `problem` **可以是** `Some`(静态不兼容 / 版本列表取不到 / 空表三种),那时错误行
|
||||||
/// `show_versions()` 为假时滚动区只剩 head + chips + 错误行,钉死区只有实例名。
|
/// **在滚动区里**、可能被滚走;`show_versions()` 为假时滚动区只剩 head + chips + 错误行,
|
||||||
|
/// 钉死区只有实例名。
|
||||||
pub(super) fn panel<'a>(ui: &'a Ui, catalog: Catalog, model: &'a Download) -> Element<'a, Message> {
|
pub(super) fn panel<'a>(ui: &'a Ui, catalog: Catalog, model: &'a Download) -> Element<'a, Message> {
|
||||||
panel_with(ui, catalog, model, TailShare::Pinned)
|
panel_with(ui, catalog, model, TailShare::Pinned)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,15 +37,12 @@ pub(super) const VIEWPORT_FADE_PX: f32 = 12.0;
|
|||||||
/// 钉死区的实例名从 668 起,所以遮罩压不到任何控件(M227 返工的零回退证据就是逐像素
|
/// 钉死区的实例名从 668 起,所以遮罩压不到任何控件(M227 返工的零回退证据就是逐像素
|
||||||
/// 差异只有 648–660 这 12 行)。
|
/// 差异只有 648–660 这 12 行)。
|
||||||
pub(super) fn viewport_fade<'a>(ui: &'a Ui, height: f32) -> Element<'a, Message> {
|
pub(super) fn viewport_fade<'a>(ui: &'a Ui, height: f32) -> Element<'a, Message> {
|
||||||
const STEPS: usize = 12;
|
|
||||||
let canvas = ui.layer(MaterialLayer::Canvas);
|
let canvas = ui.layer(MaterialLayer::Canvas);
|
||||||
let band_height = height / STEPS as f32;
|
let band_height = height / VIEWPORT_FADE_STEPS as f32;
|
||||||
|
|
||||||
let mut bands = column![].width(Length::Fill);
|
let mut bands = column![].width(Length::Fill);
|
||||||
for index in 0..STEPS {
|
for index in 0..VIEWPORT_FADE_STEPS {
|
||||||
// t:顶端 ≈0(几乎透出内容)→ 底端 = 1(完全是画布色,与视口外的背景接上)。
|
let alpha = canvas.a * step_alpha(index);
|
||||||
let t = (index + 1) as f32 / STEPS as f32;
|
|
||||||
let alpha = canvas.a * t.powf(1.6);
|
|
||||||
bands = bands.push(
|
bands = bands.push(
|
||||||
container(space::horizontal())
|
container(space::horizontal())
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
@@ -56,28 +53,73 @@ pub(super) fn viewport_fade<'a>(ui: &'a Ui, height: f32) -> Element<'a, Message>
|
|||||||
bands.into()
|
bands.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 遮罩的条数:每条高 `VIEWPORT_FADE_PX / VIEWPORT_FADE_STEPS` 像素(现在是 1px)。
|
||||||
|
///
|
||||||
|
/// 单测直接对**这一对生产常量** + [`step_alpha`] 断言,所以改步数或改曲线都会当场变红
|
||||||
|
/// ——M227 r2 复审实测过「单测空转」的形态:旧测试在函数体里又抄了一遍 `12`,改生产常量它照样绿。
|
||||||
|
pub(super) const VIEWPORT_FADE_STEPS: usize = 12;
|
||||||
|
|
||||||
|
/// 第 `index` 条(0 = 最上面、`VIEWPORT_FADE_STEPS - 1` = 视口底边)的**不透明度系数**。
|
||||||
|
///
|
||||||
|
/// 顶端 ≈0(几乎透出内容)→ 底端 = 1(完全是画布色,与视口外的背景接上);`t^1.6` 让前几条更淡,
|
||||||
|
/// 观感是「内容渐隐到背景」,不是一层均匀的纱。
|
||||||
|
pub(super) fn step_alpha(index: usize) -> f32 {
|
||||||
|
// t:0 < t <= 1(`index + 1` 让顶端不落在 0 上,否则第一条完全看不见)。
|
||||||
|
let t = (index + 1) as f32 / VIEWPORT_FADE_STEPS as f32;
|
||||||
|
t.powf(1.6)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// 遮罩的几何自检:12 条 1px 恰好铺满 12px,且 α 单调不减(顶端近透明、底端不透明)。
|
/// 遮罩的几何自检:**对生产常量断言**,不是对测试里抄的副本。
|
||||||
///
|
///
|
||||||
/// 抓得住:把步数改成 6(每档 2px ⇒ 能看到阶梯)、或把 α 曲线写成常数(等于一层纯色幕)。
|
/// 抓得住(r2 复审指出的空转形态:旧测试在函数体里又抄了一遍 `12`,改生产常量照样绿):
|
||||||
|
/// `VIEWPORT_FADE_STEPS` 改成 6(每档 2px ⇒ 见得到阶梯)、改成不能整除高度的数(半像素带)、
|
||||||
|
/// `step_alpha` 写成常数(等于一层纯色幕)、把曲线拉直(`^1.0`,前几条不再更淡)、
|
||||||
|
/// 或让末项小于 1(视口底边与画布之间留一道缝)。
|
||||||
#[test]
|
#[test]
|
||||||
fn the_fade_steps_are_one_pixel_and_monotone() {
|
fn the_fade_bands_are_one_pixel_and_the_ramp_is_convex_to_opaque() {
|
||||||
let steps = 12.0_f32;
|
// ① 每条**恰好 1px**:这是设计口径(「12 条 1px 实色块」),也是「肉眼分不出阶梯」的前提。
|
||||||
|
// 换成 6 条就是 2px/条、换成 5 条还会出半像素带 —— 两种都当场红。
|
||||||
|
let band = VIEWPORT_FADE_PX / VIEWPORT_FADE_STEPS as f32;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
(VIEWPORT_FADE_PX / steps * steps * 100.0).round() / 100.0,
|
VIEWPORT_FADE_STEPS as f32, VIEWPORT_FADE_PX,
|
||||||
VIEWPORT_FADE_PX,
|
"步数必须等于高度像素数:{VIEWPORT_FADE_PX}px 要 1px 一条,现在 {VIEWPORT_FADE_STEPS} 条 ⇒ {band}px/条"
|
||||||
"步数要能整除 12,否则会出现半像素带"
|
);
|
||||||
|
assert_eq!(band, 1.0, "每条恰好 1px");
|
||||||
|
|
||||||
|
// ② α 严格递增、除末条外都不透明(末条必须是画布色本身,与视口外无缝接上)。
|
||||||
|
let mut previous = 0.0_f32;
|
||||||
|
let mut previous_delta = 0.0_f32;
|
||||||
|
for index in 0..VIEWPORT_FADE_STEPS - 1 {
|
||||||
|
let alpha = step_alpha(index);
|
||||||
|
let delta = alpha - previous;
|
||||||
|
assert!(
|
||||||
|
delta > 0.0,
|
||||||
|
"第 {index} 条的 α ({alpha}) 必须大于前一条 ({previous}):遮罩要单调变浓"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
alpha < 1.0,
|
||||||
|
"第 {index} 条就已不透明,后面 {VIEWPORT_FADE_STEPS} 条白给"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
delta >= previous_delta,
|
||||||
|
"第 {index} 条比前一条浓得更少({delta} < {previous_delta}):曲线要凸(t^1.6),否则顶端不再「几乎透出内容」"
|
||||||
);
|
);
|
||||||
let mut previous = -1.0_f32;
|
|
||||||
for index in 0..12 {
|
|
||||||
let t = (index + 1) as f32 / steps;
|
|
||||||
let alpha = t.powf(1.6);
|
|
||||||
assert!(alpha >= previous, "α 必须单调不减(第 {index} 档)");
|
|
||||||
previous = alpha;
|
previous = alpha;
|
||||||
|
previous_delta = delta;
|
||||||
}
|
}
|
||||||
assert_eq!(previous, 1.0, "底端必须是完全不透明的画布色");
|
assert!(
|
||||||
|
step_alpha(0) < 0.1,
|
||||||
|
"最上面一条 α = {} 不够淡:遮罩顶端要几乎透出内容",
|
||||||
|
step_alpha(0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
step_alpha(VIEWPORT_FADE_STEPS - 1),
|
||||||
|
1.0,
|
||||||
|
"最末一条必须是画布色本身(否则与视口外的背景之间有一道缝)"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ pub(super) fn version_menu_height(items: usize) -> f32 {
|
|||||||
/// - `Pinned`(原版等不带版本列表的面板)走另一条路:标签、说明、菜单、实例名都在同一列里
|
/// - `Pinned`(原版等不带版本列表的面板)走另一条路:标签、说明、菜单、实例名都在同一列里
|
||||||
/// 顺序铺开(`04` 基线图就是这一档,不能改);
|
/// 顺序铺开(`04` 基线图就是这一档,不能改);
|
||||||
/// - `Shared`(三栏档 + 带版本列表):
|
/// - `Shared`(三栏档 + 带版本列表):
|
||||||
/// - **滚动区**:head(版本 id + 安装按钮)+ 六枚加载器 chips(**chips 档**还可能有错误行,见下);
|
/// - **滚动区**:head(版本 id + 安装按钮)+ 六枚加载器 chips;
|
||||||
/// - **钉死区**:说明行(有说明时;否则是「加载器版本」标签)+ 版本菜单 + 实例名输入框。
|
/// - **钉死区**:说明行(有说明时;否则是「加载器版本」标签)+ 版本菜单 + 实例名输入框。
|
||||||
/// - `Narrow`(chips 档 + 面板占高度,M227):
|
/// - `Narrow`(chips 档 + 面板占高度,M227):
|
||||||
/// - **滚动区**:head + 六枚 chips + 说明行 + 错误行 + **版本菜单**;
|
/// - **滚动区**:head + 六枚 chips + 说明行 + 错误行 + **版本菜单**;
|
||||||
@@ -110,10 +110,13 @@ pub(super) fn version_menu_height(items: usize) -> f32 {
|
|||||||
/// 而 M125 的像素守门要求 ≥3 整行。所以窄档只钉实例名,其余进滚动区(预算算术见
|
/// 而 M125 的像素守门要求 ≥3 整行。所以窄档只钉实例名,其余进滚动区(预算算术见
|
||||||
/// `rows/tail.rs::CHIPS_PANEL_BUDGET`)。
|
/// `rows/tail.rs::CHIPS_PANEL_BUDGET`)。
|
||||||
///
|
///
|
||||||
/// D30 八审实测(1180×760,`Shared`):滚动区可见高 ≈96–120px,内容(head 40 + chips 32 +
|
/// D30 八审实测(1180×760,`Shared`):滚动区可见高 ≈96–104px,内容(head 40 + chips 32 +
|
||||||
/// 间距 4)≈76px ⇒ head(墨迹 462–501)与六枚 chips(506–537,32px 四角闭合)完整在首屏。
|
/// 间距 4)≈76px ⇒ head(墨迹 462–501)与六枚 chips(506–537,32px 四角闭合)完整在首屏。
|
||||||
/// M227 实测(720×760,`Narrow`):滚动区 120px ≥ 首屏 104(head 40 + 4 + chips 32 + 8 +
|
/// M227 在 tip 上按同一条判据复量(视口 = 面板内容顶 → 钉死区上一行 − 8px 间距):
|
||||||
/// 说明行 20)⇒ head、六枚 chips、说明行三者完整在首屏,菜单露出容器上沿(有滚动条)。
|
/// 1180×760 = 462→563 = **101px**、1180×900 = 594→703 = **109px**、窄档 720×760 = 539→659 =
|
||||||
|
/// **120px**(r2 复审量的 116px 落在这个区间内,差别只在「钉死区从哪一行算起」;三档都远大于
|
||||||
|
/// 首屏内容 76px,结论不变)。窄档那 120px 对首屏 104px(head 40 + 4 + chips 32 + 8 + 说明行 20)
|
||||||
|
/// 留 16px 余量 ⇒ head、六枚 chips、说明行三者完整在首屏,版本菜单露出容器上沿(滚动条在右)。
|
||||||
pub(crate) fn section<'a>(
|
pub(crate) fn section<'a>(
|
||||||
ui: &'a Ui,
|
ui: &'a Ui,
|
||||||
catalog: Catalog,
|
catalog: Catalog,
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ use super::{bands, feed, ui, Shot, CHIPS_SHOT};
|
|||||||
///
|
///
|
||||||
/// 抓得住:①首行版本行的底色带 = 44(整行在屏);②**列表区 ≥ 3 整行**(面板上沿那条通栏
|
/// 抓得住:①首行版本行的底色带 = 44(整行在屏);②**列表区 ≥ 3 整行**(面板上沿那条通栏
|
||||||
/// 分隔线就是下界)——这是窄档预算的硬下限:面板钉死区若重新钉住版本菜单(M227 之前的样子),
|
/// 分隔线就是下界)——这是窄档预算的硬下限:面板钉死区若重新钉住版本菜单(M227 之前的样子),
|
||||||
/// 它在 459px 里只能再留 1 整行给列表;③分隔线下方 96px 内有一条 ≥ 80px 的实色带(面板头那条
|
/// 它在 459px 里只能再留 1 整行给列表;③面板头部在屏:断言在面板上沿分隔线下方 96px 的窗口
|
||||||
/// 实心「安装」按钮 / 菜单容器的满宽底边)——「能换版本」与「能看见选项面板」是这条断言的成对验收。
|
/// (分隔线 514 ⇒ 窗口 518–610)里找一条 ≥ 80px 的同色带,窄档实测命中 **y=550、宽 94px**,
|
||||||
|
/// 那是**实心「安装」按钮的药丸本身**——版本菜单容器的上沿在 636–639,落在窗口之外,与本条无关
|
||||||
|
/// (r2 复审订正:旧注释把「菜单容器的满宽底边」也列成可能来源,那是错的)。
|
||||||
|
/// 「能换版本」与「能看见选项面板」是这条断言的成对验收。
|
||||||
///
|
///
|
||||||
/// 抓不住:文本有没有被**横向**裁掉(那要看字形宽度,见 `tests/rails.rs` 的标签断言与
|
/// 抓不住:文本有没有被**横向**裁掉(那要看字形宽度,见 `tests/rails.rs` 的标签断言与
|
||||||
/// 报告里的量测表)、hover/tooltip 层(静态图拍不到)、面板内部滚动到底后长什么样
|
/// 报告里的量测表)、hover/tooltip 层(静态图拍不到)、面板内部滚动到底后长什么样
|
||||||
|
|||||||
Reference in new issue
Block a user