feat(motion): M305 —— 列表增删(错位淡入/退场后才移除)+ 进度插值(到点一次收束)

- 新轨道两条:components/motion/pump/{rows,progress}.rs(纯算术,连拍 advance(dt) 可判)
  · rows:两条清单(画出来的顺序 / 真值)+ 逐行可见度;退场行钉在原位、走完才移除
  · progress:真实读数一跳,画出来的值沿 short4 追上去;到 100% 一次脉冲(0→1→0,不循环)
- 接线:pages/download/model.rs::from_snapshot(scope 内唯一 update 侧入口)
  · 行清单 observe → 差分;退场行的数据进 leaving 池(否则退场行画不出来)
  · 进度 observe(key = 版本 id)
- 视图:rows/list.rs 换成 keyed::Column(按 id 做连续匹配)+ 逐行 revealed(裁切框收放)
  + 同色遮罩淡出;install.rs 画插值后的值 + 收束
- MotionScale::NONE:不插轨道、不留幽灵,值严格等于最终值、零采样
- 顺手:rows/tests.rs 重新挂上 mod(此前一直没编译),i18n 扫描补两个新文件

判据:motion::tests::{rows,progress}、rows/motion_tests(Tree::diff 后未变行状态盒不变)、
出图 DevDocs/artifacts/m305(probe.py 量行距与墨色)
This commit is contained in:
AskaEth committed 2026-11-13 21:42:18 +08:00
1 parent b9536c5833
commit ae33674293
24 files changed
+2175 -153

No files matched your search

+10 -34
View File
@@ -63,7 +63,7 @@
//! 本页的行是 44 的单行档,同样不加行距;[`ROW_GAP`] 只用在**行内**那三个格子的间距上。
use iced::widget::{column, container, row, scrollable};
use iced::{Alignment, Element, Length, Padding};
use iced::{Alignment, Element, Length};
use unlucky_design::color::Role;
use unlucky_design::icons::IconKind;
@@ -85,8 +85,16 @@ use super::install::{self, panel_state, PanelState};
use super::model::{Download, VersionRow};
use super::states;
mod list;
mod tail;
// 本文件的两组判据(`rows/tests.rs` 是 M102/M107 留下的,M305 起**重新挂上**:
// 它此前一直没被 `mod` 声明 ⇒ 那两条用例根本没在跑,见报告「发现」一节)。
#[cfg(test)]
mod motion_tests;
#[cfg(test)]
mod tests;
pub(crate) use tail::{menu_items, TailShare};
/// 列表列(三栏档与 chips 档共用一份)。
@@ -118,7 +126,7 @@ pub(super) fn content<'a>(
} else {
list_height
};
list(ui, catalog, model, &visible, height)
list::list(ui, catalog, model, &visible, height)
};
// 列表与尾部面板之间**总是**有一条分隔线(三态一致):M123 的取证图里「选好了版本」
@@ -252,38 +260,6 @@ pub(super) fn visible(model: &Download) -> Vec<&VersionRow> {
}
}
/// 版本行列表(**独立滚动**:只有列表滚,安装面板钉在底部不跟着滚)。
fn list<'a>(
ui: &'a Ui,
catalog: Catalog,
model: &'a Download,
visible: &[&'a VersionRow],
height: Option<f32>,
) -> Element<'a, Message> {
let entries = column(
visible
.iter()
.map(|entry| version_row(ui, catalog, model, entry))
.collect::<Vec<_>>(),
)
// M102:行距归零(见模块文档),只留横向留白
.padding(Padding::from([0.0, ui.space(Space::X2)]))
.width(Length::Fill);
scrollable(entries)
.direction(scrollable::Direction::Vertical(
scrollable::Scrollbar::new()
.width(frame::SCROLLBAR_WIDTH)
.scroller_width(frame::SCROLLBAR_WIDTH)
.margin(frame::SCROLLBAR_MARGIN),
))
// `Some` = 面板先保预算那一档按**整行**取高(三栏档 `tail::whole_rows` /
// chips 档 `tail::narrow_rows`);`None` = `Pinned`(面板矮)用 Fill。
.height(height.map_or(Length::Fill, Length::Fixed))
.style(frame::scroll_style(ui))
.into()
}
/// 一行:`ListItem`(版本号,可点选)+ 类型 + 日期 + 安装图标按钮(**四样同一行**)。
///
/// 点版本号 = [`Message::SelectVersion`](页面内选中,不 dispatch);点尾随按钮 =