gtk4/auto/
size_group.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, Buildable, SizeGroupMode, Widget};
6use glib::{
7    prelude::*,
8    signal::{connect_raw, SignalHandlerId},
9    translate::*,
10};
11use std::boxed::Box as Box_;
12
13glib::wrapper! {
14    /// [`SizeGroup`][crate::SizeGroup] groups widgets together so they all request the same size.
15    ///
16    /// This is typically useful when you want a column of widgets to have
17    /// the same size, but you can’t use a [`Grid`][crate::Grid] or [`Box`][crate::Box].
18    ///
19    /// In detail, the size requested for each widget in a [`SizeGroup`][crate::SizeGroup] is
20    /// the maximum of the sizes that would have been requested for each
21    /// widget in the size group if they were not in the size group. The
22    /// [mode][`set_mode()`][Self::set_mode()] of the size group determines
23    /// whether this applies to the horizontal size, the vertical size, or
24    /// both sizes.
25    ///
26    /// Note that size groups only affect the amount of space requested, not
27    /// the size that the widgets finally receive. If you want the widgets in
28    /// a [`SizeGroup`][crate::SizeGroup] to actually be the same size, you need to pack them in
29    /// such a way that they get the size they request and not more. In
30    /// particular it doesn't make a lot of sense to set
31    /// [the expand flags][`WidgetExt::set_hexpand()`][crate::prelude::WidgetExt::set_hexpand()] on the widgets that
32    /// are members of a size group.
33    ///
34    /// [`SizeGroup`][crate::SizeGroup] objects are referenced by each widget in the size group,
35    /// so once you have added all widgets to a [`SizeGroup`][crate::SizeGroup], you can drop
36    /// the initial reference to the size group with
37    /// `GObject::Object::unref()`. If the widgets in the size group are
38    /// subsequently destroyed, then they will be removed from the size group
39    /// and drop their references on the size group; when all widgets have been
40    /// removed, the size group will be freed.
41    ///
42    /// Widgets can be part of multiple size groups; GTK will compute the
43    /// horizontal size of a widget from the horizontal requisition of all widgets
44    /// that can be reached from the widget by a chain of size groups with mode
45    /// [enum@Gtk.SizeGroupMode.HORIZONTAL] or [enum@Gtk.SizeGroupMode.BOTH], and
46    /// the vertical size from the vertical requisition of all widgets that can be
47    /// reached from the widget by a chain of size groups with mode
48    /// [enum@Gtk.SizeGroupMode.VERTICAL] or [enum@Gtk.SizeGroupMode.BOTH].
49    ///
50    /// # Size groups and trading height-for-width
51    ///
52    /// ::: warning
53    ///     Generally, size groups don't interact well with widgets that
54    ///     trade height for width (or width for height), such as wrappable
55    ///     labels. Avoid using size groups with such widgets.
56    ///
57    /// A size group with mode [enum@Gtk.SizeGroupMode.HORIZONTAL] or
58    /// [enum@Gtk.SizeGroupMode.VERTICAL] only consults non-contextual sizes
59    /// of widgets other than the one being measured, since it has no
60    /// knowledge of what size a widget will get allocated in the other
61    /// orientation. This can lead to widgets in a group actually requesting
62    /// different contextual sizes, contrary to the purpose of
63    /// [`SizeGroup`][crate::SizeGroup].
64    ///
65    /// In contrast, a size group with mode [enum@Gtk.SizeGroupMode.BOTH] can
66    /// properly propagate the available size in the opposite orientation
67    /// when measuring widgets in the group, which results in consistent and
68    /// accurate measurements.
69    ///
70    /// In case some mechanism other than a size group is already used to
71    /// ensure that widgets in a group all get the same size in one
72    /// orientation (for example, some common ancestor is known to allocate
73    /// the same width to all its children), and the size group is only
74    /// really needed to also make the widgets request the same size in the
75    /// other orientation, it is beneficial to still set the group's mode to
76    /// [enum@Gtk.SizeGroupMode.BOTH]. This lets the group assume and count
77    /// on sizes of the widgets in the former orientation being the same,
78    /// which enables it to propagate the available size as described above.
79    ///
80    /// # Alternatives to size groups
81    ///
82    /// Size groups have many limitations, such as only influencing size
83    /// requests but not allocations, and poor height-for-width support. When
84    /// possible, prefer using dedicated mechanisms that can properly ensure
85    /// that the widgets get the same size.
86    ///
87    /// Various container widgets and layout managers support a homogeneous
88    /// layout mode, where they will explicitly give the same size to their
89    /// children (see [`homogeneous`][struct@crate::Box#homogeneous]). Using homogeneous mode
90    /// can also have large performance benefits compared to either the same
91    /// container in non-homogeneous mode, or to size groups.
92    ///
93    /// [`Grid`][crate::Grid] can be used to position widgets into rows and
94    /// columns. Members of each column will have the same width among them;
95    /// likewise, members of each row will have the same height. On top of
96    /// that, the heights can be made equal between all rows with
97    /// [`row-homogeneous`][struct@crate::Grid#row-homogeneous], and the widths can be made equal
98    /// between all columns with [`column-homogeneous`][struct@crate::Grid#column-homogeneous].
99    ///
100    /// # GtkSizeGroup as GtkBuildable
101    ///
102    /// Size groups can be specified in a UI definition by placing an `<object>`
103    /// element with `class="GtkSizeGroup"` somewhere in the UI definition. The
104    /// widgets that belong to the size group are specified by a `<widgets>` element
105    /// that may contain multiple `<widget>` elements, one for each member of the
106    /// size group. The ”name” attribute gives the id of the widget.
107    ///
108    /// An example of a UI definition fragment with [`SizeGroup`][crate::SizeGroup]:
109    /// ```xml
110    /// <object class="GtkSizeGroup">
111    ///   <property name="mode">horizontal</property>
112    ///   <widgets>
113    ///     <widget name="radio1"/>
114    ///     <widget name="radio2"/>
115    ///   </widgets>
116    /// </object>
117    /// ```
118    ///
119    /// ## Properties
120    ///
121    ///
122    /// #### `mode`
123    ///  The direction in which the size group affects requested sizes.
124    ///
125    /// Readable | Writeable
126    ///
127    /// # Implements
128    ///
129    /// [`trait@glib::ObjectExt`], [`BuildableExt`][trait@crate::prelude::BuildableExt]
130    #[doc(alias = "GtkSizeGroup")]
131    pub struct SizeGroup(Object<ffi::GtkSizeGroup>) @implements Buildable;
132
133    match fn {
134        type_ => || ffi::gtk_size_group_get_type(),
135    }
136}
137
138impl SizeGroup {
139    /// Create a new [`SizeGroup`][crate::SizeGroup].
140    /// ## `mode`
141    /// the mode for the new size group.
142    ///
143    /// # Returns
144    ///
145    /// a newly created [`SizeGroup`][crate::SizeGroup]
146    #[doc(alias = "gtk_size_group_new")]
147    pub fn new(mode: SizeGroupMode) -> SizeGroup {
148        assert_initialized_main_thread!();
149        unsafe { from_glib_full(ffi::gtk_size_group_new(mode.into_glib())) }
150    }
151
152    /// Adds a widget to a [`SizeGroup`][crate::SizeGroup].
153    ///
154    /// In the future, the requisition
155    /// of the widget will be determined as the maximum of its requisition
156    /// and the requisition of the other widgets in the size group.
157    /// Whether this applies horizontally, vertically, or in both directions
158    /// depends on the mode of the size group.
159    /// See [`set_mode()`][Self::set_mode()].
160    ///
161    /// When the widget is destroyed or no longer referenced elsewhere, it
162    /// will be removed from the size group.
163    /// ## `widget`
164    /// the [`Widget`][crate::Widget] to add
165    #[doc(alias = "gtk_size_group_add_widget")]
166    pub fn add_widget(&self, widget: &impl IsA<Widget>) {
167        unsafe {
168            ffi::gtk_size_group_add_widget(self.to_glib_none().0, widget.as_ref().to_glib_none().0);
169        }
170    }
171
172    /// Gets the current mode of the size group.
173    ///
174    /// # Returns
175    ///
176    /// the current mode of the size group.
177    #[doc(alias = "gtk_size_group_get_mode")]
178    #[doc(alias = "get_mode")]
179    pub fn mode(&self) -> SizeGroupMode {
180        unsafe { from_glib(ffi::gtk_size_group_get_mode(self.to_glib_none().0)) }
181    }
182
183    /// Returns the list of widgets associated with @self.
184    ///
185    /// # Returns
186    ///
187    /// a `GSList` of
188    ///   widgets. The list is owned by GTK and should not be modified.
189    #[doc(alias = "gtk_size_group_get_widgets")]
190    #[doc(alias = "get_widgets")]
191    pub fn widgets(&self) -> Vec<Widget> {
192        unsafe {
193            FromGlibPtrContainer::from_glib_none(ffi::gtk_size_group_get_widgets(
194                self.to_glib_none().0,
195            ))
196        }
197    }
198
199    /// Removes a widget from a [`SizeGroup`][crate::SizeGroup].
200    /// ## `widget`
201    /// the [`Widget`][crate::Widget] to remove
202    #[doc(alias = "gtk_size_group_remove_widget")]
203    pub fn remove_widget(&self, widget: &impl IsA<Widget>) {
204        unsafe {
205            ffi::gtk_size_group_remove_widget(
206                self.to_glib_none().0,
207                widget.as_ref().to_glib_none().0,
208            );
209        }
210    }
211
212    /// Sets the [`SizeGroupMode`][crate::SizeGroupMode] of the size group.
213    ///
214    /// The mode of the size group determines whether the widgets in the
215    /// size group should all have the same horizontal requisition
216    /// ([`SizeGroupMode::Horizontal`][crate::SizeGroupMode::Horizontal]) all have the same vertical requisition
217    /// ([`SizeGroupMode::Vertical`][crate::SizeGroupMode::Vertical]), or should all have the same requisition
218    /// in both directions ([`SizeGroupMode::Both`][crate::SizeGroupMode::Both]).
219    /// ## `mode`
220    /// the mode to set for the size group.
221    #[doc(alias = "gtk_size_group_set_mode")]
222    #[doc(alias = "mode")]
223    pub fn set_mode(&self, mode: SizeGroupMode) {
224        unsafe {
225            ffi::gtk_size_group_set_mode(self.to_glib_none().0, mode.into_glib());
226        }
227    }
228
229    #[doc(alias = "mode")]
230    pub fn connect_mode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
231        unsafe extern "C" fn notify_mode_trampoline<F: Fn(&SizeGroup) + 'static>(
232            this: *mut ffi::GtkSizeGroup,
233            _param_spec: glib::ffi::gpointer,
234            f: glib::ffi::gpointer,
235        ) {
236            let f: &F = &*(f as *const F);
237            f(&from_glib_borrow(this))
238        }
239        unsafe {
240            let f: Box_<F> = Box_::new(f);
241            connect_raw(
242                self.as_ptr() as *mut _,
243                b"notify::mode\0".as_ptr() as *const _,
244                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
245                    notify_mode_trampoline::<F> as *const (),
246                )),
247                Box_::into_raw(f),
248            )
249        }
250    }
251}