native_windows_gui2/resources/
icon.rs1use crate::win32::resources_helper as rh;
2use crate::{NwgError, OemIcon, OemImage};
3use std::ptr;
4use winapi::um::winnt::HANDLE;
5use winapi::um::winuser::IMAGE_ICON;
6
7#[cfg(feature = "embed-resource")]
8use super::EmbedResource;
9
10#[allow(unused)]
53pub struct Icon {
54 pub handle: HANDLE,
55 pub(crate) owned: bool,
56}
57
58impl Icon {
59 pub fn builder<'a>() -> IconBuilder<'a> {
60 IconBuilder {
61 source_text: None,
62 source_bin: None,
63 source_system: None,
64
65 #[cfg(feature = "embed-resource")]
66 source_embed: None,
67
68 #[cfg(feature = "embed-resource")]
69 source_embed_id: 0,
70
71 #[cfg(feature = "embed-resource")]
72 source_embed_str: None,
73
74 size: None,
75 strict: false,
76 }
77 }
78
79 pub fn from_system(sys_icon: OemIcon) -> Icon {
85 let mut icon = Self::default();
86
87 Self::builder()
89 .source_system(Some(sys_icon))
90 .build(&mut icon)
91 .unwrap();
92
93 icon
94 }
95
96 pub fn from_file(path: &str, strict: bool) -> Result<Icon, NwgError> {
102 let mut icon = Icon::default();
103
104 Icon::builder()
105 .source_file(Some(path))
106 .strict(strict)
107 .build(&mut icon)?;
108
109 Ok(icon)
110 }
111
112 pub fn from_bin(bin: &[u8]) -> Result<Icon, NwgError> {
118 let mut icon = Icon::default();
119
120 Icon::builder().source_bin(Some(bin)).build(&mut icon)?;
121
122 Ok(icon)
123 }
124
125 #[cfg(feature = "embed-resource")]
133 pub fn from_embed(
134 embed: &EmbedResource,
135 embed_id: Option<usize>,
136 embed_str: Option<&str>,
137 ) -> Result<Icon, NwgError> {
138 let mut icon = Icon::default();
139
140 Icon::builder()
141 .source_embed(Some(embed))
142 .source_embed_id(embed_id.unwrap_or(0))
143 .source_embed_str(embed_str)
144 .build(&mut icon)?;
145
146 Ok(icon)
147 }
148}
149
150pub struct IconBuilder<'a> {
151 source_text: Option<&'a str>,
152 source_bin: Option<&'a [u8]>,
153 source_system: Option<OemIcon>,
154
155 #[cfg(feature = "embed-resource")]
156 source_embed: Option<&'a EmbedResource>,
157
158 #[cfg(feature = "embed-resource")]
159 source_embed_id: usize,
160
161 #[cfg(feature = "embed-resource")]
162 source_embed_str: Option<&'a str>,
163
164 size: Option<(u32, u32)>,
165 strict: bool,
166}
167
168impl<'a> IconBuilder<'a> {
169 pub fn source_file(mut self, t: Option<&'a str>) -> IconBuilder<'a> {
170 self.source_text = t;
171 self
172 }
173
174 pub fn source_bin(mut self, t: Option<&'a [u8]>) -> IconBuilder<'a> {
175 self.source_bin = t;
176 self
177 }
178
179 pub fn source_system(mut self, t: Option<OemIcon>) -> IconBuilder<'a> {
180 self.source_system = t;
181 self
182 }
183
184 #[cfg(feature = "embed-resource")]
185 pub fn source_embed(mut self, em: Option<&'a EmbedResource>) -> IconBuilder<'a> {
186 self.source_embed = em;
187 self
188 }
189
190 #[cfg(feature = "embed-resource")]
191 pub fn source_embed_id(mut self, id: usize) -> IconBuilder<'a> {
192 self.source_embed_id = id;
193 self
194 }
195
196 #[cfg(feature = "embed-resource")]
197 pub fn source_embed_str(mut self, id: Option<&'a str>) -> IconBuilder<'a> {
198 self.source_embed_str = id;
199 self
200 }
201
202 pub fn size(mut self, s: Option<(u32, u32)>) -> IconBuilder<'a> {
203 self.size = s;
204 self
205 }
206
207 pub fn strict(mut self, s: bool) -> IconBuilder<'a> {
208 self.strict = s;
209 self
210 }
211
212 pub fn build(self, b: &mut Icon) -> Result<(), NwgError> {
213 if let Some(src) = self.source_text {
214 let handle = unsafe { rh::build_image(src, self.size, self.strict, IMAGE_ICON)? };
215 *b = Icon {
216 handle,
217 owned: true,
218 };
219 } else if let Some(src) = self.source_system {
220 let handle = unsafe { rh::build_oem_image(OemImage::Icon(src), self.size)? };
221 *b = Icon {
222 handle,
223 owned: true,
224 };
225 } else if let Some(src) = self.source_bin {
226 let handle = unsafe { rh::icon_from_memory(src, self.strict, self.size)? };
227 *b = Icon {
228 handle,
229 owned: true,
230 };
231 } else {
232 #[cfg(feature = "embed-resource")]
233 fn build_embed(builder: IconBuilder) -> Result<Icon, NwgError> {
234 match builder.source_embed {
235 Some(embed) => match builder.source_embed_str {
236 Some(src) => embed.icon_str(src, builder.size).ok_or_else(|| {
237 NwgError::resource_create(format!(
238 "No icon in embed resource identified by {}",
239 src
240 ))
241 }),
242 None => embed
243 .icon(builder.source_embed_id, builder.size)
244 .ok_or_else(|| {
245 NwgError::resource_create(format!(
246 "No icon in embed resource identified by {}",
247 builder.source_embed_id
248 ))
249 }),
250 },
251 None => Err(NwgError::resource_create("No source provided for Icon")),
252 }
253 }
254
255 #[cfg(not(feature = "embed-resource"))]
256 fn build_embed(_builder: IconBuilder) -> Result<Icon, NwgError> {
257 Err(NwgError::resource_create("No source provided for Icon"))
258 }
259
260 *b = build_embed(self)?;
261 }
262
263 Ok(())
264 }
265}
266
267impl Default for Icon {
268 fn default() -> Icon {
269 Icon {
270 handle: ptr::null_mut(),
271 owned: false,
272 }
273 }
274}
275
276impl PartialEq for Icon {
287 fn eq(&self, other: &Self) -> bool {
288 self.handle == other.handle
289 }
290}