Skip to main content

gtk/subclass/
icon_view.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use libc::c_int;
4
5use glib::object::Cast;
6use glib::object::IsA;
7use glib::subclass::prelude::*;
8use glib::translate::*;
9
10use super::container::ContainerImpl;
11
12use crate::MovementStep;
13use crate::TreePath;
14use crate::{IconView, ffi};
15
16pub trait IconViewImpl: ContainerImpl + ObjectSubclass<Type: IsA<IconView>> {
17    /// Activates the item determined by `path`.
18    /// ## `path`
19    /// The [`TreePath`][crate::TreePath] to be activated
20    fn item_activated(&self, path: &TreePath) {
21        self.parent_item_activated(path)
22    }
23    fn selection_changed(&self) {
24        self.parent_selection_changed()
25    }
26    /// Selects all the icons. `icon_view` must has its selection mode set
27    /// to [`SelectionMode::Multiple`][crate::SelectionMode::Multiple].
28    fn select_all(&self) {
29        self.parent_select_all()
30    }
31    /// Unselects all the icons.
32    fn unselect_all(&self) {
33        self.parent_unselect_all()
34    }
35    fn select_cursor_item(&self) {
36        self.parent_select_cursor_item()
37    }
38    fn toggle_cursor_item(&self) {
39        self.parent_toggle_cursor_item()
40    }
41    fn move_cursor(&self, step: MovementStep, count: i32) -> bool {
42        self.parent_move_cursor(step, count)
43    }
44    fn activate_cursor_item(&self) -> bool {
45        self.parent_activate_cursor_item()
46    }
47}
48
49pub trait IconViewImplExt: IconViewImpl {
50    fn parent_item_activated(&self, path: &TreePath) {
51        unsafe {
52            let data = Self::type_data();
53            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
54            if let Some(f) = (*parent_class).item_activated {
55                f(
56                    self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0,
57                    mut_override(path.to_glib_none().0),
58                )
59            }
60        }
61    }
62    fn parent_selection_changed(&self) {
63        unsafe {
64            let data = Self::type_data();
65            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
66            if let Some(f) = (*parent_class).selection_changed {
67                f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0)
68            }
69        }
70    }
71    fn parent_select_all(&self) {
72        unsafe {
73            let data = Self::type_data();
74            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
75            if let Some(f) = (*parent_class).select_all {
76                f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0)
77            }
78        }
79    }
80    fn parent_unselect_all(&self) {
81        unsafe {
82            let data = Self::type_data();
83            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
84            if let Some(f) = (*parent_class).unselect_all {
85                f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0)
86            }
87        }
88    }
89    fn parent_select_cursor_item(&self) {
90        unsafe {
91            let data = Self::type_data();
92            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
93            if let Some(f) = (*parent_class).select_cursor_item {
94                f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0)
95            }
96        }
97    }
98    fn parent_toggle_cursor_item(&self) {
99        unsafe {
100            let data = Self::type_data();
101            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
102            if let Some(f) = (*parent_class).toggle_cursor_item {
103                f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0)
104            }
105        }
106    }
107    fn parent_move_cursor(&self, step: MovementStep, count: i32) -> bool {
108        unsafe {
109            let data = Self::type_data();
110            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
111            if let Some(f) = (*parent_class).move_cursor {
112                from_glib(f(
113                    self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0,
114                    step.into_glib(),
115                    count,
116                ))
117            } else {
118                false
119            }
120        }
121    }
122    fn parent_activate_cursor_item(&self) -> bool {
123        unsafe {
124            let data = Self::type_data();
125            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkIconViewClass;
126            if let Some(f) = (*parent_class).activate_cursor_item {
127                from_glib(f(self.obj().unsafe_cast_ref::<IconView>().to_glib_none().0))
128            } else {
129                false
130            }
131        }
132    }
133}
134
135impl<T: IconViewImpl> IconViewImplExt for T {}
136
137unsafe impl<T: IconViewImpl> IsSubclassable<T> for IconView {
138    fn class_init(class: &mut ::glib::Class<Self>) {
139        Self::parent_class_init::<T>(class);
140
141        if !crate::rt::is_initialized() {
142            panic!("GTK has to be initialized first");
143        }
144
145        let klass = class.as_mut();
146        klass.item_activated = Some(icon_view_item_activated::<T>);
147        klass.selection_changed = Some(icon_view_selection_changed::<T>);
148        klass.select_all = Some(icon_view_select_all::<T>);
149        klass.unselect_all = Some(icon_view_unselect_all::<T>);
150        klass.select_cursor_item = Some(icon_view_select_cursor_item::<T>);
151        klass.toggle_cursor_item = Some(icon_view_toggle_cursor_item::<T>);
152        klass.move_cursor = Some(icon_view_move_cursor::<T>);
153        klass.activate_cursor_item = Some(icon_view_activate_cursor_item::<T>);
154    }
155}
156
157unsafe extern "C" fn icon_view_item_activated<T: IconViewImpl>(
158    ptr: *mut ffi::GtkIconView,
159    path: *mut ffi::GtkTreePath,
160) {
161    unsafe {
162        let instance = &*(ptr as *mut T::Instance);
163        let imp = instance.imp();
164        let path = from_glib_borrow(path);
165
166        imp.item_activated(&path)
167    }
168}
169
170unsafe extern "C" fn icon_view_selection_changed<T: IconViewImpl>(ptr: *mut ffi::GtkIconView) {
171    unsafe {
172        let instance = &*(ptr as *mut T::Instance);
173        let imp = instance.imp();
174
175        imp.selection_changed()
176    }
177}
178
179unsafe extern "C" fn icon_view_select_all<T: IconViewImpl>(ptr: *mut ffi::GtkIconView) {
180    unsafe {
181        let instance = &*(ptr as *mut T::Instance);
182        let imp = instance.imp();
183
184        imp.select_all()
185    }
186}
187
188unsafe extern "C" fn icon_view_unselect_all<T: IconViewImpl>(ptr: *mut ffi::GtkIconView) {
189    unsafe {
190        let instance = &*(ptr as *mut T::Instance);
191        let imp = instance.imp();
192
193        imp.unselect_all()
194    }
195}
196
197unsafe extern "C" fn icon_view_select_cursor_item<T: IconViewImpl>(ptr: *mut ffi::GtkIconView) {
198    unsafe {
199        let instance = &*(ptr as *mut T::Instance);
200        let imp = instance.imp();
201
202        imp.select_cursor_item()
203    }
204}
205
206unsafe extern "C" fn icon_view_toggle_cursor_item<T: IconViewImpl>(ptr: *mut ffi::GtkIconView) {
207    unsafe {
208        let instance = &*(ptr as *mut T::Instance);
209        let imp = instance.imp();
210
211        imp.toggle_cursor_item()
212    }
213}
214
215unsafe extern "C" fn icon_view_move_cursor<T: IconViewImpl>(
216    ptr: *mut ffi::GtkIconView,
217    step: ffi::GtkMovementStep,
218    count: c_int,
219) -> glib::ffi::gboolean {
220    unsafe {
221        let instance = &*(ptr as *mut T::Instance);
222        let imp = instance.imp();
223
224        imp.move_cursor(from_glib(step), count).into_glib()
225    }
226}
227
228unsafe extern "C" fn icon_view_activate_cursor_item<T: IconViewImpl>(
229    ptr: *mut ffi::GtkIconView,
230) -> glib::ffi::gboolean {
231    unsafe {
232        let instance = &*(ptr as *mut T::Instance);
233        let imp = instance.imp();
234
235        imp.activate_cursor_item().into_glib()
236    }
237}