fix(app-iced): M125 r2 —— chips 档「还没选版本」不再对半切;宽度表换成实测值
r1 复审 p2-1:`TailShare::of` 只判档位,于是 chips 档「刚进页面」(面板只有一行 提示)也被五五分——700×760 下列表 8 个版本只显示 4 个、下半块 ≈160px 空画布, 而修前(main)这一态是 7 整行。修法:判据加**面板形态**,`Hint` 在任何档位都钉死, `Chips` + `Options`/`Install` 才共享。实测回到 7 整行(与 main 同一水位)。 守门:新增 `options_shot/ready.rs`(`ULL_DL_READY_SHOT`,不设 `ULL_DL_DEMO` 出的 700×760 图):列表区至少读出 6 个版本号。它在 r1 的图上**红**(4 个,原生输出见 mission 报告),在修后图上绿(7 个)。三条旧守门照旧(chips / compact / wide), chips 与 compact 换修前图仍红。 r1 复审 p2-2:宽度表的实测值改正(同一张 736 图逐项量): `1.21` 26(余 6)、`1.20` 28(余 4)、`24w` **29**(余 3)、`All versions` 墨迹画到 x=247(裁切边 248,只差 1px)⇒ 桶标签余量是 **3~6px** 而不是 6;「短标签『全部』= 32 零余量」这条论证的对比强度随之写准(比桶标签的 3~6px 更薄)。 `rails/major.rs` 的表格、`options_shot/compact.rs` 的测试文档一并改成实测值; 「墨迹右边界」那条反例也从 216..244 改成实测 216..247。 r1 复审 p3-1:第二级「全部版本」的图标从网格(与第一级同字形同药丸、像素级同形) 换成文档/清单字形 `IconKind::Logs`,理由与「图标集里没有版本/历史字形」写进 `major_shape` 文档。 r1 复审 p3-2:chips 档最多三层滚动(列表 / 面板 / loader 菜单)作为**已知风险** 登记在 `install.rs` 文档里,并写明为什么「把实例名移出滚动区」本轮不做(要拆 `options::section`,动三个文件,而且改完仍无法验证滚轮冒泡——没有通道)。
This commit is contained in:
1 parent
9c623a6fd3
commit
0f26ed3753
9 files changed
+283
-58
No files matched your search
@@ -228,7 +228,12 @@ fn body<'a>(
|
||||
column![
|
||||
rails::stacked_chips(ui, catalog, model),
|
||||
divider::full(ui),
|
||||
rows::content(ui, catalog, model, rows::TailShare::of(rails.tier)),
|
||||
rows::content(
|
||||
ui,
|
||||
catalog,
|
||||
model,
|
||||
rows::TailShare::of(rails.tier, &install::panel_state(model)),
|
||||
),
|
||||
]
|
||||
.spacing(ui.space(Space::X2))
|
||||
.width(Length::Fill)
|
||||
|
||||
@@ -11,7 +11,25 @@
|
||||
//!
|
||||
//! **M125 的例外**:chips 档(窗口 < 736,竖栏退回顶部 chip 行)里这块面板太贵——它按内容高
|
||||
//! 钉死会把版本列表压成 18px 的缝。那一档改成「列表与面板各吃一半、面板自己可滚」
|
||||
//! (`rows::TailShare::Shared`),所以「钉在底部」只对三栏档成立。
|
||||
//! (`rows::TailShare::Shared`)——但只在**面板真的占高度**时(`Options` / `Install`);
|
||||
//! 只画一行提示的 `Hint` 态仍钉死,否则 8 个版本的列表会被砍到 4 行(r1 复审 P2-1)。
|
||||
//!
|
||||
//! ## 已知风险:chips 档最多会同时出现**三层**滚动(r1 复审 P3-2,未验)
|
||||
//!
|
||||
//! ```text
|
||||
//! 版本行列表 scrollable ← 第 1 层(任何档位都在)
|
||||
//! └ 面板 scrollable(chips 档才有) ← 第 2 层
|
||||
//! └ 加载器版本 menu 的 scrollable ← 第 3 层(`options/view.rs` 的 `VERSION_ROWS`)
|
||||
//! ```
|
||||
//!
|
||||
//! **鼠标落在第 3 层上滚轮会不会冒泡到第 2 层,本仓没有实测通道**(静态图拍不到滚动嵌套)。
|
||||
//! iced 的 `scrollable` 在指针悬停于内层时由内层消费滚动,所以「滚到底之后继续滚会带动外层」
|
||||
//! 属于**未验证行为**;两个方向的坏结果分别是「面板卡住滚不动」与「一滚就跳到外层」。
|
||||
//!
|
||||
//! 缓解方案(本轮**没做**,理由:不是一处小改)——把「实例名」那一格从面板的滚动区里移出去,
|
||||
//! 做成面板的固定页脚:那要把 `options::section` 拆成「可滚的上半块 + 钉死的下半块」,
|
||||
//! 动 `options/view.rs` / `install.rs` / `rows.rs` 三处,而且改完仍然**无法**验证滚轮冒泡
|
||||
//! (没有通道),只是把风险从「某一格被挡」换成「面板永不挡那一格」。所以先登记为已知风险。
|
||||
//!
|
||||
//! ## 只有意图,没有乐观回显
|
||||
//!
|
||||
|
||||
@@ -91,7 +91,7 @@ pub(super) fn three_column<'a>(
|
||||
ui,
|
||||
catalog,
|
||||
model,
|
||||
rows::TailShare::of(rails.tier),
|
||||
rows::TailShare::of(rails.tier, &super::install::panel_state(model)),
|
||||
))
|
||||
.width(Length::Fixed(rails.list))
|
||||
.height(Length::Fill),
|
||||
|
||||
@@ -11,15 +11,17 @@ use unlucky_design::spacing::Space;
|
||||
|
||||
use unlucky_i18n::{Catalog, Key};
|
||||
|
||||
use unlucky_design::icons::IconKind;
|
||||
|
||||
use crate::app::components::navigation::list_item::{list_item, ListItem};
|
||||
use crate::pages::download::group;
|
||||
use crate::pages::download::model::{Category, Download};
|
||||
use crate::pages::download::model::Download;
|
||||
use crate::pages::frame;
|
||||
use crate::pages::layout::RAIL_ICON_WIDTH;
|
||||
use crate::pages::Message;
|
||||
use crate::theme::Ui;
|
||||
|
||||
use super::{category_icon, labeled, rail_title};
|
||||
use super::{labeled, rail_title};
|
||||
|
||||
/// 第二栏:主版本桶(第一项永远是「全部版本」;没有主版本概念的版本不单独占一项)。
|
||||
pub(in crate::pages::download) fn major_rail<'a>(
|
||||
@@ -77,19 +79,32 @@ pub(in crate::pages::download) enum MajorShape<'a> {
|
||||
/// `ListItem` 两侧内边距各 16(`pad_start` / `pad_end`),所以 64 宽的栏里文本格
|
||||
/// = 64 − 32 = **32**,再长就被 `clip(true)` 切掉。`BodyLarge` 16px 下:
|
||||
///
|
||||
/// | 标签 | 墨迹宽 | 32 里放得下? |
|
||||
/// | 标签 | 墨迹(736×760 实测) | 32 的文本格里放得下? |
|
||||
/// |---|---|---|
|
||||
/// | `1.21` | 26(736×760 那张实测) | ✓ 余量 6 |
|
||||
/// | `24w` | 26(同上) | ✓ 余量 6 |
|
||||
/// | `All versions` | ≈84(12 字符,按 0.4em 下限也有 77) | ✗ 只画得出「All v」(缺陷 2 的原图) |
|
||||
/// | `全部版本` | 4 × 16 = **64**(全角 1em,精确值) | ✗ 只画得出「全部」,而且正好顶到裁切边 |
|
||||
/// | `1.21` | 26px(x=217..242) | ✓ 余量 **6** |
|
||||
/// | `1.20` | 28px(x=217..244) | ✓ 余量 **4** |
|
||||
/// | `24w` | 29px(x=216..244) | ✓ 余量 **3**(最紧的一条) |
|
||||
/// | `All versions` | 墨迹画到 x=247,裁切边在 248 | ✗ 被切:实际只画出「All v」(缺陷 2 的原图) |
|
||||
/// | `全部版本` | 4 全角字 × 16 = **64**(精确值,不是估计) | ✗ 只画得出「全部」,且顶到裁切边 |
|
||||
///
|
||||
/// 短标签这条退路也不行:中文「全部」= 2 × 16 = **32**,与文本格**一样宽、零余量**,
|
||||
/// 「裁不裁」取决于字体渲染的小数位——一个查不出、也守不住的边界。所以图标条档的
|
||||
/// 「全部版本」**不画文字**:换成与本页第一级那个「全部」同一个网格图标
|
||||
/// ([`category_icon`] 的 `Category::All`),全称进 tooltip(宽度不设限,中英文都完整)。
|
||||
/// 桶标签的余量是 **3~6px**(视字形:`24w` 最紧 3,`1.21` 最松 6)。短标签「全部」= 2 × 16 = **32**,
|
||||
/// 与文本格**一样宽、零余量**——比桶标签那 3~6px 更薄,裁不裁取决于字体渲染的小数位,
|
||||
/// 是一个查不出也守不住的边界,所以「换短标签」这条退路不采用。于是图标条档的
|
||||
/// 「全部版本」**不画文字**:换成图标(字形见 [`major_shape`] 的下文),
|
||||
/// 全称进 tooltip(宽度不设限,中英文都完整)。
|
||||
///
|
||||
/// 桶标签本来就是 3~5 字符的短串,两档都照旧画原文。
|
||||
///
|
||||
/// ## 用哪个字形(r1 复审 P3-1)
|
||||
///
|
||||
/// 这里用 **`IconKind::Logs`(文档 + 正文行)**,不用第一级「全部类型」那个网格
|
||||
/// (`category_icon(Category::All)`):Compact 档两条 64 宽的栏在屏上相邻,若两级都用网格 +
|
||||
/// 同一个 40×40 `Tonal` 药丸,**第一级「全部」与第二级「全部版本」像素级同形**,
|
||||
/// 只能靠 hover 出 tooltip 才分得清是哪个轴。文档/清单字形读作「整份版本清单」,
|
||||
/// 与网格(「全部类型」)分得开。
|
||||
///
|
||||
/// 更贴切的「版本 / 历史 / 层叠」字形本仓没有(图标语汇只有 28 个描边字形,登记在
|
||||
/// `unlucky_design::icons`),新增字形要动 `crates/design`(超出本页范围),此处按既有字形借用。
|
||||
pub(in crate::pages::download) const fn major_shape(
|
||||
entry: MajorEntry<'_>,
|
||||
icon_only: bool,
|
||||
@@ -146,17 +161,13 @@ fn major_item<'a>(ui: &'a Ui, entry: MajorEntry<'a>, icon_only: bool) -> Element
|
||||
}
|
||||
// 图标条档的「全部版本」:图标(与本页第一级的「全部」同一个网格)+ 全称 tooltip。
|
||||
// 高度对齐 `ListItem` 的行高,两档的行节奏才一样。
|
||||
MajorShape::Icon(full) => container(labeled(
|
||||
ui,
|
||||
full,
|
||||
category_icon(Category::All),
|
||||
entry.selected,
|
||||
press,
|
||||
))
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(ui.metrics().row_height))
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.into(),
|
||||
MajorShape::Icon(full) => {
|
||||
container(labeled(ui, full, IconKind::Logs, entry.selected, press))
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(ui.metrics().row_height))
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,11 @@
|
||||
//! 固定 ≈316px(版本行 40 + 标题 16 + 五个 loader chip 34 + 标题 16 + 菜单 112 + 实例名 56)。
|
||||
//! 同样的 760 高窗口里:三栏档列表还剩 158px(3 整行),chips 档只剩 18px。
|
||||
//!
|
||||
//! 修法是 [`TailShare`] 两档:三栏档照旧钉死(面板整块在屏内),chips 档改成两半各 `Fill`
|
||||
//! ——列表拿到 ≈182px(**4 整行**),面板拿到同样一半、**自己可滚**(顶端那个实心「安装」
|
||||
//! 按钮与五个 loader chip 仍在屏内,实例名那一格滚一下就到)。
|
||||
//! 修法是 [`TailShare`] 两档:三栏档照旧钉死(面板整块在屏内),chips 档**且面板真的占高度**
|
||||
//! (选项区展开 / 安装中)时改成两半各 `Fill`——列表拿到 ≈182px(**4 整行**),面板拿到同样一半、
|
||||
//! **自己可滚**(顶端那个实心「安装」按钮与五个 loader chip 仍在屏内,实例名那一格滚一下就到)。
|
||||
//! 「刚进页面还没选版本」(`Hint`,面板只有一行提示)**不共享**:那一态 8 个版本能全在屏,
|
||||
//! 五五分会砍成 4 行、下面留 ≈160px 空白(r1 复审 P2-1 的回归)。
|
||||
//!
|
||||
//! 这条判据按**档位**而不是按高度:页面的模型里只有 `window_width`,窗口高度没接进页面,
|
||||
//! 所以「760 高到底够不够」在运行时是未知量(边界写在 [`TailShare`] 的文档里)。
|
||||
@@ -70,8 +72,9 @@ use super::super::frame;
|
||||
use super::super::layout::rails::{LIST_DATE_WIDTH, LIST_KIND_WIDTH, ROW_GAP, ROW_ICON_BUTTON};
|
||||
use super::super::layout::VersionRailTier;
|
||||
use super::super::Message;
|
||||
use super::install::{self, PanelState};
|
||||
use super::model::{Download, VersionRow};
|
||||
use super::{install, states};
|
||||
use super::states;
|
||||
|
||||
/// 列表列(三栏档与 chips 档共用一份)。
|
||||
///
|
||||
@@ -129,7 +132,8 @@ pub(super) fn content<'a>(
|
||||
/// | 档 | 分法 | 为什么 |
|
||||
/// |---|---|---|
|
||||
/// | `Wide` / `Narrow` / `Compact` | [`TailShare::Pinned`]:面板按内容高钉在底部,列表吃剩下的 | 竖栏档在 760 高的窗口里列表还剩 158px(3 整行),面板整块在屏内——两样都对 |
|
||||
/// | `Chips` | [`TailShare::Shared`]:两半各 `Fill`,面板自己可滚 | chips 档比三栏档多花两行 chip(tabs 48 + chips 48 + 间距),列表只剩 **18px**(M123 实测 0.4 行),面板 316px 全在屏内也没用——版本号读不出来就换不了版本 |
|
||||
/// | `Chips` + 面板**占高度**(选项区展开 / 安装中) | [`TailShare::Shared`]:两半各 `Fill`,面板自己可滚 | chips 档比三栏档多花两行 chip(tabs 48 + chips 48 + 间距),列表只剩 **18px**(M123 实测 0.4 行),面板 316px 全在屏内也没用——版本号读不出来就换不了版本 |
|
||||
/// | 任何档 + 只画 `Hint`(没选版本,面板只有一行) | [`TailShare::Pinned`] | 一行提示不值得对半分:700×760 下 8 个版本能全在屏,对半分只剩 4 个、下面留 160px 空白(r1 复审 P2-1) |
|
||||
///
|
||||
/// 判据是**档位**不是高度:页面的模型里只有 `window_width`(`pages/model.rs`),窗口高度
|
||||
/// 没有接进页面(要接得改 `pages/mod.rs` 的入口签名,超出本页的边界)。所以这里按「哪一档
|
||||
@@ -143,13 +147,21 @@ pub(super) enum TailShare {
|
||||
}
|
||||
|
||||
impl TailShare {
|
||||
/// 档位 → 分高方式(纯函数,单测直接钉它)。
|
||||
pub(super) const fn of(tier: VersionRailTier) -> Self {
|
||||
match tier {
|
||||
VersionRailTier::Chips => Self::Shared,
|
||||
VersionRailTier::Wide | VersionRailTier::Narrow | VersionRailTier::Compact => {
|
||||
Self::Pinned
|
||||
/// 档位 + **面板形态** → 分高方式(纯函数,单测直接钉它)。
|
||||
///
|
||||
/// 两个条件必须同时成立才共享:
|
||||
/// 1. 档位是 `Chips`(多花两行 chip,竖排预算最紧的那一档);
|
||||
/// 2. 面板真的**占高度**——`Options`(选中了版本、选项区展开)或 `Install`(进度 / 失败)。
|
||||
///
|
||||
/// `Hint`(刚进页面还没选版本)只是**一行**提示(≈30px),对半分会让 8 个版本只显示 4 个、
|
||||
/// 下半块留 ≈160px 空画布(r1 复审 P2-1 实测:修前 700×760 下 8 行全在屏,只判档位的写法
|
||||
/// 把它压到 4 行)。所以 `Hint` **在任何档位都钉死**。
|
||||
pub(super) const fn of(tier: VersionRailTier, state: &PanelState<'_>) -> Self {
|
||||
match (tier, state) {
|
||||
(VersionRailTier::Chips, PanelState::Options(_) | PanelState::Install(_)) => {
|
||||
Self::Shared
|
||||
}
|
||||
_ => Self::Pinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ const WIDE_SHOT: &str = "ULL_DL_OPTIONS_SHOT";
|
||||
const CHIPS_SHOT: &str = "ULL_DL_CHIPS_SHOT";
|
||||
/// 736 宽那张(`04-options-fabric-en-light-compact736.png`)——Compact 档主版本栏用。
|
||||
const COMPACT_SHOT: &str = "ULL_DL_COMPACT_SHOT";
|
||||
/// 700 宽、**不设 `ULL_DL_DEMO`**(= `ready`,还没选版本)那张——r1 复审 P2-1 的守门用。
|
||||
const READY_SHOT: &str = "ULL_DL_READY_SHOT";
|
||||
|
||||
fn ui() -> Ui {
|
||||
Ui::with_platform(SchemeFlavor::Light, Platform::Windows, FAMILIES)
|
||||
@@ -183,6 +185,34 @@ impl Shot {
|
||||
(start, end - start + 1)
|
||||
}
|
||||
|
||||
/// `[from, to)` 里在 `[left, right)` 有墨迹的**条数**(两条之间空 ≥ 8 行才算两条)。
|
||||
///
|
||||
/// 用它数「读得出几个版本号」:一行版本号的文本墨迹约 11px 高、行距 44,中间空 30+ ⇒
|
||||
/// 一条对应一行。被压扁时整块只剩一条。
|
||||
fn ink_bands(
|
||||
&self,
|
||||
left: usize,
|
||||
right: usize,
|
||||
from: usize,
|
||||
to: usize,
|
||||
background: [u8; 3],
|
||||
) -> usize {
|
||||
let mut bands = 0;
|
||||
let mut gap = usize::MAX;
|
||||
for y in from..to.min(self.height) {
|
||||
let inked = (left..right).any(|x| self.at(x, y) != background);
|
||||
if inked {
|
||||
if gap >= 8 {
|
||||
bands += 1;
|
||||
}
|
||||
gap = 0;
|
||||
} else {
|
||||
gap = gap.saturating_add(1);
|
||||
}
|
||||
}
|
||||
bands
|
||||
}
|
||||
|
||||
/// 列表列里、`from` 起的**第一条薄通栏横线**的 y(`divider::full` 画的那条 1px 线)。
|
||||
///
|
||||
/// 用它量「版本列表到哪儿为止」:尾部面板上沿有一条通栏分隔线,它上面的高度就是列表拿到的。
|
||||
@@ -350,3 +380,5 @@ fn an_options_shot_shows_both_rails_and_the_whole_panel() {
|
||||
mod chips;
|
||||
|
||||
mod compact;
|
||||
|
||||
mod ready;
|
||||
@@ -4,12 +4,22 @@ use super::{bands, shot_path, ui, Shot, COMPACT_SHOT};
|
||||
|
||||
/// `04-…-compact736.png`(736×760,`ULL_DL_COMPACT_SHOT`)——**Compact 档主版本栏(缺陷 2)**。
|
||||
///
|
||||
/// 修前(M123 取证):主版本栏宽 64,`ListItem` 两侧内边距各 16 ⇒ 文本格 32,
|
||||
/// 而首项「All versions」要 ≈84 ⇒ 图上只剩「**All v**」。中文更糟:「全部版本」= 4 全角字 = 64,
|
||||
/// 32 里只剩「全部」而且正好顶到裁切边。
|
||||
/// 修前(M123 取证;本文件作者在 736×760 那张图上逐项量过):主版本栏宽 64,`ListItem`
|
||||
/// 两侧内边距各 16 ⇒ 文本格 **32**(x=216..247,裁切边 248):
|
||||
///
|
||||
/// | 标签 | 墨迹 | 结论 |
|
||||
/// |---|---|---|
|
||||
/// | `1.21` | 26px | 完整(余 6) |
|
||||
/// | `1.20` | 28px | 完整(余 4) |
|
||||
/// | `24w` | 29px | 完整(余 3,最紧) |
|
||||
/// | `All versions` | 画到 x=247(裁切边 248) | **被切**:只剩「All v」 |
|
||||
/// | `全部版本` | 4 全角字 = 64 > 32 | **被切**:只剩「全部」且顶到边 |
|
||||
///
|
||||
/// 即桶标签的余量是 **3~6px**,而「全部版本」这条根本放不下。
|
||||
///
|
||||
/// 修后:图标条档的「全部版本」**不画文字**(`rails::major_shape` 的 `Icon` 分支)——
|
||||
/// 画成与本页第一级那个「全部」同一个网格图标(40×40 `Tonal` 药丸 + 全称 tooltip)。
|
||||
/// 画成文档/清单字形(40×40 `Tonal` 药丸 + 全称 tooltip)。**不是**第一级那个网格:
|
||||
/// 两条 64 栏相邻,同字形 + 同药丸会让「全部类型」与「全部版本」像素级同形(r1 复审 P3-1)。
|
||||
///
|
||||
/// 抓得住:①首项是 **40×40 的图标药丸**(不是 64 宽 × 44 高的通栏文字行)——谁把它改回
|
||||
/// 「画文字」(全称或短标签都会是通栏 44 行)这条立刻红;②药丸在 64 栏里**居中**(左右各 12)。
|
||||
@@ -17,8 +27,9 @@ use super::{bands, shot_path, ui, Shot, COMPACT_SHOT};
|
||||
///
|
||||
/// ## 为什么不用「文字墨迹右边界 ≤ 栏右内边界」这条(复审建议的那条)
|
||||
///
|
||||
/// 它**在坏图上也是绿的**:修前那张图实测首项文字墨迹 x=216..244,而栏右内边界是
|
||||
/// `200 + 64 − 16 = 248` ⇒ 244 ≤ 248 成立——「All **v**」明明被裁掉了,断言却过。
|
||||
/// 它**在坏图上也是绿的**:修前那张图实测首项文字墨迹 x=216..247,而栏右内边界是
|
||||
/// `200 + 64 − 16 = 248` ⇒ 247 ≤ 248 成立(只剩 1px 余量)——「All **v**」明明被裁掉了,
|
||||
/// 断言却过。这条比 r1 报告里写的更极端:差 1px 而不是 4px。
|
||||
/// 原因是 `ListItem` 的 `clip(true)` 让墨迹**永远**停在裁切边之前,边界的比较量不出「被裁」。
|
||||
/// 所以这里改钉**形状**:文字行是 64×44 的通栏带,图标按钮是 40×40 的居中药丸,两者像素可分。
|
||||
///
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//! 「还没选版本」那一态(`ULL_DL_DEMO` 不设 = `ready`)的像素守门:r1 复审 P2-1。
|
||||
//!
|
||||
//! ## 为什么要单独守这一态
|
||||
//!
|
||||
//! M125 r1 的 `TailShare::of` **只判档位**,于是 chips 档的「刚进页面」也被五五分:
|
||||
//! 面板里只有一行提示(`PanelState::Hint`,≈30px),却拿走一半高度 ⇒ 700×760 下
|
||||
//! 8 个版本只显示 **4** 个、下半块留 ≈160px 空画布(修前是 8 行全在屏)。
|
||||
//! 同目录 `chips.rs` 只拍「选中 + 选项区展开」,正是这个盲区把回归放了过去。
|
||||
//!
|
||||
//! 现在的判据:`Chips` **且**面板真占高度(`Options` / `Install`)才共享;
|
||||
//! `Hint` 在任何档位都钉死(见 `rows::TailShare::of`)。
|
||||
//!
|
||||
//! ```text
|
||||
//! # 不设 ULL_DL_DEMO(= ready)出 700×760 那张
|
||||
//! cargo run -p unlucky-app-iced --example pages_demo -- \
|
||||
//! --screen=download --width=700 --height=760 --screenshot=ready700.png \
|
||||
//! --screenshot-theme=light --software-renderer
|
||||
//! ULL_DL_READY_SHOT=ready700.png cargo test -p unlucky-app-iced --lib options_shot
|
||||
//! ```
|
||||
//!
|
||||
//! 抓得住:①列表区 **≥ 6 整行**(数版本号那列的墨迹条数,行距 44);②尾部(提示那条
|
||||
//! 分隔线)在 6 行之后——五五分时它落在第 4 行下方,两条都立刻红。
|
||||
//! 抓不住:提示文案本身、hover/tooltip 层(静态图拍不到);也不管「选中且展开」那一态
|
||||
//!(那是 `chips.rs` 的活)。
|
||||
|
||||
use super::{bands, shot_path, ui, Shot, READY_SHOT};
|
||||
|
||||
/// `ready` 那一态(700×760):8 个版本里至少 6 行要在屏,尾部提示不许把列表压扁。
|
||||
///
|
||||
/// 修前实测(M125 r1,`TailShare::of` 只判档位的版本):列表区 `374..559` = 185px = 4 行,
|
||||
/// 版本号那列只有 4 条墨迹;面板那半块 185px 里只有一行 `Pick a version, then install`,
|
||||
/// 其余是空白 —— 这条断言在那种图上是红的(4 < 6)。
|
||||
#[test]
|
||||
fn a_ready_shot_keeps_the_whole_visible_list() {
|
||||
let Some(path) = shot_path(READY_SHOT) else {
|
||||
eprintln!("[options-shot] SKIPPED:未设置 {READY_SHOT}。");
|
||||
return;
|
||||
};
|
||||
let shot = Shot::load(&path);
|
||||
assert_eq!(shot.width, 700, "这条只认 700×760 那张(chips 档)");
|
||||
|
||||
let bands = bands(700.0);
|
||||
let canvas = shot.at(bands.list.0 + 2, 12);
|
||||
let metrics = ui().metrics();
|
||||
let right = bands.list.0 + bands.list.1 as usize - 2;
|
||||
|
||||
// ① 第一行版本号的墨迹带(ready 态没有选中行,所以量的是**文本**而不是底色;
|
||||
// x 取 `+100` 落在版本号那几个字上——`+60` 会落进「前置下载图标」与文字之间的空档)
|
||||
let (first_ink, _) = shot
|
||||
.first_filled_band(bands.list.0 + 100, 360, 440, canvas)
|
||||
.expect("列表列里应当有版本行");
|
||||
|
||||
// ② 尾部(提示)上沿的分隔线:它上面的高度才是列表拿到的
|
||||
let rule = shot
|
||||
.first_rule_y(bands.list.0, right, first_ink, canvas)
|
||||
.expect("找不到尾部那条分隔线(列表区的下界量不出来)");
|
||||
|
||||
// ③ 数得出几个版本号:8 行里至少 6 行在屏
|
||||
let rows = shot.ink_bands(
|
||||
bands.list.0 + 50,
|
||||
bands.list.0 + 140,
|
||||
first_ink,
|
||||
rule,
|
||||
canvas,
|
||||
);
|
||||
assert!(
|
||||
rows >= 6,
|
||||
"ready 态只读得出 {rows} 个版本号(要求 ≥ 6 个,演示数据共 8 个):\
|
||||
面板那一行提示把列表对半切了(列表区 y={first_ink}..{rule},\
|
||||
共 {}px,行高 {})",
|
||||
rule - first_ink,
|
||||
metrics.row_height
|
||||
);
|
||||
assert!(
|
||||
(rule - first_ink) as f32 >= 6.0 * metrics.row_height - metrics.row_height / 2.0,
|
||||
"ready 态的列表区只有 {}px(y={first_ink}..{rule}),不足 6 整行",
|
||||
rule - first_ink
|
||||
);
|
||||
}
|
||||
@@ -146,37 +146,94 @@ fn the_demo_data_is_sane() {
|
||||
assert!(demo.rows.iter().all(|row| !row.supporting.contains('版')));
|
||||
}
|
||||
|
||||
/// 列表与尾部面板怎么分高,跟着**档位**走(M125 缺陷 1 的决策面)。
|
||||
/// 列表与尾部面板怎么分高:**档位 × 面板形态**两个条件同时成立才对半分。
|
||||
///
|
||||
/// 修前:面板一律按内容高钉在底部,700×760 的 chips 档里列表只剩 18px(0.4 行)。
|
||||
/// 修后:chips 档两半各 `Fill`(面板自己可滚),三栏三档照旧钉死(760 高下列表还有 3 整行、
|
||||
/// 面板整块在屏内,两样都对)。
|
||||
/// 修前(M123):面板一律按内容高钉在底部,700×760 的 chips 档里列表只剩 18px(0.4 行)。
|
||||
/// M125 r1 修法只判档位,又踩出另一条回归:chips 档「刚进页面还没选版本」(`Hint`,面板只有
|
||||
/// 一行提示)也被五五分,700×760 下 8 个版本只显示 4 个、下半块留 ≈160px 空画布
|
||||
/// (复审 P2-1 实测,修前是 8 行全在屏)。
|
||||
///
|
||||
/// 抓得住:有人把 chips 档改回 `Pinned`(700 下的像素守门 `a_chips_tier_shot_…` 立刻红);
|
||||
/// 或者把三栏档也改成 `Shared`(1180 下选项面板被切成一半,`an_options_shot_…` 会红)。
|
||||
/// 抓不住:**实际分到多少像素**(`iced` 的 `Element` 没有几何内省,那只能出图量,
|
||||
/// 见 `options_shot` 的像素断言与报告里的数值表)。
|
||||
/// 现在的判据:`Chips` **且**面板真占高度(`Options` / `Install`)才 `Shared`;
|
||||
/// `Hint` 在任何档位都 `Pinned`。
|
||||
///
|
||||
/// 抓得住:①chips 档改回「只判档位」(`Hint` 跟着对半分 ⇒ 列表掉到 4 行,像素守门
|
||||
/// `ready::a_ready_shot_keeps_the_whole_visible_list` 立刻红);②三栏档也改成 `Shared`
|
||||
/// (1180 下选项面板被切成一半,`an_options_shot_…` 会红)。
|
||||
/// 抓不住:**实际分到多少像素**(`iced` 的 `Element` 没有几何内省,那只能出图量)。
|
||||
#[test]
|
||||
fn the_chips_tier_shares_the_height_and_the_rails_tiers_pin_it() {
|
||||
fn the_chips_tier_shares_the_height_only_when_the_panel_takes_room() {
|
||||
use crate::pages::download::install::panel_state;
|
||||
use crate::pages::download::options::{InstallDraft, Loader, OptionsView};
|
||||
use crate::pages::download::rows::TailShare;
|
||||
use crate::pages::layout::VersionRailTier;
|
||||
use unlucky_presenter::state::AppState;
|
||||
|
||||
assert_eq!(TailShare::of(VersionRailTier::Chips), TailShare::Shared);
|
||||
let catalog = Lang::En.catalog();
|
||||
let mut app = AppState::new();
|
||||
app.apply(unlucky_presenter::dto::AppEvent::Core(
|
||||
unlucky_presenter::dto::CoreEvent::VersionListChanged(vec![version(
|
||||
"1.21.9",
|
||||
VersionKind::Release,
|
||||
false,
|
||||
)]),
|
||||
));
|
||||
|
||||
let row = VersionRow::of(&version("1.21.9", VersionKind::Release, false), catalog);
|
||||
// 选中版本 ⇒ 选项区(面板真的占高度)
|
||||
let options = Download {
|
||||
options: Some(OptionsView::of(
|
||||
&row,
|
||||
&app,
|
||||
&InstallDraft {
|
||||
selected: Some("1.21.9".to_string()),
|
||||
loader: Loader::Vanilla,
|
||||
loader_version: String::new(),
|
||||
instance_name: String::new(),
|
||||
},
|
||||
catalog,
|
||||
)),
|
||||
install: None,
|
||||
loaded: true,
|
||||
..Download::default()
|
||||
};
|
||||
// 刚进页面 ⇒ 只有一行提示
|
||||
let hint = Download {
|
||||
options: None,
|
||||
install: None,
|
||||
loaded: true,
|
||||
..Download::default()
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
TailShare::of(VersionRailTier::Chips, &panel_state(&options)),
|
||||
TailShare::Shared,
|
||||
"chips 档 + 选项区展开:对半分(列表 4 整行、面板自己可滚)"
|
||||
);
|
||||
assert_eq!(
|
||||
TailShare::of(VersionRailTier::Chips, &panel_state(&hint)),
|
||||
TailShare::Pinned,
|
||||
"chips 档 + 只有一行提示:钉死(8 个版本要在屏)"
|
||||
);
|
||||
for tier in [
|
||||
VersionRailTier::Wide,
|
||||
VersionRailTier::Narrow,
|
||||
VersionRailTier::Compact,
|
||||
] {
|
||||
assert_eq!(TailShare::of(tier), TailShare::Pinned, "{tier:?}");
|
||||
assert_eq!(
|
||||
TailShare::of(tier, &panel_state(&options)),
|
||||
TailShare::Pinned,
|
||||
"{tier:?}:三栏档一律钉死(面板整块在屏)"
|
||||
);
|
||||
assert_eq!(TailShare::of(tier, &panel_state(&hint)), TailShare::Pinned);
|
||||
}
|
||||
|
||||
// 两个装配点(三栏装配 / chips 分支)都**按档位**传,不许在某一处写死一个字面量
|
||||
// 两个装配点(三栏装配 / chips 分支)都**按档位 + 面板形态**传
|
||||
let chips_branch = include_str!("../../download.rs");
|
||||
let three_column = include_str!("../rails.rs");
|
||||
assert_eq!(
|
||||
chips_branch.matches("TailShare::of(rails.tier)").count()
|
||||
+ three_column.matches("TailShare::of(rails.tier)").count(),
|
||||
chips_branch.matches("TailShare::of(rails.tier,").count()
|
||||
+ three_column.matches("TailShare::of(rails.tier,").count(),
|
||||
2,
|
||||
"三栏装配与 chips 分支都要按档位传 TailShare"
|
||||
"三栏装配与 chips 分支都要把面板形态传进 TailShare::of"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user