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}