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
|
use std::cell::RefCell;
use std::rc::Rc;
use crate::utils::format_number;
use gtk::glib;
use gtk::prelude::*;
struct DiskInfo {
label: gtk::Label,
progress: gtk::ProgressBar,
mount_point: String,
updated: bool,
}
fn update_disk(info: &mut DiskInfo, disk: &sysinfo::Disk) {
info.label.set_text(
format!(
"{} mounted on \"{}\"",
disk.name().to_str().unwrap_or(""),
&info.mount_point,
)
.as_str(),
);
info.progress.set_text(Some(
format!(
"{} / {}",
format_number(disk.total_space() - disk.available_space()),
format_number(disk.total_space())
)
.as_str(),
));
info.progress.set_fraction(
(disk.total_space() - disk.available_space()) as f64 / disk.total_space() as f64,
);
info.updated = true;
}
fn refresh_disks(container: >k::Box, disks: &[sysinfo::Disk], elems: &mut Vec<DiskInfo>) {
for disk in disks.iter() {
let mount_point = disk.mount_point().to_str().unwrap_or("");
update_disk(
if let Some(entry) = elems.iter_mut().find(|e| e.mount_point == mount_point) {
entry
} else {
let label = gtk::Label::builder()
.margin_top(if elems.is_empty() { 8 } else { 20 })
.build();
let progress = gtk::ProgressBar::new();
progress.set_show_text(true);
container.append(&label);
container.append(&progress);
elems.push(DiskInfo {
label,
progress,
mount_point: mount_point.to_owned(),
updated: false,
});
elems.last_mut().unwrap()
},
disk,
);
}
for entry in elems.iter().filter(|e| !e.updated) {
container.remove(&entry.label);
container.remove(&entry.progress);
}
elems.retain(|e| e.updated);
for entry in elems.iter_mut() {
entry.updated = false;
}
}
pub fn create_disk_info(stack: >k::Stack) {
let elems: Rc<RefCell<Vec<DiskInfo>>> = Rc::new(RefCell::new(Vec::new()));
let vertical_layout = gtk::Box::new(gtk::Orientation::Vertical, 0);
let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
let scroll = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.child(&container)
.build();
let disks = RefCell::new(sysinfo::Disks::new_with_refreshed_list());
refresh_disks(&container, &disks.borrow(), &mut elems.borrow_mut());
let refresh_but = gtk::Button::with_label("Refresh disks");
refresh_but.connect_clicked(glib::clone!(
#[weak]
container,
move |_| {
disks.borrow_mut().refresh_list();
refresh_disks(&container, &disks.borrow(), &mut elems.borrow_mut());
}
));
vertical_layout.append(&scroll);
vertical_layout.append(&refresh_but);
stack.add_titled(&vertical_layout, Some("Disks"), "Disks");
}
|