pushrod/layouts/
vertical_layout.rs1use crate::render::layout::{Layout, LayoutPosition};
17use crate::render::widget_cache::WidgetContainer;
18use crate::render::widget_config::{PaddingConstraint, CONFIG_ORIGIN, CONFIG_SIZE};
19use crate::render::{Points, Size, SIZE_HEIGHT, SIZE_WIDTH};
20
21pub struct VerticalLayout {
23 widget_ids: Vec<i32>,
24 widget_positions: Vec<LayoutPosition>,
25 origin: Points,
26 size: Size,
27 padding: PaddingConstraint,
28 invalidated: bool,
29}
30
31impl VerticalLayout {
33 pub fn new(x: i32, y: i32, w: u32, h: u32, padding: PaddingConstraint) -> Self {
34 Self {
35 widget_ids: Vec::new(),
36 widget_positions: Vec::new(),
37 origin: vec![x, y],
38 size: vec![w, h],
39 padding,
40 invalidated: false,
41 }
42 }
43}
44
45impl Layout for VerticalLayout {
49 fn insert_widget(&mut self, widget_id: i32, widget_position: LayoutPosition) {
51 self.widget_ids.push(widget_id);
52 self.widget_positions.push(widget_position);
53 self.invalidated = true;
54 }
55
56 fn append_widget(&mut self, widget_id: i32) {
58 let positions = self.widget_positions.len();
59 let widget_position = if self.widget_positions.is_empty() {
60 LayoutPosition::new(0, 0)
61 } else {
62 LayoutPosition::new(self.widget_positions[positions - 1].x + 1, 0)
63 };
64
65 self.insert_widget(widget_id, widget_position);
66 }
67
68 fn set_padding(&mut self, padding: PaddingConstraint) {
69 self.padding = padding;
70 self.invalidated = true;
71 }
72
73 fn get_padding(&self) -> PaddingConstraint {
74 self.padding
75 }
76
77 fn do_layout(&mut self, _widgets: &[WidgetContainer]) {
80 if self.widget_ids.len() <= 1 {
81 return;
82 }
83
84 let offset_x: i32 = self.origin[0];
85 let offset_y: i32 = self.origin[1];
86 let num_widgets = self.widget_ids.len() as u32;
87 let widget_height = self.size[SIZE_HEIGHT] / num_widgets as u32;
88 let subtractor_bottom = ((self.padding.spacing as f64 / 2.0).ceil()) as u32;
89 let subtractor_top = ((self.padding.spacing as f64 / 2.0).floor()) as u32;
90
91 for i in 0..num_widgets {
92 let set_y: i32;
93 let mut set_height: u32 = widget_height;
94 let widget_id = self.widget_ids[i as usize];
95
96 if i == 0 {
97 set_y = (i * set_height) as i32 + self.padding.top;
98 set_height = widget_height - subtractor_bottom - self.padding.top as u32;
99 } else if i == num_widgets - 1 {
100 set_y = (i * set_height) as i32 + subtractor_top as i32;
101 set_height = widget_height - subtractor_top - self.padding.bottom as u32;
102 } else {
103 set_y = (i * set_height) as i32 + subtractor_top as i32;
104 set_height = widget_height - subtractor_top - subtractor_bottom;
105 }
106
107 _widgets[widget_id as usize]
108 .widget
109 .borrow_mut()
110 .get_config()
111 .set_point(
112 CONFIG_ORIGIN,
113 offset_x + self.padding.left,
114 offset_y + set_y,
115 );
116
117 _widgets[widget_id as usize]
118 .widget
119 .borrow_mut()
120 .get_config()
121 .set_size(
122 CONFIG_SIZE,
123 self.size[SIZE_WIDTH] - self.padding.right as u32 - self.padding.left as u32,
124 set_height,
125 );
126
127 _widgets[widget_id as usize]
128 .widget
129 .borrow_mut()
130 .get_config()
131 .set_invalidated(true);
132 }
133
134 self.invalidated = false;
135 }
136
137 fn needs_layout(&self) -> bool {
138 self.invalidated
139 }
140}