Skip to main content

gtk/
fixed.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::Widget;
4use crate::{Fixed, ffi};
5use glib::object::IsA;
6use glib::translate::*;
7
8// All this is in order to avoid the segfault. More info in :
9// https://github.com/gtk-rs/gtk/issues/565
10fn has_widget<O: IsA<Fixed>, T: IsA<Widget>>(c: &O, item: &T) -> bool {
11    skip_assert_initialized!();
12    unsafe {
13        let glist = ffi::gtk_container_get_children(c.to_glib_none().0 as *mut _);
14        let found = !glib::ffi::g_list_find(glist, item.to_glib_none().0 as _).is_null();
15        glib::ffi::g_list_free(glist);
16        found
17    }
18}
19
20mod sealed {
21    pub trait Sealed {}
22    impl<T: glib::object::IsA<crate::Fixed>> Sealed for T {}
23}
24
25pub trait FixedExtManual: IsA<Fixed> + sealed::Sealed + 'static {
26    #[doc(alias = "get_child_x")]
27    fn child_x<T: IsA<Widget>>(&self, item: &T) -> i32 {
28        assert!(
29            has_widget(self, item),
30            "this item isn't in the Fixed's widget list"
31        );
32        let mut value = glib::Value::from(&0);
33        unsafe {
34            ffi::gtk_container_child_get_property(
35                self.to_glib_none().0 as *mut _,
36                item.as_ref().to_glib_none().0,
37                "x".to_glib_none().0,
38                value.to_glib_none_mut().0,
39            );
40        }
41        value
42            .get()
43            .expect("Return Value for `FixedExtManual::get_child_x`")
44    }
45
46    fn set_child_x<T: IsA<Widget>>(&self, item: &T, x: i32) {
47        assert!(
48            has_widget(self, item),
49            "this item isn't in the Fixed's widget list"
50        );
51        unsafe {
52            ffi::gtk_container_child_set_property(
53                self.to_glib_none().0 as *mut _,
54                item.as_ref().to_glib_none().0,
55                "x".to_glib_none().0,
56                glib::Value::from(&x).to_glib_none().0,
57            );
58        }
59    }
60
61    #[doc(alias = "get_child_y")]
62    fn child_y<T: IsA<Widget>>(&self, item: &T) -> i32 {
63        assert!(
64            has_widget(self, item),
65            "this item isn't in the Fixed's widget list"
66        );
67        let mut value = glib::Value::from(&0);
68        unsafe {
69            ffi::gtk_container_child_get_property(
70                self.to_glib_none().0 as *mut _,
71                item.as_ref().to_glib_none().0,
72                "y".to_glib_none().0,
73                value.to_glib_none_mut().0,
74            );
75        }
76        value
77            .get()
78            .expect("Return Value for `FixedExtManual::get_child_y`")
79    }
80
81    fn set_child_y<T: IsA<Widget>>(&self, item: &T, y: i32) {
82        assert!(
83            has_widget(self, item),
84            "this item isn't in the Fixed's widget list"
85        );
86        unsafe {
87            ffi::gtk_container_child_set_property(
88                self.to_glib_none().0 as *mut _,
89                item.as_ref().to_glib_none().0,
90                "y".to_glib_none().0,
91                glib::Value::from(&y).to_glib_none().0,
92            );
93        }
94    }
95}
96
97impl<O: IsA<Fixed>> FixedExtManual for O {}