GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
src/widget/layout_helper.rs (3.2K)
1 use crate::widget::WidgetHost;
2
3 pub struct ColumnLayout {
4 pub x: f32,
5 pub y: f32,
6 pub width: f32,
7 pub gap: f32,
8 pub margin: f32,
9 current_y: f32,
10 }
11
12 impl ColumnLayout {
13 pub fn new(x: f32, y: f32, width: f32, gap: f32, margin: f32) -> Self {
14 Self {
15 x,
16 y,
17 width,
18 gap,
19 margin,
20 current_y: y + margin,
21 }
22 }
23
24 /// A column inside a pane plate: the pane rung's padding as the margin
25 /// and its gap between widgets (`plate_padding` / `plate_gap`).
26 pub fn pane(x: f32, y: f32, width: f32) -> Self {
27 Self::new(x, y, width, crate::layout::plate_gap(), crate::layout::plate_padding())
28 }
29
30 /// A column of controls with the control gap between them and no
31 /// margin of its own (`control_gap`).
32 pub fn controls(x: f32, y: f32, width: f32) -> Self {
33 Self::new(x, y, width, crate::layout::control_gap(), 0.0)
34 }
35
36 /// `height` is the CONTENT height; the widget's block adds its label strip.
37 pub fn add_widget(&mut self, widget: &mut dyn WidgetHost, height: f32) {
38 let total_h = height + widget.label_strip();
39 widget.set_rect(self.x + self.margin, self.current_y, self.width - 2.0 * self.margin, total_h);
40 self.current_y += total_h + self.gap;
41 }
42
43 pub fn add_row(&mut self, widgets: &[*mut dyn WidgetHost], height: f32, gap: f32) {
44 let count = widgets.len();
45 if count == 0 {
46 return;
47 }
48 let mut max_label_off = 0.0;
49 for &widget_ptr in widgets {
50 unsafe {
51 let off = (*widget_ptr).label_strip();
52 if off > max_label_off {
53 max_label_off = off;
54 }
55 }
56 }
57 let total_h = height + max_label_off;
58 let total_width = self.width - 2.0 * self.margin;
59 let widget_w = (total_width - (count as f32 - 1.0) * gap) / count as f32;
60 let mut curr_x = self.x + self.margin;
61 for &widget_ptr in widgets {
62 unsafe {
63 // Content lines up on one row; a shorter label strip starts lower.
64 let off = (*widget_ptr).label_strip();
65 (*widget_ptr).set_rect(curr_x, self.current_y + max_label_off - off, widget_w, height + off);
66 }
67 curr_x += widget_w + gap;
68 }
69 self.current_y += total_h + self.gap;
70 }
71
72 pub fn current_y(&self) -> f32 {
73 self.current_y - self.gap + self.margin
74 }
75 }
76
77 pub struct RowLayout {
78 pub x: f32,
79 pub y: f32,
80 pub height: f32,
81 pub gap: f32,
82 pub margin: f32,
83 current_x: f32,
84 }
85
86 impl RowLayout {
87 pub fn new(x: f32, y: f32, height: f32, gap: f32, margin: f32) -> Self {
88 Self {
89 x,
90 y,
91 height,
92 gap,
93 margin,
94 current_x: x + margin,
95 }
96 }
97
98 pub fn add_widget(&mut self, widget: &mut dyn WidgetHost, width: f32) {
99 widget.set_rect(self.current_x, self.y + self.margin, width, self.height - 2.0 * self.margin);
100 self.current_x += width + self.gap;
101 }
102
103 pub fn current_x(&self) -> f32 {
104 self.current_x - self.gap + self.margin
105 }
106 }