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")]
26 #[doc(alias = "get_response_label")]
27 fn response_label(&self, response: &str) -> glib::GString {
28 assert!(self.as_ref().has_response(response));
29
30 unsafe {
31 from_glib_none(ffi::adw_alert_dialog_get_response_label(
32 self.as_ref().to_glib_none().0,
33 response.to_glib_none().0,
34 ))
35 }
36 }
37
38 #[doc(alias = "adw_alert_dialog_add_responses")]
58 fn add_responses(&self, ids_and_labels: &[(&str, &str)]) {
59 ids_and_labels.iter().for_each(|(id, label)| {
60 self.add_response(id, label);
61 });
62 }
63
64 #[doc(alias = "adw_alert_dialog_choose")]
75 fn choose<P: FnOnce(glib::GString) + 'static>(
76 self,
77 parent: Option<&impl IsA<gtk::Widget>>,
78 cancellable: Option<&impl IsA<gio::Cancellable>>,
79 callback: P,
80 ) {
81 let main_context = glib::MainContext::ref_thread_default();
82 let is_main_context_owner = main_context.is_owner();
83 let has_acquired_main_context = (!is_main_context_owner)
84 .then(|| main_context.acquire().ok())
85 .flatten();
86 assert!(
87 is_main_context_owner || has_acquired_main_context.is_some(),
88 "Async operations only allowed if the thread is owning the MainContext"
89 );
90
91 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
92 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
93 unsafe extern "C" fn choose_trampoline<P: FnOnce(glib::GString) + 'static>(
94 _source_object: *mut glib::gobject_ffi::GObject,
95 res: *mut gio::ffi::GAsyncResult,
96 user_data: glib::ffi::gpointer,
97 ) {
98 unsafe {
99 let result = from_glib_none(ffi::adw_alert_dialog_choose_finish(
100 _source_object as *mut _,
101 res,
102 ));
103 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
104 Box_::from_raw(user_data as *mut _);
105 let callback: P = callback.into_inner();
106 callback(result);
107 }
108 }
109 let callback = choose_trampoline::<P>;
110 unsafe {
111 ffi::adw_alert_dialog_choose(
112 self.upcast().into_glib_ptr(),
113 parent.map(|p| p.as_ref()).to_glib_none().0,
114 cancellable.map(|p| p.as_ref()).to_glib_none().0,
115 Some(callback),
116 Box_::into_raw(user_data) as *mut _,
117 );
118 }
119 }
120
121 fn choose_future(
122 self,
123 parent: Option<&impl IsA<gtk::Widget>>,
124 ) -> Pin<Box_<dyn std::future::Future<Output = glib::GString> + 'static>> {
125 let parent = parent.map(ToOwned::to_owned);
126 Box_::pin(gio::GioFuture::new(
127 &self,
128 move |obj: &Self, cancellable, send| {
129 obj.clone().choose(
130 parent.as_ref().map(::std::borrow::Borrow::borrow),
131 Some(cancellable),
132 move |res| {
133 send.resolve(res);
134 },
135 );
136 },
137 ))
138 }
139}
140
141impl<O: IsA<AlertDialog>> AlertDialogExtManual for O {}