native_windows_gui/resources/
bitmap.rs1use winapi::um::winnt::HANDLE;
2use winapi::um::winuser::IMAGE_BITMAP;
3use crate::win32::resources_helper as rh;
4use crate::{OemBitmap, OemImage, NwgError};
5use std::ptr;
6
7#[cfg(feature = "embed-resource")]
8use super::EmbedResource;
9
10#[allow(unused)]
59pub struct Bitmap {
60 pub handle: HANDLE,
61 pub(crate) owned: bool
62}
63
64impl Bitmap {
65
66 pub fn builder<'a>() -> BitmapBuilder<'a> {
67 BitmapBuilder {
68 source_text: None,
69 source_bin: None,
70 source_system: None,
71
72 #[cfg(feature = "embed-resource")]
73 source_embed: None,
74
75 #[cfg(feature = "embed-resource")]
76 source_embed_id: 0,
77
78 #[cfg(feature = "embed-resource")]
79 source_embed_str: None,
80
81 size: None,
82 strict: false
83 }
84 }
85
86 pub fn from_system(sys_bitmap: OemBitmap) -> Bitmap {
92 let mut bitmap = Self::default();
93
94 Self::builder()
96 .source_system(Some(sys_bitmap))
97 .build(&mut bitmap)
98 .unwrap();
99
100 bitmap
101 }
102
103 pub fn from_file(path: &str, strict: bool) -> Result<Bitmap, NwgError> {
109 let mut bitmap = Bitmap::default();
110
111 Bitmap::builder()
112 .source_file(Some(path))
113 .strict(strict)
114 .build(&mut bitmap)?;
115
116 Ok(bitmap)
117 }
118
119 pub fn from_bin(bin: &[u8]) -> Result<Bitmap, NwgError> {
125 let mut bitmap = Bitmap::default();
126
127 Bitmap::builder()
128 .source_bin(Some(bin))
129 .build(&mut bitmap)?;
130
131 Ok(bitmap)
132 }
133
134 #[cfg(feature = "embed-resource")]
142 pub fn from_embed(embed: &EmbedResource, embed_id: Option<usize>, embed_str: Option<&str>) -> Result<Bitmap, NwgError> {
143 let mut bitmap = Bitmap::default();
144
145 Bitmap::builder()
146 .source_embed(Some(embed))
147 .source_embed_id(embed_id.unwrap_or(0))
148 .source_embed_str(embed_str)
149 .build(&mut bitmap)?;
150
151 Ok(bitmap)
152 }
153
154 pub fn copy_as_icon(&self) -> crate::Icon {
160 use winapi::um::winuser::CreateIconIndirect;
161 use winapi::um::winuser::ICONINFO;
162
163 if self.handle.is_null() {
164 panic!("Bitmap was not initialized");
165 }
166
167 let mut icon_info = ICONINFO {
168 fIcon: 1,
169 xHotspot: 0,
170 yHotspot: 0,
171 hbmMask: self.handle as _,
172 hbmColor: self.handle as _
173 };
174
175 let icon = unsafe { CreateIconIndirect(&mut icon_info) };
176
177 crate::Icon {
178 handle: icon as _,
179 owned: true
180 }
181 }
182
183}
184
185pub struct BitmapBuilder<'a> {
186 source_text: Option<&'a str>,
187 source_bin: Option<&'a [u8]>,
188 source_system: Option<OemBitmap>,
189
190 #[cfg(feature = "embed-resource")]
191 source_embed: Option<&'a EmbedResource>,
192
193 #[cfg(feature = "embed-resource")]
194 source_embed_id: usize,
195
196 #[cfg(feature = "embed-resource")]
197 source_embed_str: Option<&'a str>,
198
199 size: Option<(u32, u32)>,
200 strict: bool,
201}
202
203impl<'a> BitmapBuilder<'a> {
204
205 pub fn source_file(mut self, t: Option<&'a str>) -> BitmapBuilder<'a> {
206 self.source_text = t;
207 self
208 }
209
210 pub fn source_bin(mut self, t: Option<&'a [u8]>) -> BitmapBuilder<'a> {
211 self.source_bin = t;
212 self
213 }
214
215 pub fn source_system(mut self, t: Option<OemBitmap>) -> BitmapBuilder<'a> {
216 self.source_system = t;
217 self
218 }
219
220 #[cfg(feature = "embed-resource")]
221 pub fn source_embed(mut self, em: Option<&'a EmbedResource>) -> BitmapBuilder<'a> {
222 self.source_embed = em;
223 self
224 }
225
226 #[cfg(feature = "embed-resource")]
227 pub fn source_embed_id(mut self, id: usize) -> BitmapBuilder<'a> {
228 self.source_embed_id = id;
229 self
230 }
231
232 #[cfg(feature = "embed-resource")]
233 pub fn source_embed_str(mut self, id: Option<&'a str>) -> BitmapBuilder<'a> {
234 self.source_embed_str = id;
235 self
236 }
237
238 pub fn size(mut self, s: Option<(u32, u32)>) -> BitmapBuilder<'a> {
239 self.size = s;
240 self
241 }
242
243 pub fn strict(mut self, s: bool) -> BitmapBuilder<'a> {
244 self.strict = s;
245 self
246 }
247
248 pub fn build(self, b: &mut Bitmap) -> Result<(), NwgError> {
249 if let Some(src) = self.source_text {
250 let handle = unsafe {
251 #[cfg(feature="image-decoder")]
252 let handle = rh::build_image_decoder(src, self.size, self.strict, IMAGE_BITMAP);
253
254 #[cfg(not(feature="image-decoder"))]
255 let handle = rh::build_image(src, self.size, self.strict, IMAGE_BITMAP);
256
257 handle?
258 };
259
260 *b = Bitmap { handle, owned: true };
261 } else if let Some(src) = self.source_system {
262 let handle = unsafe { rh::build_oem_image(OemImage::Bitmap(src), self.size)? };
263 *b = Bitmap { handle, owned: true };
264 } else if let Some(src) = self.source_bin {
265 let handle = unsafe { rh::bitmap_from_memory(src)? };
266
267 *b = Bitmap { handle, owned: true };
268 } else {
269 #[cfg(all(feature = "embed-resource", feature="image-decoder"))]
270 fn build_embed(builder: BitmapBuilder) -> Result<Bitmap, NwgError> {
271 match builder.source_embed {
272 Some(embed) => {
273 match builder.source_embed_str {
274 Some(src) => embed.image_str(src, builder.size)
275 .ok_or_else(|| NwgError::resource_create(format!("No bitmap in embed resource identified by {}", src))),
276 None => embed.image(builder.source_embed_id, builder.size)
277 .ok_or_else(|| NwgError::resource_create(format!("No bitmap in embed resource identified by {}", builder.source_embed_id)))
278 }
279 },
280 None => Err(NwgError::resource_create("No source provided for Bitmap"))
281 }
282 }
283
284 #[cfg(feature = "embed-resource")]
285 #[cfg(not(feature = "image-decoder"))]
286 fn build_embed(builder: BitmapBuilder) -> Result<Bitmap, NwgError> {
287 match builder.source_embed {
288 Some(embed) => {
289 match builder.source_embed_str {
290 Some(src) => embed.bitmap_str(src, builder.size)
291 .ok_or_else(|| NwgError::resource_create(format!("No bitmap in embed resource identified by {}", src))),
292 None => embed.bitmap(builder.source_embed_id, builder.size)
293 .ok_or_else(|| NwgError::resource_create(format!("No bitmap in embed resource identified by {}", builder.source_embed_id)))
294 }
295 },
296 None => Err(NwgError::resource_create("No source provided for Bitmap"))
297 }
298 }
299
300 #[cfg(not(feature = "embed-resource"))]
301 fn build_embed(_builder: BitmapBuilder) -> Result<Bitmap, NwgError> {
302 Err(NwgError::resource_create("No source provided for Bitmap"))
303 }
304
305 *b = build_embed(self)?;
306 }
307
308 Ok(())
309 }
310
311}
312
313
314impl Default for Bitmap {
315
316 fn default() -> Bitmap {
317 Bitmap {
318 handle: ptr::null_mut(),
319 owned: false
320 }
321 }
322
323}
324
325impl PartialEq for Bitmap {
326
327 fn eq(&self, other: &Self) -> bool {
328 self.handle == other.handle
329 }
330
331}
332
333impl Drop for Bitmap {
334
335 fn drop(&mut self) {
336 if self.owned && !self.handle.is_null() {
337 rh::destroy_obj(self.handle);
338 }
339 }
340
341}