From cff1103cf4e5789b6e5ef03af6779147c1ee814c Mon Sep 17 00:00:00 2001 From: amrbashir Date: Thu, 5 May 2022 17:04:48 +0200 Subject: [PATCH] add menu item handler on linux --- examples/tao.rs | 18 ++++++------- examples/winit.rs | 17 ++++++------ src/lib.rs | 13 ++++----- src/platform_impl/linux.rs | 55 +++++++++++++++++++++----------------- 4 files changed, 56 insertions(+), 47 deletions(-) diff --git a/examples/tao.rs b/examples/tao.rs index 949759e..25c7d6c 100644 --- a/examples/tao.rs +++ b/examples/tao.rs @@ -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(); } diff --git a/examples/winit.rs b/examples/winit.rs index d3ed363..8c9a9ab 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -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(); } diff --git a/src/lib.rs b/src/lib.rs index d93f8d5..140b00c 100644 --- a/src/lib.rs +++ b/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, enabled: bool) -> TextMenuItem { - TextMenuItem(self.0.add_text_item(label, enabled)) - } - #[cfg(target_os = "linux")] pub fn init_for_gtk_window(&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, enabled: bool) -> TextMenuItem { - TextMenuItem(self.0.add_text_item(label, enabled)) + pub fn add_text_item( + &mut self, + label: impl AsRef, + enabled: bool, + f: F, + ) -> TextMenuItem { + TextMenuItem(self.0.add_text_item(label, enabled, f)) } } diff --git a/src/platform_impl/linux.rs b/src/platform_impl/linux.rs index ec8c514..0bf8b54 100644 --- a/src/platform_impl/linux.rs +++ b/src/platform_impl/linux.rs @@ -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>>>, etype: MenuEntryType, + item_handler: Option>>, + item_id: Option, menu_gtk_items: Option>>>, item_gtk_items: Option>>>, } @@ -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, 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(&self, w: &W) where W: IsA, @@ -95,6 +78,7 @@ impl Menu { fn add_entries_to_menu>(gtk_menu: &M, entries: &Vec>>) { 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>(gtk_menu: &M, entries: &Vec, enabled: bool) -> TextMenuItem { + pub fn add_text_item( + &mut self, + label: impl AsRef, + 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, } } }