libadwaita/
alert_dialog.rs1use glib::object::IsA;
2use glib::translate::*;
3
4use crate::prelude::*;
5use crate::AlertDialog;
6
7use std::boxed::Box as Box_;
8use std::pin::Pin;
9
10mod sealed {
11 pub trait Sealed {}
12 impl<T: super::IsA<super::AlertDialog>> Sealed for T {}
13}
14
15pub trait AlertDialogExtManual: sealed::Sealed + IsA<AlertDialog> + 'static {
16 #[doc(alias = "adw_alert_dialog_get_response_label")]
17 #[doc(alias = "get_response_label")]
18 fn response_label(&self, response: &str) -> glib::GString {
19 assert!(self.as_ref().has_response(response));
20
21 unsafe {
22 from_glib_none(ffi::adw_alert_dialog_get_response_label(
23 self.as_ref().to_glib_none().0,
24 response.to_glib_none().0,
25 ))
26 }
27 }
28
29 #[doc(alias = "adw_alert_dialog_add_responses")]
30 fn add_responses(&self, ids_and_labels: &[(&str, &str)]) {
31 ids_and_labels.iter().for_each(|(id, label)| {
32 self.add_response(id, label);
33 });
34 }
35
36 #[doc(alias = "adw_alert_dialog_choose")]
37 fn choose<P: FnOnce(glib::GString) + 'static>(
38 self,
39 parent: Option<&impl IsA<gtk::Widget>>,
40 cancellable: Option<&impl IsA<gio::Cancellable>>,
41 callback: P,
42 ) {
43 let main_context = glib::MainContext::ref_thread_default();
44 let is_main_context_owner = main_context.is_owner();
45 let has_acquired_main_context = (!is_main_context_owner)
46 .then(|| main_context.acquire().ok())
47 .flatten();
48 assert!(
49 is_main_context_owner || has_acquired_main_context.is_some(),
50 "Async operations only allowed if the thread is owning the MainContext"
51 );
52
53 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
54 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
55 unsafe extern "C" fn choose_trampoline<P: FnOnce(glib::GString) + 'static>(
56 _source_object: *mut glib::gobject_ffi::GObject,
57 res: *mut gio::ffi::GAsyncResult,
58 user_data: glib::ffi::gpointer,
59 ) {
60 unsafe {
61 let result = from_glib_none(ffi::adw_alert_dialog_choose_finish(
62 _source_object as *mut _,
63 res,
64 ));
65 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
66 Box_::from_raw(user_data as *mut _);
67 let callback: P = callback.into_inner();
68 callback(result);
69 }
70 }
71 let callback = choose_trampoline::<P>;
72 unsafe {
73 ffi::adw_alert_dialog_choose(
74 self.upcast().into_glib_ptr(),
75 parent.map(|p| p.as_ref()).to_glib_none().0,
76 cancellable.map(|p| p.as_ref()).to_glib_none().0,
77 Some(callback),
78 Box_::into_raw(user_data) as *mut _,
79 );
80 }
81 }
82
83 fn choose_future(
84 self,
85 parent: Option<&impl IsA<gtk::Widget>>,
86 ) -> Pin<Box_<dyn std::future::Future<Output = glib::GString> + 'static>> {
87 let parent = parent.map(ToOwned::to_owned);
88 Box_::pin(gio::GioFuture::new(
89 &self,
90 move |obj: &Self, cancellable, send| {
91 obj.clone().choose(
92 parent.as_ref().map(::std::borrow::Borrow::borrow),
93 Some(cancellable),
94 move |res| {
95 send.resolve(res);
96 },
97 );
98 },
99 ))
100 }
101}
102
103impl<O: IsA<AlertDialog>> AlertDialogExtManual for O {}