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