gtk_test/
observer.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3
4/// Used to wait for a widget's signal.
5///
6/// It's recommended to use it with the [`observer_new`] macro.
7///
8/// Example:
9///
10/// ```
11/// extern crate gtk;
12/// #[macro_use]
13/// extern crate gtk_test;
14///
15/// use gtk::prelude::GtkWindowExt;
16///
17/// # fn main() {
18/// gtk::init().expect("initialization failed");
19/// let window = gtk::Window::new(gtk::WindowType::Toplevel);
20///
21/// let observer = observer_new!(window, connect_activate_focus, |_|);
22/// window.emit_activate_focus();
23/// observer.wait();
24/// # }
25/// ```
26pub struct Observer {
27    result: Rc<RefCell<bool>>,
28}
29
30impl Observer {
31    /// Returns a new observer.
32    ///
33    /// It's recommended to not use it directly as is but instead to use the [`observer_new`] macro.
34    ///
35    /// But anyway, here's an example using it as is:
36    ///
37    /// ```
38    /// extern crate gtk;
39    /// #[macro_use]
40    /// extern crate gtk_test;
41    ///
42    /// use gtk::prelude::GtkWindowExt;
43    ///
44    /// # fn main() {
45    /// gtk::init().expect("GTK init failed");
46    ///
47    /// let window = gtk::Window::new(gtk::WindowType::Toplevel);
48    ///
49    /// let observer = gtk_test::Observer::new();
50    /// let inner = observer.get_inner().clone();
51    /// window.connect_activate_focus(move |_| {
52    ///     *inner.borrow_mut() = true;
53    /// });
54    ///
55    /// window.emit_activate_focus();
56    /// observer.wait();
57    /// # }
58    /// ```
59    pub fn new() -> Observer {
60        Observer {
61            result: Rc::new(RefCell::new(false)),
62        }
63    }
64
65    /// Returns the inner field. Just don't use it.
66    pub fn get_inner(&self) -> &Rc<RefCell<bool>> {
67        &self.result
68    }
69
70    /// Wait for the signal to be triggered.
71    ///
72    /// ```
73    /// extern crate gtk;
74    /// #[macro_use]
75    /// extern crate gtk_test;
76    ///
77    /// use gtk::prelude::GtkWindowExt;
78    ///
79    /// # fn main() {
80    /// gtk::init().expect("initialization failed");
81    /// let window = gtk::Window::new(gtk::WindowType::Toplevel);
82    ///
83    /// let observer = observer_new!(window, connect_activate_focus, |_|);
84    /// window.emit_activate_focus();
85    /// observer.wait();
86    /// # }
87    /// ```
88    pub fn wait(&self) {
89        loop {
90            if let Ok(ref result) = self.result.try_borrow() {
91                if **result {
92                    break;
93                }
94            }
95            crate::run_loop();
96        }
97    }
98}
99
100impl Default for Observer {
101    fn default() -> Self {
102        Self::new()
103    }
104}