egui_menu/
lib.rs

1pub mod menu;
2pub mod model;
3
4pub use model::MenuEntry;
5
6use egui::{Widget, Response, Vec2};
7use menu::Menu;
8
9pub struct Dropdown<'a, T: MenuEntry> {
10    selected: &'a mut usize,
11    entries: &'a Vec<T>, 
12    open: &'a mut bool,
13    dimensions: Option<Vec2>,
14}
15
16impl<'a, T: MenuEntry> Dropdown<'a, T> {
17    pub fn new (buf: &'a mut usize, entries: &'a Vec<T>, open: &'a mut bool) -> Self {
18        Self {
19            selected: buf,
20            entries,
21            open,
22            dimensions: None
23        }
24    }
25
26    pub fn size (&mut self, size: Vec2) {
27        self.dimensions = Some(size);
28    }
29}
30
31impl<'a, T: MenuEntry> Widget for Dropdown<'a, T> {
32    fn ui (self, ui: &mut egui::Ui) -> Response {
33        let open_button = ui.button(self.entries[*self.selected].label());
34
35        let mut open = *self.open ^ open_button.clicked();
36
37        let mut menu = Menu::new(ui.next_widget_position(), |ui| {
38            for (idx, e) in self.entries.iter().enumerate() {
39                let button = ui.button(e.label());
40                if button.clicked() {
41                    *self.selected = idx;
42                    open = false;
43                }
44            }
45        });
46
47        if let Some(size) = self.dimensions {
48            menu.min_size(size);
49        }
50
51        if *self.open {
52            menu.show(ui);
53        }
54
55        *self.open = open;
56
57        open_button
58    }
59}