gtk4/subclass/
builder_scope.rs
1use 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}