Skip to main content

gtk4/subclass/
builder_scope.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 [`BuilderScope`] interface.
5
6use glib::{GString, translate::*};
7
8use crate::{
9    Builder, BuilderCScope, BuilderClosureFlags, BuilderScope, ffi, prelude::*,
10    subclass::prelude::*,
11};
12
13pub trait BuilderCScopeImpl: BuilderScopeImpl + ObjectSubclass<Type: IsA<BuilderCScope>> {}
14
15unsafe impl<T: BuilderCScopeImpl> IsSubclassable<T> for BuilderCScope {}
16
17pub trait BuilderScopeImpl: ObjectImpl + ObjectSubclass<Type: IsA<BuilderScope>> {
18    #[doc(alias = "get_type_from_name")]
19    fn type_from_name(&self, builder: &Builder, type_name: &str) -> glib::Type {
20        self.parent_type_from_name(builder, type_name)
21    }
22
23    #[doc(alias = "get_type_from_function")]
24    fn type_from_function(&self, builder: &Builder, function_name: &str) -> glib::Type {
25        self.parent_type_from_function(builder, function_name)
26    }
27
28    fn create_closure(
29        &self,
30        builder: &Builder,
31        function_name: &str,
32        flags: BuilderClosureFlags,
33        object: Option<&glib::Object>,
34    ) -> Result<glib::Closure, glib::Error>;
35}
36
37pub trait BuilderScopeImplExt: BuilderScopeImpl {
38    fn parent_type_from_name(&self, builder: &Builder, type_name: &str) -> glib::Type {
39        unsafe {
40            let type_data = Self::type_data();
41            let parent_iface = type_data.as_ref().parent_interface::<BuilderScope>()
42                as *const ffi::GtkBuilderScopeInterface;
43
44            let func = (*parent_iface)
45                .get_type_from_name
46                .expect("no parent \"get_type_from_name\" implementation");
47
48            from_glib(func(
49                self.obj()
50                    .unsafe_cast_ref::<BuilderScope>()
51                    .to_glib_none()
52                    .0,
53                builder.to_glib_none().0,
54                type_name.to_glib_none().0,
55            ))
56        }
57    }
58
59    fn parent_type_from_function(&self, builder: &Builder, function_name: &str) -> glib::Type {
60        unsafe {
61            let type_data = Self::type_data();
62            let parent_iface = type_data.as_ref().parent_interface::<BuilderScope>()
63                as *const ffi::GtkBuilderScopeInterface;
64
65            let func = (*parent_iface)
66                .get_type_from_function
67                .expect("no parent \"get_type_from_function\" implementation");
68
69            from_glib(func(
70                self.obj()
71                    .unsafe_cast_ref::<BuilderScope>()
72                    .to_glib_none()
73                    .0,
74                builder.to_glib_none().0,
75                function_name.to_glib_none().0,
76            ))
77        }
78    }
79
80    fn parent_create_closure(
81        &self,
82        builder: &Builder,
83        function_name: &str,
84        flags: BuilderClosureFlags,
85        object: Option<&glib::Object>,
86    ) -> Result<glib::Closure, glib::Error> {
87        unsafe {
88            let type_data = Self::type_data();
89            let parent_iface = type_data.as_ref().parent_interface::<BuilderScope>()
90                as *const ffi::GtkBuilderScopeInterface;
91
92            let func = (*parent_iface)
93                .create_closure
94                .expect("no parent \"create_closure\" implementation");
95
96            let mut error = std::ptr::null_mut();
97            let closure = func(
98                self.obj()
99                    .unsafe_cast_ref::<BuilderScope>()
100                    .to_glib_none()
101                    .0,
102                builder.to_glib_none().0,
103                function_name.to_glib_none().0,
104                flags.into_glib(),
105                object.to_glib_none().0,
106                &mut error,
107            );
108            if error.is_null() {
109                Ok(from_glib_none(closure))
110            } else {
111                Err(from_glib_full(error))
112            }
113        }
114    }
115}
116
117impl<T: BuilderScopeImpl> BuilderScopeImplExt for T {}
118
119unsafe impl<T: BuilderScopeImpl> IsImplementable<T> for BuilderScope {
120    fn interface_init(iface: &mut glib::Interface<Self>) {
121        let iface = iface.as_mut();
122
123        assert_initialized_main_thread!();
124
125        iface.get_type_from_name = Some(builder_scope_get_type_from_name::<T>);
126        iface.get_type_from_function = Some(builder_scope_get_type_from_function::<T>);
127        iface.create_closure = Some(builder_scope_create_closure::<T>);
128    }
129}
130
131unsafe extern "C" fn builder_scope_get_type_from_name<T: BuilderScopeImpl>(
132    builder_scope: *mut ffi::GtkBuilderScope,
133    builderptr: *mut ffi::GtkBuilder,
134    type_nameptr: *const libc::c_char,
135) -> glib::ffi::GType {
136    unsafe {
137        let instance = &*(builder_scope as *mut T::Instance);
138        let imp = instance.imp();
139        let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
140        let type_name: Borrowed<GString> = from_glib_borrow(type_nameptr);
141
142        imp.type_from_name(&builder, &type_name).into_glib()
143    }
144}
145
146unsafe extern "C" fn builder_scope_get_type_from_function<T: BuilderScopeImpl>(
147    builder_scope: *mut ffi::GtkBuilderScope,
148    builderptr: *mut ffi::GtkBuilder,
149    func_nameptr: *const libc::c_char,
150) -> glib::ffi::GType {
151    unsafe {
152        let instance = &*(builder_scope as *mut T::Instance);
153        let imp = instance.imp();
154        let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
155        let func_name: Borrowed<GString> = from_glib_borrow(func_nameptr);
156
157        imp.type_from_function(&builder, &func_name).into_glib()
158    }
159}
160
161unsafe extern "C" fn builder_scope_create_closure<T: BuilderScopeImpl>(
162    builder_scope: *mut ffi::GtkBuilderScope,
163    builderptr: *mut ffi::GtkBuilder,
164    func_nameptr: *const libc::c_char,
165    flags: ffi::GtkBuilderClosureFlags,
166    objectptr: *mut glib::gobject_ffi::GObject,
167    errorptr: *mut *mut glib::ffi::GError,
168) -> *mut glib::gobject_ffi::GClosure {
169    unsafe {
170        let instance = &*(builder_scope as *mut T::Instance);
171        let imp = instance.imp();
172        let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
173        let func_name: Borrowed<GString> = from_glib_borrow(func_nameptr);
174        let object: Borrowed<Option<glib::Object>> = from_glib_borrow(objectptr);
175
176        let ret = imp.create_closure(
177            &builder,
178            &func_name,
179            from_glib(flags),
180            object.as_ref().as_ref(),
181        );
182
183        match ret {
184            Ok(closure) => closure.into_glib_ptr(),
185            Err(e) => {
186                if !errorptr.is_null() {
187                    *errorptr = e.into_glib_ptr();
188                }
189                std::ptr::null_mut()
190            }
191        }
192    }
193}