gtk/subclass/
container.rs1use glib::translate::*;
4
5use glib::subclass::prelude::*;
6
7use glib::Cast;
8
9use super::widget::WidgetImpl;
10use crate::Container;
11use crate::Widget;
12use crate::WidgetPath;
13
14pub trait ContainerImpl: ContainerImplExt + WidgetImpl {
15 fn add(&self, widget: &Widget) {
30 self.parent_add(widget)
31 }
32
33 fn remove(&self, widget: &Widget) {
45 self.parent_remove(widget)
46 }
47
48 fn check_resize(&self) {
49 self.parent_check_resize()
50 }
51
52 fn set_focus_child(&self, widget: Option<&Widget>) {
63 self.parent_set_focus_child(widget)
64 }
65
66 fn child_type(&self) -> glib::Type {
76 self.parent_child_type()
77 }
78
79 #[doc(alias = "get_path_for_child")]
88 fn path_for_child(&self, widget: &Widget) -> WidgetPath {
89 self.parent_path_for_child(widget)
90 }
91
92 fn forall(&self, include_internals: bool, callback: &Callback) {
105 self.parent_forall(include_internals, callback);
106 }
107}
108
109mod sealed {
110 pub trait Sealed {}
111 impl<T: super::ContainerImpl> Sealed for T {}
112}
113
114pub trait ContainerImplExt: ObjectSubclass + sealed::Sealed {
115 fn parent_add(&self, widget: &Widget) {
116 unsafe {
117 let data = Self::type_data();
118 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
119 if let Some(f) = (*parent_class).add {
120 f(
121 self.obj().unsafe_cast_ref::<Container>().to_glib_none().0,
122 widget.to_glib_none().0,
123 )
124 }
125 }
126 }
127 fn parent_remove(&self, widget: &Widget) {
128 unsafe {
129 let data = Self::type_data();
130 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
131 if let Some(f) = (*parent_class).remove {
132 f(
133 self.obj().unsafe_cast_ref::<Container>().to_glib_none().0,
134 widget.to_glib_none().0,
135 )
136 }
137 }
138 }
139 fn parent_check_resize(&self) {
140 unsafe {
141 let data = Self::type_data();
142 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
143 if let Some(f) = (*parent_class).check_resize {
144 f(self.obj().unsafe_cast_ref::<Container>().to_glib_none().0)
145 }
146 }
147 }
148 fn parent_set_focus_child(&self, widget: Option<&Widget>) {
149 unsafe {
150 let data = Self::type_data();
151 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
152 if let Some(f) = (*parent_class).set_focus_child {
153 f(
154 self.obj().unsafe_cast_ref::<Container>().to_glib_none().0,
155 widget.to_glib_none().0,
156 )
157 }
158 }
159 }
160 fn parent_child_type(&self) -> glib::Type {
161 unsafe {
162 let data = Self::type_data();
163 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
164 if let Some(f) = (*parent_class).child_type {
165 from_glib(f(self
166 .obj()
167 .unsafe_cast_ref::<Container>()
168 .to_glib_none()
169 .0))
170 } else {
171 glib::Type::UNIT
172 }
173 }
174 }
175 fn parent_path_for_child(&self, widget: &Widget) -> WidgetPath {
176 unsafe {
177 let data = Self::type_data();
178 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
179 let f = (*parent_class)
180 .get_path_for_child
181 .expect("No parent class impl for \"get_path_for_child\"");
182 from_glib_none(f(
183 self.obj().unsafe_cast_ref::<Container>().to_glib_none().0,
184 widget.to_glib_none().0,
185 ))
186 }
187 }
188 fn parent_forall(&self, include_internals: bool, callback: &Callback) {
189 unsafe {
190 let data = Self::type_data();
191 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
192 if let Some(f) = (*parent_class).forall {
193 f(
194 self.obj().unsafe_cast_ref::<Container>().to_glib_none().0,
195 include_internals.into_glib(),
196 callback.callback,
197 callback.user_data,
198 )
199 }
200 }
201 }
202}
203
204impl<T: ContainerImpl> ContainerImplExt for T {}
205
206unsafe impl<T: ContainerImpl> IsSubclassable<T> for Container {
207 fn class_init(class: &mut ::glib::Class<Self>) {
208 Self::parent_class_init::<T>(class);
209
210 if !crate::rt::is_initialized() {
211 panic!("GTK has to be initialized first");
212 }
213
214 let klass = class.as_mut();
215 klass.add = Some(container_add::<T>);
216 klass.remove = Some(container_remove::<T>);
217 klass.check_resize = Some(container_check_resize::<T>);
218 klass.set_focus_child = Some(container_set_focus_child::<T>);
219 klass.child_type = Some(container_child_type::<T>);
220 klass.get_path_for_child = Some(container_get_path_for_child::<T>);
221 klass.forall = Some(container_forall::<T>);
222 }
223}
224
225unsafe extern "C" fn container_add<T: ContainerImpl>(
226 ptr: *mut ffi::GtkContainer,
227 wdgtptr: *mut ffi::GtkWidget,
228) {
229 let instance = &*(ptr as *mut T::Instance);
230 let imp = instance.imp();
231 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
232
233 imp.add(&widget)
234}
235
236unsafe extern "C" fn container_remove<T: ContainerImpl>(
237 ptr: *mut ffi::GtkContainer,
238 wdgtptr: *mut ffi::GtkWidget,
239) {
240 let instance = &*(ptr as *mut T::Instance);
241 let imp = instance.imp();
242 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
243
244 imp.remove(&widget)
245}
246
247unsafe extern "C" fn container_check_resize<T: ContainerImpl>(ptr: *mut ffi::GtkContainer) {
248 let instance = &*(ptr as *mut T::Instance);
249 let imp = instance.imp();
250
251 imp.check_resize()
252}
253
254unsafe extern "C" fn container_set_focus_child<T: ContainerImpl>(
255 ptr: *mut ffi::GtkContainer,
256 wdgtptr: *mut ffi::GtkWidget,
257) {
258 let instance = &*(ptr as *mut T::Instance);
259 let imp = instance.imp();
260 let widget: Borrowed<Option<Widget>> = from_glib_borrow(wdgtptr);
261
262 imp.set_focus_child(widget.as_ref().as_ref())
263}
264
265unsafe extern "C" fn container_child_type<T: ContainerImpl>(
266 ptr: *mut ffi::GtkContainer,
267) -> glib::ffi::GType {
268 let instance = &*(ptr as *mut T::Instance);
269 let imp = instance.imp();
270
271 imp.child_type().into_glib()
272}
273
274unsafe extern "C" fn container_get_path_for_child<T: ContainerImpl>(
275 ptr: *mut ffi::GtkContainer,
276 wdgtptr: *mut ffi::GtkWidget,
277) -> *mut ffi::GtkWidgetPath {
278 let instance = &*(ptr as *mut T::Instance);
279 let imp = instance.imp();
280 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
281
282 imp.path_for_child(&widget).to_glib_none().0
283}
284
285unsafe extern "C" fn container_forall<T: ObjectSubclass>(
286 ptr: *mut ffi::GtkContainer,
287 include_internals: glib::ffi::gboolean,
288 callback: ffi::GtkCallback,
289 user_data: glib::ffi::gpointer,
290) where
291 T: ContainerImpl,
292{
293 let instance = &*(ptr as *mut T::Instance);
294 let imp = instance.imp();
295 let callback = Callback {
296 callback,
297 user_data,
298 };
299
300 imp.forall(from_glib(include_internals), &callback)
301}
302
303#[derive(Debug)]
304pub struct Callback {
305 callback: ffi::GtkCallback,
306 user_data: glib::ffi::gpointer,
307}
308
309impl Callback {
310 pub fn call(&self, widget: &Widget) {
311 unsafe {
312 if let Some(callback) = self.callback {
313 callback(widget.to_glib_none().0, self.user_data);
314 }
315 }
316 }
317}
318
319pub unsafe trait ContainerClassSubclassExt: ClassStruct {
320 #[doc(alias = "gtk_container_class_handle_border_width")]
321 fn handle_border_width(&mut self) {
322 unsafe {
323 let widget_class = self as *mut _ as *mut ffi::GtkContainerClass;
324 ffi::gtk_container_class_handle_border_width(widget_class);
325 }
326 }
327}
328
329unsafe impl<T: ClassStruct> ContainerClassSubclassExt for T where T::Type: ContainerImpl {}