add menu item handler on linux

This commit is contained in:
amrbashir 2022-05-05 17:04:48 +02:00
parent a46c53dbe9
commit cff1103cf4
No known key found for this signature in database
GPG key ID: BBD7A47A2003FF33
4 changed files with 56 additions and 47 deletions

View file

@ -17,12 +17,15 @@ fn main() {
let mut file_menu = menu_bar.add_submenu("File", true);
let mut edit_menu = menu_bar.add_submenu("Edit", true);
let _open_item = file_menu.add_text_item("Open", true);
let mut save_item = file_menu.add_text_item("Save", true);
let _quit_item = file_menu.add_text_item("Quit", true);
let _open_item = file_menu.add_text_item("Open", true, |_| {});
let _save_item = file_menu.add_text_item("Save", true, |i| {
i.set_enabled(false);
i.set_label("Save disabled");
});
let _quit_item = file_menu.add_text_item("Quit", true, |_| {});
let _copy_item = edit_menu.add_text_item("Copy", true);
let _cut_item = edit_menu.add_text_item("Cut", true);
let _copy_item = edit_menu.add_text_item("Copy", true, |_| {});
let _cut_item = edit_menu.add_text_item("Cut", true, |_| {});
#[cfg(target_os = "windows")]
menu_bar.init_for_hwnd(window.hwnd() as _);
@ -38,10 +41,7 @@ fn main() {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
save_item.set_enabled(false);
save_item.set_label("Save disabled");
}
} => *control_flow = ControlFlow::Exit,
Event::MainEventsCleared => {
window.request_redraw();
}

View file

@ -14,12 +14,15 @@ fn main() {
let mut file_menu = menu_bar.add_submenu("File", true);
let mut edit_menu = menu_bar.add_submenu("Edit", true);
let _open_item = file_menu.add_text_item("Open", true);
let mut save_item = file_menu.add_text_item("Save", true);
let _quit_item = file_menu.add_text_item("Quit", true);
let _open_item = file_menu.add_text_item("Open", true, |_| {});
let _save_item = file_menu.add_text_item("Save", true, |i| {
i.set_enabled(false);
i.set_label("Save disabled");
});
let _quit_item = file_menu.add_text_item("Quit", true, |_| {});
let _copy_item = edit_menu.add_text_item("Copy", true);
let _cut_item = edit_menu.add_text_item("Cut", true);
let _copy_item = edit_menu.add_text_item("Copy", true, |_| {});
let _cut_item = edit_menu.add_text_item("Cut", true, |_| {});
#[cfg(target_os = "windows")]
menu_bar.init_for_hwnd(window.hwnd() as _);
@ -31,9 +34,7 @@ fn main() {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
save_item.set_enabled(false);
}
} => *control_flow = ControlFlow::Exit,
Event::MainEventsCleared => {
window.request_redraw();
}

View file

@ -12,10 +12,6 @@ impl Menu {
Submenu(self.0.add_submenu(label, enabled))
}
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
TextMenuItem(self.0.add_text_item(label, enabled))
}
#[cfg(target_os = "linux")]
pub fn init_for_gtk_window<W>(&self, w: &W)
where
@ -40,8 +36,13 @@ impl Submenu {
Submenu(self.0.add_submenu(label, enabled))
}
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
TextMenuItem(self.0.add_text_item(label, enabled))
pub fn add_text_item<F: FnMut(&mut TextMenuItem) + 'static>(
&mut self,
label: impl AsRef<str>,
enabled: bool,
f: F,
) -> TextMenuItem {
TextMenuItem(self.0.add_text_item(label, enabled, f))
}
}

View file

@ -1,5 +1,5 @@
use parking_lot::Mutex;
use std::sync::Arc;
use std::{cell::RefCell, rc::Rc, sync::Arc};
use gtk::{prelude::*, Orientation};
@ -17,6 +17,8 @@ struct MenuEntry {
enabled: bool,
entries: Option<Vec<Arc<Mutex<MenuEntry>>>>,
etype: MenuEntryType,
item_handler: Option<Rc<RefCell<dyn FnMut(&mut crate::TextMenuItem) + 'static>>>,
item_id: Option<u64>,
menu_gtk_items: Option<Arc<Mutex<Vec<(gtk::MenuItem, gtk::Menu)>>>>,
item_gtk_items: Option<Arc<Mutex<Vec<gtk::MenuItem>>>>,
}
@ -44,6 +46,8 @@ impl Menu {
enabled,
entries: Some(Vec::new()),
etype: MenuEntryType::Submenu,
item_handler: None,
item_id: None,
menu_gtk_items: Some(gtk_items.clone()),
item_gtk_items: None,
}));
@ -56,27 +60,6 @@ impl Menu {
}
}
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
let label = label.as_ref().to_string();
let gtk_items = Arc::new(Mutex::new(Vec::new()));
let entry = Arc::new(Mutex::new(MenuEntry {
label: label.clone(),
enabled,
entries: None,
etype: MenuEntryType::Text,
menu_gtk_items: None,
item_gtk_items: Some(gtk_items.clone()),
}));
self.0.lock().entries.push(entry.clone());
TextMenuItem {
label,
enabled,
entry,
gtk_items,
id: COUNTER.next(),
}
}
pub fn init_for_gtk_window<W>(&self, w: &W)
where
W: IsA<gtk::Container>,
@ -95,6 +78,7 @@ impl Menu {
fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(gtk_menu: &M, entries: &Vec<Arc<Mutex<MenuEntry>>>) {
for entry in entries {
let entry_clone = entry.clone();
let mut entry = entry.lock();
let gtk_item = gtk::MenuItem::with_label(&entry.label);
gtk_menu.append(&gtk_item);
@ -110,6 +94,19 @@ fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(gtk_menu: &M, entries: &Vec<Arc<M
.lock()
.push((gtk_item, gtk_menu));
} else {
let handler = Rc::clone(&entry.item_handler.as_mut().unwrap());
let item = TextMenuItem {
label: entry.label.clone(),
enabled: entry.enabled,
id: entry.item_id.unwrap(),
entry: entry_clone,
gtk_items: entry.item_gtk_items.as_ref().unwrap().clone(),
};
gtk_item.connect_activate(move |_| {
let mut handler = handler.borrow_mut();
let mut item = crate::TextMenuItem(item.clone());
handler(&mut item);
});
entry.item_gtk_items.as_mut().unwrap().lock().push(gtk_item);
}
}
@ -151,6 +148,8 @@ impl Submenu {
enabled,
entries: Some(Vec::new()),
etype: MenuEntryType::Submenu,
item_handler: None,
item_id: None,
menu_gtk_items: Some(gtk_items.clone()),
item_gtk_items: None,
}));
@ -168,7 +167,13 @@ impl Submenu {
}
}
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
pub fn add_text_item<F: FnMut(&mut crate::TextMenuItem) + 'static>(
&mut self,
label: impl AsRef<str>,
enabled: bool,
f: F,
) -> TextMenuItem {
let id = COUNTER.next();
let label = label.as_ref().to_string();
let gtk_items = Arc::new(Mutex::new(Vec::new()));
let entry = Arc::new(Mutex::new(MenuEntry {
@ -176,6 +181,8 @@ impl Submenu {
enabled,
entries: None,
etype: MenuEntryType::Text,
item_handler: Some(Rc::new(RefCell::new(f))),
item_id: Some(id),
menu_gtk_items: None,
item_gtk_items: Some(gtk_items.clone()),
}));
@ -190,7 +197,7 @@ impl Submenu {
enabled,
entry,
gtk_items,
id: COUNTER.next(),
id,
}
}
}