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}