telar_ui_core/
scroll_page.rs1use layout_core::{AvailableSpace, LayoutError, LayoutStyle, NodeId, SizeDimension};
4use platform_core::Event;
5use ui_tree::{Component, EventResult, RenderNode};
6
7use crate::context::{compute_layout, mark_dirty, new_container};
8use crate::layout_item::LayoutItem;
9use crate::scroll_area::LayoutScrollArea;
10
11pub struct ScrollPage {
17 root: NodeId,
18 content_node: NodeId,
19 scroll_area: LayoutScrollArea,
20}
21
22impl ScrollPage {
23 pub fn new(content: Box<dyn LayoutItem>) -> Result<Self, LayoutError> {
24 let content_node = content.layout_node();
25 let scroll_area = LayoutScrollArea::new(
26 LayoutStyle::new().flex_grow(1.0).align_self_stretch(),
27 content,
28 )?;
29 let root = new_container(
32 LayoutStyle::new()
33 .flex_column()
34 .width(SizeDimension::Percent(1.0))
35 .height(SizeDimension::Percent(1.0)),
36 &[scroll_area.layout_node()],
37 )?;
38 Ok(Self {
39 root,
40 content_node,
41 scroll_area,
42 })
43 }
44
45 pub fn relayout(&mut self, width: f32, height: f32) {
48 mark_dirty(self.root).ok();
49 compute_layout(
50 self.root,
51 AvailableSpace::Definite(width),
52 AvailableSpace::Definite(height),
53 )
54 .ok();
55 compute_layout(
56 self.content_node,
57 AvailableSpace::Definite(width),
58 AvailableSpace::MaxContent,
59 )
60 .ok();
61 self.scroll_area.clamp_scroll();
62 }
63}
64
65impl Component for ScrollPage {
66 fn view(&self) -> RenderNode {
67 self.scroll_area.view()
68 }
69
70 fn on_event(&mut self, event: &Event) -> EventResult {
72 if let Event::WindowResized { width, height } = event {
73 self.relayout(*width as f32, *height as f32);
74 return EventResult::Handled;
75 }
76 self.scroll_area.on_event(event)
77 }
78}