1use crate::{ffi, Filter, Window};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GtkFontDialog")]
15 pub struct FontDialog(Object<ffi::GtkFontDialog, ffi::GtkFontDialogClass>);
16
17 match fn {
18 type_ => || ffi::gtk_font_dialog_get_type(),
19 }
20}
21
22impl FontDialog {
23 #[doc(alias = "gtk_font_dialog_new")]
24 pub fn new() -> FontDialog {
25 assert_initialized_main_thread!();
26 unsafe { from_glib_full(ffi::gtk_font_dialog_new()) }
27 }
28
29 pub fn builder() -> FontDialogBuilder {
34 FontDialogBuilder::new()
35 }
36
37 #[doc(alias = "gtk_font_dialog_choose_face")]
38 pub fn choose_face<P: FnOnce(Result<pango::FontFace, glib::Error>) + 'static>(
39 &self,
40 parent: Option<&impl IsA<Window>>,
41 initial_value: Option<&impl IsA<pango::FontFace>>,
42 cancellable: Option<&impl IsA<gio::Cancellable>>,
43 callback: P,
44 ) {
45 let main_context = glib::MainContext::ref_thread_default();
46 let is_main_context_owner = main_context.is_owner();
47 let has_acquired_main_context = (!is_main_context_owner)
48 .then(|| main_context.acquire().ok())
49 .flatten();
50 assert!(
51 is_main_context_owner || has_acquired_main_context.is_some(),
52 "Async operations only allowed if the thread is owning the MainContext"
53 );
54
55 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
56 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
57 unsafe extern "C" fn choose_face_trampoline<
58 P: FnOnce(Result<pango::FontFace, glib::Error>) + 'static,
59 >(
60 _source_object: *mut glib::gobject_ffi::GObject,
61 res: *mut gio::ffi::GAsyncResult,
62 user_data: glib::ffi::gpointer,
63 ) {
64 let mut error = std::ptr::null_mut();
65 let ret =
66 ffi::gtk_font_dialog_choose_face_finish(_source_object as *mut _, res, &mut error);
67 let result = if error.is_null() {
68 Ok(from_glib_full(ret))
69 } else {
70 Err(from_glib_full(error))
71 };
72 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
73 Box_::from_raw(user_data as *mut _);
74 let callback: P = callback.into_inner();
75 callback(result);
76 }
77 let callback = choose_face_trampoline::<P>;
78 unsafe {
79 ffi::gtk_font_dialog_choose_face(
80 self.to_glib_none().0,
81 parent.map(|p| p.as_ref()).to_glib_none().0,
82 initial_value.map(|p| p.as_ref()).to_glib_none().0,
83 cancellable.map(|p| p.as_ref()).to_glib_none().0,
84 Some(callback),
85 Box_::into_raw(user_data) as *mut _,
86 );
87 }
88 }
89
90 pub fn choose_face_future(
91 &self,
92 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
93 initial_value: Option<&(impl IsA<pango::FontFace> + Clone + 'static)>,
94 ) -> Pin<Box_<dyn std::future::Future<Output = Result<pango::FontFace, glib::Error>> + 'static>>
95 {
96 let parent = parent.map(ToOwned::to_owned);
97 let initial_value = initial_value.map(ToOwned::to_owned);
98 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
99 obj.choose_face(
100 parent.as_ref().map(::std::borrow::Borrow::borrow),
101 initial_value.as_ref().map(::std::borrow::Borrow::borrow),
102 Some(cancellable),
103 move |res| {
104 send.resolve(res);
105 },
106 );
107 }))
108 }
109
110 #[doc(alias = "gtk_font_dialog_choose_family")]
111 pub fn choose_family<P: FnOnce(Result<pango::FontFamily, glib::Error>) + 'static>(
112 &self,
113 parent: Option<&impl IsA<Window>>,
114 initial_value: Option<&impl IsA<pango::FontFamily>>,
115 cancellable: Option<&impl IsA<gio::Cancellable>>,
116 callback: P,
117 ) {
118 let main_context = glib::MainContext::ref_thread_default();
119 let is_main_context_owner = main_context.is_owner();
120 let has_acquired_main_context = (!is_main_context_owner)
121 .then(|| main_context.acquire().ok())
122 .flatten();
123 assert!(
124 is_main_context_owner || has_acquired_main_context.is_some(),
125 "Async operations only allowed if the thread is owning the MainContext"
126 );
127
128 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
129 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
130 unsafe extern "C" fn choose_family_trampoline<
131 P: FnOnce(Result<pango::FontFamily, glib::Error>) + 'static,
132 >(
133 _source_object: *mut glib::gobject_ffi::GObject,
134 res: *mut gio::ffi::GAsyncResult,
135 user_data: glib::ffi::gpointer,
136 ) {
137 let mut error = std::ptr::null_mut();
138 let ret = ffi::gtk_font_dialog_choose_family_finish(
139 _source_object as *mut _,
140 res,
141 &mut error,
142 );
143 let result = if error.is_null() {
144 Ok(from_glib_full(ret))
145 } else {
146 Err(from_glib_full(error))
147 };
148 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
149 Box_::from_raw(user_data as *mut _);
150 let callback: P = callback.into_inner();
151 callback(result);
152 }
153 let callback = choose_family_trampoline::<P>;
154 unsafe {
155 ffi::gtk_font_dialog_choose_family(
156 self.to_glib_none().0,
157 parent.map(|p| p.as_ref()).to_glib_none().0,
158 initial_value.map(|p| p.as_ref()).to_glib_none().0,
159 cancellable.map(|p| p.as_ref()).to_glib_none().0,
160 Some(callback),
161 Box_::into_raw(user_data) as *mut _,
162 );
163 }
164 }
165
166 pub fn choose_family_future(
167 &self,
168 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
169 initial_value: Option<&(impl IsA<pango::FontFamily> + Clone + 'static)>,
170 ) -> Pin<Box_<dyn std::future::Future<Output = Result<pango::FontFamily, glib::Error>> + 'static>>
171 {
172 let parent = parent.map(ToOwned::to_owned);
173 let initial_value = initial_value.map(ToOwned::to_owned);
174 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
175 obj.choose_family(
176 parent.as_ref().map(::std::borrow::Borrow::borrow),
177 initial_value.as_ref().map(::std::borrow::Borrow::borrow),
178 Some(cancellable),
179 move |res| {
180 send.resolve(res);
181 },
182 );
183 }))
184 }
185
186 #[doc(alias = "gtk_font_dialog_choose_font")]
187 pub fn choose_font<P: FnOnce(Result<pango::FontDescription, glib::Error>) + 'static>(
188 &self,
189 parent: Option<&impl IsA<Window>>,
190 initial_value: Option<&pango::FontDescription>,
191 cancellable: Option<&impl IsA<gio::Cancellable>>,
192 callback: P,
193 ) {
194 let main_context = glib::MainContext::ref_thread_default();
195 let is_main_context_owner = main_context.is_owner();
196 let has_acquired_main_context = (!is_main_context_owner)
197 .then(|| main_context.acquire().ok())
198 .flatten();
199 assert!(
200 is_main_context_owner || has_acquired_main_context.is_some(),
201 "Async operations only allowed if the thread is owning the MainContext"
202 );
203
204 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
205 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
206 unsafe extern "C" fn choose_font_trampoline<
207 P: FnOnce(Result<pango::FontDescription, glib::Error>) + 'static,
208 >(
209 _source_object: *mut glib::gobject_ffi::GObject,
210 res: *mut gio::ffi::GAsyncResult,
211 user_data: glib::ffi::gpointer,
212 ) {
213 let mut error = std::ptr::null_mut();
214 let ret =
215 ffi::gtk_font_dialog_choose_font_finish(_source_object as *mut _, res, &mut error);
216 let result = if error.is_null() {
217 Ok(from_glib_full(ret))
218 } else {
219 Err(from_glib_full(error))
220 };
221 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
222 Box_::from_raw(user_data as *mut _);
223 let callback: P = callback.into_inner();
224 callback(result);
225 }
226 let callback = choose_font_trampoline::<P>;
227 unsafe {
228 ffi::gtk_font_dialog_choose_font(
229 self.to_glib_none().0,
230 parent.map(|p| p.as_ref()).to_glib_none().0,
231 mut_override(initial_value.to_glib_none().0),
232 cancellable.map(|p| p.as_ref()).to_glib_none().0,
233 Some(callback),
234 Box_::into_raw(user_data) as *mut _,
235 );
236 }
237 }
238
239 pub fn choose_font_future(
240 &self,
241 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
242 initial_value: Option<&pango::FontDescription>,
243 ) -> Pin<
244 Box_<
245 dyn std::future::Future<Output = Result<pango::FontDescription, glib::Error>> + 'static,
246 >,
247 > {
248 let parent = parent.map(ToOwned::to_owned);
249 let initial_value = initial_value.map(ToOwned::to_owned);
250 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
251 obj.choose_font(
252 parent.as_ref().map(::std::borrow::Borrow::borrow),
253 initial_value.as_ref().map(::std::borrow::Borrow::borrow),
254 Some(cancellable),
255 move |res| {
256 send.resolve(res);
257 },
258 );
259 }))
260 }
261
262 #[doc(alias = "gtk_font_dialog_get_filter")]
263 #[doc(alias = "get_filter")]
264 pub fn filter(&self) -> Option<Filter> {
265 unsafe { from_glib_none(ffi::gtk_font_dialog_get_filter(self.to_glib_none().0)) }
266 }
267
268 #[doc(alias = "gtk_font_dialog_get_font_map")]
269 #[doc(alias = "get_font_map")]
270 #[doc(alias = "font-map")]
271 pub fn font_map(&self) -> Option<pango::FontMap> {
272 unsafe { from_glib_none(ffi::gtk_font_dialog_get_font_map(self.to_glib_none().0)) }
273 }
274
275 #[doc(alias = "gtk_font_dialog_get_language")]
276 #[doc(alias = "get_language")]
277 pub fn language(&self) -> Option<pango::Language> {
278 unsafe { from_glib_full(ffi::gtk_font_dialog_get_language(self.to_glib_none().0)) }
279 }
280
281 #[doc(alias = "gtk_font_dialog_get_modal")]
282 #[doc(alias = "get_modal")]
283 #[doc(alias = "modal")]
284 pub fn is_modal(&self) -> bool {
285 unsafe { from_glib(ffi::gtk_font_dialog_get_modal(self.to_glib_none().0)) }
286 }
287
288 #[doc(alias = "gtk_font_dialog_get_title")]
289 #[doc(alias = "get_title")]
290 pub fn title(&self) -> glib::GString {
291 unsafe { from_glib_none(ffi::gtk_font_dialog_get_title(self.to_glib_none().0)) }
292 }
293
294 #[doc(alias = "gtk_font_dialog_set_filter")]
295 #[doc(alias = "filter")]
296 pub fn set_filter(&self, filter: Option<&impl IsA<Filter>>) {
297 unsafe {
298 ffi::gtk_font_dialog_set_filter(
299 self.to_glib_none().0,
300 filter.map(|p| p.as_ref()).to_glib_none().0,
301 );
302 }
303 }
304
305 #[doc(alias = "gtk_font_dialog_set_font_map")]
306 #[doc(alias = "font-map")]
307 pub fn set_font_map(&self, fontmap: Option<&impl IsA<pango::FontMap>>) {
308 unsafe {
309 ffi::gtk_font_dialog_set_font_map(
310 self.to_glib_none().0,
311 fontmap.map(|p| p.as_ref()).to_glib_none().0,
312 );
313 }
314 }
315
316 #[doc(alias = "gtk_font_dialog_set_language")]
317 #[doc(alias = "language")]
318 pub fn set_language(&self, language: &pango::Language) {
319 unsafe {
320 ffi::gtk_font_dialog_set_language(
321 self.to_glib_none().0,
322 mut_override(language.to_glib_none().0),
323 );
324 }
325 }
326
327 #[doc(alias = "gtk_font_dialog_set_modal")]
328 #[doc(alias = "modal")]
329 pub fn set_modal(&self, modal: bool) {
330 unsafe {
331 ffi::gtk_font_dialog_set_modal(self.to_glib_none().0, modal.into_glib());
332 }
333 }
334
335 #[doc(alias = "gtk_font_dialog_set_title")]
336 #[doc(alias = "title")]
337 pub fn set_title(&self, title: &str) {
338 unsafe {
339 ffi::gtk_font_dialog_set_title(self.to_glib_none().0, title.to_glib_none().0);
340 }
341 }
342
343 #[cfg(feature = "v4_10")]
344 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
345 #[doc(alias = "filter")]
346 pub fn connect_filter_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
347 unsafe extern "C" fn notify_filter_trampoline<F: Fn(&FontDialog) + 'static>(
348 this: *mut ffi::GtkFontDialog,
349 _param_spec: glib::ffi::gpointer,
350 f: glib::ffi::gpointer,
351 ) {
352 let f: &F = &*(f as *const F);
353 f(&from_glib_borrow(this))
354 }
355 unsafe {
356 let f: Box_<F> = Box_::new(f);
357 connect_raw(
358 self.as_ptr() as *mut _,
359 c"notify::filter".as_ptr() as *const _,
360 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
361 notify_filter_trampoline::<F> as *const (),
362 )),
363 Box_::into_raw(f),
364 )
365 }
366 }
367
368 #[cfg(feature = "v4_10")]
369 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
370 #[doc(alias = "font-map")]
371 pub fn connect_font_map_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
372 unsafe extern "C" fn notify_font_map_trampoline<F: Fn(&FontDialog) + 'static>(
373 this: *mut ffi::GtkFontDialog,
374 _param_spec: glib::ffi::gpointer,
375 f: glib::ffi::gpointer,
376 ) {
377 let f: &F = &*(f as *const F);
378 f(&from_glib_borrow(this))
379 }
380 unsafe {
381 let f: Box_<F> = Box_::new(f);
382 connect_raw(
383 self.as_ptr() as *mut _,
384 c"notify::font-map".as_ptr() as *const _,
385 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
386 notify_font_map_trampoline::<F> as *const (),
387 )),
388 Box_::into_raw(f),
389 )
390 }
391 }
392
393 #[cfg(feature = "v4_10")]
394 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
395 #[doc(alias = "language")]
396 pub fn connect_language_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
397 unsafe extern "C" fn notify_language_trampoline<F: Fn(&FontDialog) + 'static>(
398 this: *mut ffi::GtkFontDialog,
399 _param_spec: glib::ffi::gpointer,
400 f: glib::ffi::gpointer,
401 ) {
402 let f: &F = &*(f as *const F);
403 f(&from_glib_borrow(this))
404 }
405 unsafe {
406 let f: Box_<F> = Box_::new(f);
407 connect_raw(
408 self.as_ptr() as *mut _,
409 c"notify::language".as_ptr() as *const _,
410 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
411 notify_language_trampoline::<F> as *const (),
412 )),
413 Box_::into_raw(f),
414 )
415 }
416 }
417
418 #[cfg(feature = "v4_10")]
419 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
420 #[doc(alias = "modal")]
421 pub fn connect_modal_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
422 unsafe extern "C" fn notify_modal_trampoline<F: Fn(&FontDialog) + 'static>(
423 this: *mut ffi::GtkFontDialog,
424 _param_spec: glib::ffi::gpointer,
425 f: glib::ffi::gpointer,
426 ) {
427 let f: &F = &*(f as *const F);
428 f(&from_glib_borrow(this))
429 }
430 unsafe {
431 let f: Box_<F> = Box_::new(f);
432 connect_raw(
433 self.as_ptr() as *mut _,
434 c"notify::modal".as_ptr() as *const _,
435 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
436 notify_modal_trampoline::<F> as *const (),
437 )),
438 Box_::into_raw(f),
439 )
440 }
441 }
442
443 #[cfg(feature = "v4_10")]
444 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
445 #[doc(alias = "title")]
446 pub fn connect_title_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
447 unsafe extern "C" fn notify_title_trampoline<F: Fn(&FontDialog) + 'static>(
448 this: *mut ffi::GtkFontDialog,
449 _param_spec: glib::ffi::gpointer,
450 f: glib::ffi::gpointer,
451 ) {
452 let f: &F = &*(f as *const F);
453 f(&from_glib_borrow(this))
454 }
455 unsafe {
456 let f: Box_<F> = Box_::new(f);
457 connect_raw(
458 self.as_ptr() as *mut _,
459 c"notify::title".as_ptr() as *const _,
460 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
461 notify_title_trampoline::<F> as *const (),
462 )),
463 Box_::into_raw(f),
464 )
465 }
466 }
467}
468
469#[cfg(feature = "v4_10")]
470#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
471impl Default for FontDialog {
472 fn default() -> Self {
473 Self::new()
474 }
475}
476
477#[must_use = "The builder must be built to be used"]
482pub struct FontDialogBuilder {
483 builder: glib::object::ObjectBuilder<'static, FontDialog>,
484}
485
486impl FontDialogBuilder {
487 fn new() -> Self {
488 Self {
489 builder: glib::object::Object::builder(),
490 }
491 }
492
493 #[cfg(feature = "v4_10")]
494 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
495 pub fn filter(self, filter: &impl IsA<Filter>) -> Self {
496 Self {
497 builder: self.builder.property("filter", filter.clone().upcast()),
498 }
499 }
500
501 #[cfg(feature = "v4_10")]
502 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
503 pub fn font_map(self, font_map: &impl IsA<pango::FontMap>) -> Self {
504 Self {
505 builder: self.builder.property("font-map", font_map.clone().upcast()),
506 }
507 }
508
509 #[cfg(feature = "v4_10")]
510 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
511 pub fn language(self, language: &pango::Language) -> Self {
512 Self {
513 builder: self.builder.property("language", language),
514 }
515 }
516
517 #[cfg(feature = "v4_10")]
518 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
519 pub fn modal(self, modal: bool) -> Self {
520 Self {
521 builder: self.builder.property("modal", modal),
522 }
523 }
524
525 #[cfg(feature = "v4_10")]
526 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
527 pub fn title(self, title: impl Into<glib::GString>) -> Self {
528 Self {
529 builder: self.builder.property("title", title.into()),
530 }
531 }
532
533 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
536 pub fn build(self) -> FontDialog {
537 assert_initialized_main_thread!();
538 self.builder.build()
539 }
540}