Files
Unlucky-Launcher/crates/app-iced/src/pages/download/rows/tail.rs
T
AskaEth 0ca28d24ff fix(app-iced): 版本行节距/列表 chrome 标定重算(44/97)+ 中性说明挪到版本菜单之后
三审给了独立量测,两处都按它的数字收敛:

1. `ROW_PITCH` 278/6=46.33 → **44.0**(278 里含列表与面板之间的 8px `Space::X2`);
   `LIST_CHROME` 93 → **97**(列顶 156 → 列表顶 253)。1180×760 分隔线 492 → **481**、
   列表视口 **220px = 5 整行**;1180×900 加测 = 308px = 7 整行,三审报的 900 高残影不复发。
2. S7 钉页脚引入的新问题:面板上半块的滚动切点压在字形上(宽窗切「加载器版本」标签上沿、
   窄窗把 chips 切成 4px 条)。把中性说明从菜单**之前**移到**之后**——它两行高,排前面正是把
   唯一的加载器专属控件顶出首屏的元凶。

顺带纠正一处文档:面板结构不是「头部 + 可滚上半 + 钉页脚」,head(版本 id + 安装按钮)是上半块
的第一个子项、**安装按钮也在滚动区**,只有实例名是钉死的。
2026-11-10 19:34:14 +08:00

82 lines
5.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 「列表与尾巴面板怎么分高」+ 版本行的整行取整(M125 / M222 D30)。
//!
//! 从 `rows.rs` 拆出来的理由只有一条:那边撞 400 行硬线(项目自带
//! `components::gate::every_source_file_stays_under_the_line_limit` 会判红)。本文件是
//! [`TailShare`] 的**纯搬移**,加上 M222 新增的三个只读量([`ROW_PITCH`] / [`LIST_CHROME`] /
//! [`whole_rows`],见 `rows.rs::content` 的用法)。
use crate::pages::layout::VersionRailTier;
use crate::pages::download::install::PanelState;
/// 列表与尾部面板怎么分这块高度(M125 缺陷 1 的修法)。
///
/// | 档 | 分法 | 为什么 |
/// |---|---|---|
/// | `Wide` / `Narrow` / `Compact` | [`TailShare::Pinned`]:面板按内容高钉在底部,列表吃剩下的 | 竖栏档在 760 高的窗口里列表还剩 158px(3 整行),面板整块在屏内——两样都对 |
/// | `Chips` + 面板**占高度**(选项区展开 / 安装中) | [`TailShare::Shared`]:两半各 `Fill`,面板自己可滚 | chips 档比三栏档多花两行 chip(tabs 48 + chips 48 + 间距),列表只剩 **18px**(M123 实测 0.4 行),面板 316px 全在屏内也没用——版本号读不出来就换不了版本 |
/// | 任何档 + 只画 `Hint`(没选版本,面板只有一行) | [`TailShare::Pinned`] | 一行提示不值得对半分:700×760 下 main 是 **7 整行**在屏(不是 8——第 8 条墨迹其实是 `Pick a version, then install` 那句 hint,横向范围对不上版本号;要放 8 行得 352px,实测只剩 309~322px),对半分只剩 **4 整行**、下面留 160px 空白(r1 复审 P2-1,r2 修回 7) |
///
/// 判据是**档位**不是高度:页面的模型里只有 `window_width`(`pages/model.rs`),窗口高度
/// 没有接进页面(要接得改 `pages/mod.rs` 的入口签名,超出本页的边界)。所以这里按「哪一档
/// 的竖排 chrome 会把列表压没」来分,并在报告里登记这条判据的边界。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum TailShare {
/// 面板钉在底部(三栏档)。
Pinned,
/// 面板与列表各吃一半(chips 档)。
Shared,
}
impl TailShare {
/// 档位 + **面板形态** → 分高方式(纯函数,单测直接钉它)。
///
/// 两个条件必须同时成立才共享:
/// 1. 档位是 `Chips`(多花两行 chip,竖排预算最紧的那一档);
/// 2. 面板真的**占高度**——`Options`(选中了版本、选项区展开)或 `Install`(进度 / 失败)。
///
/// `Hint`(刚进页面还没选版本)只是**一行**提示(≈30px),对半分会让列表从 **7 整行**
/// 掉到 **4 整行**、下半块留 ≈160px 空画布(r1 复审 P2-1 实测:main 在 700×760 的
/// `Hint` 态是 7 整行——不是 8,第 8 条墨迹其实是 `Pick a version, then install` 那句
/// hint,横向范围对不上版本号;r2 修回 7 整行)。所以 `Hint` **在任何档位都钉死**。
pub(crate) fn of(tier: VersionRailTier, state: &PanelState<'_>) -> Self {
match (tier, state) {
(VersionRailTier::Chips, PanelState::Options(_) | PanelState::Install(_)) => {
Self::Shared
}
// M222 D30 r1 S1 / r2 S7:**带加载器版本列表**的选项区在任何档位都太高。
// 三栏档(1180×760)实测:修前面板 204→372px,版本列表 6.0 行(278px)被压到
// 2.4 行(110px,底缘切在第三行图标上);改成 Shared 之后版本列表 **245px = 5.29 行**、
// 面板 237px(分隔线 y=498)。面板因此变矮,实例名会被挤出首屏 ⇒ 同一轮把它
// **钉成面板页脚**(`install::panel_with` 的 `shared` 分支 + `options::section`)。
// 仍欠一项:245px 不是行高整数倍,列表底缘仍切在第 6 行中间(S1b/S9)。
// 修它要把「分给列表的高度」从 `pages/download.rs` 传进来做 floor 取整
// (`responsive` 在 Fill 子项上拿不到确定高度,实测无效,已回退)。
(_, PanelState::Options(options)) if options.has_loader_versions() => Self::Shared,
_ => Self::Pinned,
}
}
}
/// 版本行的**实测节距**(D30 三审:`04` 图行内下载图标的行首 265/309/353/397/441/485,
/// 节距恰 **44.0**;首行选中高亮矩形 253–296 也是 44px)。
///
/// 列表是 `Fill + scrollable` 时,视口高度不是节距整数倍就会切在某一行中间——D30 r2 实测
/// `01` 是 245px(5.3 行),英文态露出 6px 竖干、中文态露出「预览版」上半截。三栏档的
/// 「列表与面板对半分」那一档现在按整行取高([`whole_rows`]),底缘落在行边界上。
pub(crate) const ROW_PITCH: f32 = 44.0;
/// 列表以外、列内要扣掉的固定占位(**列顶 156 → 列表顶 253**,D30 三审实测 = 97)。
///
/// 1180×760:正文列 580 ⇒ floor((580−97)/2 / 44) × 44 = **220px = 5 整行**,分隔线落在 481。
/// 1180×900:floor((720−97)/2 / 44) × 44 = **308px = 7 整行**(三审在 900 高实测过:旧标定
/// 会在 y529–530 复发残影,新标定不复发)。**改搜索条 / 表头高度时要同步这个数。**
pub(crate) const LIST_CHROME: f32 = 97.0;
/// 正文列高度 → 列表视口的**整行高度**(只给三栏档的 Shared 分支用)。
#[must_use]
pub(crate) fn whole_rows(column_height: f32) -> f32 {
let half = ((column_height - LIST_CHROME) / 2.0).max(ROW_PITCH);
(half / ROW_PITCH).floor() * ROW_PITCH
}