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