gtk4/subclass/
accessible.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 [`Accessible`](crate::Accessible)
5//! interface.
6
7use std::mem::MaybeUninit;
8
9use glib::translate::*;
10
11use crate::{
12    ffi, prelude::*, subclass::prelude::*, ATContext, Accessible, AccessiblePlatformState,
13};
14
15pub trait AccessibleImpl: ObjectImpl {
16    #[doc(alias = "get_platform_state")]
17    fn platform_state(&self, state: AccessiblePlatformState) -> bool {
18        self.parent_platform_state(state)
19    }
20
21    #[doc(alias = "get_bounds")]
22    fn bounds(&self) -> Option<(i32, i32, i32, i32)> {
23        self.parent_bounds()
24    }
25
26    #[doc(alias = "get_at_context")]
27    fn at_context(&self) -> Option<ATContext> {
28        self.parent_at_context()
29    }
30
31    #[doc(alias = "get_accessible_parent")]
32    fn accessible_parent(&self) -> Option<Accessible> {
33        self.parent_accessible_parent()
34    }
35
36    #[doc(alias = "get_first_accessible_child")]
37    fn first_accessible_child(&self) -> Option<Accessible> {
38        self.parent_first_accessible_child()
39    }
40
41    #[doc(alias = "get_next_accessible_sibling")]
42    fn next_accessible_sibling(&self) -> Option<Accessible> {
43        self.parent_next_accessible_sibling()
44    }
45}
46
47mod sealed {
48    pub trait Sealed {}
49    impl<T: super::AccessibleImplExt> Sealed for T {}
50}
51
52pub trait AccessibleImplExt: sealed::Sealed + ObjectSubclass {
53    fn parent_platform_state(&self, state: AccessiblePlatformState) -> bool {
54        unsafe {
55            let type_data = Self::type_data();
56            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
57                as *const ffi::GtkAccessibleInterface;
58
59            let func = (*parent_iface)
60                .get_platform_state
61                .expect("no parent \"get_platform_state\" implementation");
62
63            from_glib(func(
64                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
65                state.into_glib(),
66            ))
67        }
68    }
69
70    fn parent_bounds(&self) -> Option<(i32, i32, i32, i32)> {
71        unsafe {
72            let type_data = Self::type_data();
73            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
74                as *const ffi::GtkAccessibleInterface;
75
76            let func = (*parent_iface)
77                .get_bounds
78                .expect("no parent \"get_bounds\" implementation");
79
80            let mut x = MaybeUninit::uninit();
81            let mut y = MaybeUninit::uninit();
82            let mut width = MaybeUninit::uninit();
83            let mut height = MaybeUninit::uninit();
84            let res = from_glib(func(
85                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
86                x.as_mut_ptr(),
87                y.as_mut_ptr(),
88                width.as_mut_ptr(),
89                height.as_mut_ptr(),
90            ));
91            if res {
92                Some((
93                    x.assume_init(),
94                    y.assume_init(),
95                    width.assume_init(),
96                    height.assume_init(),
97                ))
98            } else {
99                None
100            }
101        }
102    }
103
104    fn parent_at_context(&self) -> Option<ATContext> {
105        unsafe {
106            let type_data = Self::type_data();
107            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
108                as *const ffi::GtkAccessibleInterface;
109
110            let func = (*parent_iface)
111                .get_at_context
112                .expect("no parent \"get_at_context\" implementation");
113
114            from_glib_full(func(
115                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
116            ))
117        }
118    }
119
120    fn parent_accessible_parent(&self) -> Option<Accessible> {
121        unsafe {
122            let type_data = Self::type_data();
123            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
124                as *const ffi::GtkAccessibleInterface;
125
126            let func = (*parent_iface)
127                .get_accessible_parent
128                .expect("no parent \"get_accessible_parent\" implementation");
129
130            from_glib_full(func(
131                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
132            ))
133        }
134    }
135
136    fn parent_first_accessible_child(&self) -> Option<Accessible> {
137        unsafe {
138            let type_data = Self::type_data();
139            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
140                as *const ffi::GtkAccessibleInterface;
141
142            let func = (*parent_iface)
143                .get_first_accessible_child
144                .expect("no parent \"get_first_accessible_child\" implementation");
145
146            from_glib_full(func(
147                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
148            ))
149        }
150    }
151
152    fn parent_next_accessible_sibling(&self) -> Option<Accessible> {
153        unsafe {
154            let type_data = Self::type_data();
155            let parent_iface = type_data.as_ref().parent_interface::<Accessible>()
156                as *const ffi::GtkAccessibleInterface;
157
158            let func = (*parent_iface)
159                .get_next_accessible_sibling
160                .expect("no parent \"get_next_accessible_sibling\" implementation");
161
162            from_glib_full(func(
163                self.obj().unsafe_cast_ref::<Accessible>().to_glib_none().0,
164            ))
165        }
166    }
167}
168
169impl<T: AccessibleImpl> AccessibleImplExt for T {}
170
171unsafe impl<T: AccessibleImpl> IsImplementable<T> for Accessible {
172    fn interface_init(iface: &mut glib::Interface<Self>) {
173        let iface = iface.as_mut();
174
175        iface.get_platform_state = Some(accessible_get_platform_state::<T>);
176        iface.get_bounds = Some(accessible_get_bounds::<T>);
177        iface.get_at_context = Some(accessible_get_at_context::<T>);
178        iface.get_accessible_parent = Some(accessible_get_accessible_parent::<T>);
179        iface.get_first_accessible_child = Some(accessible_get_first_accessible_child::<T>);
180        iface.get_next_accessible_sibling = Some(accessible_get_next_accessible_sibling::<T>);
181    }
182}
183
184unsafe extern "C" fn accessible_get_platform_state<T: AccessibleImpl>(
185    accessible: *mut ffi::GtkAccessible,
186    state: ffi::GtkAccessiblePlatformState,
187) -> glib::ffi::gboolean {
188    let instance = &*(accessible as *mut T::Instance);
189    let imp = instance.imp();
190
191    imp.platform_state(from_glib(state)).into_glib()
192}
193
194unsafe extern "C" fn accessible_get_bounds<T: AccessibleImpl>(
195    accessible: *mut ffi::GtkAccessible,
196    xptr: *mut libc::c_int,
197    yptr: *mut libc::c_int,
198    widthptr: *mut libc::c_int,
199    heightptr: *mut libc::c_int,
200) -> glib::ffi::gboolean {
201    let instance = &*(accessible as *mut T::Instance);
202    let imp = instance.imp();
203
204    if let Some((x, y, width, height)) = imp.bounds() {
205        *xptr = x;
206        *yptr = y;
207        *widthptr = width;
208        *heightptr = height;
209
210        true.into_glib()
211    } else {
212        false.into_glib()
213    }
214}
215
216unsafe extern "C" fn accessible_get_at_context<T: AccessibleImpl>(
217    accessible: *mut ffi::GtkAccessible,
218) -> *mut ffi::GtkATContext {
219    let instance = &*(accessible as *mut T::Instance);
220    let imp = instance.imp();
221
222    imp.at_context().into_glib_ptr()
223}
224
225unsafe extern "C" fn accessible_get_accessible_parent<T: AccessibleImpl>(
226    accessible: *mut ffi::GtkAccessible,
227) -> *mut ffi::GtkAccessible {
228    let instance = &*(accessible as *mut T::Instance);
229    let imp = instance.imp();
230
231    imp.accessible_parent().into_glib_ptr()
232}
233
234unsafe extern "C" fn accessible_get_first_accessible_child<T: AccessibleImpl>(
235    accessible: *mut ffi::GtkAccessible,
236) -> *mut ffi::GtkAccessible {
237    let instance = &*(accessible as *mut T::Instance);
238    let imp = instance.imp();
239
240    imp.first_accessible_child().into_glib_ptr()
241}
242
243unsafe extern "C" fn accessible_get_next_accessible_sibling<T: AccessibleImpl>(
244    accessible: *mut ffi::GtkAccessible,
245) -> *mut ffi::GtkAccessible {
246    let instance = &*(accessible as *mut T::Instance);
247    let imp = instance.imp();
248
249    imp.next_accessible_sibling().into_glib_ptr()
250}