Skip to content

Commit

Permalink
feat(macos): implement CustomMenuItem::set_icon() (#459)
Browse files Browse the repository at this point in the history
* feat(macos): implement set icon

* refactor: remove set_icon definition from CustomMenuItemExtMacos

* refactor: remove comment

* feat: add set_icon definition to CustomMenuItem

* refactor: remove unused imports

* * fix: change icon parameter type from Vec<u8> to Icon
* refactor: use crate::icon::Icon instead of crate::system_tray::Icon

* refactor: update set_icon definition for ios and android

* refactor: Icon import

* add change file
  • Loading branch information
ahkohd committed Jul 7, 2022
1 parent 286ee65 commit 13f9f18
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changes/set_icon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": patch
---

Add `CustomMenuItem::set_icon`. Only implemented on macOS for now.
15 changes: 10 additions & 5 deletions examples/system_tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
fn main() {
#[cfg(target_os = "linux")]
use tao::platform::linux::SystemTrayBuilderExtLinux;
#[cfg(target_os = "macos")]
use tao::platform::macos::{CustomMenuItemExtMacOS, NativeImage, SystemTrayBuilderExtMacOS};
use tao::{
event::Event,
event_loop::{ControlFlow, EventLoop},
Expand All @@ -20,9 +18,6 @@ fn main() {
env_logger::init();
let event_loop = EventLoop::new();

let mut tray_menu = Menu::new();
let quit = tray_menu.add_item(MenuItemAttributes::new("Quit"));

// You'll have to choose an icon size at your own discretion. On Linux, the icon should be
// provided in whatever size it was naturally drawn; that is, don’t scale the image before passing
// it to Tao. But on Windows, you will have to account for screen scaling. Here we use 32px,
Expand All @@ -31,6 +26,16 @@ fn main() {
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/icon.png");

let icon = load_icon(std::path::Path::new(path));
let mut tray_menu = Menu::new();

#[cfg(target_os = "macos")]
{
tray_menu
.add_item(MenuItemAttributes::new("Item 1"))
.set_icon(icon.clone());
}

let quit = tray_menu.add_item(MenuItemAttributes::new("Quit"));

#[cfg(target_os = "linux")]
let system_tray = SystemTrayBuilder::new(icon, Some(tray_menu))
Expand Down
13 changes: 9 additions & 4 deletions src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use std::{
use crate::{
accelerator::Accelerator,
platform_impl::{Menu as MenuPlatform, MenuItemAttributes as CustomMenuItemPlatform},
window::Icon,
};

/// Object that allows you to create a `ContextMenu`.
Expand Down Expand Up @@ -397,10 +398,14 @@ impl CustomMenuItem {
self.0.set_selected(is_selected)
}

// todo: Add set_icon
// pub fn set_icon(&mut self, icon: Vec<u8>) {
// self.0.set_icon(icon)
// }
/// Set icon of the menu item.
///
/// ## Platform-specific
///
/// - **Windows / Linux:** Not implemented
pub fn set_icon(&mut self, icon: Icon) {
self.0.set_icon(icon)
}
}

/// Identifier of a custom menu item.
Expand Down
2 changes: 1 addition & 1 deletion src/platform/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
menu::CustomMenuItem,
monitor::MonitorHandle,
platform_impl::{get_aux_state_mut, Parent},
window::{Theme, Window, WindowBuilder},
window::{Icon, Theme, Window, WindowBuilder},
};

#[cfg(feature = "tray")]
Expand Down
3 changes: 2 additions & 1 deletion src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
error, event,
event_loop::{self, ControlFlow},
icon::Icon,
keyboard::{Key, KeyCode, KeyLocation, NativeKeyCode},
menu::{CustomMenuItem, MenuId, MenuItem, MenuType},
monitor, window,
Expand Down Expand Up @@ -107,7 +108,7 @@ impl MenuItemAttributes {
pub fn set_enabled(&mut self, _is_enabled: bool) {}
pub fn set_title(&mut self, _title: &str) {}
pub fn set_selected(&mut self, _is_selected: bool) {}
pub fn set_icon(&mut self, _icon: Vec<u8>) {}
pub fn set_icon(&mut self, _icon: Icon) {}
}

pub struct EventLoop<T: 'static> {
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/ios/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub use self::{
window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId},
};

pub(crate) use crate::icon::NoIcon as PlatformIcon;
pub(crate) use crate::icon::{Icon, NoIcon as PlatformIcon};

// todo: implement iOS keyboard event
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -151,7 +151,7 @@ impl MenuItemAttributes {
pub fn set_enabled(&mut self, _is_enabled: bool) {}
pub fn set_title(&mut self, _title: &str) {}
pub fn set_selected(&mut self, _is_selected: bool) {}
pub fn set_icon(&mut self, _icon: Vec<u8>) {}
pub fn set_icon(&mut self, _icon: Icon) {}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down
3 changes: 2 additions & 1 deletion src/platform_impl/linux/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use super::{
};
use crate::{
accelerator::Accelerator,
icon::Icon,
keyboard::{KeyCode, ModifiersState},
menu::{CustomMenuItem, MenuId, MenuItem, MenuType},
};
Expand Down Expand Up @@ -99,7 +100,7 @@ impl MenuItemAttributes {
}

// TODO
pub fn set_icon(&mut self, _icon: Vec<u8>) {}
pub fn set_icon(&mut self, _icon: Icon) {}
}

impl Default for Menu {
Expand Down
21 changes: 17 additions & 4 deletions src/platform_impl/macos/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

use cocoa::{
appkit::{NSApp, NSApplication, NSButton, NSEventModifierFlags, NSMenu, NSMenuItem},
appkit::{NSApp, NSApplication, NSButton, NSEventModifierFlags, NSImage, NSMenu, NSMenuItem},
base::{id, nil, selector},
foundation::{NSAutoreleasePool, NSString},
foundation::{NSAutoreleasePool, NSData, NSString},
};
use objc::{
declare::ClassDecl,
Expand All @@ -15,6 +15,7 @@ use std::sync::Once;
use crate::{
accelerator::{Accelerator, RawMods},
event::Event,
icon::Icon,
keyboard::{KeyCode, ModifiersState},
menu::{CustomMenuItem, MenuId, MenuItem, MenuType},
platform::macos::NativeImage,
Expand Down Expand Up @@ -79,8 +80,20 @@ impl MenuItemAttributes {
}
}

// todo: set custom icon to the menu item
pub fn set_icon(&mut self, _icon: Vec<u8>) {}
pub fn set_icon(&mut self, icon: Icon) {
unsafe {
let icon = icon.inner.to_png();

let nsdata = NSData::dataWithBytes_length_(
nil,
icon.as_ptr() as *const std::os::raw::c_void,
icon.len() as u64,
);

let nsimage = NSImage::initWithData_(NSImage::alloc(nil), nsdata);
let _: () = msg_send![self.1, setImage: nsimage];
}
}

// Available only with CustomMenuItemExtMacOS
pub fn set_native_image(&mut self, icon: NativeImage) {
Expand Down
3 changes: 2 additions & 1 deletion src/platform_impl/windows/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use windows::{
use crate::{
accelerator::Accelerator,
event::{Event, WindowEvent},
icon::Icon,
keyboard::{KeyCode, ModifiersState},
menu::{CustomMenuItem, MenuId, MenuItem, MenuType},
window::WindowId as RootWindowId,
Expand Down Expand Up @@ -146,7 +147,7 @@ impl MenuItemAttributes {
}

// todo: set custom icon to the menu item
pub fn set_icon(&mut self, _icon: Vec<u8>) {}
pub fn set_icon(&mut self, _icon: Icon) {}
}

#[derive(Debug, Clone)]
Expand Down

0 comments on commit 13f9f18

Please sign in to comment.