//! Scrolling moves content and stops at its ends. use iris::harness::{Harness, assert_corners}; use iris::prelude::*; #[test] fn scrollable_enables_a_region_node_but_raw_scroll_does_not() { let mut h = Harness::new((100, 100)); let default_child = ().add(&mut h.rsc); let _default = default_child.scrollable().add(&mut h.rsc); assert!(h.rsc.widgets().is_region_node(default_child)); h.rsc.widgets_mut().set_region_node(default_child, false); assert!(!h.rsc.widgets().is_region_node(default_child)); let raw_child = ().add(&mut h.rsc); let _raw = Scroll::new(raw_child.add_strong(&mut h.rsc), Axis::Y).add(&mut h.rsc); assert!(!h.rsc.widgets().is_region_node(raw_child)); let explicit = ().region_node().add(&mut h.rsc); assert!(h.rsc.widgets().is_region_node(explicit)); } #[test] fn a_scrollable_child_can_drop_its_region_node() { let mut h = Harness::new((400, 200)); let top = rect(Color::RED).height(200).add(&mut h.rsc); let bottom = rect(Color::BLUE).height(200).add(&mut h.rsc); let content = (top, bottom).span(Dir::DOWN).add(&mut h.rsc); h.set_root(content.scrollable()); h.rsc.widgets_mut().set_region_node(content, false); h.frame(); h.move_to((200, 100)); h.scroll((0, 1)); h.frame(); assert!(!h.rsc.widgets().is_region_node(content)); assert_corners!(h, top, (0, -150), (400, 50)); } #[test] fn a_wheel_scrolls_the_content_and_stops_at_its_end() { let mut h = Harness::new((400, 200)); // Twice the window's height, so there is 200 to scroll. let top = rect(Color::RED).height(200).add(&mut h.rsc); let bottom = rect(Color::BLUE).height(200).add(&mut h.rsc); h.set_root((top, bottom).span(Dir::DOWN).scrollable()); h.move_to((200, 100)); // `Scroll` starts snapped to the end. assert_corners!(h, top, (0, -200), (400, 0)); // The handler scales a wheel line by 50. h.scroll((0, 1)); h.frame(); assert_corners!(h, top, (0, -150), (400, 50)); h.scroll((0, 10)); h.frame(); assert_corners!(h, top, (0, 0), (400, 200)); } /// A widget that clips to its box may not report more than the box: its /// parent would place the part it cut off, and the framework would put a /// drawing longer than its box somewhere. `Masked` is the second of these /// after `Scroll`, and the assertion in `draw_at` is what says so. #[test] #[should_panic = "clips to"] fn a_clipping_widget_reporting_more_than_its_box_is_caught() { struct Clipper(StrongWidget); impl Widget for Clipper { fn draw(&mut self, painter: &mut Painter) -> Size { painter.set_mask(painter.region()); painter.widget(&self.0).size() } } let mut h = Harness::new((100, 100)); let tall = rect(Color::RED).height(400).add_strong(&mut h.rsc); let clipper = Clipper(tall).add(&mut h.rsc); h.set_root(clipper); h.frame(); }