1use std::{boxed::Box as Box_, pin::Pin, ptr};
4
5use glib::translate::*;
6
7use crate::{ffi, prelude::*, FontDialog, Window};
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 let mut error = ptr::null_mut();
75 let mut font_desc = ptr::null_mut();
76 let mut font_features = ptr::null_mut();
77 let mut language = ptr::null_mut();
78 let _ = ffi::gtk_font_dialog_choose_font_and_features_finish(
79 _source_object as *mut _,
80 res,
81 &mut font_desc,
82 &mut font_features,
83 &mut language,
84 &mut error,
85 );
86 let result = if error.is_null() {
87 Ok((
88 from_glib_full(font_desc),
89 from_glib_full(font_features),
90 from_glib_full(language),
91 ))
92 } else {
93 Err(from_glib_full(error))
94 };
95 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
96 Box_::from_raw(user_data as *mut _);
97 let callback: P = callback.into_inner();
98 callback(result);
99 }
100 let callback = choose_font_and_features_trampoline::<P>;
101 unsafe {
102 ffi::gtk_font_dialog_choose_font_and_features(
103 self.to_glib_none().0,
104 parent.map(|p| p.as_ref()).to_glib_none().0,
105 mut_override(initial_value.to_glib_none().0),
106 cancellable.map(|p| p.as_ref()).to_glib_none().0,
107 Some(callback),
108 Box_::into_raw(user_data) as *mut _,
109 );
110 }
111 }
112
113 #[allow(clippy::type_complexity)]
114 pub fn choose_font_and_features_future(
115 &self,
116 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
117 initial_value: Option<&pango::FontDescription>,
118 ) -> Pin<
119 Box_<
120 dyn std::future::Future<
121 Output = Result<
122 (
123 Option<pango::FontDescription>,
124 glib::GString,
125 pango::Language,
126 ),
127 glib::Error,
128 >,
129 > + 'static,
130 >,
131 > {
132 let parent = parent.map(ToOwned::to_owned);
133 let initial_value = initial_value.map(ToOwned::to_owned);
134 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
135 obj.choose_font_and_features(
136 parent.as_ref().map(::std::borrow::Borrow::borrow),
137 initial_value.as_ref().map(::std::borrow::Borrow::borrow),
138 Some(cancellable),
139 move |res| {
140 send.resolve(res);
141 },
142 );
143 }))
144 }
145}