1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
| | // SPDX-License-Identifier: EUPL-1.2+
// SPDX-FileCopyrightText: 2025 Johannes Süllner <johannes.suellner@mailbox.org>
use iced::{
Element, Length,
widget::{Button, Column, Row, button, column, container, row, text},
};
use iced_fonts::{BOOTSTRAP_FONT as ICON_FONT, Bootstrap as Icon};
use lsblk::BlockDevice;
use super::Event;
#[macro_export]
macro_rules! center_horizontal_in_container {
($e:expr) => {
iced::widget::container($e)
.width(iced::Length::Fill)
.center_x(iced::Length::Fill)
};
}
#[macro_export]
macro_rules! center_in_container {
($e:expr) => {
iced::widget::container($e)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.center_x(iced::Length::Fill)
.center_y(iced::Length::Fill)
};
}
const BOTTOM_BUTTON_SPACE: f32 = 2.0;
const BOTTOM_BUTTON_ROW_HEIGHT: f32 = 50.0;
const DISK_ICON_SIZE: u16 = 50;
fn bottom_button<'a>(
button_content: Element<'a, Event>,
button_on_press: Option<Event>,
) -> Button<'a, Event> {
button(
center_in_container!(button_content)
.height(Length::Fill)
.center_y(Length::Fill),
)
.on_press_maybe(button_on_press)
.width(Length::Fill)
.height(Length::Fill)
}
pub fn bottom_buttons_layout<'a>(
button_matrix: impl IntoIterator<
Item = impl IntoIterator<Item = (Element<'a, Event>, Option<Event>)>,
>,
main_element: Element<'a, Event>,
) -> Element<'a, Event> {
let mut bottom_height = 0.0;
let mut bottom_element = Column::new().spacing(BOTTOM_BUTTON_SPACE);
for input_row in button_matrix.into_iter() {
let mut output_row = Row::new().spacing(BOTTOM_BUTTON_SPACE);
for (button_content, button_on_press) in input_row.into_iter() {
output_row = output_row.push(bottom_button(button_content, button_on_press));
}
bottom_element = bottom_element.push(output_row);
bottom_height += BOTTOM_BUTTON_ROW_HEIGHT;
}
column![
center_horizontal_in_container!(main_element).height(Length::Fill),
container(bottom_element).height(bottom_height)
]
.into()
}
pub fn disk_element(device: &BlockDevice) -> Element<'static, Event> {
let icon: Element<Event> = text(Icon::Hdd.to_string())
.font(ICON_FONT)
.size(DISK_ICON_SIZE)
.into();
let disk_size = if let Ok(Some(capacity)) = device.capacity() {
let mut size_factor: f32 = (capacity * 512) as f32;
let mut exponent = 0; // base = 1024
while size_factor >= 1000.0 {
exponent += 1;
size_factor = size_factor / 1000.0;
}
let unit = match exponent {
0 => "",
1 => "K",
2 => "M",
3 => "G",
4 => "T",
5 => "P",
6 => "E",
7 => "Z",
8 => "Y",
9 => "R",
_ => "???",
};
Ok(format!("{:.2} {}B", size_factor, unit))
} else {
Err("Failed to get disk size")
};
let disk_id = if let Some(id) = &device.id { id } else { "" };
row![
icon,
text(format!(
"{}\n{}\n{}",
device.fullname.display(),
disk_id,
if let Ok(size) = disk_size {
size
} else {
String::from("(unknown size)")
}
))
]
.spacing(8)
.into()
}
|