Skip to content

Commit

Permalink
Export more internals so muda can be used in combination with ksni
Browse files Browse the repository at this point in the history
  • Loading branch information
dfaust committed Nov 1, 2024
1 parent cea276a commit 61c3f3e
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 50 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ features = [
[target.'cfg(target_os = "linux")'.dependencies]
gtk = "0.18"
libxdo = { version = "0.6.0", optional = true }
png = "0.17"

[target.'cfg(target_os = "macos")'.dependencies]
objc2 = "0.5.2"
Expand Down
12 changes: 12 additions & 0 deletions src/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ impl Icon {
let win_icon = PlatformIcon::from_resource(ordinal, size)?;
Ok(Icon { inner: win_icon })
}

/// Convert the icon into a GTK pixbuf object.
#[cfg(target_os = "linux")]
pub fn to_pixbuf(&self) -> gtk::gdk_pixbuf::Pixbuf {
self.inner.to_pixbuf()
}

/// Convert the icon into PNG.
#[cfg(target_os = "linux")]
pub fn to_png(&self) -> Vec<u8> {
self.inner.to_png()
}
}

/// A native Icon to be used for the menu item
Expand Down
15 changes: 10 additions & 5 deletions src/items/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,24 +145,24 @@ impl IconMenuItem {
&self.id
}

/// Get the text for this check menu item.
/// Get the text for this menu item.
pub fn text(&self) -> String {
self.inner.borrow().text()
}

/// Set the text for this check menu item. `text` could optionally contain
/// Set the text for this menu item. `text` could optionally contain
/// an `&` before a character to assign this character as the mnemonic
/// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
/// for this menu item. To display a `&` without assigning a mnemenonic, use `&&`.
pub fn set_text<S: AsRef<str>>(&self, text: S) {
self.inner.borrow_mut().set_text(text.as_ref())
}

/// Get whether this check menu item is enabled or not.
/// Get whether this menu item is enabled or not.
pub fn is_enabled(&self) -> bool {
self.inner.borrow().is_enabled()
}

/// Enable or disable this check menu item.
/// Enable or disable this menu item.
pub fn set_enabled(&self, enabled: bool) {
self.inner.borrow_mut().set_enabled(enabled)
}
Expand All @@ -172,6 +172,11 @@ impl IconMenuItem {
self.inner.borrow_mut().set_accelerator(accelerator)
}

/// Get the icon for this menu item.
pub fn icon(&self) -> Option<Icon> {
self.inner.borrow().icon.clone()
}

/// Change this menu item icon or remove it.
pub fn set_icon(&self, icon: Option<Icon>) {
self.inner.borrow_mut().set_icon(icon)
Expand Down
7 changes: 6 additions & 1 deletion src/items/predefined.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ impl IsMenuItem for PredefinedMenuItem {
}

impl PredefinedMenuItem {
/// The type of predefined menu item
pub fn predefined_item_type(&self) -> Option<PredefinedMenuItemType> {
self.inner.borrow().predefined_item_type.clone()
}

/// Separator menu item
pub fn separator() -> PredefinedMenuItem {
PredefinedMenuItem::new::<&str>(PredefinedMenuItemType::Separator, None)
Expand Down Expand Up @@ -241,7 +246,7 @@ fn test_about_metadata() {
#[derive(Debug, Clone)]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
pub(crate) enum PredefinedMenuItemType {
pub enum PredefinedMenuItemType {
Separator,
Copy,
Cut,
Expand Down
4 changes: 4 additions & 0 deletions src/items/submenu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ impl ContextMenu for Submenu {
self.inner.borrow_mut().gtk_context_menu()
}

fn items(&self) -> Vec<MenuItemKind> {
self.inner.borrow_mut().items()
}

#[cfg(target_os = "macos")]
unsafe fn show_context_menu_for_nsview(
&self,
Expand Down
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ pub use items::*;
pub use menu::*;
pub use menu_id::MenuId;

#[cfg(target_os = "linux")]
pub use platform_impl::AboutDialog;

/// An enumeration of all available menu types, useful to match against
/// the items returned from [`Menu::items`] or [`Submenu::items`]
#[derive(Clone)]
Expand Down Expand Up @@ -350,6 +353,9 @@ pub trait ContextMenu {
#[cfg(target_os = "linux")]
fn gtk_context_menu(&self) -> gtk::Menu;

/// Get all menu items as a vector of `MenuItemKind` elements.
fn items(&self) -> Vec<MenuItemKind>;

/// Shows this menu as a context menu for the specified `NSView`.
///
/// - `position` is relative to the window top-left corner, if `None`, the cursor position is used.
Expand Down Expand Up @@ -417,7 +423,7 @@ impl MenuEvent {
}
}

pub(crate) fn send(event: MenuEvent) {
pub fn send(event: MenuEvent) {
if let Some(handler) = MENU_EVENT_HANDLER.get_or_init(|| None) {
handler(event);
} else {
Expand Down
4 changes: 4 additions & 0 deletions src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ impl ContextMenu for Menu {
self.inner.borrow_mut().gtk_context_menu()
}

fn items(&self) -> Vec<MenuItemKind> {
self.inner.borrow_mut().items()
}

#[cfg(target_os = "macos")]
unsafe fn show_context_menu_for_nsview(
&self,
Expand Down
56 changes: 56 additions & 0 deletions src/platform_impl/gtk/about_dialog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use gtk::prelude::*;

use crate::AboutMetadata;

/// Displays an about dialog using GTK with the provided metadata.
pub struct AboutDialog {
metadata: AboutMetadata,
}

impl AboutDialog {
/// Create a new about dialog using `metadata` but without showing it.
pub fn new(metadata: AboutMetadata) -> AboutDialog {
AboutDialog { metadata }
}

/// Show the about dialog and block until it is closed.
pub fn show(&self) {
let mut builder = gtk::AboutDialog::builder().modal(true).resizable(false);

if let Some(name) = &self.metadata.name {
builder = builder.program_name(name);
}
if let Some(version) = &self.metadata.full_version() {
builder = builder.version(version);
}
if let Some(authors) = &self.metadata.authors {
builder = builder.authors(authors.clone());
}
if let Some(comments) = &self.metadata.comments {
builder = builder.comments(comments);
}
if let Some(copyright) = &self.metadata.copyright {
builder = builder.copyright(copyright);
}
if let Some(license) = &self.metadata.license {
builder = builder.license(license);
}
if let Some(website) = &self.metadata.website {
builder = builder.website(website);
}
if let Some(website_label) = &self.metadata.website_label {
builder = builder.website_label(website_label);
}
if let Some(icon) = &self.metadata.icon {
builder = builder.logo(&icon.to_pixbuf());
}

let about = builder.build();

about.run();

unsafe {
about.destroy();
}
}
}
18 changes: 18 additions & 0 deletions src/platform_impl/gtk/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright 2021-2022 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0

use std::io::Cursor;

use gtk::gdk_pixbuf::{Colorspace, Pixbuf};

use crate::icon::BadIcon;
Expand Down Expand Up @@ -62,4 +64,20 @@ impl PlatformIcon {
.scale_simple(w, h, gtk::gdk_pixbuf::InterpType::Bilinear)
.unwrap()
}

pub fn to_png(&self) -> Vec<u8> {
let mut png = Vec::new();

{
let mut encoder =
png::Encoder::new(Cursor::new(&mut png), self.width as _, self.height as _);
encoder.set_color(png::ColorType::Rgba);
encoder.set_depth(png::BitDepth::Eight);

let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&self.raw).unwrap();
}

png
}
}
46 changes: 7 additions & 39 deletions src/platform_impl/gtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

mod about_dialog;
mod accelerator;
mod icon;

pub use about_dialog::AboutDialog;
pub(crate) use icon::PlatformIcon;

use crate::{
Expand All @@ -17,7 +19,7 @@ use crate::{
};
use accelerator::{from_gtk_mnemonic, parse_accelerator, to_gtk_mnemonic};
use glib::translate::ToGlibPtr;
use gtk::{gdk, glib, prelude::*, AboutDialog, Container, Orientation};
use gtk::{gdk, glib, prelude::*, Container, Orientation};
use std::{
cell::RefCell,
collections::{hash_map::Entry, HashMap},
Expand Down Expand Up @@ -408,14 +410,14 @@ pub struct MenuChild {
gtk_accelerator: Option<(gdk::ModifierType, u32)>,

// predefined menu item fields
predefined_item_type: Option<PredefinedMenuItemType>,
pub(crate) predefined_item_type: Option<PredefinedMenuItemType>,

// check menu item fields
checked: Option<Rc<AtomicBool>>,
is_syncing_checked_state: Option<Rc<AtomicBool>>,

// icon menu item fields
icon: Option<Icon>,
pub(crate) icon: Option<Icon>,

// submenu fields
pub children: Option<Vec<Rc<RefCell<MenuChild>>>>,
Expand Down Expand Up @@ -1144,42 +1146,8 @@ impl MenuChild {
let item = make_item();
register_accel(&item);
item.connect_activate(move |_| {
if let Some(metadata) = &metadata {
let mut builder = AboutDialog::builder().modal(true).resizable(false);

if let Some(name) = &metadata.name {
builder = builder.program_name(name);
}
if let Some(version) = &metadata.full_version() {
builder = builder.version(version);
}
if let Some(authors) = &metadata.authors {
builder = builder.authors(authors.clone());
}
if let Some(comments) = &metadata.comments {
builder = builder.comments(comments);
}
if let Some(copyright) = &metadata.copyright {
builder = builder.copyright(copyright);
}
if let Some(license) = &metadata.license {
builder = builder.license(license);
}
if let Some(website) = &metadata.website {
builder = builder.website(website);
}
if let Some(website_label) = &metadata.website_label {
builder = builder.website_label(website_label);
}
if let Some(icon) = &metadata.icon {
builder = builder.logo(&icon.inner.to_pixbuf());
}

let about = builder.build();
about.run();
unsafe {
about.destroy();
}
if let Some(metadata) = metadata.clone() {
AboutDialog::new(metadata).show();
}
});
item
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ pub struct MenuChild {
accelerator: Option<Accelerator>,

// predefined menu item fields
predefined_item_type: Option<PredefinedMenuItemType>,
pub(crate) predefined_item_type: Option<PredefinedMenuItemType>,

// check menu item fields
checked: Cell<bool>,

// icon menu item fields
icon: Option<Icon>,
pub(crate) icon: Option<Icon>,
native_icon: Option<NativeIcon>,

// submenu fields
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ mod platform;
#[path = "macos/mod.rs"]
mod platform;

#[cfg(target_os = "linux")]
pub use platform::AboutDialog;

use std::{
cell::{Ref, RefCell, RefMut},
rc::Rc,
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,13 +450,13 @@ pub(crate) struct MenuChild {
accelerator: Option<Accelerator>,

// predefined menu item fields
predefined_item_type: Option<PredefinedMenuItemType>,
pub(crate) predefined_item_type: Option<PredefinedMenuItemType>,

// check menu item fields
checked: bool,

// icon menu item fields
icon: Option<Icon>,
pub(crate) icon: Option<Icon>,

// submenu fields
hmenu: HMENU,
Expand Down

0 comments on commit 61c3f3e

Please sign in to comment.