dioxus_desktop/
default_icon.rs1use anyhow::Result;
2use image::load_from_memory;
3use image::GenericImageView;
4use image::ImageReader;
5use std::path::Path;
6
7const FALLBACK_ICON_RGBA: &[u8] = include_bytes!("./assets/default_icon.bin");
9const FALLBACK_ICON_WIDTH: u32 = 460;
10const FALLBACK_ICON_HEIGHT: u32 = 460;
11
12pub trait DioxusIconTrait {
14 fn get_icon() -> Result<Self>
15 where
16 Self: Sized;
17 fn from_memory(value: &[u8]) -> Result<Self>
18 where
19 Self: Sized;
20 fn path<P: AsRef<Path>>(path: P, size: Option<(u32, u32)>) -> Result<Self>
21 where
22 Self: Sized;
23}
24
25#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
26use crate::trayicon::DioxusTrayIcon;
27
28fn load_image_from_memory(value: &[u8]) -> Result<(Vec<u8>, u32, u32)> {
29 let img = load_from_memory(value)?;
30 let rgba = img.to_rgba8();
31 let (width, height) = img.dimensions();
32 Ok((rgba.to_vec(), width, height))
33}
34
35fn load_image_from_path<P: AsRef<Path>>(path: P) -> Result<(Vec<u8>, u32, u32)> {
36 let img = ImageReader::open(path)?.decode()?;
37 let rgba = img.to_rgba8();
38 let (width, height) = img.dimensions();
39 Ok((rgba.to_vec(), width, height))
40}
41
42#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
43impl DioxusIconTrait for DioxusTrayIcon {
44 fn get_icon() -> Result<Self>
45 where
46 Self: Sized,
47 {
48 #[cfg(target_os = "windows")]
49 if let Ok(icon) = DioxusTrayIcon::from_resource(32512, None) {
50 return Ok(icon);
51 }
52 DioxusTrayIcon::from_rgba(
53 FALLBACK_ICON_RGBA.to_vec(),
54 FALLBACK_ICON_WIDTH,
55 FALLBACK_ICON_HEIGHT,
56 )
57 .map_err(Into::into)
58 }
59
60 fn from_memory(value: &[u8]) -> Result<Self>
61 where
62 Self: Sized,
63 {
64 let (icon, width, height) = load_image_from_memory(value)?;
65 DioxusTrayIcon::from_rgba(icon, width, height).map_err(Into::into)
66 }
67
68 fn path<P: AsRef<Path>>(path: P, size: Option<(u32, u32)>) -> Result<Self>
69 where
70 Self: Sized,
71 {
72 let (img, width, height) = load_image_from_path(path)?;
73 if let Some((width, height)) = size {
74 Ok(DioxusTrayIcon::from_rgba(img, width, height)?)
75 } else {
76 Ok(DioxusTrayIcon::from_rgba(img, width, height)?)
77 }
78 }
79}
80
81#[cfg(not(any(target_os = "ios", target_os = "android")))]
82use crate::menubar::DioxusMenuIcon;
83
84#[cfg(not(any(target_os = "ios", target_os = "android")))]
85impl DioxusIconTrait for DioxusMenuIcon {
86 fn get_icon() -> Result<Self>
87 where
88 Self: Sized,
89 {
90 #[cfg(target_os = "windows")]
91 if let Ok(icon) = DioxusMenuIcon::from_resource(32512, None) {
92 return Ok(icon);
93 }
94 DioxusMenuIcon::from_rgba(
95 FALLBACK_ICON_RGBA.to_vec(),
96 FALLBACK_ICON_WIDTH,
97 FALLBACK_ICON_HEIGHT,
98 )
99 .map_err(Into::into)
100 }
101
102 fn from_memory(value: &[u8]) -> Result<Self>
103 where
104 Self: Sized,
105 {
106 let (icon, width, height) = load_image_from_memory(value)?;
107 DioxusMenuIcon::from_rgba(icon, width, height).map_err(Into::into)
108 }
109
110 fn path<P: AsRef<Path>>(path: P, size: Option<(u32, u32)>) -> Result<Self>
111 where
112 Self: Sized,
113 {
114 let (img, width, height) = load_image_from_path(path)?;
115 if let Some((width, height)) = size {
116 Ok(DioxusMenuIcon::from_rgba(img, width, height)?)
117 } else {
118 Ok(DioxusMenuIcon::from_rgba(img, width, height)?)
119 }
120 }
121}
122
123use tao::window::Icon;
124
125#[cfg(target_os = "windows")]
126use tao::platform::windows::IconExtWindows;
127
128impl DioxusIconTrait for Icon {
129 fn get_icon() -> Result<Self>
130 where
131 Self: Sized,
132 {
133 #[cfg(target_os = "windows")]
134 if let Ok(icon) = Icon::from_resource(32512, None) {
135 return Ok(icon);
136 }
137 Icon::from_rgba(
138 FALLBACK_ICON_RGBA.to_vec(),
139 FALLBACK_ICON_WIDTH,
140 FALLBACK_ICON_HEIGHT,
141 )
142 .map_err(Into::into)
143 }
144
145 fn from_memory(value: &[u8]) -> Result<Self>
146 where
147 Self: Sized,
148 {
149 let (icon, width, height) = load_image_from_memory(value)?;
150 Icon::from_rgba(icon, width, height).map_err(Into::into)
151 }
152
153 fn path<P: AsRef<Path>>(path: P, size: Option<(u32, u32)>) -> Result<Self>
154 where
155 Self: Sized,
156 {
157 let (img, width, height) = load_image_from_path(path)?;
158 if let Some((width, height)) = size {
159 Ok(Icon::from_rgba(img, width, height)?)
160 } else {
161 Ok(Icon::from_rgba(img, width, height)?)
162 }
163 }
164}
165
166pub fn default_icon<T: DioxusIconTrait>() -> Result<T> {
173 T::get_icon()
174}
175
176pub fn icon_from_memory<T: DioxusIconTrait>(value: &[u8]) -> Result<T> {
178 T::from_memory(value)
179}
180
181pub fn icon_from_path<T: DioxusIconTrait, P: AsRef<Path>>(
183 path: P,
184 size: Option<(u32, u32)>,
185) -> Result<T> {
186 T::path(path, size)
187}