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