Skip to main content

gtk4/
constraint_layout.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{Constraint, ConstraintLayout, Widget, ffi, prelude::*};
6
7impl ConstraintLayout {
8    /// =20)]-|
9    ///
10    ///   // Operators
11    ///   [button1(button2 / 3 + 50)]
12    ///
13    ///   // Named attributes
14    ///   [button1(==button2.height)]
15    /// ```text
16    ///
17    /// ## `lines`
18    /// an array of Visual Format Language lines
19    ///   defining a set of constraints
20    /// ## `hspacing`
21    /// default horizontal spacing value, or -1 for the fallback value
22    /// ## `vspacing`
23    /// default vertical spacing value, or -1 for the fallback value
24    /// ## `views`
25    /// a dictionary of `[ name, target ]`
26    ///   pairs; the `name` keys map to the view names in the VFL lines, while
27    ///   the `target` values map to children of the widget using a [`ConstraintLayout`][crate::ConstraintLayout],
28    ///   or guides
29    ///
30    /// # Returns
31    ///
32    /// the list of
33    ///   [`Constraint`][crate::Constraint] instances that were added to the layout
34    #[doc(alias = "gtk_constraint_layout_add_constraints_from_descriptionv")]
35    #[doc(alias = "gtk_constraint_layout_add_constraints_from_description")]
36    #[doc(alias = "add_constraints_from_descriptionv")]
37    pub fn add_constraints_from_description<'a, W: IsA<Widget>>(
38        &self,
39        lines: impl IntoStrV,
40        hspacing: i32,
41        vspacing: i32,
42        views: impl IntoIterator<Item = (&'a str, &'a W)>,
43    ) -> Result<Vec<Constraint>, glib::Error> {
44        unsafe {
45            let mut err = std::ptr::null_mut();
46            let hash_table = glib::ffi::g_hash_table_new_full(
47                Some(glib::ffi::g_str_hash),
48                Some(glib::ffi::g_str_equal),
49                Some(glib::ffi::g_free),
50                None,
51            );
52
53            for (key, widget) in views {
54                let key_ptr: *mut libc::c_char = key.to_glib_full();
55                glib::ffi::g_hash_table_insert(
56                    hash_table,
57                    key_ptr as *mut _,
58                    widget.as_ptr() as *mut _,
59                );
60            }
61
62            lines.run_with_strv(|lines| {
63                let out = ffi::gtk_constraint_layout_add_constraints_from_descriptionv(
64                    self.to_glib_none().0,
65                    lines.as_ptr() as *const _,
66                    lines.len() as _,
67                    hspacing,
68                    vspacing,
69                    hash_table,
70                    &mut err,
71                );
72
73                glib::ffi::g_hash_table_unref(hash_table);
74
75                if !err.is_null() {
76                    Err(from_glib_full(err))
77                } else {
78                    Ok(FromGlibPtrContainer::from_glib_container(out))
79                }
80            })
81        }
82    }
83}