feat(menu): add header menu component

This commit is contained in:
doryan 2024-08-16 23:23:09 +04:00
parent e6a38f3ffe
commit 5f544f4fe5
2 changed files with 82 additions and 0 deletions

View File

@ -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<T> {
model: Menu,
actions_group: (SimpleActionGroup, Option<T>),
button: MenuButton,
}
impl<T> HeaderMenu<T>
where
T: Into<String> + 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<T>) {
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<Iterable, F>(&self, items: Iterable)
where
Iterable: IntoIterator<Item = (F, &'static str, &'static str)>,
F: Fn(&SimpleAction, Option<&Variant>) + 'static,
{
for (callback, action_name, action_label) in items {
let action = ActionEntry::<SimpleActionGroup>::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));
}
}
}

View File

@ -1,5 +1,6 @@
pub mod info_bar;
pub mod input;
pub mod menu;
pub mod pages;
pub mod tabs;
pub mod wrapper;