Skip to main content

libsurfer/
server_file_window.rs

1use ecolor::Color32;
2use egui::{Context, Key, ScrollArea, TextWrapMode, Window};
3use surver::SurverFileInfo;
4
5use crate::{SystemState, message::Message, wave_source::LoadOptions};
6
7fn draw_file_info_tooltip(ui: &mut egui::Ui, file_info: &SurverFileInfo, is_loadable: bool) {
8    ui.set_max_width(ui.spacing().tooltip_width);
9    if is_loadable {
10        ui.label(format!("Size: {} bytes", file_info.bytes));
11        ui.label(format!(
12            "Last modified: {}",
13            file_info.modification_time_string()
14        ));
15    } else {
16        ui.colored_label(Color32::RED, "File cannot be loaded. See logs for details.");
17    }
18}
19
20impl SystemState {
21    pub fn draw_surver_file_window(&self, ctx: &Context, msgs: &mut Vec<Message>) {
22        let mut open = true;
23        let mut load_options = *self.surver_load_options.borrow();
24        let mut should_load = false;
25
26        Window::new("Select wave file")
27            .resizable(true)
28            .open(&mut open)
29            .show(ctx, |ui| {
30                ScrollArea::both().id_salt("file_list").show(ui, |ui| {
31                    ui.vertical(|ui| {
32                        ui.style_mut().wrap_mode = Some(TextWrapMode::Extend);
33                        if let Some(file_infos) = self.user.surver_file_infos.as_ref() {
34                            let selected_idx = *self.surver_selected_file.borrow();
35                            for (i, file_info) in file_infos.iter().enumerate() {
36                                // Only make item selectable if last_load_ok is true
37                                ui.add_enabled_ui(file_info.last_load_ok, |ui| {
38                                    let response = ui
39                                        .selectable_label(
40                                            Some(i) == selected_idx && file_info.last_load_ok,
41                                            &file_info.filename,
42                                        )
43                                        .on_hover_ui(|ui| {
44                                            draw_file_info_tooltip(
45                                                ui,
46                                                file_info,
47                                                file_info.last_load_ok,
48                                            );
49                                        });
50
51                                    // Handle click and double-click to select (and optionally load)
52                                    if (response.clicked() || response.double_clicked())
53                                        && file_info.last_load_ok
54                                    {
55                                        *self.surver_selected_file.borrow_mut() = Some(i);
56                                        if response.double_clicked() {
57                                            should_load = true;
58                                        }
59                                    }
60                                });
61                            }
62                        }
63                    });
64                });
65
66                // Handle keyboard navigation
67                if ui.input(|i| i.key_pressed(Key::Escape)) {
68                    msgs.push(Message::SetSurverFileWindowVisible(false));
69                    return;
70                }
71
72                if ui.input(|i| i.key_pressed(Key::Enter))
73                    && self.surver_selected_file.borrow().is_some()
74                {
75                    should_load = true;
76                }
77
78                if self.user.selected_server_file_index.is_some() {
79                    ui.separator();
80                    ui.radio_value(
81                        &mut load_options,
82                        LoadOptions::Clear,
83                        "Clean load (do not keep any variables)",
84                    );
85                    ui.radio_value(
86                        &mut load_options,
87                        LoadOptions::KeepAvailable,
88                        "Reload and keep available variables",
89                    );
90                    ui.radio_value(
91                        &mut load_options,
92                        LoadOptions::KeepAll,
93                        "Reload and keep all variables",
94                    );
95                }
96
97                ui.separator();
98                ui.horizontal(|ui| {
99                    if ui.button("Cancel").clicked() {
100                        msgs.push(Message::SetSurverFileWindowVisible(false));
101                    }
102
103                    // Disable Select button when nothing is selected
104                    ui.add_enabled_ui(self.surver_selected_file.borrow().is_some(), |ui| {
105                        if ui.button("Select").clicked() {
106                            should_load = true;
107                        }
108                    });
109                });
110            });
111
112        // Handle file loading
113        if should_load && let Some(file_idx) = *self.surver_selected_file.borrow() {
114            msgs.push(Message::SetSurverFileWindowVisible(false));
115            msgs.push(Message::LoadSurverFileByIndex(
116                Some(file_idx),
117                if self.user.selected_server_file_index.is_some() {
118                    load_options
119                } else {
120                    LoadOptions::Clear
121                },
122            ));
123        }
124
125        if !open {
126            msgs.push(Message::SetSurverFileWindowVisible(false));
127        }
128
129        // Update persisted state
130        *self.surver_load_options.borrow_mut() = load_options;
131    }
132}