1use 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 fn activate_cursor_row(&self) {
18 self.list_box_activate_cursor_row()
19 }
20
21 fn move_cursor(&self, step: MovementStep, count: i32) {
23 self.list_box_move_cursor(step, count)
24 }
25
26 fn row_activated(&self, row: &ListBoxRow) {
28 self.list_box_row_activated(row)
29 }
30
31 fn row_selected(&self, row: Option<&ListBoxRow>) {
33 self.list_box_row_selected(row)
34 }
35
36 fn select_all(&self) {
38 self.list_box_select_all()
39 }
40
41 fn selected_rows_changed(&self) {
43 self.list_box_selected_rows_changed()
44 }
45
46 fn toggle_cursor_row(&self) {
48 self.list_box_toggle_cursor_row()
49 }
50
51 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}