ketcindyinstaller/
app.rs

1use eframe::egui;
2
3use crate::installer::Installer;
4use crate::package::PackageState;
5
6pub struct GUIFrontend {
7    installer: Installer,
8}
9
10impl GUIFrontend {
11    pub fn new(_creation_context: &eframe::CreationContext<'_>) -> Self {
12        Self { installer: Installer::new() }
13    }
14}
15
16impl eframe::App for GUIFrontend {
17    fn update(&mut self, context: &egui::Context, _frame: &mut eframe::Frame) {
18        context.request_repaint();
19        self.installer.poll_events();
20
21        egui::CentralPanel::default()
22            .frame(egui::Frame::default().inner_margin(15))
23            .show(context, |ui| {
24                ui.heading("KeTCindy Installer");
25                let packages = self.installer.packages();
26
27                for package in packages {
28                    ui.indent(format!("package_{}", package.kind), |ui| {
29                        ui.label(format!("{}", package.kind));
30                        ui.horizontal(|ui| {
31                            match package.state {
32                                PackageState::Initialized => {
33                                    ui.label("Initialized");
34                                    self.installer.fetch_versions(package.kind);
35                                },
36                                PackageState::Fetching => {
37                                    ui.spinner();
38                                    ui.label("Fetching...");
39                                },
40                                PackageState::Fetched { versions, selected_index } => {
41                                    let mut is_selected = selected_index.is_some();
42                                    if ui.checkbox(&mut is_selected, "").changed() {
43                                        if is_selected {
44                                            self.installer.select_version(package.kind, Some(0));
45                                        } else {
46                                            self.installer.select_version(package.kind, None);
47                                        }
48                                    }
49                                    ui.add_enabled_ui(is_selected, |ui| {
50                                        if let Some(index) = selected_index {
51                                            let mut temp_index = index;
52                                            if egui::ComboBox::from_id_salt(format!("versions_{}", package.kind))
53                                                .show_index(ui, &mut temp_index, versions.len(), |i| &versions[i])
54                                                .changed()
55                                            {
56                                                self.installer.select_version(package.kind, Some(temp_index));
57                                            }
58                                        } else {
59                                            ui.label("(will not be installed)");
60                                        }
61                                    });
62                                },
63                                PackageState::Downloading { progress } => {
64                                    ui.add(egui::ProgressBar::new(progress).show_percentage());
65                                },
66                                PackageState::Downloaded { .. } => {
67                                    ui.label("downloaded");
68                                },
69                                PackageState::Installing => {
70                                    ui.spinner();
71                                    ui.label("Installing...");
72                                },
73                                PackageState::Installed => {
74                                    ui.label("Installed");
75                                },
76                                PackageState::Error(msg) => {
77                                    ui.colored_label(egui::Color32::RED, format!("Error: {}", msg));
78                                }
79                            }
80                        });
81                    });
82                }
83                ui.with_layout(egui::Layout::right_to_left(egui::Align::BOTTOM), |ui| {
84                    let can_install = self.installer.packages().iter().any(|p| {
85                        matches!(p.state, PackageState::Fetched { selected_index: Some(_), .. })
86                    });
87                    if ui.add_enabled(can_install, egui::Button::new("Install")).clicked() {
88                        self.installer.start_installation();
89                    }
90                });
91            });
92    }
93}