|
|
|
@ -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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|