Skip to main content

nifty_macos/
icons.rs

1//! Nifty's icons as SF Symbols, which come with macOS, so apps bundle no images.
2
3use objc2::rc::Retained;
4use objc2_app_kit::{NSColor, NSImage, NSImageSymbolConfiguration};
5use objc2_foundation::NSString;
6
7use nifty_runtime::Icon;
8
9/// The symbol for `icon`, drawn in the text color around it; `None` for `Icon::None`.
10pub(crate) fn symbol(icon: Icon) -> Option<Retained<NSImage>> {
11    let name = symbol_name(icon)?;
12    let image = NSImage::imageWithSystemSymbolName_accessibilityDescription(
13        &NSString::from_str(name),
14        None,
15    );
16    Some(image.unwrap_or_else(|| panic!("macOS has the SF Symbol `{name}`")))
17}
18
19/// The symbol for `icon` in `color` rather than the text color, as sidebars draw theirs.
20pub(crate) fn tinted_symbol(icon: Icon, color: &NSColor) -> Option<Retained<NSImage>> {
21    let image = symbol(icon)?;
22    let tint = NSImageSymbolConfiguration::configurationWithHierarchicalColor(color);
23    Some(image.imageWithSymbolConfiguration(&tint).unwrap_or(image))
24}
25
26fn symbol_name(icon: Icon) -> Option<&'static str> {
27    Some(match icon {
28        Icon::None => return None,
29        Icon::Plus => "plus",
30        Icon::Trash => "trash",
31        Icon::Star => "star",
32        Icon::StarFill => "star.fill",
33        Icon::Check => "checkmark",
34        Icon::CheckCircle => "checkmark.circle",
35        Icon::Circle => "circle",
36        Icon::Home => "house",
37        Icon::Inbox => "tray",
38        Icon::Archive => "archivebox",
39        Icon::List => "list.bullet",
40        Icon::Calendar => "calendar",
41        Icon::Sun => "sun.max",
42        Icon::Flag => "flag",
43        Icon::Close => "xmark",
44        Icon::Gear => "gearshape",
45        Icon::Search => "magnifyingglass",
46        Icon::Mail => "envelope",
47        Icon::Send => "paperplane",
48        Icon::Folder => "folder",
49        Icon::Clock => "clock",
50        Icon::Tag => "tag",
51        Icon::Person => "person",
52        Icon::Document => "doc",
53        Icon::Download => "arrow.down.circle",
54        Icon::Heart => "heart",
55        Icon::Bell => "bell",
56        Icon::Pencil => "pencil",
57        Icon::Share => "square.and.arrow.up",
58        Icon::Info => "info.circle",
59    })
60}