diff --git a/crates/app-iced/src/pages/download/options/tests.rs b/crates/app-iced/src/pages/download/options/tests.rs index f0b26f7..6084dbd 100644 --- a/crates/app-iced/src/pages/download/options/tests.rs +++ b/crates/app-iced/src/pages/download/options/tests.rs @@ -291,11 +291,10 @@ fn liteloader_carries_a_neutral_note_without_blocking_confirm() { Lang::En.catalog(), ); let note = options.note.as_deref().expect("LiteLoader 应带中性说明"); - assert!(note.contains("vanilla"), "{note}"); - assert!( - note.contains("--loader liteloader"), - "要给出可执行的下一步:{note}" - ); + // 文案在 D30 五审后压成**单行**(两行 28px 是滚动区最大的可压项),断言随之改为 + // 「说清只支持原版父链、且确实只有一行」;完整命令行说法在 `ull help install` 里。 + assert!(note.contains("Vanilla parent only"), "{note}"); + assert_eq!(note.lines().count(), 1, "必须是一行:{note}"); assert!(options.problem.is_none(), "中性说明不能变成错误"); assert!(options.can_confirm, "说明不该禁用确认键"); @@ -312,7 +311,7 @@ fn liteloader_carries_a_neutral_note_without_blocking_confirm() { Lang::ZhCn.catalog(), ); let note = options.note.as_deref().expect("中文也要有说明"); - assert!(note.contains("原版"), "{note}"); + assert!(note.contains("只叠原版"), "{note}"); assert!(options.can_confirm); // 别家加载器不带这条说明。 diff --git a/crates/app-iced/src/pages/download/options/view.rs b/crates/app-iced/src/pages/download/options/view.rs index 9d08cdb..5d8ec8b 100644 --- a/crates/app-iced/src/pages/download/options/view.rs +++ b/crates/app-iced/src/pages/download/options/view.rs @@ -76,7 +76,8 @@ pub(super) fn version_menu_height(items: usize) -> f32 { /// 为什么菜单也要钉(D30 四审):裁切位置由**钉死区高度**决定,与窗宽无关(1180 与 720 都切在 /// 同一个 y)。之前只钉实例名,菜单就正好落在切线上——760 下菜单容器 642–706 只有 18px 可见、 /// 条目文字一格都没画出来。把菜单一起钉住之后,它不再依赖首屏剩余高度分配,可达性由结构保证; -/// 滚动区溢出时滚的是说明/错误行,那是可以接受被滚走的内容。 +/// 滚动区溢出时滚走的是**说明/错误行**(非控件);D30 六审把说明压成单行之后, +/// 1180×760 下滚动区 ≈150px,head + 标签 + 六枚 chip + 单行说明全在首屏、**无需滚动**。 pub(crate) fn section<'a>( ui: &'a Ui, catalog: Catalog, diff --git a/crates/app-iced/src/pages/download/rows/tail.rs b/crates/app-iced/src/pages/download/rows/tail.rs index 8bff2f2..107b554 100644 --- a/crates/app-iced/src/pages/download/rows/tail.rs +++ b/crates/app-iced/src/pages/download/rows/tail.rs @@ -73,9 +73,22 @@ pub(crate) const ROW_PITCH: f32 = 44.0; /// 会在 y529–530 复发残影,新标定不复发)。**改搜索条 / 表头高度时要同步这个数。** pub(crate) const LIST_CHROME: f32 = 97.0; +/// 面板(滚动区 + 钉死区)的**最小预算**。 +/// +/// 滚动区要装下 head 40 + 标签 16 + 六枚 chips 32 + 说明单行 20 + 间距约 20 ≈ 128; +/// 钉死区 = 菜单 64 + 实例名 56 + 间距 16 ≈ 136。取 300 是两者之和的整档。 +/// D30 五审实测:上一版「对半分」把滚动区压到 82px——宽档切「安装选项」字身、六枚 chip +/// 0 像素;窄档 24px 全被留白吃掉。 +pub(crate) const PANEL_BUDGET: f32 = 300.0; + /// 正文列高度 → 列表视口的**整行高度**(只给三栏档的 Shared 分支用)。 +/// +/// 分高规则从「对半分」改成「**面板先保预算,剩下的按整行给列表**」:760 档 +/// (正文列 580)⇒ 580 − 97 − 300 = 183 ⇒ floor(183/44)×44 = **176px = 4 整行**; +/// 900 档 ⇒ 720 − 97 − 300 = 323 ⇒ **308px = 7 整行**(五审在 900 已验 7 行)。 +/// 公式不变的部分是「列表只吃整行」,变的是分子——这正是塔要的「一次性预算重分配」。 #[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 + let room = (column_height - LIST_CHROME - PANEL_BUDGET).max(ROW_PITCH); + (room / ROW_PITCH).floor() * ROW_PITCH } diff --git a/crates/i18n/src/catalog/download.rs b/crates/i18n/src/catalog/download.rs index ea02d03..6e3ee35 100644 --- a/crates/i18n/src/catalog/download.rs +++ b/crates/i18n/src/catalog/download.rs @@ -102,8 +102,8 @@ macro_rules! download_entries { // M222:下载页只做「原版 + 加载器」一层,Forge 父链只有命令行能走。中性说明, // 不是错误(不禁用确认键、不套错误色)——所以它不走 `problem` 那条通道。 DownloadOptionsLiteLoaderVanillaOnly => ( - "LiteLoader stacks on vanilla only — for Forge, run: ull install --loader liteloader", - "LiteLoader 只叠在原版上 —— 要叠 Forge 请运行:ull install --loader liteloader" + "Vanilla parent only — Forge goes through the CLI", + "只叠原版;叠 Forge 请走命令行" ), DownloadCancelled => ( "Install cancelled — finished files are kept, the instance was not created", diff --git a/crates/i18n/src/catalog/golden/tail_ai.rs b/crates/i18n/src/catalog/golden/tail_ai.rs index a60e932..9cd5dcc 100644 --- a/crates/i18n/src/catalog/golden/tail_ai.rs +++ b/crates/i18n/src/catalog/golden/tail_ai.rs @@ -106,7 +106,7 @@ pub(super) const ROWS: &[(&str, &str, &str)] = &[ ("DownloadOptionsInstanceNameHint", "Empty = use the version id", "留空就用版本号"), ("DownloadOptionsIncompatible", "{loader} has no builds for {version}", "{loader} 没有适配 {version} 的构建"), ("DownloadOptionsNeedsAtLeast", "{loader} needs Minecraft {min} or newer", "{loader} 需要 Minecraft {min} 或更新"), - ("DownloadOptionsLiteLoaderVanillaOnly", "LiteLoader stacks on vanilla only — for Forge, run: ull install --loader liteloader", "LiteLoader 只叠在原版上 —— 要叠 Forge 请运行:ull install --loader liteloader"), + ("DownloadOptionsLiteLoaderVanillaOnly", "Vanilla parent only — Forge goes through the CLI", "只叠原版;叠 Forge 请走命令行"), ("DownloadCancelled", "Install cancelled — finished files are kept, the instance was not created", "安装已取消 —— 已下好的文件保留,实例未登记"), ("LogsSubtitleIdle", "Nothing is running right now", "当前没有运行中的实例"), ("LogsStatus", "{instance} · {when} · {outcome}", "{instance}|{when}|{outcome}"),