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