mirror of
https://github.com/italicsjenga/muda.git
synced 2025-01-11 04:11:32 +11:00
refactor(linux): combine r#type
and native_*
into sum type
This commit is contained in:
parent
7520e19645
commit
421b00f597
|
@ -323,7 +323,7 @@ impl TextMenuItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub enum NativeMenuItem {
|
pub enum NativeMenuItem {
|
||||||
/// A native “About” menu item.
|
/// A native “About” menu item.
|
||||||
///
|
///
|
||||||
|
@ -427,7 +427,7 @@ pub enum NativeMenuItem {
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **macOS**: The metadata is ignored.
|
/// - **macOS**: The metadata is ignored.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(PartialEq, Eq, Debug, Clone, Default)]
|
||||||
pub struct AboutMetadata {
|
pub struct AboutMetadata {
|
||||||
/// The application name.
|
/// The application name.
|
||||||
pub version: Option<String>,
|
pub version: Option<String>,
|
||||||
|
|
|
@ -8,34 +8,25 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
static COUNTER: Counter = Counter::new();
|
static COUNTER: Counter = Counter::new();
|
||||||
|
|
||||||
/// Generic shared type describing a menu entry. It can be one of [`MenuEntryType`]
|
/// Generic shared type describing a menu entry. It can be one of [`MenuEntryType`]
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
struct MenuEntry {
|
struct MenuEntry {
|
||||||
label: String,
|
label: String,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
r#type: MenuEntryType,
|
r#type: MenuEntryType,
|
||||||
item_id: Option<u64>,
|
item_id: Option<u64>,
|
||||||
accelerator: Option<String>,
|
accelerator: Option<String>,
|
||||||
native_menu_item: Option<NativeMenuItem>,
|
|
||||||
// NOTE(amrbashir): because gtk doesn't allow using the same [`gtk::MenuItem`]
|
|
||||||
// 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`] if its a menu
|
|
||||||
// and push to it every time [`Menu::init_for_gtk_window`] is called.
|
|
||||||
native_items: Option<Vec<gtk::MenuItem>>,
|
|
||||||
native_menus: Option<Vec<(gtk::MenuItem, gtk::Menu)>>,
|
|
||||||
entries: Option<Vec<Rc<RefCell<MenuEntry>>>>,
|
entries: Option<Vec<Rc<RefCell<MenuEntry>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
enum MenuEntryType {
|
enum MenuEntryType {
|
||||||
Submenu,
|
// NOTE(amrbashir): because gtk doesn't allow using the same [`gtk::MenuItem`]
|
||||||
Text,
|
// multiple times, and thus can't be used in multiple windows, each entry
|
||||||
Native,
|
// keeps a vector of a [`gtk::MenuItem`] or a tuple of [`gtk::MenuItem`] and [`gtk::Menu`] if its a menu
|
||||||
}
|
// and push to it every time [`Menu::init_for_gtk_window`] is called.
|
||||||
|
Submenu(Vec<(gtk::MenuItem, gtk::Menu)>),
|
||||||
impl Default for MenuEntryType {
|
Text(Vec<gtk::MenuItem>),
|
||||||
fn default() -> Self {
|
Native(NativeMenuItem),
|
||||||
MenuEntryType::Text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InnerMenu {
|
struct InnerMenu {
|
||||||
|
@ -67,9 +58,9 @@ impl Menu {
|
||||||
label: label.clone(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu(Vec::new()),
|
||||||
native_menus: Some(Vec::new()),
|
item_id: Default::default(),
|
||||||
..Default::default()
|
accelerator: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut inner = self.0.borrow_mut();
|
let mut inner = self.0.borrow_mut();
|
||||||
|
@ -77,12 +68,10 @@ impl Menu {
|
||||||
if let Some(menu_bar) = menu_bar {
|
if let Some(menu_bar) = menu_bar {
|
||||||
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
||||||
menu_bar.append(&item);
|
menu_bar.append(&item);
|
||||||
entry
|
let mut native_menus = entry.borrow_mut();
|
||||||
.borrow_mut()
|
if let MenuEntryType::Submenu(m) = &mut native_menus.r#type {
|
||||||
.native_menus
|
m.push((item, submenu));
|
||||||
.as_mut()
|
}
|
||||||
.unwrap()
|
|
||||||
.push((item, submenu));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +188,11 @@ impl Submenu {
|
||||||
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.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for (item, _) in entry.native_menus.as_ref().unwrap() {
|
if let MenuEntryType::Submenu(native_menus) = &mut entry.r#type {
|
||||||
|
for (item, _) in native_menus {
|
||||||
item.set_label(&to_gtk_menemenoic(&label));
|
item.set_label(&to_gtk_menemenoic(&label));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,10 +203,12 @@ impl Submenu {
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
entry.enabled = true;
|
entry.enabled = true;
|
||||||
for (item, _) in entry.native_menus.as_ref().unwrap() {
|
if let MenuEntryType::Submenu(native_menus) = &mut entry.r#type {
|
||||||
|
for (item, _) in native_menus {
|
||||||
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 label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
|
@ -224,21 +217,20 @@ impl Submenu {
|
||||||
label: label.clone(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu(Vec::new()),
|
||||||
native_menus: Some(Vec::new()),
|
item_id: Default::default(),
|
||||||
..Default::default()
|
accelerator: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut inner = self.0.borrow_mut();
|
let mut inner = self.0.borrow_mut();
|
||||||
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
if let MenuEntryType::Submenu(native_menus) = &mut inner.r#type {
|
||||||
|
for (_, menu) in native_menus {
|
||||||
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
||||||
menu.append(&item);
|
menu.append(&item);
|
||||||
entry
|
if let MenuEntryType::Submenu(menus) = &mut entry.borrow_mut().r#type {
|
||||||
.borrow_mut()
|
menus.push((item, submenu));
|
||||||
.native_menus
|
}
|
||||||
.as_mut()
|
}
|
||||||
.unwrap()
|
|
||||||
.push((item, submenu));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.entries.as_mut().unwrap().push(entry.clone());
|
inner.entries.as_mut().unwrap().push(entry.clone());
|
||||||
|
@ -257,16 +249,16 @@ impl Submenu {
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.clone(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
r#type: MenuEntryType::Text,
|
r#type: MenuEntryType::Text(Vec::new()),
|
||||||
item_id: Some(id),
|
item_id: Some(id),
|
||||||
accelerator: accelerator.map(|s| s.to_string()),
|
accelerator: accelerator.map(|s| s.to_string()),
|
||||||
native_items: Some(Vec::new()),
|
entries: None,
|
||||||
..Default::default()
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut inner = self.0.borrow_mut();
|
let mut inner = self.0.borrow_mut();
|
||||||
|
|
||||||
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
if let MenuEntryType::Submenu(native_menus) = &mut inner.r#type {
|
||||||
|
for (_, menu) in native_menus {
|
||||||
let item = create_gtk_text_menu_item(
|
let item = create_gtk_text_menu_item(
|
||||||
&label,
|
&label,
|
||||||
enabled,
|
enabled,
|
||||||
|
@ -275,7 +267,10 @@ impl Submenu {
|
||||||
&*self.1,
|
&*self.1,
|
||||||
);
|
);
|
||||||
menu.append(&item);
|
menu.append(&item);
|
||||||
entry.borrow_mut().native_items.as_mut().unwrap().push(item);
|
if let MenuEntryType::Text(native_items) = &mut entry.borrow_mut().r#type {
|
||||||
|
native_items.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.entries.as_mut().unwrap().push(entry.clone());
|
inner.entries.as_mut().unwrap().push(entry.clone());
|
||||||
|
@ -285,14 +280,19 @@ impl Submenu {
|
||||||
pub fn add_native_item(&mut self, item: NativeMenuItem) {
|
pub fn add_native_item(&mut self, item: NativeMenuItem) {
|
||||||
let mut inner = self.0.borrow_mut();
|
let mut inner = self.0.borrow_mut();
|
||||||
|
|
||||||
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
if let MenuEntryType::Submenu(native_menus) = &mut inner.r#type {
|
||||||
|
for (_, menu) in native_menus {
|
||||||
item.add_to_gtk_menu(menu);
|
item.add_to_gtk_menu(menu);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
r#type: MenuEntryType::Native,
|
r#type: MenuEntryType::Native(item),
|
||||||
native_menu_item: Some(item),
|
label: Default::default(),
|
||||||
..Default::default()
|
enabled: Default::default(),
|
||||||
|
item_id: Default::default(),
|
||||||
|
accelerator: Default::default(),
|
||||||
|
entries: Default::default(),
|
||||||
}));
|
}));
|
||||||
inner.entries.as_mut().unwrap().push(entry);
|
inner.entries.as_mut().unwrap().push(entry);
|
||||||
}
|
}
|
||||||
|
@ -309,9 +309,11 @@ impl TextMenuItem {
|
||||||
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.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.native_items.as_ref().unwrap() {
|
if let MenuEntryType::Text(native_items) = &mut entry.r#type {
|
||||||
|
for item in native_items {
|
||||||
item.set_label(&to_gtk_menemenoic(&label));
|
item.set_label(&to_gtk_menemenoic(&label));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,9 +323,11 @@ impl TextMenuItem {
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.native_items.as_ref().unwrap() {
|
if let MenuEntryType::Text(native_items) = &mut entry.r#type {
|
||||||
|
for item in native_items {
|
||||||
item.set_sensitive(enabled);
|
item.set_sensitive(enabled);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
entry.enabled = enabled;
|
entry.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,14 +343,14 @@ fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(
|
||||||
) {
|
) {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let mut entry = entry.borrow_mut();
|
let mut entry = entry.borrow_mut();
|
||||||
match entry.r#type {
|
let (item, submenu) = match &entry.r#type {
|
||||||
MenuEntryType::Submenu => {
|
MenuEntryType::Submenu(_) => {
|
||||||
let (item, submenu) = create_gtk_submenu(&entry.label, entry.enabled);
|
let (item, submenu) = create_gtk_submenu(&entry.label, entry.enabled);
|
||||||
gtk_menu.append(&item);
|
gtk_menu.append(&item);
|
||||||
add_entries_to_menu(&submenu, entry.entries.as_ref().unwrap(), accel_group);
|
add_entries_to_menu(&submenu, entry.entries.as_ref().unwrap(), accel_group);
|
||||||
entry.native_menus.as_mut().unwrap().push((item, submenu));
|
(Some(item), Some(submenu))
|
||||||
}
|
}
|
||||||
MenuEntryType::Text => {
|
MenuEntryType::Text(_) => {
|
||||||
let item = create_gtk_text_menu_item(
|
let item = create_gtk_text_menu_item(
|
||||||
&entry.label,
|
&entry.label,
|
||||||
entry.enabled,
|
entry.enabled,
|
||||||
|
@ -355,14 +359,23 @@ fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(
|
||||||
accel_group,
|
accel_group,
|
||||||
);
|
);
|
||||||
gtk_menu.append(&item);
|
gtk_menu.append(&item);
|
||||||
entry.native_items.as_mut().unwrap().push(item);
|
(Some(item), None)
|
||||||
}
|
}
|
||||||
MenuEntryType::Native => entry
|
MenuEntryType::Native(native_menu_item) => {
|
||||||
.native_menu_item
|
native_menu_item.add_to_gtk_menu(gtk_menu);
|
||||||
.as_ref()
|
(None, None)
|
||||||
.unwrap()
|
|
||||||
.add_to_gtk_menu(gtk_menu),
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match &mut entry.r#type {
|
||||||
|
MenuEntryType::Submenu(native_menus) => {
|
||||||
|
native_menus.push((item.unwrap(), submenu.unwrap()));
|
||||||
|
}
|
||||||
|
MenuEntryType::Text(native_items) => {
|
||||||
|
native_items.push(item.unwrap());
|
||||||
|
}
|
||||||
|
MenuEntryType::Native(_) => {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue