gtk/subclass/scrollable.rs
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for implementing the [`Scrollable`] interface.
5
6use glib::translate::*;
7
8use crate::{Border, Scrollable, ffi, prelude::*, subclass::prelude::*};
9
10pub trait ScrollableImpl: ObjectImpl + ObjectSubclass<Type: IsA<Scrollable>> {
11 #[doc(alias = "get_border")]
12 fn border(&self) -> Option<Border> {
13 self.parent_border()
14 }
15}
16
17pub trait ScrollableImplExt: ScrollableImpl {
18 fn parent_border(&self) -> Option<Border> {
19 unsafe {
20 let type_data = Self::type_data();
21 let parent_iface = type_data.as_ref().parent_interface::<Scrollable>()
22 as *const ffi::GtkScrollableInterface;
23
24 (*parent_iface).get_border.and_then(|func| {
25 let mut border = Border::uninitialized();
26 from_glib::<_, bool>(func(
27 self.obj().unsafe_cast_ref::<Scrollable>().to_glib_none().0,
28 border.to_glib_none_mut().0,
29 ))
30 .then_some(border)
31 })
32 }
33 }
34}
35
36impl<T: ScrollableImpl> ScrollableImplExt for T {}
37
38unsafe impl<T: ScrollableImpl> IsImplementable<T> for Scrollable {
39 fn interface_init(iface: &mut glib::Interface<Self>) {
40 let iface = iface.as_mut();
41
42 if !crate::rt::is_initialized() {
43 panic!("GTK has to be initialized first");
44 }
45
46 iface.get_border = Some(scrollable_get_border::<T>);
47 }
48}
49
50unsafe extern "C" fn scrollable_get_border<T: ScrollableImpl>(
51 scrollableptr: *mut ffi::GtkScrollable,
52 borderptr: *mut ffi::GtkBorder,
53) -> glib::ffi::gboolean {
54 unsafe {
55 let instance = &*(scrollableptr as *mut T::Instance);
56 let imp = instance.imp();
57
58 if let Some(border) = imp.border() {
59 if !borderptr.is_null() {
60 *borderptr = *border;
61 }
62 glib::ffi::GTRUE
63 } else {
64 glib::ffi::GFALSE
65 }
66 }
67}