fission_core/ui/widgets/
scroll.rs1use crate::lowering::{LoweringContext, NodeBuilder};
2use crate::ui::{traits::Lower, Node};
3use fission_ir::{
4 op::{FlexDirection, LayoutOp, Op},
5 NodeId,
6};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Scroll {
28 pub id: Option<NodeId>,
30 pub child: Option<Box<Node>>,
32 pub direction: FlexDirection,
34 pub width: Option<f32>,
36 pub height: Option<f32>,
38 pub show_scrollbar: bool,
40 pub flex_grow: f32,
42 pub flex_shrink: f32,
44}
45
46impl Scroll {
47 pub fn into_node(self) -> Node {
48 Node::Scroll(self)
49 }
50}
51
52impl Default for Scroll {
53 fn default() -> Self {
54 Self {
55 id: None,
56 child: None,
57 direction: FlexDirection::Column,
58 width: None,
59 height: None,
60 show_scrollbar: false,
61 flex_grow: 0.0,
62 flex_shrink: 0.0,
63 }
64 }
65}
66
67impl Lower for Scroll {
68 fn lower(&self, cx: &mut LoweringContext) -> NodeId {
69 let layout_id = self.id.unwrap_or_else(|| cx.next_node_id());
70
71 cx.push_scope(layout_id);
72
73 let mut builder = NodeBuilder::new(
74 layout_id,
75 Op::Layout(LayoutOp::Scroll {
76 direction: self.direction,
77 show_scrollbar: self.show_scrollbar,
78 width: self.width,
79 height: self.height,
80 min_width: None,
81 max_width: None,
82 min_height: None,
83 max_height: None,
84 padding: [0.0; 4],
85 flex_grow: self.flex_grow,
86 flex_shrink: self.flex_shrink,
87 }),
88 );
89 if let Some(child) = &self.child {
90 let content_id = cx.next_node_id();
93 let mut content_box = NodeBuilder::new(
94 content_id,
95 Op::Layout(LayoutOp::Box {
96 width: None,
97 height: None,
98 min_width: None,
99 max_width: None,
100 min_height: None,
101 max_height: None,
102 padding: [0.0; 4],
103 flex_grow: 0.0,
104 flex_shrink: 0.0,
105 aspect_ratio: None,
106 })
107 );
108 content_box.add_child(child.lower(cx));
109 builder.add_child(content_box.build(cx));
110 }
111
112 cx.pop_scope();
113
114 builder.build(cx)
115 }
116}