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