feat(app-iced): 页面层把卡片底接进禁用/交互控件(M237)

M234 把 `interaction::Base` 与组件侧的 `.base(..)` 接好了,但页面层仍是默认的画布底:
卡片(`Role::SurfaceContainerLow`)里的禁用按钮 / chip / 开关把 10% / 12% / 38% 叠在画布色上。
M223 记的「卡片里禁用控件 CR 1.05、形丢失」因此只在 gallery 里修好,产品页没修。

- 导出容器底:`pages::frame::BASE = Base::of(MaterialLayer::Card.surface_role())`
  —— 取的是 `card()` **真正画出来的那一层**(不是「反正是 surface」);`logs::panel::BASE`
  是同一个常量的别名(两张卡画的是同一个材质层)。
- 接线(改前一律 `Base::CANVAS`,改后 `frame::BASE`):设置·Java(扫描 / 取消 / 设为默认 chip /
  三个输入框 / 添加 / 保存 / 预置项 chip / 下载徽标);设置·通用(语言三档、主题三档、日志行
  两个手写按钮 → 状态层叠 `BASE.role()`);实例详情(MODS 开关、SAVES 的重试与打开文件夹、
  启动参数区的两个输入框 + 后端 chip + 保存 / 恢复);日志页(诊断卡页脚 `Copy summary`)。
  详情头的启动 / 停止 / 动作行**不在卡里**,保持画布底并加注释。
- 判据:`pages/frame/tests.rs` 逐值断言「`BASE` == 卡片画出来的颜色」+ 源码结构盯 `card()`
  不许改画别的材质层;`pages/settings/tests/java_shot.rs` 是**页面级像素判据**(读 1180×760
  真截图、逐位匹配:卡区里「叠卡底」3136 px vs「叠画布」21 px,深色 3128 / 1);
  `pages/tests/base_wiring.rs` 数接线点,守像素够不到的页面(实例详情 MODS / SAVES)。
- 变异自证:撤掉「立即扫描」的 `.base(BASE)` ⇒ 像素判据红(73 px vs 3083 px,退出码 101);
  撤掉诊断卡页脚的 `.base(..)` ⇒ 接线判据红(0 vs 1,退出码 101)。均已还原。
- 门禁:fmt / check -p unlucky-app-iced --all-targets / test --workspace(3344 通过,0 失败)/
  clippy --workspace --all-targets -D warnings / 文件 ≤400(最大 389),全部本地过。
- 已知未尽:面板 α<1 的半透明卡(`Base` 只装一个 `Role`)、GPU 档、实例详情与日志页在
  1180×760 出图里没有可量测的禁用控件(夹具缺 running,已报 finding);app_bar / adopt pick /
  设置页分组列仍未导出 `BASE`;设置·下载 / 更新 / 助手、账户页、内容库、下载页仍未接线。
This commit is contained in:
AskaEth committed 2026-11-11 07:56:11 +08:00
1 parent cf8a951e29
commit 3dcd5fd117
20 files changed
+518 -42

No files matched your search

@@ -195,6 +195,10 @@ fn detail_head<'a>(
.width(Length::Fill);
// 主操作:**全屏唯一**实心 accent(rubric K2)。不可用时退化成禁用态(只清消息,不改身份)。
//
// M237:这一行**不在卡片里**(详情列直接铺在画布上),所以这两个按钮的底保持
// `Base::CANVAS`——把卡底传进来反而会让禁用色叠错层。卡片内的控件(MODS / SAVES /
// 启动参数区)各自传 `frame::BASE`,见那几个模块。
let launch = if detail.can_launch {
buttons::filled(
ui,
@@ -28,6 +28,7 @@ use crate::app::components::selection::{chip, Chip};
use crate::theme::Ui;
use super::super::frame::BASE;
use super::super::model::LaunchFacts;
use super::super::Message as PageMessage;
use super::state::{LaunchForm, Message};
@@ -120,7 +121,7 @@ fn args_field<'a>(
on_input: impl Fn(String) -> PageMessage + 'a,
) -> Element<'a, PageMessage> {
column![
text_field(ui, Field::new(value).label(label), on_input),
text_field(ui, Field::new(value).label(label).base(BASE), on_input),
super::super::frame::text_role(
ui,
TypeRole::BodySmall,
@@ -143,7 +144,7 @@ fn text_field_with_hint<'a>(
on_input: impl Fn(String) -> PageMessage + 'a,
) -> Element<'a, PageMessage> {
column![
text_field(ui, Field::new(value).label(label), on_input),
text_field(ui, Field::new(value).label(label).base(BASE), on_input),
hint,
]
.spacing(ui.space(Space::X1))
@@ -188,7 +189,8 @@ fn backend_row<'a>(
} else {
spec.disabled()
};
chips = chips.push(chip(ui, spec));
// M237:启动参数区是一张 `frame::card`,chip 的禁用配色(12% 容器 / 38% 内容)叠卡底。
chips = chips.push(chip(ui, spec.base(BASE)));
}
let mut meta = column![
@@ -226,8 +228,14 @@ fn backend_row<'a>(
fn actions_row<'a>(ui: &'a Ui, texts: Texts) -> Element<'a, PageMessage> {
row![
buttons::filled(ui, Button::new(texts.launch_save(), page(Message::Save))),
buttons::text(ui, Button::new(texts.launch_reset(), page(Message::Reset))),
buttons::filled(
ui,
Button::new(texts.launch_save(), page(Message::Save)).base(BASE)
),
buttons::text(
ui,
Button::new(texts.launch_reset(), page(Message::Reset)).base(BASE)
),
]
.spacing(ui.space(Space::X2))
.into()
@@ -290,6 +290,9 @@ fn entry_row<'a>(
}),
)
};
// M237:开关住在 `frame::card` 里,禁用态的 12% 轨道 / 38% 滑块要叠**卡底**(`frame::BASE`),
// 不是画布底——否则「游戏在跑 / 请求在飞」那两档的开关会与卡片底色脱节。
let toggle = toggle.base(frame::BASE);
// 出图取证(`--force-state`)把开关也钉到同一档:否则截图里只有按钮是 hover、
// 开关还是静息态,视觉复审没法判"悬停时的开关长什么样"。
let toggle = match forced {
+6 -2
View File
@@ -236,7 +236,9 @@ pub(super) fn section<'a>(
Message::Instances(PageMessage::ReloadSaves),
),
forced,
),
)
// M237:卡片里的控件把底传成卡底(hover / 禁用状态层叠卡实色)。
.base(frame::BASE),
));
}
// 旧列表还在时照旧画出来(失败不清列表),用户能看见上一次读到的东西;
@@ -322,7 +324,9 @@ fn head<'a>(
Message::Instances(PageMessage::OpenSavesFolder),
),
forced,
),
)
// M237:这枚按钮在 SAVES 卡里 ⇒ 状态层叠卡底(`frame::BASE`),不是画布底。
.base(frame::BASE),
);
row![
container(left)