1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use gtk::{glib, prelude::*, subclass::prelude::*};

mod imp {
    use super::*;

    #[derive(Default, gtk::CompositeTemplate)]
    #[template(resource = "/com/belmoussaoui/Authenticator/error_revealer.ui")]
    pub struct ErrorRevealer {
        #[template_child]
        pub label: TemplateChild<gtk::Label>,
        #[template_child]
        pub revealer: TemplateChild<gtk::Revealer>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for ErrorRevealer {
        const NAME: &'static str = "ErrorRevealer";
        type Type = super::ErrorRevealer;
        type ParentType = gtk::Widget;

        fn class_init(klass: &mut Self::Class) {
            klass.set_layout_manager_type::<gtk::BinLayout>();
            klass.bind_template();
        }

        fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
            obj.init_template();
        }
    }

    impl ObjectImpl for ErrorRevealer {
        fn dispose(&self) {
            self.revealer.unparent();
            self.label.unparent();
        }
    }

    impl WidgetImpl for ErrorRevealer {}
}

glib::wrapper! {
    pub struct ErrorRevealer(ObjectSubclass<imp::ErrorRevealer>)
        @extends gtk::Widget;
}

impl ErrorRevealer {
    pub fn popup(&self, text: &str) {
        let imp = self.imp();
        imp.label.set_text(text);
        self.set_visible(true);
        imp.revealer.set_reveal_child(true);
        glib::timeout_add_seconds_local(
            2,
            glib::clone!(@weak self as error_revealer => @default-return glib::ControlFlow::Break, move || {
                error_revealer.imp().revealer.set_reveal_child(false);
                error_revealer.set_visible(false);
                glib::ControlFlow::Break
            }),
        );
    }
}