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