gtk4/auto/selection_model.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::{Bitset, ffi};
6use glib::{
7 object::ObjectType as _,
8 prelude::*,
9 signal::{SignalHandlerId, connect_raw},
10 translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15 /// An interface that adds support for selection to list models.
16 ///
17 /// This support is then used by widgets using list models to add the ability
18 /// to select and unselect various items.
19 ///
20 /// GTK provides default implementations of the most common selection modes such
21 /// as [`SingleSelection`][crate::SingleSelection], so you will only need to implement this
22 /// interface if you want detailed control about how selections should be handled.
23 ///
24 /// A [`SelectionModel`][crate::SelectionModel] supports a single boolean per item indicating if an item is
25 /// selected or not. This can be queried via [`SelectionModelExt::is_selected()`][crate::prelude::SelectionModelExt::is_selected()].
26 /// When the selected state of one or more items changes, the model will emit the
27 /// [`selection-changed`][struct@crate::SelectionModel#selection-changed] signal by calling the
28 /// [`SelectionModelExt::selection_changed()`][crate::prelude::SelectionModelExt::selection_changed()] function. The positions given
29 /// in that signal may have their selection state changed, though that is not a
30 /// requirement. If new items added to the model via the
31 /// [`items-changed`][struct@crate::gio::ListModel#items-changed] signal are selected or not is up to the
32 /// implementation.
33 ///
34 /// Note that items added via [`items-changed`][struct@crate::gio::ListModel#items-changed] may already
35 /// be selected and no [`selection-changed`][struct@crate::SelectionModel#selection-changed] will be
36 /// emitted for them. So to track which items are selected, it is necessary to
37 /// listen to both signals.
38 ///
39 /// Additionally, the interface can expose functionality to select and unselect
40 /// items. If these functions are implemented, GTK's list widgets will allow users
41 /// to select and unselect items. However, [`SelectionModel`][crate::SelectionModel]s are free to only
42 /// implement them partially or not at all. In that case the widgets will not
43 /// support the unimplemented operations.
44 ///
45 /// When selecting or unselecting is supported by a model, the return values of
46 /// the selection functions do *not* indicate if selection or unselection happened.
47 /// They are only meant to indicate complete failure, like when this mode of
48 /// selecting is not supported by the model.
49 ///
50 /// Selections may happen asynchronously, so the only reliable way to find out
51 /// when an item was selected is to listen to the signals that indicate selection.
52 ///
53 /// ## Signals
54 ///
55 ///
56 /// #### `selection-changed`
57 /// Emitted when the selection state of some of the items in @model changes.
58 ///
59 /// Note that this signal does not specify the new selection state of the
60 /// items, they need to be queried manually. It is also not necessary for
61 /// a model to change the selection state of any of the items in the selection
62 /// model, though it would be rather useless to emit such a signal.
63 ///
64 /// ::: warning
65 /// Note that you have to be careful when modifying the model in signal
66 /// handlers, as it may cause reentrancy problems. This is also the
67 /// case when you modify base models underneath the selection model.
68 /// When in doubt, defer changes to an idle.
69 ///
70 ///
71 /// <details><summary><h4>ListModel</h4></summary>
72 ///
73 ///
74 /// #### `items-changed`
75 /// This signal is emitted whenever items were added to or removed
76 /// from @list. At @position, @removed items were removed and @added
77 /// items were added in their place.
78 ///
79 /// Note: If `removed != added`, the positions of all later items
80 /// in the model change.
81 ///
82 ///
83 /// </details>
84 ///
85 /// # Implements
86 ///
87 /// [`SelectionModelExt`][trait@crate::prelude::SelectionModelExt], [`trait@gio::prelude::ListModelExt`]
88 #[doc(alias = "GtkSelectionModel")]
89 pub struct SelectionModel(Interface<ffi::GtkSelectionModel, ffi::GtkSelectionModelInterface>) @requires gio::ListModel;
90
91 match fn {
92 type_ => || ffi::gtk_selection_model_get_type(),
93 }
94}
95
96impl SelectionModel {
97 pub const NONE: Option<&'static SelectionModel> = None;
98}
99
100/// Trait containing all [`struct@SelectionModel`] methods.
101///
102/// # Implementors
103///
104/// [`MultiSelection`][struct@crate::MultiSelection], [`NoSelection`][struct@crate::NoSelection], [`SelectionModel`][struct@crate::SelectionModel], [`SingleSelection`][struct@crate::SingleSelection]
105pub trait SelectionModelExt: IsA<SelectionModel> + 'static {
106 /// Gets the set containing all currently selected items in the model.
107 ///
108 /// This function may be slow, so if you are only interested in single item,
109 /// consider using [`is_selected()`][Self::is_selected()] or if you are only
110 /// interested in a few, consider [`selection_in_range()`][Self::selection_in_range()].
111 ///
112 /// # Returns
113 ///
114 /// a [`Bitset`][crate::Bitset] containing all the values currently
115 /// selected in @self. If no items are selected, the bitset is empty.
116 /// The bitset must not be modified.
117 #[doc(alias = "gtk_selection_model_get_selection")]
118 #[doc(alias = "get_selection")]
119 fn selection(&self) -> Bitset {
120 unsafe {
121 from_glib_full(ffi::gtk_selection_model_get_selection(
122 self.as_ref().to_glib_none().0,
123 ))
124 }
125 }
126
127 /// Gets the set of selected items in a range.
128 ///
129 /// This function is an optimization for
130 /// [`selection()`][Self::selection()] when you are only
131 /// interested in part of the model's selected state. A common use
132 /// case is in response to the [`selection-changed`][struct@crate::SelectionModel#selection-changed]
133 /// signal.
134 /// ## `position`
135 /// start of the queried range
136 /// ## `n_items`
137 /// number of items in the queried range
138 ///
139 /// # Returns
140 ///
141 /// A [`Bitset`][crate::Bitset] that matches the selection state
142 /// for the given range with all other values being undefined.
143 /// The bitset must not be modified.
144 #[doc(alias = "gtk_selection_model_get_selection_in_range")]
145 #[doc(alias = "get_selection_in_range")]
146 fn selection_in_range(&self, position: u32, n_items: u32) -> Bitset {
147 unsafe {
148 from_glib_full(ffi::gtk_selection_model_get_selection_in_range(
149 self.as_ref().to_glib_none().0,
150 position,
151 n_items,
152 ))
153 }
154 }
155
156 /// Checks if the given item is selected.
157 /// ## `position`
158 /// the position of the item to query
159 ///
160 /// # Returns
161 ///
162 /// [`true`] if the item is selected
163 #[doc(alias = "gtk_selection_model_is_selected")]
164 fn is_selected(&self, position: u32) -> bool {
165 unsafe {
166 from_glib(ffi::gtk_selection_model_is_selected(
167 self.as_ref().to_glib_none().0,
168 position,
169 ))
170 }
171 }
172
173 /// Requests to select all items in the model.
174 ///
175 /// # Returns
176 ///
177 /// [`true`] if this action was supported and no fallback should be
178 /// tried. This does not mean that all items are now selected.
179 #[doc(alias = "gtk_selection_model_select_all")]
180 fn select_all(&self) -> bool {
181 unsafe {
182 from_glib(ffi::gtk_selection_model_select_all(
183 self.as_ref().to_glib_none().0,
184 ))
185 }
186 }
187
188 /// Requests to select an item in the model.
189 /// ## `position`
190 /// the position of the item to select
191 /// ## `unselect_rest`
192 /// whether previously selected items should be unselected
193 ///
194 /// # Returns
195 ///
196 /// [`true`] if this action was supported and no fallback should be
197 /// tried. This does not mean the item was selected.
198 #[doc(alias = "gtk_selection_model_select_item")]
199 fn select_item(&self, position: u32, unselect_rest: bool) -> bool {
200 unsafe {
201 from_glib(ffi::gtk_selection_model_select_item(
202 self.as_ref().to_glib_none().0,
203 position,
204 unselect_rest.into_glib(),
205 ))
206 }
207 }
208
209 /// Requests to select a range of items in the model.
210 /// ## `position`
211 /// the first item to select
212 /// ## `n_items`
213 /// the number of items to select
214 /// ## `unselect_rest`
215 /// whether previously selected items should be unselected
216 ///
217 /// # Returns
218 ///
219 /// [`true`] if this action was supported and no fallback should be
220 /// tried. This does not mean the range was selected.
221 #[doc(alias = "gtk_selection_model_select_range")]
222 fn select_range(&self, position: u32, n_items: u32, unselect_rest: bool) -> bool {
223 unsafe {
224 from_glib(ffi::gtk_selection_model_select_range(
225 self.as_ref().to_glib_none().0,
226 position,
227 n_items,
228 unselect_rest.into_glib(),
229 ))
230 }
231 }
232
233 /// Helper function for implementations of [`SelectionModel`][crate::SelectionModel].
234 ///
235 /// Call this when the selection changes to emit the
236 /// [`selection-changed`][struct@crate::SelectionModel#selection-changed] signal.
237 /// ## `position`
238 /// the first changed item
239 /// ## `n_items`
240 /// the number of changed items
241 #[doc(alias = "gtk_selection_model_selection_changed")]
242 fn selection_changed(&self, position: u32, n_items: u32) {
243 unsafe {
244 ffi::gtk_selection_model_selection_changed(
245 self.as_ref().to_glib_none().0,
246 position,
247 n_items,
248 );
249 }
250 }
251
252 /// Make selection changes.
253 ///
254 /// This is the most advanced selection updating method that allows
255 /// the most fine-grained control over selection changes. If you can,
256 /// you should try the simpler versions, as implementations are more
257 /// likely to implement support for those.
258 ///
259 /// Requests that the selection state of all positions set in @mask
260 /// be updated to the respective value in the @selected bitmask.
261 ///
262 /// In pseudocode, it would look something like this:
263 ///
264 /// **⚠️ The following code is in c ⚠️**
265 ///
266 /// ```c
267 /// for (i = 0; i < n_items; i++)
268 /// {
269 /// // don't change values not in the mask
270 /// if (!gtk_bitset_contains (mask, i))
271 /// continue;
272 ///
273 /// if (gtk_bitset_contains (selected, i))
274 /// select_item (i);
275 /// else
276 /// unselect_item (i);
277 /// }
278 ///
279 /// gtk_selection_model_selection_changed (model,
280 /// first_changed_item,
281 /// n_changed_items);
282 /// ```
283 ///
284 /// @mask and @selected must not be modified. They may refer to the
285 /// same bitset, which would mean that every item in the set should
286 /// be selected.
287 /// ## `selected`
288 /// bitmask specifying if items should be selected or unselected
289 /// ## `mask`
290 /// bitmask specifying which items should be updated
291 ///
292 /// # Returns
293 ///
294 /// [`true`] if this action was supported and no fallback should be
295 /// tried. This does not mean that all items were updated according
296 /// to the inputs.
297 #[doc(alias = "gtk_selection_model_set_selection")]
298 fn set_selection(&self, selected: &Bitset, mask: &Bitset) -> bool {
299 unsafe {
300 from_glib(ffi::gtk_selection_model_set_selection(
301 self.as_ref().to_glib_none().0,
302 selected.to_glib_none().0,
303 mask.to_glib_none().0,
304 ))
305 }
306 }
307
308 /// Requests to unselect all items in the model.
309 ///
310 /// # Returns
311 ///
312 /// [`true`] if this action was supported and no fallback should be
313 /// tried. This does not mean that all items are now unselected.
314 #[doc(alias = "gtk_selection_model_unselect_all")]
315 fn unselect_all(&self) -> bool {
316 unsafe {
317 from_glib(ffi::gtk_selection_model_unselect_all(
318 self.as_ref().to_glib_none().0,
319 ))
320 }
321 }
322
323 /// Requests to unselect an item in the model.
324 /// ## `position`
325 /// the position of the item to unselect
326 ///
327 /// # Returns
328 ///
329 /// [`true`] if this action was supported and no fallback should be
330 /// tried. This does not mean the item was unselected.
331 #[doc(alias = "gtk_selection_model_unselect_item")]
332 fn unselect_item(&self, position: u32) -> bool {
333 unsafe {
334 from_glib(ffi::gtk_selection_model_unselect_item(
335 self.as_ref().to_glib_none().0,
336 position,
337 ))
338 }
339 }
340
341 /// Requests to unselect a range of items in the model.
342 /// ## `position`
343 /// the first item to unselect
344 /// ## `n_items`
345 /// the number of items to unselect
346 ///
347 /// # Returns
348 ///
349 /// [`true`] if this action was supported and no fallback should be
350 /// tried. This does not mean the range was unselected.
351 #[doc(alias = "gtk_selection_model_unselect_range")]
352 fn unselect_range(&self, position: u32, n_items: u32) -> bool {
353 unsafe {
354 from_glib(ffi::gtk_selection_model_unselect_range(
355 self.as_ref().to_glib_none().0,
356 position,
357 n_items,
358 ))
359 }
360 }
361
362 /// Emitted when the selection state of some of the items in @model changes.
363 ///
364 /// Note that this signal does not specify the new selection state of the
365 /// items, they need to be queried manually. It is also not necessary for
366 /// a model to change the selection state of any of the items in the selection
367 /// model, though it would be rather useless to emit such a signal.
368 ///
369 /// ::: warning
370 /// Note that you have to be careful when modifying the model in signal
371 /// handlers, as it may cause reentrancy problems. This is also the
372 /// case when you modify base models underneath the selection model.
373 /// When in doubt, defer changes to an idle.
374 /// ## `position`
375 /// The first item that may have changed
376 /// ## `n_items`
377 /// number of items with changes
378 #[doc(alias = "selection-changed")]
379 fn connect_selection_changed<F: Fn(&Self, u32, u32) + 'static>(&self, f: F) -> SignalHandlerId {
380 unsafe extern "C" fn selection_changed_trampoline<
381 P: IsA<SelectionModel>,
382 F: Fn(&P, u32, u32) + 'static,
383 >(
384 this: *mut ffi::GtkSelectionModel,
385 position: std::ffi::c_uint,
386 n_items: std::ffi::c_uint,
387 f: glib::ffi::gpointer,
388 ) {
389 unsafe {
390 let f: &F = &*(f as *const F);
391 f(
392 SelectionModel::from_glib_borrow(this).unsafe_cast_ref(),
393 position,
394 n_items,
395 )
396 }
397 }
398 unsafe {
399 let f: Box_<F> = Box_::new(f);
400 connect_raw(
401 self.as_ptr() as *mut _,
402 c"selection-changed".as_ptr(),
403 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
404 selection_changed_trampoline::<Self, F> as *const (),
405 )),
406 Box_::into_raw(f),
407 )
408 }
409 }
410}
411
412impl<O: IsA<SelectionModel>> SelectionModelExt for O {}