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::{translate::*, GString};
7
8use crate::{
9    ffi, prelude::*, subclass::prelude::*, Builder, BuilderCScope, BuilderClosureFlags,
10    BuilderScope,
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    let instance = &*(builder_scope as *mut T::Instance);
137    let imp = instance.imp();
138    let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
139    let type_name: Borrowed<GString> = from_glib_borrow(type_nameptr);
140
141    imp.type_from_name(&builder, &type_name).into_glib()
142}
143
144unsafe extern "C" fn builder_scope_get_type_from_function<T: BuilderScopeImpl>(
145    builder_scope: *mut ffi::GtkBuilderScope,
146    builderptr: *mut ffi::GtkBuilder,
147    func_nameptr: *const libc::c_char,
148) -> glib::ffi::GType {
149    let instance = &*(builder_scope as *mut T::Instance);
150    let imp = instance.imp();
151    let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
152    let func_name: Borrowed<GString> = from_glib_borrow(func_nameptr);
153
154    imp.type_from_function(&builder, &func_name).into_glib()
155}
156
157unsafe extern "C" fn builder_scope_create_closure<T: BuilderScopeImpl>(
158    builder_scope: *mut ffi::GtkBuilderScope,
159    builderptr: *mut ffi::GtkBuilder,
160    func_nameptr: *const libc::c_char,
161    flags: ffi::GtkBuilderClosureFlags,
162    objectptr: *mut glib::gobject_ffi::GObject,
163    errorptr: *mut *mut glib::ffi::GError,
164) -> *mut glib::gobject_ffi::GClosure {
165    let instance = &*(builder_scope as *mut T::Instance);
166    let imp = instance.imp();
167    let builder: Borrowed<Builder> = from_glib_borrow(builderptr);
168    let func_name: Borrowed<GString> = from_glib_borrow(func_nameptr);
169    let object: Borrowed<Option<glib::Object>> = from_glib_borrow(objectptr);
170
171    let ret = imp.create_closure(
172        &builder,
173        &func_name,
174        from_glib(flags),
175        object.as_ref().as_ref(),
176    );
177
178    match ret {
179        Ok(closure) => closure.into_glib_ptr(),
180        Err(e) => {
181            if !errorptr.is_null() {
182                *errorptr = e.into_glib_ptr();
183            }
184            std::ptr::null_mut()
185        }
186    }
187}