1use cairo;
6#[cfg(feature = "futures")]
7use futures::future;
8use gdk;
9use gdk_pixbuf;
10use gio;
11use gio_sys;
12use glib::object::IsA;
13use glib::translate::*;
14use glib_sys;
15use gobject_sys;
16use gtk_sys;
17use std;
18#[cfg(feature = "futures")]
19use std::boxed::Box as Box_;
20use std::fmt;
21use std::mem;
22use std::ptr;
23use Error;
24use IconTheme;
25use StyleContext;
26
27glib_wrapper! {
28 pub struct IconInfo(Object<gtk_sys::GtkIconInfo, gtk_sys::GtkIconInfoClass, IconInfoClass>);
29
30 match fn {
31 get_type => || gtk_sys::gtk_icon_info_get_type(),
32 }
33}
34
35impl IconInfo {
36 pub fn new_for_pixbuf<P: IsA<IconTheme>>(
37 icon_theme: &P,
38 pixbuf: &gdk_pixbuf::Pixbuf,
39 ) -> IconInfo {
40 skip_assert_initialized!();
41 unsafe {
42 from_glib_full(gtk_sys::gtk_icon_info_new_for_pixbuf(
43 icon_theme.as_ref().to_glib_none().0,
44 pixbuf.to_glib_none().0,
45 ))
46 }
47 }
48
49 pub fn get_base_scale(&self) -> i32 {
50 unsafe { gtk_sys::gtk_icon_info_get_base_scale(self.to_glib_none().0) }
51 }
52
53 pub fn get_base_size(&self) -> i32 {
54 unsafe { gtk_sys::gtk_icon_info_get_base_size(self.to_glib_none().0) }
55 }
56
57 pub fn get_filename(&self) -> Option<std::path::PathBuf> {
58 unsafe { from_glib_none(gtk_sys::gtk_icon_info_get_filename(self.to_glib_none().0)) }
59 }
60
61 pub fn is_symbolic(&self) -> bool {
62 unsafe { from_glib(gtk_sys::gtk_icon_info_is_symbolic(self.to_glib_none().0)) }
63 }
64
65 pub fn load_icon(&self) -> Result<gdk_pixbuf::Pixbuf, Error> {
66 unsafe {
67 let mut error = ptr::null_mut();
68 let ret = gtk_sys::gtk_icon_info_load_icon(self.to_glib_none().0, &mut error);
69 if error.is_null() {
70 Ok(from_glib_full(ret))
71 } else {
72 Err(from_glib_full(error))
73 }
74 }
75 }
76
77 pub fn load_icon_async<
78 P: IsA<gio::Cancellable>,
79 Q: FnOnce(Result<gdk_pixbuf::Pixbuf, Error>) + Send + 'static,
80 >(
81 &self,
82 cancellable: Option<&P>,
83 callback: Q,
84 ) {
85 let user_data: Box<Q> = Box::new(callback);
86 unsafe extern "C" fn load_icon_async_trampoline<
87 Q: FnOnce(Result<gdk_pixbuf::Pixbuf, Error>) + Send + 'static,
88 >(
89 _source_object: *mut gobject_sys::GObject,
90 res: *mut gio_sys::GAsyncResult,
91 user_data: glib_sys::gpointer,
92 ) {
93 let mut error = ptr::null_mut();
94 let ret =
95 gtk_sys::gtk_icon_info_load_icon_finish(_source_object as *mut _, res, &mut error);
96 let result = if error.is_null() {
97 Ok(from_glib_full(ret))
98 } else {
99 Err(from_glib_full(error))
100 };
101 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
102 callback(result);
103 }
104 let callback = load_icon_async_trampoline::<Q>;
105 unsafe {
106 gtk_sys::gtk_icon_info_load_icon_async(
107 self.to_glib_none().0,
108 cancellable.map(|p| p.as_ref()).to_glib_none().0,
109 Some(callback),
110 Box::into_raw(user_data) as *mut _,
111 );
112 }
113 }
114
115 #[cfg(feature = "futures")]
116 pub fn load_icon_async_future(
117 &self,
118 ) -> Box_<dyn future::Future<Output = Result<gdk_pixbuf::Pixbuf, Error>> + std::marker::Unpin>
119 {
120 use fragile::Fragile;
121 use gio::GioFuture;
122
123 GioFuture::new(self, move |obj, send| {
124 let cancellable = gio::Cancellable::new();
125 let send = Fragile::new(send);
126 obj.load_icon_async(Some(&cancellable), move |res| {
127 let _ = send.into_inner().send(res);
128 });
129
130 cancellable
131 })
132 }
133
134 pub fn load_surface<P: IsA<gdk::Window>>(
135 &self,
136 for_window: Option<&P>,
137 ) -> Result<cairo::Surface, Error> {
138 unsafe {
139 let mut error = ptr::null_mut();
140 let ret = gtk_sys::gtk_icon_info_load_surface(
141 self.to_glib_none().0,
142 for_window.map(|p| p.as_ref()).to_glib_none().0,
143 &mut error,
144 );
145 if error.is_null() {
146 Ok(from_glib_full(ret))
147 } else {
148 Err(from_glib_full(error))
149 }
150 }
151 }
152
153 pub fn load_symbolic(
154 &self,
155 fg: &gdk::RGBA,
156 success_color: Option<&gdk::RGBA>,
157 warning_color: Option<&gdk::RGBA>,
158 error_color: Option<&gdk::RGBA>,
159 ) -> Result<(gdk_pixbuf::Pixbuf, bool), Error> {
160 unsafe {
161 let mut was_symbolic = mem::uninitialized();
162 let mut error = ptr::null_mut();
163 let ret = gtk_sys::gtk_icon_info_load_symbolic(
164 self.to_glib_none().0,
165 fg.to_glib_none().0,
166 success_color.to_glib_none().0,
167 warning_color.to_glib_none().0,
168 error_color.to_glib_none().0,
169 &mut was_symbolic,
170 &mut error,
171 );
172 if error.is_null() {
173 Ok((from_glib_full(ret), from_glib(was_symbolic)))
174 } else {
175 Err(from_glib_full(error))
176 }
177 }
178 }
179
180 pub fn load_symbolic_async<
181 P: IsA<gio::Cancellable>,
182 Q: FnOnce(Result<(gdk_pixbuf::Pixbuf, bool), Error>) + Send + 'static,
183 >(
184 &self,
185 fg: &gdk::RGBA,
186 success_color: Option<&gdk::RGBA>,
187 warning_color: Option<&gdk::RGBA>,
188 error_color: Option<&gdk::RGBA>,
189 cancellable: Option<&P>,
190 callback: Q,
191 ) {
192 let user_data: Box<Q> = Box::new(callback);
193 unsafe extern "C" fn load_symbolic_async_trampoline<
194 Q: FnOnce(Result<(gdk_pixbuf::Pixbuf, bool), Error>) + Send + 'static,
195 >(
196 _source_object: *mut gobject_sys::GObject,
197 res: *mut gio_sys::GAsyncResult,
198 user_data: glib_sys::gpointer,
199 ) {
200 let mut error = ptr::null_mut();
201 let mut was_symbolic = mem::uninitialized();
202 let ret = gtk_sys::gtk_icon_info_load_symbolic_finish(
203 _source_object as *mut _,
204 res,
205 &mut was_symbolic,
206 &mut error,
207 );
208 let result = if error.is_null() {
209 Ok((from_glib_full(ret), from_glib(was_symbolic)))
210 } else {
211 Err(from_glib_full(error))
212 };
213 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
214 callback(result);
215 }
216 let callback = load_symbolic_async_trampoline::<Q>;
217 unsafe {
218 gtk_sys::gtk_icon_info_load_symbolic_async(
219 self.to_glib_none().0,
220 fg.to_glib_none().0,
221 success_color.to_glib_none().0,
222 warning_color.to_glib_none().0,
223 error_color.to_glib_none().0,
224 cancellable.map(|p| p.as_ref()).to_glib_none().0,
225 Some(callback),
226 Box::into_raw(user_data) as *mut _,
227 );
228 }
229 }
230
231 #[cfg(feature = "futures")]
232 pub fn load_symbolic_async_future(
233 &self,
234 fg: &gdk::RGBA,
235 success_color: Option<&gdk::RGBA>,
236 warning_color: Option<&gdk::RGBA>,
237 error_color: Option<&gdk::RGBA>,
238 ) -> Box_<
239 dyn future::Future<Output = Result<(gdk_pixbuf::Pixbuf, bool), Error>> + std::marker::Unpin,
240 > {
241 use fragile::Fragile;
242 use gio::GioFuture;
243
244 let fg = fg.clone();
245 let success_color = success_color.map(ToOwned::to_owned);
246 let warning_color = warning_color.map(ToOwned::to_owned);
247 let error_color = error_color.map(ToOwned::to_owned);
248 GioFuture::new(self, move |obj, send| {
249 let cancellable = gio::Cancellable::new();
250 let send = Fragile::new(send);
251 obj.load_symbolic_async(
252 &fg,
253 success_color.as_ref().map(::std::borrow::Borrow::borrow),
254 warning_color.as_ref().map(::std::borrow::Borrow::borrow),
255 error_color.as_ref().map(::std::borrow::Borrow::borrow),
256 Some(&cancellable),
257 move |res| {
258 let _ = send.into_inner().send(res);
259 },
260 );
261
262 cancellable
263 })
264 }
265
266 pub fn load_symbolic_for_context<P: IsA<StyleContext>>(
267 &self,
268 context: &P,
269 ) -> Result<(gdk_pixbuf::Pixbuf, bool), Error> {
270 unsafe {
271 let mut was_symbolic = mem::uninitialized();
272 let mut error = ptr::null_mut();
273 let ret = gtk_sys::gtk_icon_info_load_symbolic_for_context(
274 self.to_glib_none().0,
275 context.as_ref().to_glib_none().0,
276 &mut was_symbolic,
277 &mut error,
278 );
279 if error.is_null() {
280 Ok((from_glib_full(ret), from_glib(was_symbolic)))
281 } else {
282 Err(from_glib_full(error))
283 }
284 }
285 }
286
287 pub fn load_symbolic_for_context_async<
288 P: IsA<StyleContext>,
289 Q: IsA<gio::Cancellable>,
290 R: FnOnce(Result<(gdk_pixbuf::Pixbuf, bool), Error>) + Send + 'static,
291 >(
292 &self,
293 context: &P,
294 cancellable: Option<&Q>,
295 callback: R,
296 ) {
297 let user_data: Box<R> = Box::new(callback);
298 unsafe extern "C" fn load_symbolic_for_context_async_trampoline<
299 R: FnOnce(Result<(gdk_pixbuf::Pixbuf, bool), Error>) + Send + 'static,
300 >(
301 _source_object: *mut gobject_sys::GObject,
302 res: *mut gio_sys::GAsyncResult,
303 user_data: glib_sys::gpointer,
304 ) {
305 let mut error = ptr::null_mut();
306 let mut was_symbolic = mem::uninitialized();
307 let ret = gtk_sys::gtk_icon_info_load_symbolic_for_context_finish(
308 _source_object as *mut _,
309 res,
310 &mut was_symbolic,
311 &mut error,
312 );
313 let result = if error.is_null() {
314 Ok((from_glib_full(ret), from_glib(was_symbolic)))
315 } else {
316 Err(from_glib_full(error))
317 };
318 let callback: Box<R> = Box::from_raw(user_data as *mut _);
319 callback(result);
320 }
321 let callback = load_symbolic_for_context_async_trampoline::<R>;
322 unsafe {
323 gtk_sys::gtk_icon_info_load_symbolic_for_context_async(
324 self.to_glib_none().0,
325 context.as_ref().to_glib_none().0,
326 cancellable.map(|p| p.as_ref()).to_glib_none().0,
327 Some(callback),
328 Box::into_raw(user_data) as *mut _,
329 );
330 }
331 }
332
333 #[cfg(feature = "futures")]
334 pub fn load_symbolic_for_context_async_future<P: IsA<StyleContext> + Clone + 'static>(
335 &self,
336 context: &P,
337 ) -> Box_<
338 dyn future::Future<Output = Result<(gdk_pixbuf::Pixbuf, bool), Error>> + std::marker::Unpin,
339 > {
340 use fragile::Fragile;
341 use gio::GioFuture;
342
343 let context = context.clone();
344 GioFuture::new(self, move |obj, send| {
345 let cancellable = gio::Cancellable::new();
346 let send = Fragile::new(send);
347 obj.load_symbolic_for_context_async(&context, Some(&cancellable), move |res| {
348 let _ = send.into_inner().send(res);
349 });
350
351 cancellable
352 })
353 }
354}
355
356impl fmt::Display for IconInfo {
357 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
358 write!(f, "IconInfo")
359 }
360}