use gtk::glib::Cast;
use gtk::prelude::{GtkMenuExt, GtkMenuExtManual, GtkMenuItemExt, IsA, MenuShellExt, WidgetExt};
use std::borrow::Cow;
pub struct Menu {
inner: gtk::Menu,
buttons: Vec<gtk::MenuItem>,
title: Option<Cow<'static, str>>,
}
impl Menu {
pub fn new() -> Self {
Self {
inner: gtk::Menu::builder().take_focus(true).visible(true).build(),
buttons: vec![],
title: None,
}
}
pub fn attach_to_widget(self, widget: &impl IsA<gtk::Widget>) -> Self {
self.inner.set_attach_widget(Some(widget.upcast_ref()));
self
}
pub fn title(mut self, title: Option<Cow<'static, str>>) -> Self {
self.title = title;
if let Some(title) = self.title.as_ref() {
let name = gtk::MenuItem::builder()
.label(title.as_ref())
.sensitive(false)
.visible(true)
.build();
self.inner.append(&name);
}
self
}
pub fn separator(self) -> Self {
self.inner
.append(>k::SeparatorMenuItem::builder().visible(true).build());
self
}
pub fn add_button(mut self, label: &str) -> Self {
let button: gtk::MenuItem = gtk::MenuItem::with_label(label);
button.set_sensitive(false);
self.inner.append(&button);
self.buttons.push(button);
self
}
pub fn add_button_cb<F>(mut self, label: &str, callback: F) -> Self
where
F: Fn(>k::MenuItem) + 'static,
{
let button: gtk::MenuItem = gtk::MenuItem::builder()
.label(label)
.sensitive(true)
.visible(true)
.build();
button.connect_activate(callback);
self.inner.append(&button);
self.buttons.push(button);
self
}
pub fn popup(&self, activate_time: u32) {
self.inner.show_all();
self.inner
.popup_easy(gtk::gdk::BUTTON_PRIMARY, activate_time);
}
}
impl Default for Menu {
fn default() -> Self {
Self::new()
}
}