add scrollarea
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
use gpui::{
|
||||
Context, IntoElement, Modifiers, ParentElement as _, Render, ScrollDelta, ScrollEvent,
|
||||
ScrollHandle, SharedString, Styled as _, TestAppContext, VisualTestContext, Window, div, point,
|
||||
px,
|
||||
};
|
||||
use gpui_native_core::scroll_area::ScrollArea;
|
||||
use gpui_native_theme::Theme;
|
||||
|
||||
struct Harness {
|
||||
scroll: ScrollHandle,
|
||||
rows: usize,
|
||||
}
|
||||
|
||||
impl Render for Harness {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div().size_full().child(
|
||||
ScrollArea::new("test-scroll")
|
||||
.handle(self.scroll.clone())
|
||||
.h(px(200.))
|
||||
.w(px(300.))
|
||||
.child(div().flex().flex_col().children((0..self.rows).map(|row| {
|
||||
div()
|
||||
.h(px(20.))
|
||||
.child(SharedString::from(format!("row {row}")))
|
||||
}))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A 300×200 scroll area over `rows` 20px rows, with the handle the test
|
||||
/// can inspect directly.
|
||||
fn scroll_area_window(rows: usize) -> (TestAppContext, VisualTestContext, ScrollHandle) {
|
||||
let mut cx = TestAppContext::single();
|
||||
cx.update(Theme::init);
|
||||
let handle = ScrollHandle::new();
|
||||
let handle_for_view = handle.clone();
|
||||
let window = cx.add_window(move |_, _| Harness {
|
||||
scroll: handle_for_view,
|
||||
rows,
|
||||
});
|
||||
let mut visual = VisualTestContext::from_window(window.into(), &cx);
|
||||
visual.update(|window, cx| {
|
||||
window.draw(cx).clear(cx);
|
||||
});
|
||||
(cx, visual, handle)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_scrolling_moves_the_offset_and_stays_inside_the_content() {
|
||||
let (_cx, mut visual, handle) = scroll_area_window(30);
|
||||
|
||||
// 30 rows × 20px = 600px of content in a 200px viewport.
|
||||
visual.simulate_event(ScrollEvent {
|
||||
position: point(px(100.), px(100.)),
|
||||
delta: ScrollDelta::Pixels(point(px(0.), px(-60.))),
|
||||
modifiers: Modifiers::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let offset = handle.offset().y;
|
||||
assert_eq!(offset, px(-60.));
|
||||
|
||||
// Wheeling far past the end clamps to the content.
|
||||
for _ in 0..10 {
|
||||
visual.simulate_event(ScrollEvent {
|
||||
position: point(px(100.), px(100.)),
|
||||
delta: ScrollDelta::Pixels(point(px(0.), px(-60.))),
|
||||
modifiers: Modifiers::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
// max_offset = 600 - 200 = 400.
|
||||
assert_eq!(handle.offset().y, px(-400.));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_content_starts_unscrolled_and_horizontal_axes_scroll_x() {
|
||||
let (_cx, mut visual, handle) = scroll_area_window(30);
|
||||
assert_eq!(handle.offset(), gpui::point(px(0.), px(0.)));
|
||||
|
||||
// A vertical-only area ignores horizontal wheel deltas.
|
||||
visual.simulate_event(ScrollEvent {
|
||||
position: point(px(100.), px(100.)),
|
||||
delta: ScrollDelta::Pixels(point(px(-60.), px(0.))),
|
||||
modifiers: Modifiers::default(),
|
||||
..Default::default()
|
||||
});
|
||||
assert_eq!(handle.offset().x, px(0.));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_thumb_paints_when_the_content_overflows() {
|
||||
let (_cx, _visual, handle) = scroll_area_window(30);
|
||||
// 30 rows × 20px in a 200px viewport: the thumb has something to report.
|
||||
assert!(handle.max_offset().y > px(0.));
|
||||
}
|
||||
Reference in New Issue
Block a user