grx/gtk_components/
menu.rs1use self::menu_item::MenuItem;
6use crate::{new_gc, props};
7use glib::prelude::Cast;
8use grx_macros::gtk_component;
9use gtk::glib;
10use gtk::prelude::WidgetExt;
11use std::rc::Rc;
12
13use super::gtk_props::apply;
14
15#[props]
16#[derive(Default, Debug)]
17pub struct Props {
18 pub items: Vec<MenuItem>,
19}
20
21pub fn menu(mut props: Props) -> Rc<Menu> {
22 let model = gtk::gio::Menu::new();
23 for item in &props.items {
24 model.append(Some(&item.label), item.action.as_deref());
25 }
26 let menu = gtk::PopoverMenu::from_model(Some(&model));
27 let widget = menu.upcast();
28 let comp = new_gc!(Menu { widget, props });
29 apply(comp.clone());
30 comp
31}
32
33#[gtk_component(gtk::Widget)]
34#[derive(Debug)]
35pub struct Menu {}
36
37impl Menu {
38 pub fn show(self: &Rc<Self>) {
39 self.widget.set_visible(true);
40 }
41}
42
43pub mod menu_item {
44 use gstore::Actionable;
45
46 pub fn menu_item(label: String, action: Option<impl Actionable>) -> MenuItem {
47 MenuItem {
48 label,
49 action: action.map(|s| format!("app.{}", s.name())),
50 }
51 }
52
53 #[derive(Debug, Clone)]
54 pub struct MenuItem {
55 pub label: String,
56 pub action: Option<String>,
57 }
58}