relm4/extensions/
object_ext.rs

1use glib::prelude::{IsA, ObjectExt};
2use gtk::glib;
3
4use crate::binding::Binding;
5
6/// Trait that extends [`gtk::prelude::ObjectExt`].
7pub trait RelmObjectExt {
8    /// Runs the given function when the object is destroyed.
9    fn on_destroy<F: FnOnce() + 'static>(&self, func: F);
10
11    /// Bind a data binding to a property of an object.
12    ///
13    /// This is similar to [`gtk::prelude::ObjectExt::bind_property`] and
14    /// always bidirectional.
15    fn add_binding<B: Binding>(&self, binding: &B, property_name: &str);
16
17    /// Bind a data binding to a property of an object with
18    /// uni-directional access, so values can only be written but are not synced
19    /// in the other direction.
20    fn add_write_only_binding<B: Binding>(&self, binding: &B, property_name: &str);
21}
22
23impl<T: IsA<glib::Object>> RelmObjectExt for T {
24    fn on_destroy<F: FnOnce() + 'static>(&self, func: F) {
25        let func = std::cell::RefCell::new(Some(func));
26        self.as_ref().add_weak_ref_notify_local(move || {
27            if let Some(func) = func.take() {
28                func();
29            }
30        });
31    }
32
33    fn add_binding<B: Binding>(&self, binding: &B, property_name: &str) {
34        binding
35            .bind_property(B::property_name(), self, property_name)
36            .bidirectional()
37            .sync_create()
38            .build();
39    }
40
41    fn add_write_only_binding<B: Binding>(&self, binding: &B, property_name: &str) {
42        binding
43            .bind_property(B::property_name(), self, property_name)
44            .sync_create()
45            .build();
46    }
47}