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