Skip to main content

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 {}