fix(m173): 设置页滚动条并排在内容右侧(右侧恒留 10dp 槽)
根因(读 iced 0.14 源码,不是猜):`scrollable` 的竖直滚动条是浮层—— `iced_widget-0.14.2/src/scrollable.rs:1970-1980` 把轨道定位在 `bounds.right - (width.max(scroller_width) + 2*margin)`,而同文件 `:437` 给内容的横向 约束是整个视口宽(`Scrollbar::spacing` 默认 None ⇒ 右内边距恒 0)。本仓 6 轨 + 2×2 内缩 = 10dp,于是这 10dp 整条压在表单列内容上(1180 与 880 宽窗口都一样)。 改法:`components::scroll::vertical()` 在内容右侧恒留一条 `轨宽 + 2×margin` 的槽,轨道画在 槽里;`pages/settings/frame.rs::scroll` 改成一行转发。不采用 iced 的 `Scrollbar::spacing`, 因为它只在滑块可见时才预留(`scrollable.rs:478-500`),长/短页面切换内容会横跳 10dp。 数值(1180×760、100% DPI、tiny-skia、实测像素): - 卡片右缘 799 → 789(内容可用宽 424 → 414 = 424 − 10); - 滑块仍是 792..797(没有移动),与内容之间隔 2px 页面底色(= SCROLLBAR_MARGIN); - 长页面(外观组)与短页面(Java 组,无滑块)左边界 376、宽 414 **逐项相同**; - 150% 缩放下 621px = 414×1.5、滑块 9px = 6×1.5、槽 15px = 10×1.5,同比例不重叠。 守卫(两条都是数值,不看图):`components/scroll.rs` 与 `pages/settings/tests/scroll_fit.rs` 用 `Renderer = ()` 真跑 iced 的 `layout()`,断言「内容宽 == 容器宽 − 槽宽」且长/短两态一致; 把 `beside` 的 padding 改回 `Padding::ZERO`,4 条断言立刻红(424 vs 414)。
This commit is contained in:
1 parent
da5b837c7c
commit
037c68d0e6
5 files changed
+391
-15
No files matched your search
@@ -12,8 +12,8 @@ pub(super) use super::super::frame::{
|
||||
text_action, text_role, Header, ICON_PX, SCROLLBAR_MARGIN, SCROLLBAR_WIDTH,
|
||||
};
|
||||
|
||||
use iced::widget::{column, container, mouse_area, row, scrollable};
|
||||
use iced::{Alignment, Background, Border, Element, Length, Padding};
|
||||
use iced::widget::{column, container, mouse_area, row};
|
||||
use iced::{Alignment, Background, Border, Element, Length, Padding, Theme};
|
||||
|
||||
use unlucky_design::color::Role;
|
||||
use unlucky_design::component_map::Component;
|
||||
@@ -137,20 +137,39 @@ fn group_item<'a>(
|
||||
/// 表单列的滚动区:只有正文滚,页头不动(与实例页列表列同一套口径)。
|
||||
///
|
||||
/// 「外观」分组有 7 个控件 + 最多 3 行诊断,1180×760 下会超出可视区,所以这一层是必需的。
|
||||
pub(super) fn scroll<'a>(
|
||||
///
|
||||
/// ## M173:滚动条**并排**在内容右侧
|
||||
///
|
||||
/// 原来这里是 `scrollable(content)` 裸调 + 轨宽 6 / 内缩 2。iced 的竖直滚动条是浮层:轨道按
|
||||
/// 视口右边缘定位(`iced_widget-0.14.2/src/scrollable.rs:1970`),而内容拿到的横向约束是**整个
|
||||
/// 视口宽**(同文件 `:437`,`Scrollbar::spacing` 默认 `None` ⇒ 右内边距 0)。于是滚动条占的那条
|
||||
/// 10dp 竖带(轨 6 + 两侧内缩 2×2)整条压在表单列最右边——用户看到的就是「滚动条骑在卡片上」。
|
||||
///
|
||||
/// 改法在 [`crate::app::components::scroll::vertical`]:内容右侧恒留一条 10dp 的槽,轨道画在槽里。
|
||||
/// 槽宽来自同一个式子 `轨宽 + 2 × margin`,所以:
|
||||
///
|
||||
/// - 内容可用宽度 = 视口宽(424)− 槽宽(10)= **414**;
|
||||
/// - 长页面(出滑块)与短页面(不出滑块)**内容宽度一致**——槽是内边距,不依赖 iced 的
|
||||
/// `is_scrollbar_visible`(那正是 `Scrollbar::spacing` 不能用在这里的理由:它只在可见时预留,
|
||||
/// 滑块一出现内容就横跳 10dp)。
|
||||
///
|
||||
/// 数值由 `components/scroll.rs` 与 `tests/scroll_fit.rs` 的**布局级**断言钉住(`Renderer = ()`
|
||||
/// 真跑 iced 的 `layout()`),不是看图。
|
||||
///
|
||||
/// 只泛型到 `Renderer` 是为了让上面那条断言能在 `()` 渲染器上跑;产品调用点不写泛型。
|
||||
pub(super) fn scroll<'a, Renderer>(
|
||||
ui: &'a Ui,
|
||||
content: impl Into<Element<'a, Message>>,
|
||||
) -> Element<'a, Message> {
|
||||
scrollable(content)
|
||||
.direction(scrollable::Direction::Vertical(
|
||||
scrollable::Scrollbar::new()
|
||||
.width(SCROLLBAR_WIDTH)
|
||||
.scroller_width(SCROLLBAR_WIDTH)
|
||||
.margin(SCROLLBAR_MARGIN),
|
||||
))
|
||||
.height(Length::Fill)
|
||||
.style(scroll_style(ui))
|
||||
.into()
|
||||
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||
) -> Element<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: iced::advanced::text::Renderer + 'a,
|
||||
{
|
||||
crate::app::components::scroll::vertical(
|
||||
SCROLLBAR_WIDTH,
|
||||
SCROLLBAR_MARGIN,
|
||||
scroll_style(ui),
|
||||
content,
|
||||
)
|
||||
}
|
||||
|
||||
/// 演示行构成的一组设置 = 一张卡,行间 1px 分隔线(M3 设置列表的常规做法)。
|
||||
|
||||
Reference in new issue
Block a user