Fixed Align::FILL in scroll.
This commit is contained in:
parent
1ff0769f9b
commit
bcc1dee304
|
@ -32,8 +32,11 @@
|
|||
|
||||
# Scroll
|
||||
|
||||
* `scroll_to` does not work correctly when requested by text `line_up`
|
||||
* `scroll_to` does not work correctly when requested by text `line_up`.
|
||||
- Never works correctly when target is above.
|
||||
* Implement touch scroll inertia.
|
||||
* Fill forces min-size.
|
||||
- Needs to work the same as `Container!`.
|
||||
|
||||
# Touch Events
|
||||
|
||||
|
|
|
@ -141,11 +141,16 @@ fn scroll_node(
|
|||
nodes::scrollbar_joiner_presenter(),
|
||||
];
|
||||
|
||||
let scroll_info = ScrollInfo::default();
|
||||
|
||||
let mut viewport = PxSize::zero();
|
||||
let mut joiner = PxSize::zero();
|
||||
let spatial_id = SpatialFrameId::new_unique();
|
||||
|
||||
match_node_list(children, move |children, op| match op {
|
||||
UiNodeOp::Info { info } => {
|
||||
info.set_meta(&SCROLL_INFO_ID, scroll_info.clone());
|
||||
}
|
||||
UiNodeOp::Measure { wm, desired_size } => {
|
||||
let constraints = LAYOUT.constraints();
|
||||
*desired_size = if constraints.is_fill_max().all() {
|
||||
|
@ -177,24 +182,11 @@ fn scroll_node(
|
|||
// joiner
|
||||
let _ = LAYOUT.with_constraints(PxConstraints2d::new_fill_size(joiner), || children.with_node(3, |n| n.layout(wl)));
|
||||
|
||||
scroll_info.set_joiner_size(joiner);
|
||||
|
||||
// viewport
|
||||
let mut vp = LAYOUT.with_constraints(c.with_less_size(joiner), || children.with_node(0, |n| n.layout(wl)));
|
||||
|
||||
// arrange
|
||||
let fs = vp + joiner;
|
||||
let content_size = SCROLL_CONTENT_SIZE_VAR.get();
|
||||
|
||||
if content_size.height > fs.height {
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR.set(true).unwrap();
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR.set(content_size.width > vp.width).unwrap();
|
||||
} else if content_size.width > fs.width {
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR.set(true).unwrap();
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR.set(content_size.height > vp.height).unwrap();
|
||||
} else {
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR.set(false).unwrap();
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR.set(false).unwrap();
|
||||
}
|
||||
|
||||
// collapse scrollbars if they take more the 1/3 of the total area.
|
||||
if vp.width < joiner.width * 3.0.fct() {
|
||||
vp.width += joiner.width;
|
||||
|
|
|
@ -27,7 +27,12 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
let mut content_scale = 1.fct();
|
||||
let mut auto_hide_extra = PxSideOffsets::zero();
|
||||
let mut last_render_offset = PxVector::zero();
|
||||
let scroll_info = ScrollInfo::default();
|
||||
let mut scroll_info = None;
|
||||
let mut scroll_info = move || {
|
||||
scroll_info
|
||||
.get_or_insert_with(|| WIDGET.info().meta().get_clone(&SCROLL_INFO_ID).unwrap())
|
||||
.clone()
|
||||
};
|
||||
|
||||
match_node(child, move |child, op| match op {
|
||||
UiNodeOp::Init => {
|
||||
|
@ -38,9 +43,7 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
.sub_var_layout(&SCROLL_SCALE_VAR)
|
||||
.sub_var_layout(&child_align);
|
||||
}
|
||||
UiNodeOp::Info { info } => {
|
||||
info.set_meta(&SCROLL_INFO_ID, scroll_info.clone());
|
||||
}
|
||||
|
||||
UiNodeOp::Measure { wm, desired_size } => {
|
||||
let constraints = LAYOUT.constraints();
|
||||
if constraints.is_fill_max().all() {
|
||||
|
@ -60,13 +63,12 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
|
||||
let mut content_size = LAYOUT.with_constraints(
|
||||
{
|
||||
let mut c = child_align.child_constraints(constraints);
|
||||
c = c.with_min_size(viewport_unit);
|
||||
let mut c = child_align.child_constraints(constraints.with_new_min_size(viewport_unit));
|
||||
if mode.contains(ScrollMode::VERTICAL) {
|
||||
c = c.with_unbounded_y().with_new_min_y(Px(0));
|
||||
c = c.with_unbounded_y();
|
||||
}
|
||||
if mode.contains(ScrollMode::HORIZONTAL) {
|
||||
c = c.with_unbounded_x().with_new_min_x(Px(0));
|
||||
c = c.with_unbounded_x();
|
||||
}
|
||||
c
|
||||
},
|
||||
|
@ -97,16 +99,17 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
&& vp_unit.width > Px(0) // and has fill-size
|
||||
&& vp_unit.height > Px(0)
|
||||
&& constraints.max_size() == Some(vp_unit); // that is not just min size.
|
||||
|
||||
let joiner_size = scroll_info().joiner_size();
|
||||
|
||||
let mut content_size = LAYOUT.with_constraints(
|
||||
{
|
||||
let mut c = child_align.child_constraints(constraints);
|
||||
c = c.with_min_size(vp_unit);
|
||||
let mut c = child_align.child_constraints(constraints.with_new_min_size(vp_unit + joiner_size));
|
||||
if mode.contains(ScrollMode::VERTICAL) {
|
||||
c = c.with_unbounded_y().with_new_min_y(Px(0));
|
||||
c = c.with_unbounded_y();
|
||||
}
|
||||
if mode.contains(ScrollMode::HORIZONTAL) {
|
||||
c = c.with_unbounded_x().with_new_min_x(Px(0));
|
||||
c = c.with_unbounded_x();
|
||||
}
|
||||
c
|
||||
},
|
||||
|
@ -146,7 +149,7 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
auto_hide_extra.bottom = auto_hide_extra.bottom.max(Px(0));
|
||||
auto_hide_extra.left = auto_hide_extra.left.max(Px(0));
|
||||
|
||||
scroll_info.set_viewport_size(vp_size);
|
||||
scroll_info().set_viewport_size(vp_size);
|
||||
|
||||
let align_offset = child_align.child_offset(content_size, viewport_size, LAYOUT.direction());
|
||||
|
||||
|
@ -199,10 +202,27 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
SCROLL_HORIZONTAL_RATIO_VAR.set(h_ratio.fct()).unwrap();
|
||||
SCROLL_CONTENT_SIZE_VAR.set(content_size).unwrap();
|
||||
|
||||
let full_size = viewport_size + joiner_size;
|
||||
|
||||
if content_size.height > full_size.height {
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR.set(true).unwrap();
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR
|
||||
.set(content_size.width > viewport_size.width)
|
||||
.unwrap();
|
||||
} else if content_size.width > full_size.width {
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR.set(true).unwrap();
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR
|
||||
.set(content_size.height > viewport_size.height)
|
||||
.unwrap();
|
||||
} else {
|
||||
SCROLL_VERTICAL_CONTENT_OVERFLOWS_VAR.set(false).unwrap();
|
||||
SCROLL_HORIZONTAL_CONTENT_OVERFLOWS_VAR.set(false).unwrap();
|
||||
}
|
||||
|
||||
*final_size = viewport_size;
|
||||
}
|
||||
UiNodeOp::Render { frame } => {
|
||||
scroll_info.set_viewport_transform(*frame.transform());
|
||||
scroll_info().set_viewport_transform(*frame.transform());
|
||||
last_render_offset = content_offset;
|
||||
|
||||
let mut culling_rect = PxBox::from_size(viewport_size);
|
||||
|
@ -224,7 +244,7 @@ pub fn viewport(child: impl UiNode, mode: impl IntoVar<ScrollMode>, child_align:
|
|||
});
|
||||
}
|
||||
UiNodeOp::RenderUpdate { update } => {
|
||||
scroll_info.set_viewport_transform(*update.transform());
|
||||
scroll_info().set_viewport_transform(*update.transform());
|
||||
|
||||
let transform = if content_scale != 1.fct() {
|
||||
PxTransform::scale(content_scale.0, content_scale.0).then_translate(content_offset.cast())
|
||||
|
|
|
@ -865,6 +865,7 @@ impl WidgetInfoExt for WidgetInfo {
|
|||
struct ScrollData {
|
||||
viewport_transform: PxTransform,
|
||||
viewport_size: PxSize,
|
||||
joiner_size: PxSize,
|
||||
}
|
||||
|
||||
/// Shared reference to the viewport bounds of a scroll.
|
||||
|
@ -889,6 +890,14 @@ impl ScrollInfo {
|
|||
self.0.lock().viewport_transform
|
||||
}
|
||||
|
||||
/// Gets the layout size of both scroll-bars.
|
||||
///
|
||||
/// Joiner here is the corner joiner visual, it is sized by the width of the vertical bar and
|
||||
/// height of the horizontal bar.
|
||||
pub fn joiner_size(&self) -> PxSize {
|
||||
self.0.lock().joiner_size
|
||||
}
|
||||
|
||||
pub(super) fn set_viewport_size(&self, size: PxSize) {
|
||||
self.0.lock().viewport_size = size;
|
||||
}
|
||||
|
@ -896,6 +905,10 @@ impl ScrollInfo {
|
|||
pub(super) fn set_viewport_transform(&self, transform: PxTransform) {
|
||||
self.0.lock().viewport_transform = transform;
|
||||
}
|
||||
|
||||
pub(super) fn set_joiner_size(&self, size: PxSize) {
|
||||
self.0.lock().joiner_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) static SCROLL_INFO_ID: StaticStateId<ScrollInfo> = StaticStateId::new_unique();
|
||||
|
|
Loading…
Reference in New Issue