use std::cell::Cell;
use std::rc::Rc;
use super::*;
use crate::base::{Rect, Size};
use crate::layout::Style as LayoutStyle;
use crate::theme::default_theme;
use crate::ui::{text, Element, MouseKind};
use crate::widgets::itest_util::{mount_widget, mouse, settle};
type Probe = Rc<Cell<Option<Rect>>>;
const VIEW_H: i32 = 4;
const PROBED_ROW: i32 = 12;
fn column_with_a_probed_child(probe: Probe, culled_probe: bool) -> (View, i32) {
let mut col = Element::new().style(LayoutStyle::column());
for i in 0..20 {
if i == PROBED_ROW {
let p = probe.clone();
let mut marked = Element::new()
.style(LayoutStyle::column())
.child(text(format!("row {i}")))
.draw(move |_canvas, rect| p.set(Some(rect)));
if culled_probe {
marked = marked.probe_when_culled();
}
col = col.child(marked.build());
} else {
col = col.child(text(format!("row {i}")));
}
}
(col.build(), 20)
}
#[test]
fn a_culled_child_never_reports_its_offset() {
let t = &default_theme().tokens;
let size = Size::new(12, VIEW_H);
let probe: Probe = Rc::new(Cell::new(None));
let (content, h) = column_with_a_probed_child(probe.clone(), false);
let (_root, mut tree) = mount_widget(size, |cx| {
Scroll::new(content)
.content_size(10, h)
.element(cx, t)
.build()
});
settle(&mut tree, size);
assert_eq!(
probe.get(),
None,
"0910: a child below the fold is culled by draw.rs, so a paint \
probe on it never fires — an app cannot learn where it landed, \
which is exactly the child an ensure-visible verb must locate"
);
mouse(&mut tree, MouseKind::ScrollDown, 2, 1);
mouse(&mut tree, MouseKind::ScrollDown, 2, 1);
mouse(&mut tree, MouseKind::ScrollDown, 2, 1);
mouse(&mut tree, MouseKind::ScrollDown, 2, 1);
settle(&mut tree, size);
let seen = probe.get().expect(
"control: the probe must fire once its child is scrolled into \
view, or the None above proves nothing about culling",
);
assert!(
seen.y >= 0 && seen.y < VIEW_H,
"control: the probed child reports a rect inside the viewport \
once visible, got {seen:?}"
);
}
#[test]
fn probe_when_culled_reports_the_offset_of_an_off_screen_child() {
let t = &default_theme().tokens;
let size = Size::new(12, VIEW_H);
let probe: Probe = Rc::new(Cell::new(None));
let (content, h) = column_with_a_probed_child(probe.clone(), true);
let (_root, mut tree) = mount_widget(size, |cx| {
Scroll::new(content)
.content_size(10, h)
.element(cx, t)
.build()
});
settle(&mut tree, size);
let seen = probe
.get()
.expect("probe_when_culled keeps a culled node's own paint alive");
assert_eq!(
seen.y, PROBED_ROW,
"the culled probe reports the child's TRUE solved offset, not a \
clamped or zeroed one — {seen:?}"
);
assert!(
seen.y >= VIEW_H,
"sanity: the probed child really is outside the {VIEW_H}-row \
viewport, so this is the off-screen case and not a visible one"
);
}