mirror of
https://github.com/italicsjenga/muda.git
synced 2025-01-26 02:56:34 +11:00
refactor(linux): use Rc<RefCell>
instead of Arc<Mutex>
This commit is contained in:
parent
6cb2ce1c7a
commit
68f16f15a3
2 changed files with 55 additions and 39 deletions
|
@ -25,7 +25,6 @@ features = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
parking_lot = "0.12"
|
|
||||||
gtk = "0.15"
|
gtk = "0.15"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
use crate::util::Counter;
|
use crate::util::Counter;
|
||||||
use gtk::{prelude::*, Orientation};
|
use gtk::{prelude::*, Orientation};
|
||||||
use parking_lot::Mutex;
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use std::{rc::Rc, sync::Arc};
|
|
||||||
|
|
||||||
static COUNTER: Counter = Counter::new();
|
static COUNTER: Counter = Counter::new();
|
||||||
|
|
||||||
|
@ -22,13 +21,13 @@ struct MenuEntry {
|
||||||
// multiple times, and thus can't be used in multiple windows, each entry
|
// multiple times, and thus can't be used in multiple windows, each entry
|
||||||
// keeps a vector of a `gtk::MenuItem` or a tuple of `gtk::MenuItem` and `gtk::Menu`
|
// keeps a vector of a `gtk::MenuItem` or a tuple of `gtk::MenuItem` and `gtk::Menu`
|
||||||
// and push to it every time `Menu::init_for_gtk_window` is called.
|
// and push to it every time `Menu::init_for_gtk_window` is called.
|
||||||
item_gtk_items: Option<Arc<Mutex<Vec<gtk::MenuItem>>>>,
|
item_gtk_items: Option<Rc<RefCell<Vec<gtk::MenuItem>>>>,
|
||||||
menu_gtk_items: Option<Arc<Mutex<Vec<(gtk::MenuItem, gtk::Menu)>>>>,
|
menu_gtk_items: Option<Rc<RefCell<Vec<(gtk::MenuItem, gtk::Menu)>>>>,
|
||||||
entries: Option<Vec<Arc<Mutex<MenuEntry>>>>,
|
entries: Option<Vec<Rc<RefCell<MenuEntry>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InnerMenu {
|
struct InnerMenu {
|
||||||
entries: Vec<Arc<Mutex<MenuEntry>>>,
|
entries: Vec<Rc<RefCell<MenuEntry>>>,
|
||||||
// NOTE(amrbashir): because gtk doesn't allow using the same `gtk::MenuBar` and `gtk::Box`
|
// NOTE(amrbashir): because gtk doesn't allow using the same `gtk::MenuBar` and `gtk::Box`
|
||||||
// multiple times, and thus can't be used in multiple windows, entry
|
// multiple times, and thus can't be used in multiple windows, entry
|
||||||
// keeps a vector of a tuple of `gtk::MenuBar` and `gtk::Box`
|
// keeps a vector of a tuple of `gtk::MenuBar` and `gtk::Box`
|
||||||
|
@ -36,11 +35,11 @@ struct InnerMenu {
|
||||||
gtk_items: Vec<(gtk::MenuBar, Rc<gtk::Box>)>,
|
gtk_items: Vec<(gtk::MenuBar, Rc<gtk::Box>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Menu(Arc<Mutex<InnerMenu>>);
|
pub struct Menu(Rc<RefCell<InnerMenu>>);
|
||||||
|
|
||||||
impl Menu {
|
impl Menu {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Arc::new(Mutex::new(InnerMenu {
|
Self(Rc::new(RefCell::new(InnerMenu {
|
||||||
entries: Vec::new(),
|
entries: Vec::new(),
|
||||||
gtk_items: Vec::new(),
|
gtk_items: Vec::new(),
|
||||||
})))
|
})))
|
||||||
|
@ -48,16 +47,16 @@ impl Menu {
|
||||||
|
|
||||||
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
||||||
let label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
let entry = Arc::new(Mutex::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.clone(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu,
|
||||||
item_id: None,
|
item_id: None,
|
||||||
menu_gtk_items: Some(Arc::new(Mutex::new(Vec::new()))),
|
menu_gtk_items: Some(Rc::new(RefCell::new(Vec::new()))),
|
||||||
item_gtk_items: None,
|
item_gtk_items: None,
|
||||||
}));
|
}));
|
||||||
self.0.lock().entries.push(entry.clone());
|
self.0.borrow_mut().entries.push(entry.clone());
|
||||||
Submenu(entry)
|
Submenu(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@ impl Menu {
|
||||||
W: IsA<gtk::Container>,
|
W: IsA<gtk::Container>,
|
||||||
{
|
{
|
||||||
let menu_bar = gtk::MenuBar::new();
|
let menu_bar = gtk::MenuBar::new();
|
||||||
add_entries_to_menu(&menu_bar, &self.0.lock().entries);
|
add_entries_to_menu(&menu_bar, &self.0.borrow().entries);
|
||||||
|
|
||||||
let vbox = gtk::Box::new(Orientation::Vertical, 0);
|
let vbox = gtk::Box::new(Orientation::Vertical, 0);
|
||||||
vbox.pack_start(&menu_bar, false, false, 0);
|
vbox.pack_start(&menu_bar, false, false, 0);
|
||||||
|
@ -76,15 +75,18 @@ impl Menu {
|
||||||
let vbox = Rc::new(vbox);
|
let vbox = Rc::new(vbox);
|
||||||
let vbox_c = Rc::clone(&vbox);
|
let vbox_c = Rc::clone(&vbox);
|
||||||
|
|
||||||
self.0.lock().gtk_items.push((menu_bar, vbox));
|
self.0.borrow_mut().gtk_items.push((menu_bar, vbox));
|
||||||
|
|
||||||
vbox_c
|
vbox_c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(gtk_menu: &M, entries: &Vec<Arc<Mutex<MenuEntry>>>) {
|
fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(
|
||||||
|
gtk_menu: &M,
|
||||||
|
entries: &Vec<Rc<RefCell<MenuEntry>>>,
|
||||||
|
) {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let mut entry = entry.lock();
|
let mut entry = entry.borrow_mut();
|
||||||
let gtk_item = gtk::MenuItem::with_label(&entry.label);
|
let gtk_item = gtk::MenuItem::with_label(&entry.label);
|
||||||
gtk_menu.append(>k_item);
|
gtk_menu.append(>k_item);
|
||||||
gtk_item.set_sensitive(entry.enabled);
|
gtk_item.set_sensitive(entry.enabled);
|
||||||
|
@ -96,106 +98,121 @@ fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(gtk_menu: &M, entries: &Vec<Arc<M
|
||||||
.menu_gtk_items
|
.menu_gtk_items
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lock()
|
.borrow_mut()
|
||||||
.push((gtk_item, gtk_menu));
|
.push((gtk_item, gtk_menu));
|
||||||
} else {
|
} else {
|
||||||
let id = entry.item_id.unwrap_or_default();
|
let id = entry.item_id.unwrap_or_default();
|
||||||
gtk_item.connect_activate(move |_| {
|
gtk_item.connect_activate(move |_| {
|
||||||
let _ = crate::MENU_CHANNEL.0.send(crate::MenuEvent { id });
|
let _ = crate::MENU_CHANNEL.0.send(crate::MenuEvent { id });
|
||||||
});
|
});
|
||||||
entry.item_gtk_items.as_mut().unwrap().lock().push(gtk_item);
|
entry
|
||||||
|
.item_gtk_items
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.push(gtk_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Submenu(Arc<Mutex<MenuEntry>>);
|
pub struct Submenu(Rc<RefCell<MenuEntry>>);
|
||||||
|
|
||||||
impl Submenu {
|
impl Submenu {
|
||||||
pub fn label(&self) -> String {
|
pub fn label(&self) -> String {
|
||||||
self.0.lock().label.clone()
|
self.0.borrow().label.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
let label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
let mut entry = self.0.lock();
|
let mut entry = self.0.borrow_mut();
|
||||||
for (item, _) in entry.menu_gtk_items.as_ref().unwrap().lock().iter() {
|
for (item, _) in entry.menu_gtk_items.as_ref().unwrap().borrow().iter() {
|
||||||
item.set_label(&label);
|
item.set_label(&label);
|
||||||
}
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enabled(&self) -> bool {
|
pub fn enabled(&self) -> bool {
|
||||||
self.0.lock().enabled
|
self.0.borrow().enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.lock();
|
let mut entry = self.0.borrow_mut();
|
||||||
entry.enabled = true;
|
entry.enabled = true;
|
||||||
for (item, _) in entry.menu_gtk_items.as_ref().unwrap().lock().iter() {
|
for (item, _) in entry.menu_gtk_items.as_ref().unwrap().borrow().iter() {
|
||||||
item.set_sensitive(enabled);
|
item.set_sensitive(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
||||||
let entry = Arc::new(Mutex::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.as_ref().to_string(),
|
label: label.as_ref().to_string(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu,
|
||||||
item_id: None,
|
item_id: None,
|
||||||
menu_gtk_items: Some(Arc::new(Mutex::new(Vec::new()))),
|
menu_gtk_items: Some(Rc::new(RefCell::new(Vec::new()))),
|
||||||
item_gtk_items: None,
|
item_gtk_items: None,
|
||||||
}));
|
}));
|
||||||
self.0.lock().entries.as_mut().unwrap().push(entry.clone());
|
self.0
|
||||||
|
.borrow_mut()
|
||||||
|
.entries
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.push(entry.clone());
|
||||||
Submenu(entry)
|
Submenu(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
|
pub fn add_text_item(&mut self, label: impl AsRef<str>, enabled: bool) -> TextMenuItem {
|
||||||
let entry = Arc::new(Mutex::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.as_ref().to_string(),
|
label: label.as_ref().to_string(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: None,
|
entries: None,
|
||||||
r#type: MenuEntryType::Text,
|
r#type: MenuEntryType::Text,
|
||||||
item_id: Some(COUNTER.next()),
|
item_id: Some(COUNTER.next()),
|
||||||
menu_gtk_items: None,
|
menu_gtk_items: None,
|
||||||
item_gtk_items: Some(Arc::new(Mutex::new(Vec::new()))),
|
item_gtk_items: Some(Rc::new(RefCell::new(Vec::new()))),
|
||||||
}));
|
}));
|
||||||
self.0.lock().entries.as_mut().unwrap().push(entry.clone());
|
self.0
|
||||||
|
.borrow_mut()
|
||||||
|
.entries
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.push(entry.clone());
|
||||||
TextMenuItem(entry)
|
TextMenuItem(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TextMenuItem(Arc<Mutex<MenuEntry>>);
|
pub struct TextMenuItem(Rc<RefCell<MenuEntry>>);
|
||||||
|
|
||||||
impl TextMenuItem {
|
impl TextMenuItem {
|
||||||
pub fn label(&self) -> String {
|
pub fn label(&self) -> String {
|
||||||
self.0.lock().label.clone()
|
self.0.borrow().label.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
let label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
let mut entry = self.0.lock();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.item_gtk_items.as_ref().unwrap().lock().iter() {
|
for item in entry.item_gtk_items.as_ref().unwrap().borrow().iter() {
|
||||||
item.set_label(&label);
|
item.set_label(&label);
|
||||||
}
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enabled(&self) -> bool {
|
pub fn enabled(&self) -> bool {
|
||||||
self.0.lock().enabled
|
self.0.borrow().enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.lock();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.item_gtk_items.as_ref().unwrap().lock().iter() {
|
for item in entry.item_gtk_items.as_ref().unwrap().borrow().iter() {
|
||||||
item.set_sensitive(enabled);
|
item.set_sensitive(enabled);
|
||||||
}
|
}
|
||||||
entry.enabled = enabled;
|
entry.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> u64 {
|
pub fn id(&self) -> u64 {
|
||||||
self.0.lock().item_id.unwrap()
|
self.0.borrow().item_id.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue