feat(app-iced): 禁用态合成底改成容器给的 Base(M234)
`interaction::disabled` 的四个入口一直收一个「底」,但 8 个调用点全传死 `Role::Surface`:卡片(SurfaceContainer)/ 面板(SurfaceContainerLow)里的禁用控件 把 10%(按钮族)/ 12%(面状控件族)叠在画布色上 —— M223「CR 1.05、形丢失」的根因。 - 新增 `interaction::Base`(画布 / 容器底的一等参数,`From<Role>` 兼容历史调用点); 四个入口改成 `(ui, base, …)`,内部不再出现任何写死的 `Role::Surface`。 - 容器导出自己的 `BASE`:`surfaces::elevated::BASE`(卡)、`inputs::menu::PANEL_BASE` (菜单面板,项的 38% 与状态层都改叠它)、`navigation::drawer::BASE`。 - 控件收 `.base(..)`:Button / icon_on / Field / SearchBar / Slider / Checkbox / Radio / Switch / Chip / ListItem / Tabs;Fab 与 icon() 是画布默认值。 - `feedback/action.rs` 的本地 α 合成删掉,改走 `disabled_content_over_role` 并给真实容器底 (Snackbar `InverseSurface` / Dialog `SurfaceContainerHigh`)。 - 判据:`interaction::disabled::tests`(卡片/面板/画布三档逐值)、 `buttons::tests::base`(Button::base → StyleSpec → style_closure 接线)、 `gallery` 新增 `disabledbase` 段 + `gallery::probe::bases` 精确像素断言 (±10 容差区分不了 1/255 的差,所以自己数逐位相等的像素)。 - 变异自证:assemble 的调用点改回画布底后,上面两条都红(见 artifacts/m234/README.md)。 已知未尽:`crates/app-iced/src/pages/**` 不在 scope 内,页面侧「把控件放进卡片/面板」的 调用点尚未接 `.base(..)`(行为与本 mission 之前一致);`pages/…/java/tests/marker.rs` 有一行被迫更新(入口多了一个实参,语义不变 = 画布底)。
This commit is contained in:
1 parent
a9d1cb4c44
commit
35dbefb08d
48 files changed
+1690
-496
No files matched your search
@@ -42,7 +42,7 @@ use crate::icons;
|
||||
use crate::theme::Ui;
|
||||
|
||||
use super::super::divider;
|
||||
use super::super::interaction::{self, Interaction};
|
||||
use super::super::interaction::{self, Base, Interaction};
|
||||
use super::super::layout;
|
||||
use super::geometry::MenuGeometry;
|
||||
|
||||
@@ -171,10 +171,10 @@ struct ItemPalette {
|
||||
}
|
||||
|
||||
/// 解析一项的颜色:选中优先,其余按五态叠状态层(`interaction::overlay_color`)。
|
||||
fn item_palette(ui: &Ui, state: Interaction, selected: bool) -> ItemPalette {
|
||||
fn item_palette(ui: &Ui, base: Base, state: Interaction, selected: bool) -> ItemPalette {
|
||||
if state.is_disabled() {
|
||||
// 禁用:内容 38%(无容器时叠在表面色上;菜单项本身透明)
|
||||
let ink = interaction::disabled_content_over_role(ui, Role::OnSurface, false);
|
||||
// 禁用:内容 38%,叠在**菜单面板的底**上(项本身透明,透出来的就是面板色)
|
||||
let ink = interaction::disabled_content_over_role(ui, base, Role::OnSurface, false);
|
||||
return ItemPalette {
|
||||
fill: None,
|
||||
ink,
|
||||
@@ -201,14 +201,20 @@ fn item_palette(ui: &Ui, state: Interaction, selected: bool) -> ItemPalette {
|
||||
}
|
||||
|
||||
ItemPalette {
|
||||
// 状态层叠在**菜单容器色**上(SurfaceContainer),得到不透明结果(D27)
|
||||
fill: interaction::overlay_color(ui, state, Role::OnSurface, Role::SurfaceContainer),
|
||||
// 状态层叠在**菜单容器色**上(`PANEL_BASE` = SurfaceContainer),得到不透明结果(D27)
|
||||
fill: interaction::overlay_color(ui, state, Role::OnSurface, base.role()),
|
||||
ink: ui.color(Role::OnSurface),
|
||||
icon: ui.color(Role::OnSecondaryContainer),
|
||||
shape: ShapeScale::Small,
|
||||
}
|
||||
}
|
||||
|
||||
/// 菜单弹出层的底(**面板画这个色,项就叠在它上面**)。
|
||||
///
|
||||
/// 8.2 的 `MenuTokens.ContainerColor = SurfaceContainer`:面板用 `ui.color(PANEL_BASE.role())` 画底,
|
||||
/// 项的禁用态(38% 内容)与状态层拿同一个 [`Base`] 合成——两边同源,改色不会只改一半(M234)。
|
||||
pub const PANEL_BASE: Base = Base::of(Role::SurfaceContainer);
|
||||
|
||||
/// 菜单弹出层(`SurfaceContainer` + L2 阴影)。
|
||||
pub fn menu<'a, M: Clone + 'a>(ui: &'a Ui, menu: Menu<'a, M>) -> Element<'a, M> {
|
||||
let geometry = MenuGeometry::of(ui);
|
||||
@@ -220,13 +226,13 @@ pub fn menu<'a, M: Clone + 'a>(ui: &'a Ui, menu: Menu<'a, M>) -> Element<'a, M>
|
||||
"MenuTokens.ContainerElevation"
|
||||
);
|
||||
let shadow_spec = elevation.shadow();
|
||||
let panel = ui.color(Role::SurfaceContainer);
|
||||
let panel = ui.color(PANEL_BASE.role());
|
||||
let shape = geometry.shape;
|
||||
|
||||
let mut rows = column![].width(Length::Fill);
|
||||
for entry in menu.entries {
|
||||
rows = rows.push(match entry {
|
||||
Entry::Item(item) => item_row(ui, item, geometry),
|
||||
Entry::Item(item) => item_row(ui, PANEL_BASE, item, geometry),
|
||||
// 分组分隔线:复用 `divider::full`(一像素线 + OutlineVariant),不自己画
|
||||
Entry::Divider => divider::full::<M>(ui),
|
||||
});
|
||||
@@ -256,6 +262,7 @@ pub fn menu<'a, M: Clone + 'a>(ui: &'a Ui, menu: Menu<'a, M>) -> Element<'a, M>
|
||||
/// 一行菜单项(用 `button` 承载命中与四态,几何与颜色自绘)。
|
||||
fn item_row<'a, M: Clone + 'a>(
|
||||
ui: &'a Ui,
|
||||
base: Base,
|
||||
item: MenuItem<'a, M>,
|
||||
geometry: MenuGeometry,
|
||||
) -> Element<'a, M> {
|
||||
@@ -265,7 +272,12 @@ fn item_row<'a, M: Clone + 'a>(
|
||||
None
|
||||
});
|
||||
// 选中项的背景也要跟态走:禁用时不许留满档 SecondaryContainer
|
||||
let colors = item_palette(ui, forced.unwrap_or(Interaction::Enabled), item.selected);
|
||||
let colors = item_palette(
|
||||
ui,
|
||||
base,
|
||||
forced.unwrap_or(Interaction::Enabled),
|
||||
item.selected,
|
||||
);
|
||||
let body = ui.style(TypeRole::BodyMedium);
|
||||
|
||||
let label = text(item.label)
|
||||
@@ -308,7 +320,7 @@ fn item_row<'a, M: Clone + 'a>(
|
||||
let selected = item.selected;
|
||||
let style = move |_theme: &iced::Theme, status: button::Status| {
|
||||
let state = forced.unwrap_or_else(|| Interaction::from_status(status));
|
||||
let colors = item_palette(ui, state, selected);
|
||||
let colors = item_palette(ui, base, state, selected);
|
||||
button::Style {
|
||||
background: colors.fill.map(Background::Color),
|
||||
text_color: colors.ink,
|
||||
|
||||
Reference in new issue
Block a user