use std::time::Instant;
use guido::prelude::*;
mod common;
use common::Harness;
fn scrolled(scroll: Scroll, padding: f32, content: (f32, f32), on_scroller: bool) -> (f32, f32) {
let inner = container().width(content.0).height(content.1);
let view = if on_scroller {
container()
.width(200.0)
.height(100.0)
.padding(padding)
.scroll(scroll)
.child(inner)
} else {
container()
.width(200.0)
.height(100.0)
.scroll(scroll)
.child(container().padding(padding).child(inner))
};
let mut h = Harness::laid_out(view, 200.0, 100.0);
let at = |h: &mut Harness| {
let t = h.paint().children[0].local_transform;
(t.tx(), t.ty())
};
let before = at(&mut h);
h.send_at(
Event::scroll(100.0, 50.0, 1000.0, 1000.0, ScrollSource::Wheel),
Instant::now(),
);
let after = at(&mut h);
(before.0 - after.0, before.1 - after.1)
}
fn both_ways(scroll: impl Fn() -> Scroll, padding: f32, content: (f32, f32)) -> (f32, f32) {
let on_scroller = scrolled(scroll(), padding, content, true);
let on_child = scrolled(scroll(), padding, content, false);
assert_eq!(
on_scroller, on_child,
"padding on the scroller or on its child"
);
on_scroller
}
#[test]
fn a_padded_scroller_stops_where_its_content_and_padding_end() {
assert_eq!(
both_ways(Scroll::vertical, 20.0, (100.0, 300.0)),
(0.0, 240.0)
);
assert_eq!(
both_ways(Scroll::horizontal, 20.0, (300.0, 50.0)),
(140.0, 0.0)
);
assert_eq!(
both_ways(
|| Scroll::both().reserve_gutter(false),
20.0,
(300.0, 300.0)
),
(140.0, 240.0)
);
}
#[test]
fn padding_larger_than_the_box_still_scrolls_to_its_end() {
assert_eq!(
both_ways(Scroll::vertical, 70.0, (100.0, 300.0)),
(0.0, 340.0)
);
}
#[test]
fn a_padded_scroller_whose_content_fits_does_not_scroll() {
assert_eq!(both_ways(Scroll::vertical, 20.0, (100.0, 50.0)), (0.0, 0.0));
assert_eq!(
scrolled(
Scroll::vertical().fill_viewport(true),
20.0,
(100.0, 10.0),
true
),
(0.0, 0.0),
"content filling the viewport fits it, padding and all"
);
}
#[test]
fn a_padded_scroller_with_a_gutter_stops_where_its_content_and_padding_end() {
assert_eq!(
both_ways(Scroll::both, 20.0, (300.0, 300.0)),
(150.0, 250.0)
);
}
#[test]
fn a_padded_scroller_sized_to_its_content_does_not_scroll() {
let view = container()
.padding(20.0)
.scroll(Scroll::both())
.child(container().width(100.0).height(40.0));
let mut h = Harness::laid_out(view, 200.0, 100.0);
let at = |h: &mut Harness| {
let t = h.paint().children[0].local_transform;
(t.tx(), t.ty())
};
let before = at(&mut h);
h.send_at(
Event::scroll(50.0, 30.0, 1000.0, 1000.0, ScrollSource::Wheel),
Instant::now(),
);
assert_eq!(at(&mut h), before);
}
#[test]
fn a_padded_scroller_sizes_its_thumb_as_its_child_would() {
let thumb = |on_scroller: bool| {
let inner = container().width(100.0).height(300.0);
let view = if on_scroller {
container()
.width(200.0)
.height(100.0)
.padding(20.0)
.scroll(Scroll::vertical())
.child(inner)
} else {
container()
.width(200.0)
.height(100.0)
.scroll(Scroll::vertical())
.child(container().padding(20.0).child(inner))
};
let rects = Harness::laid_out(view, 200.0, 100.0).painted_rects();
assert_eq!(rects.len(), 2, "the track, then the thumb on it");
rects[1]
};
assert_eq!(thumb(true), thumb(false));
assert!(thumb(true).height > 20.0, "a thumb past its minimum");
}