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