ferrite_ui/
help_menu.rs

1use eframe::egui::{self, Color32};
2use ferrite_config::{ControlsConfig, HelpMenuConfig};
3
4pub struct HelpMenu {
5    visible: bool,
6}
7
8impl HelpMenu {
9    pub fn new() -> Self {
10        Self { visible: false }
11    }
12
13    pub fn toggle(&mut self) {
14        self.visible = !self.visible;
15    }
16
17    pub fn render(
18        &self,
19        ui: &mut egui::Ui,
20        config: &HelpMenuConfig,
21        controls: &ControlsConfig,
22    ) {
23        if !self.visible {
24            return;
25        }
26
27        let base_font_size = config.font_size as f32;
28        let heading_size = base_font_size * 1.2;
29        let row_height = base_font_size * 1.5;
30        let spacing = row_height * 0.5;
31        let column_width = base_font_size * 10.0;
32        let total_width = column_width * 3.0 + spacing * 2.0;
33
34        let screen_rect = ui.ctx().screen_rect();
35        egui::Area::new("help_menu".into())
36            .fixed_pos(egui::pos2(
37                screen_rect.center().x - total_width * 0.5,
38                screen_rect.center().y - (heading_size + row_height * 4.0),
39            ))
40            .show(ui.ctx(), |ui| {
41                egui::Frame::new()
42                    .fill(Color32::from_rgba_unmultiplied(
43                        config.background_color.r,
44                        config.background_color.g,
45                        config.background_color.b,
46                        config.background_color.a,
47                    ))
48                    .corner_radius(row_height * 0.5)
49                    .inner_margin(spacing)
50                    .show(ui, |ui| {
51                        ui.set_max_width(total_width);
52
53                        ui.columns(3, |columns| {
54                            for col in columns.iter_mut() {
55                                col.set_max_width(column_width);
56                            }
57
58                            columns[0].vertical(|ui| {
59                                render_section(
60                                    ui,
61                                    "Navigation",
62                                    &[
63                                        "LEFT or A: Previous",
64                                        "RIGHT or D: Next",
65                                    ],
66                                    config,
67                                    heading_size,
68                                )
69                            });
70
71                            columns[1].vertical(|ui| {
72                                let zoom_in_keys = format!(
73                                    "{:?}: Zoom in",
74                                    controls.zoom_in_keys
75                                );
76                                let zoom_out_keys = format!(
77                                    "{:?}: Zoom out",
78                                    controls.zoom_out_keys
79                                );
80                                let reset_zoom = format!(
81                                    "{:?}: Reset zoom",
82                                    controls.reset_zoom_key
83                                );
84                                let toggle_fit = format!(
85                                    "{:?}: Toggle fit",
86                                    controls.toggle_fit_key
87                                );
88
89                                render_section(
90                                    ui,
91                                    "Zoom",
92                                    &[
93                                        "Mouse Wheel",
94                                        &zoom_in_keys,
95                                        &zoom_out_keys,
96                                        &reset_zoom,
97                                        &toggle_fit,
98                                    ],
99                                    config,
100                                    heading_size,
101                                )
102                            });
103
104                            columns[2].vertical(|ui| {
105                                let help_text = format!(
106                                    "{:?}: Toggle help",
107                                    controls.help_key
108                                );
109                                let quit_text =
110                                    format!("{:?}: Quit", controls.quit_key);
111                                let delete_text =
112                                    format!("{:?}: Delete file", controls.delete_key);
113
114                                render_section(
115                                    ui,
116                                    "Other",
117                                    &[&help_text, &quit_text, &delete_text],
118                                    config,
119                                    heading_size,
120                                )
121                            });
122                        });
123                    });
124            });
125    }
126}
127
128fn render_section(
129    ui: &mut egui::Ui,
130    title: &str,
131    items: &[&str],
132    config: &HelpMenuConfig,
133    heading_size: f32,
134) {
135    ui.heading(
136        egui::RichText::new(title)
137            .color(Color32::from_rgba_unmultiplied(
138                config.text_color.r,
139                config.text_color.g,
140                config.text_color.b,
141                config.text_color.a,
142            ))
143            .size(heading_size),
144    );
145
146    ui.add_space(config.font_size as f32 * 0.5);
147
148    let text_color = Color32::from_rgba_unmultiplied(
149        config.text_color.r,
150        config.text_color.g,
151        config.text_color.b,
152        config.text_color.a,
153    );
154
155    for item in items {
156        ui.label(
157            egui::RichText::new(*item)
158                .color(text_color)
159                .size(config.font_size as f32),
160        );
161    }
162}