1use std::{boxed::Box as Box_, pin::Pin, ptr};
4
5use glib::translate::*;
6
7use crate::{FontDialog, Window, ffi, prelude::*};
8
9impl FontDialog {
10 #[doc(alias = "gtk_font_dialog_choose_font_and_features")]
27 #[doc(alias = "gtk_font_dialog_choose_font_and_features_finish")]
28 pub fn choose_font_and_features<
29 P: FnOnce(
30 Result<
31 (
32 Option<pango::FontDescription>,
33 glib::GString,
34 pango::Language,
35 ),
36 glib::Error,
37 >,
38 ) + 'static,
39 >(
40 &self,
41 parent: Option<&impl IsA<Window>>,
42 initial_value: Option<&pango::FontDescription>,
43 cancellable: Option<&impl IsA<gio::Cancellable>>,
44 callback: P,
45 ) {
46 let main_context = glib::MainContext::ref_thread_default();
47 let is_main_context_owner = main_context.is_owner();
48 let has_acquired_main_context = (!is_main_context_owner)
49 .then(|| main_context.acquire().ok())
50 .flatten();
51 assert!(
52 is_main_context_owner || has_acquired_main_context.is_some(),
53 "Async operations only allowed if the thread is owning the MainContext"
54 );
55
56 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
57 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
58 unsafe extern "C" fn choose_font_and_features_trampoline<
59 P: FnOnce(
60 Result<
61 (
62 Option<pango::FontDescription>,
63 glib::GString,
64 pango::Language,
65 ),
66 glib::Error,
67 >,
68 ) + 'static,
69 >(
70 _source_object: *mut glib::gobject_ffi::GObject,
71 res: *mut gio::ffi::GAsyncResult,
72 user_data: glib::ffi::gpointer,
73 ) {
74 unsafe {
75 let mut error = ptr::null_mut();
76 let mut font_desc = ptr::null_mut();
77 let mut font_features = ptr::null_mut();
78 let mut language = ptr::null_mut();
79 let _ = ffi::gtk_font_dialog_choose_font_and_features_finish(
80 _source_object as *mut _,
81 res,
82 &mut font_desc,
83 &mut font_features,
84 &mut language,
85 &mut error,
86 );
87 let result = if error.is_null() {
88 Ok((
89 from_glib_full(font_desc),
90 from_glib_full(font_features),
91 from_glib_full(language),
92 ))
93 } else {
94 Err(from_glib_full(error))
95 };
96 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
97 Box_::from_raw(user_data as *mut _);
98 let callback: P = callback.into_inner();
99 callback(result);
100 }
101 }
102 let callback = choose_font_and_features_trampoline::<P>;
103 unsafe {
104 ffi::gtk_font_dialog_choose_font_and_features(
105 self.to_glib_none().0,
106 parent.map(|p| p.as_ref()).to_glib_none().0,
107 mut_override(initial_value.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 #[allow(clippy::type_complexity)]
116 pub fn choose_font_and_features_future(
117 &self,
118 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
119 initial_value: Option<&pango::FontDescription>,
120 ) -> Pin<
121 Box_<
122 dyn std::future::Future<
123 Output = Result<
124 (
125 Option<pango::FontDescription>,
126 glib::GString,
127 pango::Language,
128 ),
129 glib::Error,
130 >,
131 > + 'static,
132 >,
133 > {
134 let parent = parent.map(ToOwned::to_owned);
135 let initial_value = initial_value.map(ToOwned::to_owned);
136 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
137 obj.choose_font_and_features(
138 parent.as_ref().map(::std::borrow::Borrow::borrow),
139 initial_value.as_ref().map(::std::borrow::Borrow::borrow),
140 Some(cancellable),
141 move |res| {
142 send.resolve(res);
143 },
144 );
145 }))
146 }
147}