1use crate::prelude::*;
4use crate::Dialog;
5use crate::DialogFlags;
6use crate::ResponseType;
7use crate::Widget;
8use crate::Window;
9use glib::translate::*;
10use std::cell::Cell;
11use std::future::Future;
12use std::pin::Pin;
13use std::ptr;
14
15impl Dialog {
16 #[doc(alias = "gtk_dialog_new_with_buttons")]
17 pub fn with_buttons<T: IsA<Window>>(
18 title: Option<&str>,
19 parent: Option<&T>,
20 flags: DialogFlags,
21 buttons: &[(&str, ResponseType)],
22 ) -> Dialog {
23 assert_initialized_main_thread!();
24 let ret: Dialog = unsafe {
25 Widget::from_glib_none(ffi::gtk_dialog_new_with_buttons(
26 title.to_glib_none().0,
27 parent.map(|p| p.as_ref()).to_glib_none().0,
28 flags.into_glib(),
29 ptr::null_mut(),
30 ))
31 .unsafe_cast()
32 };
33
34 ret.add_buttons(buttons);
35 ret
36 }
37}
38
39mod sealed {
40 pub trait Sealed {}
41 impl<T: glib::IsA<crate::Dialog> + glib::IsA<crate::Widget>> Sealed for T {}
42}
43
44pub trait DialogExtManual: IsA<Dialog> + IsA<Widget> + sealed::Sealed + 'static {
45 #[doc(alias = "gtk_dialog_add_buttons")]
46 fn add_buttons(&self, buttons: &[(&str, ResponseType)]) {
47 for &(text, id) in buttons {
48 Self::add_button(self, text, id);
50 }
51 }
52
53 fn run_future<'a>(&'a self) -> Pin<Box<dyn Future<Output = ResponseType> + 'a>> {
72 Box::pin(async move {
73 let (sender, receiver) = futures_channel::oneshot::channel();
74
75 let sender = Cell::new(Some(sender));
76
77 let response_handler = self.connect_response(move |_, response_type| {
78 if let Some(m) = sender.replace(None) {
79 let _result = m.send(response_type);
80 }
81 });
82
83 self.show();
84
85 if let Ok(response) = receiver.await {
86 if response != ResponseType::DeleteEvent {
87 self.disconnect(response_handler);
88 }
89 response
90 } else {
91 ResponseType::None
92 }
93 })
94 }
95}
96
97impl<O: IsA<Dialog> + IsA<Widget>> DialogExtManual for O {}