Skip to main content

gtk/subclass/
list_box.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::object::Cast;
4use glib::subclass::prelude::*;
5use glib::translate::*;
6
7use super::{container::ContainerImpl, widget::WidgetImpl};
8
9use libc::c_int;
10
11use crate::ListBoxRow;
12use crate::MovementStep;
13use crate::{ListBox, ffi};
14
15pub trait ListBoxImpl: ListBoxImplExt + ContainerImpl + WidgetImpl {
16    /// Class handler for the [`activate-cursor-row`][struct@crate::ListBox#activate-cursor-row] signal
17    fn activate_cursor_row(&self) {
18        self.list_box_activate_cursor_row()
19    }
20
21    /// Class handler for the [`move-cursor`][struct@crate::ListBox#move-cursor] signal
22    fn move_cursor(&self, step: MovementStep, count: i32) {
23        self.list_box_move_cursor(step, count)
24    }
25
26    /// Class handler for the [`row-activated`][struct@crate::ListBox#row-activated] signal
27    fn row_activated(&self, row: &ListBoxRow) {
28        self.list_box_row_activated(row)
29    }
30
31    /// Class handler for the [`row-selected`][struct@crate::ListBox#row-selected] signal
32    fn row_selected(&self, row: Option<&ListBoxRow>) {
33        self.list_box_row_selected(row)
34    }
35
36    /// Select all children of `box_`, if the selection mode allows it.
37    fn select_all(&self) {
38        self.list_box_select_all()
39    }
40
41    /// Class handler for the [`selected-rows-changed`][struct@crate::ListBox#selected-rows-changed] signal
42    fn selected_rows_changed(&self) {
43        self.list_box_selected_rows_changed()
44    }
45
46    /// Class handler for the [`toggle-cursor-row`][struct@crate::ListBox#toggle-cursor-row] signal
47    fn toggle_cursor_row(&self) {
48        self.list_box_toggle_cursor_row()
49    }
50
51    /// Unselect all children of `box_`, if the selection mode allows it.
52    fn unselect_all(&self) {
53        self.list_box_unselect_all()
54    }
55}
56
57mod sealed {
58    pub trait Sealed {}
59    impl<T: super::ListBoxImpl> Sealed for T {}
60}
61
62pub trait ListBoxImplExt: ObjectSubclass + sealed::Sealed {
63    fn list_box_activate_cursor_row(&self) {
64        unsafe {
65            let data = Self::type_data();
66            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
67            if let Some(f) = (*parent_class).activate_cursor_row {
68                f(self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0)
69            }
70        }
71    }
72    fn list_box_move_cursor(&self, step: MovementStep, count: i32) {
73        unsafe {
74            let data = Self::type_data();
75            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
76            if let Some(f) = (*parent_class).move_cursor {
77                f(
78                    self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0,
79                    step.into_glib(),
80                    count,
81                );
82            }
83        }
84    }
85    fn list_box_row_activated(&self, row: &ListBoxRow) {
86        unsafe {
87            let data = Self::type_data();
88            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
89            if let Some(f) = (*parent_class).row_activated {
90                f(
91                    self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0,
92                    row.to_glib_none().0,
93                )
94            }
95        }
96    }
97    fn list_box_row_selected(&self, row: Option<&ListBoxRow>) {
98        unsafe {
99            let data = Self::type_data();
100            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
101            if let Some(f) = (*parent_class).row_selected {
102                f(
103                    self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0,
104                    mut_override(row.to_glib_none().0),
105                )
106            }
107        }
108    }
109    fn list_box_select_all(&self) {
110        unsafe {
111            let data = Self::type_data();
112            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
113            if let Some(f) = (*parent_class).select_all {
114                f(self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0)
115            }
116        }
117    }
118    fn list_box_selected_rows_changed(&self) {
119        unsafe {
120            let data = Self::type_data();
121            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
122            if let Some(f) = (*parent_class).selected_rows_changed {
123                f(self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0)
124            }
125        }
126    }
127    fn list_box_toggle_cursor_row(&self) {
128        unsafe {
129            let data = Self::type_data();
130            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
131            if let Some(f) = (*parent_class).toggle_cursor_row {
132                f(self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0)
133            }
134        }
135    }
136    fn list_box_unselect_all(&self) {
137        unsafe {
138            let data = Self::type_data();
139            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkListBoxClass;
140            if let Some(f) = (*parent_class).unselect_all {
141                f(self.obj().unsafe_cast_ref::<ListBox>().to_glib_none().0)
142            }
143        }
144    }
145}
146
147impl<T: ListBoxImpl> ListBoxImplExt for T {}
148
149unsafe impl<T: ListBoxImpl> IsSubclassable<T> for ListBox {
150    fn class_init(class: &mut ::glib::Class<Self>) {
151        Self::parent_class_init::<T>(class);
152
153        if !crate::rt::is_initialized() {
154            panic!("GTK has to be initialized first");
155        }
156
157        let klass = class.as_mut();
158        klass.activate_cursor_row = Some(list_box_activate_cursor_row::<T>);
159        klass.move_cursor = Some(list_box_move_cursor::<T>);
160        klass.row_activated = Some(list_box_row_activated::<T>);
161        klass.row_selected = Some(list_box_row_selected::<T>);
162        klass.select_all = Some(list_box_select_all::<T>);
163        klass.selected_rows_changed = Some(list_box_selected_rows_changed::<T>);
164        klass.toggle_cursor_row = Some(list_box_toggle_cursor_row::<T>);
165        klass.unselect_all = Some(list_box_unselect_all::<T>);
166    }
167}
168
169unsafe extern "C" fn list_box_activate_cursor_row<T: ListBoxImpl>(ptr: *mut ffi::GtkListBox) {
170    unsafe {
171        let instance = &*(ptr as *mut T::Instance);
172        let imp = instance.imp();
173
174        imp.activate_cursor_row()
175    }
176}
177
178unsafe extern "C" fn list_box_move_cursor<T: ListBoxImpl>(
179    ptr: *mut ffi::GtkListBox,
180    step: ffi::GtkMovementStep,
181    count: c_int,
182) {
183    unsafe {
184        let instance = &*(ptr as *mut T::Instance);
185        let imp = instance.imp();
186
187        imp.move_cursor(from_glib(step), count)
188    }
189}
190
191unsafe extern "C" fn list_box_row_activated<T: ListBoxImpl>(
192    ptr: *mut ffi::GtkListBox,
193    rowptr: *mut ffi::GtkListBoxRow,
194) {
195    unsafe {
196        let instance = &*(ptr as *mut T::Instance);
197        let imp = instance.imp();
198        let row: Borrowed<ListBoxRow> = from_glib_borrow(rowptr);
199
200        imp.row_activated(&row)
201    }
202}
203
204unsafe extern "C" fn list_box_row_selected<T: ListBoxImpl>(
205    ptr: *mut ffi::GtkListBox,
206    rowptr: *mut ffi::GtkListBoxRow,
207) {
208    unsafe {
209        let instance = &*(ptr as *mut T::Instance);
210        let imp = instance.imp();
211        let row: Borrowed<Option<ListBoxRow>> = from_glib_borrow(rowptr);
212
213        imp.row_selected(row.as_ref().as_ref())
214    }
215}
216
217unsafe extern "C" fn list_box_select_all<T: ListBoxImpl>(ptr: *mut ffi::GtkListBox) {
218    unsafe {
219        let instance = &*(ptr as *mut T::Instance);
220        let imp = instance.imp();
221
222        imp.select_all()
223    }
224}
225
226unsafe extern "C" fn list_box_selected_rows_changed<T: ListBoxImpl>(ptr: *mut ffi::GtkListBox) {
227    unsafe {
228        let instance = &*(ptr as *mut T::Instance);
229        let imp = instance.imp();
230
231        imp.selected_rows_changed()
232    }
233}
234
235unsafe extern "C" fn list_box_toggle_cursor_row<T: ListBoxImpl>(ptr: *mut ffi::GtkListBox) {
236    unsafe {
237        let instance = &*(ptr as *mut T::Instance);
238        let imp = instance.imp();
239
240        imp.toggle_cursor_row()
241    }
242}
243
244unsafe extern "C" fn list_box_unselect_all<T: ListBoxImpl>(ptr: *mut ffi::GtkListBox) {
245    unsafe {
246        let instance = &*(ptr as *mut T::Instance);
247        let imp = instance.imp();
248
249        imp.unselect_all()
250    }
251}