1use crate::core::Rect;
4use crate::layout::{DesiredSize, Layout, SizeConstraints};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ScrollDirection {
9 Vertical,
10 Horizontal,
11 Both,
12}
13
14pub struct ScrollContainer {
16 direction: ScrollDirection,
17 offset_x: f32,
18 offset_y: f32,
19}
20
21impl ScrollContainer {
22 pub fn new(direction: ScrollDirection) -> Self {
23 Self {
24 direction,
25 offset_x: 0.0,
26 offset_y: 0.0,
27 }
28 }
29
30 pub fn offset(mut self, offset: f32) -> Self {
32 match self.direction {
33 ScrollDirection::Vertical => self.offset_y = offset,
34 ScrollDirection::Horizontal => self.offset_x = offset,
35 ScrollDirection::Both => {
36 self.offset_x = offset;
37 self.offset_y = offset;
38 }
39 }
40 self
41 }
42
43 pub fn offset_xy(mut self, x: f32, y: f32) -> Self {
44 self.offset_x = x;
45 self.offset_y = y;
46 self
47 }
48
49 pub fn viewport(&self, area: Rect) -> Rect {
51 area
52 }
53
54 pub fn max_offset(&self, content: DesiredSize, viewport: Rect) -> (f32, f32) {
56 let max_x = (content.width - viewport.width).max(0.0);
57 let max_y = (content.height - viewport.height).max(0.0);
58 (max_x, max_y)
59 }
60}
61
62impl Layout for ScrollContainer {
63 fn measure(&self, children: &[DesiredSize], constraints: SizeConstraints) -> DesiredSize {
64 if children.is_empty() {
66 return DesiredSize::zero();
67 }
68 let width = children.iter().map(|c| c.width).fold(0.0f32, f32::max);
69 let height: f32 = children.iter().map(|c| c.height).sum();
70 let (w, h) = constraints.clamp(width, height);
71 DesiredSize::new(w, h)
72 }
73
74 fn arrange(&self, children: &[DesiredSize], area: Rect) -> Vec<Rect> {
75 let mut rects = Vec::with_capacity(children.len());
76 let mut y = area.y - self.offset_y;
77 for child in children {
78 let x = area.x - self.offset_x;
79 let w = match self.direction {
80 ScrollDirection::Horizontal | ScrollDirection::Both => child.width,
81 ScrollDirection::Vertical => child.width.max(area.width),
82 };
83 rects.push(Rect::new(x, y, w, child.height));
84 y += child.height;
85 }
86 rects
87 }
88}