fractal/login/
advanced_dialog.rs

1use adw::{prelude::*, subclass::prelude::*};
2use futures_channel::oneshot;
3use gtk::{glib, CompositeTemplate};
4
5mod imp {
6    use std::cell::{Cell, RefCell};
7
8    use glib::subclass::InitializingObject;
9
10    use super::*;
11
12    #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
13    #[template(resource = "/org/gnome/Fractal/ui/login/advanced_dialog.ui")]
14    #[properties(wrapper_type = super::LoginAdvancedDialog)]
15    pub struct LoginAdvancedDialog {
16        /// Whether auto-discovery is enabled.
17        #[property(get, set, default = true)]
18        autodiscovery: Cell<bool>,
19        sender: RefCell<Option<oneshot::Sender<()>>>,
20    }
21
22    #[glib::object_subclass]
23    impl ObjectSubclass for LoginAdvancedDialog {
24        const NAME: &'static str = "LoginAdvancedDialog";
25        type Type = super::LoginAdvancedDialog;
26        type ParentType = adw::PreferencesDialog;
27
28        fn class_init(klass: &mut Self::Class) {
29            Self::bind_template(klass);
30        }
31
32        fn instance_init(obj: &InitializingObject<Self>) {
33            obj.init_template();
34        }
35    }
36
37    #[glib::derived_properties]
38    impl ObjectImpl for LoginAdvancedDialog {}
39
40    impl WidgetImpl for LoginAdvancedDialog {}
41
42    impl AdwDialogImpl for LoginAdvancedDialog {
43        fn closed(&self) {
44            if let Some(sender) = self.sender.take() {
45                sender.send(()).expect("receiver was not dropped");
46            }
47        }
48    }
49
50    impl PreferencesDialogImpl for LoginAdvancedDialog {}
51
52    impl LoginAdvancedDialog {
53        /// Present this dialog.
54        ///
55        /// Returns when the dialog is closed.
56        pub(super) async fn run_future(&self, parent: &gtk::Widget) {
57            let (sender, receiver) = oneshot::channel();
58            self.sender.replace(Some(sender));
59
60            self.obj().present(Some(parent));
61            receiver.await.expect("sender was not dropped");
62        }
63    }
64}
65
66glib::wrapper! {
67    /// A dialog with advanced settings for the login flow.
68    pub struct LoginAdvancedDialog(ObjectSubclass<imp::LoginAdvancedDialog>)
69        @extends gtk::Widget, adw::Dialog, adw::PreferencesDialog,
70        @implements gtk::Accessible;
71}
72
73impl LoginAdvancedDialog {
74    pub fn new() -> Self {
75        glib::Object::new()
76    }
77
78    /// Present this dialog.
79    ///
80    /// Returns when the dialog is closed.
81    pub(crate) async fn run_future(&self, parent: &impl IsA<gtk::Widget>) {
82        self.imp().run_future(parent.upcast_ref()).await;
83    }
84}