// SPDX-License-Identifier: EUPL-1.2+ // SPDX-FileCopyrightText: 2025 Johannes Süllner 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, ) -> 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, Option)>, >, 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 = 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() }