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}