gtk4/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`](crate::Scrollable)
5//! interface.
6
7use glib::translate::*;
8
9use crate::{ffi, prelude::*, subclass::prelude::*, Border, Scrollable};
10
11pub trait ScrollableImpl: WidgetImpl {
12    #[doc(alias = "get_border")]
13    fn border(&self) -> Option<Border> {
14        self.parent_border()
15    }
16}
17
18mod sealed {
19    pub trait Sealed {}
20    impl<T: super::ScrollableImplExt> Sealed for T {}
21}
22
23pub trait ScrollableImplExt: sealed::Sealed + ObjectSubclass {
24    fn parent_border(&self) -> Option<Border> {
25        unsafe {
26            let type_data = Self::type_data();
27            let parent_iface = type_data.as_ref().parent_interface::<Scrollable>()
28                as *const ffi::GtkScrollableInterface;
29
30            if let Some(func) = (*parent_iface).get_border {
31                let border = std::ptr::null_mut();
32                if from_glib(func(
33                    self.obj().unsafe_cast_ref::<Scrollable>().to_glib_none().0,
34                    border,
35                )) {
36                    return Some(from_glib_none(border));
37                }
38            }
39            None
40        }
41    }
42}
43
44impl<T: ScrollableImpl> ScrollableImplExt for T {}
45
46unsafe impl<T: ScrollableImpl> IsImplementable<T> for Scrollable {
47    fn interface_init(iface: &mut glib::Interface<Self>) {
48        let iface = iface.as_mut();
49
50        iface.get_border = Some(scrollable_get_border::<T>);
51    }
52}
53
54unsafe extern "C" fn scrollable_get_border<T: ScrollableImpl>(
55    scrollable: *mut ffi::GtkScrollable,
56    borderptr: *mut ffi::GtkBorder,
57) -> glib::ffi::gboolean {
58    let instance = &*(scrollable as *mut T::Instance);
59    let imp = instance.imp();
60
61    if let Some(border) = imp.border() {
62        *borderptr = *IntoGlibPtr::<*mut _>::into_glib_ptr(border);
63        true.into_glib()
64    } else {
65        *borderptr = ffi::GtkBorder {
66            top: 0,
67            right: 0,
68            left: 0,
69            bottom: 0,
70        };
71        false.into_glib()
72    }
73}