clutter/auto/
grid_layout.rs

1use crate::{Actor, GridPosition, LayoutManager, Orientation};
2use glib::{
3    object as gobject,
4    object::{Cast, IsA},
5    signal::{connect_raw, SignalHandlerId},
6    translate::*,
7};
8use std::boxed::Box as Box_;
9use std::{fmt, mem::transmute};
10
11glib_wrapper! {
12    pub struct GridLayout(Object<ffi::ClutterGridLayout, ffi::ClutterGridLayoutClass, GridLayoutClass>) @extends LayoutManager, gobject::InitiallyUnowned;
13
14    match fn {
15        get_type => || ffi::clutter_grid_layout_get_type(),
16    }
17}
18
19impl GridLayout {
20    /// Creates a new `GridLayout`
21    ///
22    /// # Returns
23    ///
24    /// the new `GridLayout`
25    pub fn new() -> GridLayout {
26        unsafe { LayoutManager::from_glib_none(ffi::clutter_grid_layout_new()).unsafe_cast() }
27    }
28}
29
30impl Default for GridLayout {
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36pub const NONE_GRID_LAYOUT: Option<&GridLayout> = None;
37
38/// Trait containing all `GridLayout` methods.
39///
40/// # Implementors
41///
42/// [`GridLayout`](struct.GridLayout.html)
43pub trait GridLayoutExt: 'static {
44    /// Adds a widget to the grid.
45    ///
46    /// The position of `child` is determined by `left` and `top`. The
47    /// number of 'cells' that `child` will occupy is determined by
48    /// `width` and `height`.
49    /// ## `child`
50    /// the `Actor` to add
51    /// ## `left`
52    /// the column number to attach the left side of `child` to
53    /// ## `top`
54    /// the row number to attach the top side of `child` to
55    /// ## `width`
56    /// the number of columns that `child` will span
57    /// ## `height`
58    /// the number of rows that `child` will span
59    fn attach<P: IsA<Actor>>(&self, child: &P, left: i32, top: i32, width: i32, height: i32);
60
61    /// Adds a actor to the grid.
62    ///
63    /// The actor is placed next to `sibling`, on the side determined by
64    /// `side`. When `sibling` is `None`, the actor is placed in row (for
65    /// left or right placement) or column 0 (for top or bottom placement),
66    /// at the end indicated by `side`.
67    ///
68    /// Attaching widgets labeled [1], [2], [3] with `sibling` == `None` and
69    /// `side` == `GridPosition::Left` yields a layout of [3][2][1].
70    /// ## `child`
71    /// the actor to add
72    /// ## `sibling`
73    /// the child of `self` that `child` will be placed
74    ///  next to, or `None` to place `child` at the beginning or end
75    /// ## `side`
76    /// the side of `sibling` that `child` is positioned next to
77    /// ## `width`
78    /// the number of columns that `child` will span
79    /// ## `height`
80    /// the number of rows that `child` will span
81    fn attach_next_to<P: IsA<Actor>, Q: IsA<Actor>>(
82        &self,
83        child: &P,
84        sibling: Option<&Q>,
85        side: GridPosition,
86        width: i32,
87        height: i32,
88    );
89
90    /// Gets the child of `self` whose area covers the grid
91    /// cell whose upper left corner is at `left`, `top`.
92    /// ## `left`
93    /// the left edge of the cell
94    /// ## `top`
95    /// the top edge of the cell
96    ///
97    /// # Returns
98    ///
99    /// the child at the given position, or `None`
100    fn get_child_at(&self, left: i32, top: i32) -> Option<Actor>;
101
102    /// Returns whether all columns of `self` have the same width.
103    ///
104    /// # Returns
105    ///
106    /// whether all columns of `self` have the same width.
107    fn get_column_homogeneous(&self) -> bool;
108
109    /// Retrieves the spacing set using `GridLayoutExt::set_column_spacing`
110    ///
111    /// # Returns
112    ///
113    /// the spacing between coluns of `self`
114    fn get_column_spacing(&self) -> u32;
115
116    /// Retrieves the orientation of the `self`.
117    ///
118    /// # Returns
119    ///
120    /// the orientation of the layout
121    fn get_orientation(&self) -> Orientation;
122
123    /// Returns whether all rows of `self` have the same height.
124    ///
125    /// # Returns
126    ///
127    /// whether all rows of `self` have the same height.
128    fn get_row_homogeneous(&self) -> bool;
129
130    /// Retrieves the spacing set using `GridLayoutExt::set_row_spacing`
131    ///
132    /// # Returns
133    ///
134    /// the spacing between rows of `self`
135    fn get_row_spacing(&self) -> u32;
136
137    /// Inserts a column at the specified position.
138    ///
139    /// Children which are attached at or to the right of this position
140    /// are moved one column to the right. Children which span across this
141    /// position are grown to span the new column.
142    /// ## `position`
143    /// the position to insert the column at
144    fn insert_column(&self, position: i32);
145
146    /// Inserts a row or column at the specified position.
147    ///
148    /// The new row or column is placed next to `sibling`, on the side
149    /// determined by `side`. If `side` is `GridPosition::Left` or
150    /// `GridPosition::Bottom`, a row is inserted. If `side` is
151    /// `GridPosition::Left` of `GridPosition::Right`,
152    /// a column is inserted.
153    /// ## `sibling`
154    /// the child of `self` that the new row or column will be
155    ///  placed next to
156    /// ## `side`
157    /// the side of `sibling` that `child` is positioned next to
158    fn insert_next_to<P: IsA<Actor>>(&self, sibling: &P, side: GridPosition);
159
160    /// Inserts a row at the specified position.
161    ///
162    /// Children which are attached at or below this position
163    /// are moved one row down. Children which span across this
164    /// position are grown to span the new row.
165    /// ## `position`
166    /// the position to insert the row at
167    fn insert_row(&self, position: i32);
168
169    /// Sets whether all columns of `self` will have the same width.
170    /// ## `homogeneous`
171    /// `true` to make columns homogeneous
172    fn set_column_homogeneous(&self, homogeneous: bool);
173
174    /// Sets the spacing between columns of `self`
175    /// ## `spacing`
176    /// the spacing between columns of the layout, in pixels
177    fn set_column_spacing(&self, spacing: u32);
178
179    /// Sets the orientation of the `self`.
180    ///
181    /// `GridLayout` uses the orientation as a hint when adding
182    /// children to the `Actor` using it as a layout manager via
183    /// `ActorExt::add_child`; changing this value will not have
184    /// any effect on children that are already part of the layout.
185    /// ## `orientation`
186    /// the orientation of the `GridLayout`
187    fn set_orientation(&self, orientation: Orientation);
188
189    /// Sets whether all rows of `self` will have the same height.
190    /// ## `homogeneous`
191    /// `true` to make rows homogeneous
192    fn set_row_homogeneous(&self, homogeneous: bool);
193
194    /// Sets the spacing between rows of `self`
195    /// ## `spacing`
196    /// the spacing between rows of the layout, in pixels
197    fn set_row_spacing(&self, spacing: u32);
198
199    fn connect_property_column_homogeneous_notify<F: Fn(&Self) + 'static>(
200        &self,
201        f: F,
202    ) -> SignalHandlerId;
203
204    fn connect_property_column_spacing_notify<F: Fn(&Self) + 'static>(
205        &self,
206        f: F,
207    ) -> SignalHandlerId;
208
209    fn connect_property_orientation_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
210
211    fn connect_property_row_homogeneous_notify<F: Fn(&Self) + 'static>(
212        &self,
213        f: F,
214    ) -> SignalHandlerId;
215
216    fn connect_property_row_spacing_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
217}
218
219impl<O: IsA<GridLayout>> GridLayoutExt for O {
220    fn attach<P: IsA<Actor>>(&self, child: &P, left: i32, top: i32, width: i32, height: i32) {
221        unsafe {
222            ffi::clutter_grid_layout_attach(
223                self.as_ref().to_glib_none().0,
224                child.as_ref().to_glib_none().0,
225                left,
226                top,
227                width,
228                height,
229            );
230        }
231    }
232
233    fn attach_next_to<P: IsA<Actor>, Q: IsA<Actor>>(
234        &self,
235        child: &P,
236        sibling: Option<&Q>,
237        side: GridPosition,
238        width: i32,
239        height: i32,
240    ) {
241        unsafe {
242            ffi::clutter_grid_layout_attach_next_to(
243                self.as_ref().to_glib_none().0,
244                child.as_ref().to_glib_none().0,
245                sibling.map(|p| p.as_ref()).to_glib_none().0,
246                side.to_glib(),
247                width,
248                height,
249            );
250        }
251    }
252
253    fn get_child_at(&self, left: i32, top: i32) -> Option<Actor> {
254        unsafe {
255            from_glib_none(ffi::clutter_grid_layout_get_child_at(
256                self.as_ref().to_glib_none().0,
257                left,
258                top,
259            ))
260        }
261    }
262
263    fn get_column_homogeneous(&self) -> bool {
264        unsafe {
265            from_glib(ffi::clutter_grid_layout_get_column_homogeneous(
266                self.as_ref().to_glib_none().0,
267            ))
268        }
269    }
270
271    fn get_column_spacing(&self) -> u32 {
272        unsafe { ffi::clutter_grid_layout_get_column_spacing(self.as_ref().to_glib_none().0) }
273    }
274
275    fn get_orientation(&self) -> Orientation {
276        unsafe {
277            from_glib(ffi::clutter_grid_layout_get_orientation(
278                self.as_ref().to_glib_none().0,
279            ))
280        }
281    }
282
283    fn get_row_homogeneous(&self) -> bool {
284        unsafe {
285            from_glib(ffi::clutter_grid_layout_get_row_homogeneous(
286                self.as_ref().to_glib_none().0,
287            ))
288        }
289    }
290
291    fn get_row_spacing(&self) -> u32 {
292        unsafe { ffi::clutter_grid_layout_get_row_spacing(self.as_ref().to_glib_none().0) }
293    }
294
295    fn insert_column(&self, position: i32) {
296        unsafe {
297            ffi::clutter_grid_layout_insert_column(self.as_ref().to_glib_none().0, position);
298        }
299    }
300
301    fn insert_next_to<P: IsA<Actor>>(&self, sibling: &P, side: GridPosition) {
302        unsafe {
303            ffi::clutter_grid_layout_insert_next_to(
304                self.as_ref().to_glib_none().0,
305                sibling.as_ref().to_glib_none().0,
306                side.to_glib(),
307            );
308        }
309    }
310
311    fn insert_row(&self, position: i32) {
312        unsafe {
313            ffi::clutter_grid_layout_insert_row(self.as_ref().to_glib_none().0, position);
314        }
315    }
316
317    fn set_column_homogeneous(&self, homogeneous: bool) {
318        unsafe {
319            ffi::clutter_grid_layout_set_column_homogeneous(
320                self.as_ref().to_glib_none().0,
321                homogeneous.to_glib(),
322            );
323        }
324    }
325
326    fn set_column_spacing(&self, spacing: u32) {
327        unsafe {
328            ffi::clutter_grid_layout_set_column_spacing(self.as_ref().to_glib_none().0, spacing);
329        }
330    }
331
332    fn set_orientation(&self, orientation: Orientation) {
333        unsafe {
334            ffi::clutter_grid_layout_set_orientation(
335                self.as_ref().to_glib_none().0,
336                orientation.to_glib(),
337            );
338        }
339    }
340
341    fn set_row_homogeneous(&self, homogeneous: bool) {
342        unsafe {
343            ffi::clutter_grid_layout_set_row_homogeneous(
344                self.as_ref().to_glib_none().0,
345                homogeneous.to_glib(),
346            );
347        }
348    }
349
350    fn set_row_spacing(&self, spacing: u32) {
351        unsafe {
352            ffi::clutter_grid_layout_set_row_spacing(self.as_ref().to_glib_none().0, spacing);
353        }
354    }
355
356    fn connect_property_column_homogeneous_notify<F: Fn(&Self) + 'static>(
357        &self,
358        f: F,
359    ) -> SignalHandlerId {
360        unsafe extern "C" fn notify_column_homogeneous_trampoline<P, F: Fn(&P) + 'static>(
361            this: *mut ffi::ClutterGridLayout,
362            _param_spec: glib_sys::gpointer,
363            f: glib_sys::gpointer,
364        ) where
365            P: IsA<GridLayout>,
366        {
367            let f: &F = &*(f as *const F);
368            f(&GridLayout::from_glib_borrow(this).unsafe_cast_ref())
369        }
370        unsafe {
371            let f: Box_<F> = Box_::new(f);
372            connect_raw(
373                self.as_ptr() as *mut _,
374                b"notify::column-homogeneous\0".as_ptr() as *const _,
375                Some(transmute::<_, unsafe extern "C" fn()>(
376                    notify_column_homogeneous_trampoline::<Self, F> as *const (),
377                )),
378                Box_::into_raw(f),
379            )
380        }
381    }
382
383    fn connect_property_column_spacing_notify<F: Fn(&Self) + 'static>(
384        &self,
385        f: F,
386    ) -> SignalHandlerId {
387        unsafe extern "C" fn notify_column_spacing_trampoline<P, F: Fn(&P) + 'static>(
388            this: *mut ffi::ClutterGridLayout,
389            _param_spec: glib_sys::gpointer,
390            f: glib_sys::gpointer,
391        ) where
392            P: IsA<GridLayout>,
393        {
394            let f: &F = &*(f as *const F);
395            f(&GridLayout::from_glib_borrow(this).unsafe_cast_ref())
396        }
397        unsafe {
398            let f: Box_<F> = Box_::new(f);
399            connect_raw(
400                self.as_ptr() as *mut _,
401                b"notify::column-spacing\0".as_ptr() as *const _,
402                Some(transmute::<_, unsafe extern "C" fn()>(
403                    notify_column_spacing_trampoline::<Self, F> as *const (),
404                )),
405                Box_::into_raw(f),
406            )
407        }
408    }
409
410    fn connect_property_orientation_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
411        unsafe extern "C" fn notify_orientation_trampoline<P, F: Fn(&P) + 'static>(
412            this: *mut ffi::ClutterGridLayout,
413            _param_spec: glib_sys::gpointer,
414            f: glib_sys::gpointer,
415        ) where
416            P: IsA<GridLayout>,
417        {
418            let f: &F = &*(f as *const F);
419            f(&GridLayout::from_glib_borrow(this).unsafe_cast_ref())
420        }
421        unsafe {
422            let f: Box_<F> = Box_::new(f);
423            connect_raw(
424                self.as_ptr() as *mut _,
425                b"notify::orientation\0".as_ptr() as *const _,
426                Some(transmute::<_, unsafe extern "C" fn()>(
427                    notify_orientation_trampoline::<Self, F> as *const (),
428                )),
429                Box_::into_raw(f),
430            )
431        }
432    }
433
434    fn connect_property_row_homogeneous_notify<F: Fn(&Self) + 'static>(
435        &self,
436        f: F,
437    ) -> SignalHandlerId {
438        unsafe extern "C" fn notify_row_homogeneous_trampoline<P, F: Fn(&P) + 'static>(
439            this: *mut ffi::ClutterGridLayout,
440            _param_spec: glib_sys::gpointer,
441            f: glib_sys::gpointer,
442        ) where
443            P: IsA<GridLayout>,
444        {
445            let f: &F = &*(f as *const F);
446            f(&GridLayout::from_glib_borrow(this).unsafe_cast_ref())
447        }
448        unsafe {
449            let f: Box_<F> = Box_::new(f);
450            connect_raw(
451                self.as_ptr() as *mut _,
452                b"notify::row-homogeneous\0".as_ptr() as *const _,
453                Some(transmute::<_, unsafe extern "C" fn()>(
454                    notify_row_homogeneous_trampoline::<Self, F> as *const (),
455                )),
456                Box_::into_raw(f),
457            )
458        }
459    }
460
461    fn connect_property_row_spacing_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
462        unsafe extern "C" fn notify_row_spacing_trampoline<P, F: Fn(&P) + 'static>(
463            this: *mut ffi::ClutterGridLayout,
464            _param_spec: glib_sys::gpointer,
465            f: glib_sys::gpointer,
466        ) where
467            P: IsA<GridLayout>,
468        {
469            let f: &F = &*(f as *const F);
470            f(&GridLayout::from_glib_borrow(this).unsafe_cast_ref())
471        }
472        unsafe {
473            let f: Box_<F> = Box_::new(f);
474            connect_raw(
475                self.as_ptr() as *mut _,
476                b"notify::row-spacing\0".as_ptr() as *const _,
477                Some(transmute::<_, unsafe extern "C" fn()>(
478                    notify_row_spacing_trampoline::<Self, F> as *const (),
479                )),
480                Box_::into_raw(f),
481            )
482        }
483    }
484}
485
486impl fmt::Display for GridLayout {
487    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
488        write!(f, "GridLayout")
489    }
490}