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