Skip to main content

plot_redactor/view/
menu.rs

1//! Top application menu widgets.
2//!
3//! Currently provides import/export actions via the `Files` dropdown.
4
5use crate::controller::action::Action;
6use crate::model::{ImageFormat, ImageSize};
7use eframe::egui::{self, TopBottomPanel};
8
9/// EN: Dedicated top menu module for file import/export actions.
10/// RU: Otdelnyy modul verhnego menyu dlya importa/eksporta failov.
11pub struct FilesMenu;
12
13impl FilesMenu {
14    /// Draws the top menu and returns generated file-related actions.
15    pub fn draw(ctx: &egui::Context) -> Vec<Action> {
16        let mut actions = Vec::new();
17
18        TopBottomPanel::top("top_files_menu").show(ctx, |ui| {
19            ui.horizontal(|ui| {
20                ui.menu_button("Files", |ui| {
21                    if ui.button("From CSV").clicked() {
22                        if let Some(path) = rfd::FileDialog::new()
23                            .add_filter("CSV", &["csv"])
24                            .pick_file()
25                        {
26                            actions.push(Action::ImportFromCsv {
27                                path: path.display().to_string(),
28                            });
29                        }
30                        ui.close();
31                    }
32
33                    if ui.button("From TXT").clicked() {
34                        if let Some(path) = rfd::FileDialog::new()
35                            .add_filter("Text", &["txt"])
36                            .pick_file()
37                        {
38                            actions.push(Action::ImportFromTxt {
39                                path: path.display().to_string(),
40                            });
41                        }
42                        ui.close();
43                    }
44
45                    if ui.button("Save as...").clicked() {
46                        let size = ctx.screen_rect().size();
47                        if let Some(path) = rfd::FileDialog::new()
48                            .add_filter("PNG image", &["png"])
49                            .add_filter("SVG image", &["svg"])
50                            .save_file()
51                        {
52                            let ext = path
53                                .extension()
54                                .and_then(|s| s.to_str())
55                                .unwrap_or_default()
56                                .to_lowercase();
57                            let format = if ext == "svg" {
58                                ImageFormat::Svg
59                            } else {
60                                ImageFormat::Png
61                            };
62                            actions.push(Action::RequestSaveAs {
63                                path: path.display().to_string(),
64                                format,
65                                size: ImageSize {
66                                    width: size.x.max(1.0) as u32,
67                                    height: size.y.max(1.0) as u32,
68                                },
69                            });
70                        }
71                        ui.close();
72                    }
73                });
74            });
75        });
76
77        actions
78    }
79}
80
81