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