native_windows_gui2/resources/
cursor.rs1use crate::win32::resources_helper as rh;
2use crate::{NwgError, OemCursor, OemImage};
3use std::ptr;
4use winapi::um::winnt::HANDLE;
5use winapi::um::winuser::IMAGE_CURSOR;
6
7#[cfg(feature = "embed-resource")]
8use super::EmbedResource;
9
10#[allow(unused)]
38pub struct Cursor {
39 pub handle: HANDLE,
40 pub(crate) owned: bool,
41}
42
43impl Cursor {
44 pub fn builder<'a>() -> CursorBuilder<'a> {
45 CursorBuilder {
46 source_text: None,
47 source_system: None,
48 size: None,
49
50 #[cfg(feature = "embed-resource")]
51 source_embed: None,
52
53 #[cfg(feature = "embed-resource")]
54 source_embed_id: 0,
55
56 #[cfg(feature = "embed-resource")]
57 source_embed_str: None,
58
59 strict: false,
60 }
61 }
62
63 pub fn from_system(cursor: OemCursor) -> Cursor {
64 let mut out = Self::default();
65
66 Self::builder()
68 .source_system(Some(cursor))
69 .build(&mut out)
70 .unwrap();
71
72 out
73 }
74
75 pub fn from_file(path: &str, strict: bool) -> Result<Cursor, NwgError> {
81 let mut cursor = Cursor::default();
82
83 Cursor::builder()
84 .source_file(Some(path))
85 .strict(strict)
86 .build(&mut cursor)?;
87
88 Ok(cursor)
89 }
90
91 #[cfg(feature = "embed-resource")]
99 pub fn from_embed(
100 embed: &EmbedResource,
101 embed_id: Option<usize>,
102 embed_str: Option<&str>,
103 ) -> Result<Cursor, NwgError> {
104 let mut bitmap = Cursor::default();
105
106 Cursor::builder()
107 .source_embed(Some(embed))
108 .source_embed_id(embed_id.unwrap_or(0))
109 .source_embed_str(embed_str)
110 .build(&mut bitmap)?;
111
112 Ok(bitmap)
113 }
114}
115
116pub struct CursorBuilder<'a> {
117 source_text: Option<&'a str>,
118 source_system: Option<OemCursor>,
119 size: Option<(u32, u32)>,
120
121 #[cfg(feature = "embed-resource")]
122 source_embed: Option<&'a EmbedResource>,
123
124 #[cfg(feature = "embed-resource")]
125 source_embed_id: usize,
126
127 #[cfg(feature = "embed-resource")]
128 source_embed_str: Option<&'a str>,
129
130 strict: bool,
131}
132
133impl<'a> CursorBuilder<'a> {
134 pub fn source_file(mut self, t: Option<&'a str>) -> CursorBuilder<'a> {
135 self.source_text = t;
136 self
137 }
138
139 pub fn source_system(mut self, t: Option<OemCursor>) -> CursorBuilder<'a> {
140 self.source_system = t;
141 self
142 }
143
144 #[cfg(feature = "embed-resource")]
145 pub fn source_embed(mut self, em: Option<&'a EmbedResource>) -> CursorBuilder<'a> {
146 self.source_embed = em;
147 self
148 }
149
150 #[cfg(feature = "embed-resource")]
151 pub fn source_embed_id(mut self, id: usize) -> CursorBuilder<'a> {
152 self.source_embed_id = id;
153 self
154 }
155
156 #[cfg(feature = "embed-resource")]
157 pub fn source_embed_str(mut self, id: Option<&'a str>) -> CursorBuilder<'a> {
158 self.source_embed_str = id;
159 self
160 }
161
162 pub fn size(mut self, s: Option<(u32, u32)>) -> CursorBuilder<'a> {
163 self.size = s;
164 self
165 }
166
167 pub fn strict(mut self, s: bool) -> CursorBuilder<'a> {
168 self.strict = s;
169 self
170 }
171
172 pub fn build(self, b: &mut Cursor) -> Result<(), NwgError> {
173 if let Some(src) = self.source_text {
174 let handle = unsafe { rh::build_image(src, self.size, self.strict, IMAGE_CURSOR)? };
175 *b = Cursor {
176 handle,
177 owned: true,
178 };
179 } else if let Some(src) = self.source_system {
180 let handle = unsafe { rh::build_oem_image(OemImage::Cursor(src), self.size)? };
181 *b = Cursor {
182 handle,
183 owned: true,
184 };
185 } else {
186 #[cfg(feature = "embed-resource")]
187 fn build_embed(builder: CursorBuilder) -> Result<Cursor, NwgError> {
188 match builder.source_embed {
189 Some(embed) => match builder.source_embed_str {
190 Some(src) => embed.cursor_str(src).ok_or_else(|| {
191 NwgError::resource_create(format!(
192 "No cursor in embed resource identified by {}",
193 src
194 ))
195 }),
196 None => embed.cursor(builder.source_embed_id).ok_or_else(|| {
197 NwgError::resource_create(format!(
198 "No cursor in embed resource identified by {}",
199 builder.source_embed_id
200 ))
201 }),
202 },
203 None => Err(NwgError::resource_create("No source provided for Cursor")),
204 }
205 }
206
207 #[cfg(not(feature = "embed-resource"))]
208 fn build_embed(_builder: CursorBuilder) -> Result<Cursor, NwgError> {
209 Err(NwgError::resource_create("No source provided for Cursor"))
210 }
211
212 *b = build_embed(self)?;
213 }
214
215 Ok(())
216 }
217}
218
219impl Default for Cursor {
220 fn default() -> Cursor {
221 Cursor {
222 handle: ptr::null_mut(),
223 owned: false,
224 }
225 }
226}
227
228impl PartialEq for Cursor {
229 fn eq(&self, other: &Self) -> bool {
230 self.handle == other.handle
231 }
232}
233
234impl Drop for Cursor {
235 fn drop(&mut self) {
236 if self.owned && !self.handle.is_null() {
237 rh::destroy_cursor(self.handle);
238 }
239 }
240}