mirror of
https://github.com/italicsjenga/muda.git
synced 2024-12-23 20:11:29 +11:00
add menu item handler on linux
This commit is contained in:
parent
a46c53dbe9
commit
cff1103cf4
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
13
src/lib.rs
13
src/lib.rs
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(>k_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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue