diff --git a/src/view/components/menu.rs b/src/view/components/menu.rs new file mode 100644 index 0000000..fc4c3e8 --- /dev/null +++ b/src/view/components/menu.rs @@ -0,0 +1,81 @@ +use std::fmt::{Debug, Display}; + +use gtk4 as gtk; + +use gio::{ + glib::Variant, prelude::ActionMapExtManual, ActionEntry, Menu, SimpleAction, SimpleActionGroup, +}; + +use gtk::{MenuButton, PopoverMenu}; + +pub struct HeaderMenu { + model: Menu, + actions_group: (SimpleActionGroup, Option), + button: MenuButton, +} + +impl HeaderMenu +where + T: Into + Debug + Display + Clone, +{ + pub fn new() -> Self { + let menu_btn = MenuButton::builder().icon_name("open-menu").build(); + let menu_model = Menu::new(); + let menu_popover = PopoverMenu::from_model(Some(&menu_model)); + + menu_btn.set_popover(Some(&menu_popover)); + + let action_group = SimpleActionGroup::new(); + + Self { + model: menu_model, + actions_group: (action_group, None), + button: menu_btn, + } + } + + #[inline] + pub fn set_action_group_name(&mut self, name: Option) { + self.actions_group.1 = name; + } + + #[inline] + pub fn get_button(&self) -> &MenuButton { + &self.button + } + + #[inline] + pub fn get_model(&self) -> &Menu { + &self.model + } + + #[inline] + pub fn get_actions_group(&self) -> &SimpleActionGroup { + &self.actions_group.0 + } + + pub fn append_items(&self, items: Iterable) + where + Iterable: IntoIterator, + F: Fn(&SimpleAction, Option<&Variant>) + 'static, + { + for (callback, action_name, action_label) in items { + let action = ActionEntry::::builder(action_name) + .activate(move |_, a, b| callback(a, b)) + .build(); + + let action_path = &*format!( + "{}.{}", + self.actions_group + .1 + .clone() + .expect("ActionGroupName isn't defined"), + action_name + ); + + self.actions_group.0.add_action_entries([action]); + + self.model.append(Some(action_label), Some(action_path)); + } + } +} diff --git a/src/view/components/mod.rs b/src/view/components/mod.rs index 331e707..3c345bd 100644 --- a/src/view/components/mod.rs +++ b/src/view/components/mod.rs @@ -1,5 +1,6 @@ pub mod info_bar; pub mod input; +pub mod menu; pub mod pages; pub mod tabs; pub mod wrapper;