1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 use glib::translate::*;
4
5 use glib::subclass::prelude::*;
6
7 use glib::Cast;
8
9 use super::widget::WidgetImpl;
10 use crate::Container;
11 use crate::Widget;
12 use crate::WidgetPath;
13
14 pub trait ContainerImpl: ContainerImplExt + WidgetImpl {
add(&self, container: &Self::Type, widget: &Widget)15 fn add(&self, container: &Self::Type, widget: &Widget) {
16 self.parent_add(container, widget)
17 }
18
remove(&self, container: &Self::Type, widget: &Widget)19 fn remove(&self, container: &Self::Type, widget: &Widget) {
20 self.parent_remove(container, widget)
21 }
22
check_resize(&self, container: &Self::Type)23 fn check_resize(&self, container: &Self::Type) {
24 self.parent_check_resize(container)
25 }
26
set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>)27 fn set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>) {
28 self.parent_set_focus_child(container, widget)
29 }
30
child_type(&self, container: &Self::Type) -> glib::Type31 fn child_type(&self, container: &Self::Type) -> glib::Type {
32 self.parent_child_type(container)
33 }
34
35 #[doc(alias = "get_path_for_child")]
path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath36 fn path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath {
37 self.parent_path_for_child(container, widget)
38 }
39
forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback)40 fn forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback) {
41 self.parent_forall(container, include_internals, callback);
42 }
43 }
44
45 pub trait ContainerImplExt: ObjectSubclass {
parent_add(&self, container: &Self::Type, widget: &Widget)46 fn parent_add(&self, container: &Self::Type, widget: &Widget);
parent_remove(&self, container: &Self::Type, widget: &Widget)47 fn parent_remove(&self, container: &Self::Type, widget: &Widget);
parent_check_resize(&self, container: &Self::Type)48 fn parent_check_resize(&self, container: &Self::Type);
parent_set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>)49 fn parent_set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>);
parent_child_type(&self, container: &Self::Type) -> glib::Type50 fn parent_child_type(&self, container: &Self::Type) -> glib::Type;
parent_path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath51 fn parent_path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath;
parent_forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback)52 fn parent_forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback);
53 }
54
55 impl<T: ContainerImpl> ContainerImplExt for T {
parent_add(&self, container: &Self::Type, widget: &Widget)56 fn parent_add(&self, container: &Self::Type, widget: &Widget) {
57 unsafe {
58 let data = T::type_data();
59 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
60 if let Some(f) = (*parent_class).add {
61 f(
62 container.unsafe_cast_ref::<Container>().to_glib_none().0,
63 widget.to_glib_none().0,
64 )
65 }
66 }
67 }
68
parent_remove(&self, container: &Self::Type, widget: &Widget)69 fn parent_remove(&self, container: &Self::Type, widget: &Widget) {
70 unsafe {
71 let data = T::type_data();
72 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
73 if let Some(f) = (*parent_class).remove {
74 f(
75 container.unsafe_cast_ref::<Container>().to_glib_none().0,
76 widget.to_glib_none().0,
77 )
78 }
79 }
80 }
81
parent_check_resize(&self, container: &Self::Type)82 fn parent_check_resize(&self, container: &Self::Type) {
83 unsafe {
84 let data = T::type_data();
85 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
86 if let Some(f) = (*parent_class).check_resize {
87 f(container.unsafe_cast_ref::<Container>().to_glib_none().0)
88 }
89 }
90 }
91
parent_set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>)92 fn parent_set_focus_child(&self, container: &Self::Type, widget: Option<&Widget>) {
93 unsafe {
94 let data = T::type_data();
95 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
96 if let Some(f) = (*parent_class).set_focus_child {
97 f(
98 container.unsafe_cast_ref::<Container>().to_glib_none().0,
99 widget.to_glib_none().0,
100 )
101 }
102 }
103 }
104
parent_child_type(&self, container: &Self::Type) -> glib::Type105 fn parent_child_type(&self, container: &Self::Type) -> glib::Type {
106 unsafe {
107 let data = T::type_data();
108 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
109 if let Some(f) = (*parent_class).child_type {
110 from_glib(f(container.unsafe_cast_ref::<Container>().to_glib_none().0))
111 } else {
112 glib::Type::UNIT
113 }
114 }
115 }
116
parent_path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath117 fn parent_path_for_child(&self, container: &Self::Type, widget: &Widget) -> WidgetPath {
118 unsafe {
119 let data = T::type_data();
120 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
121 let f = (*parent_class)
122 .get_path_for_child
123 .expect("No parent class impl for \"get_path_for_child\"");
124 from_glib_none(f(
125 container.unsafe_cast_ref::<Container>().to_glib_none().0,
126 widget.to_glib_none().0,
127 ))
128 }
129 }
130
parent_forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback)131 fn parent_forall(&self, container: &Self::Type, include_internals: bool, callback: &Callback) {
132 unsafe {
133 let data = T::type_data();
134 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkContainerClass;
135 if let Some(f) = (*parent_class).forall {
136 f(
137 container.unsafe_cast_ref::<Container>().to_glib_none().0,
138 include_internals.into_glib(),
139 callback.callback,
140 callback.user_data,
141 )
142 }
143 }
144 }
145 }
146
147 unsafe impl<T: ContainerImpl> IsSubclassable<T> for Container {
class_init(class: &mut ::glib::Class<Self>)148 fn class_init(class: &mut ::glib::Class<Self>) {
149 <Widget as IsSubclassable<T>>::class_init(class);
150
151 let klass = class.as_mut();
152 klass.add = Some(container_add::<T>);
153 klass.remove = Some(container_remove::<T>);
154 klass.check_resize = Some(container_check_resize::<T>);
155 klass.set_focus_child = Some(container_set_focus_child::<T>);
156 klass.child_type = Some(container_child_type::<T>);
157 klass.get_path_for_child = Some(container_get_path_for_child::<T>);
158 klass.forall = Some(container_forall::<T>);
159 }
160
instance_init(instance: &mut glib::subclass::InitializingObject<T>)161 fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
162 <Widget as IsSubclassable<T>>::instance_init(instance);
163 }
164 }
165
container_add<T: ContainerImpl>( ptr: *mut ffi::GtkContainer, wdgtptr: *mut ffi::GtkWidget, )166 unsafe extern "C" fn container_add<T: ContainerImpl>(
167 ptr: *mut ffi::GtkContainer,
168 wdgtptr: *mut ffi::GtkWidget,
169 ) {
170 let instance = &*(ptr as *mut T::Instance);
171 let imp = instance.impl_();
172 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
173 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
174
175 imp.add(wrap.unsafe_cast_ref(), &widget)
176 }
177
container_remove<T: ContainerImpl>( ptr: *mut ffi::GtkContainer, wdgtptr: *mut ffi::GtkWidget, )178 unsafe extern "C" fn container_remove<T: ContainerImpl>(
179 ptr: *mut ffi::GtkContainer,
180 wdgtptr: *mut ffi::GtkWidget,
181 ) {
182 let instance = &*(ptr as *mut T::Instance);
183 let imp = instance.impl_();
184 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
185 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
186
187 imp.remove(wrap.unsafe_cast_ref(), &widget)
188 }
189
container_check_resize<T: ContainerImpl>(ptr: *mut ffi::GtkContainer)190 unsafe extern "C" fn container_check_resize<T: ContainerImpl>(ptr: *mut ffi::GtkContainer) {
191 let instance = &*(ptr as *mut T::Instance);
192 let imp = instance.impl_();
193 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
194
195 imp.check_resize(wrap.unsafe_cast_ref())
196 }
197
container_set_focus_child<T: ContainerImpl>( ptr: *mut ffi::GtkContainer, wdgtptr: *mut ffi::GtkWidget, )198 unsafe extern "C" fn container_set_focus_child<T: ContainerImpl>(
199 ptr: *mut ffi::GtkContainer,
200 wdgtptr: *mut ffi::GtkWidget,
201 ) {
202 let instance = &*(ptr as *mut T::Instance);
203 let imp = instance.impl_();
204 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
205 let widget: Borrowed<Option<Widget>> = from_glib_borrow(wdgtptr);
206
207 imp.set_focus_child(wrap.unsafe_cast_ref(), widget.as_ref().as_ref())
208 }
209
container_child_type<T: ContainerImpl>( ptr: *mut ffi::GtkContainer, ) -> glib::ffi::GType210 unsafe extern "C" fn container_child_type<T: ContainerImpl>(
211 ptr: *mut ffi::GtkContainer,
212 ) -> glib::ffi::GType {
213 let instance = &*(ptr as *mut T::Instance);
214 let imp = instance.impl_();
215 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
216
217 imp.child_type(wrap.unsafe_cast_ref()).into_glib()
218 }
219
container_get_path_for_child<T: ContainerImpl>( ptr: *mut ffi::GtkContainer, wdgtptr: *mut ffi::GtkWidget, ) -> *mut ffi::GtkWidgetPath220 unsafe extern "C" fn container_get_path_for_child<T: ContainerImpl>(
221 ptr: *mut ffi::GtkContainer,
222 wdgtptr: *mut ffi::GtkWidget,
223 ) -> *mut ffi::GtkWidgetPath {
224 let instance = &*(ptr as *mut T::Instance);
225 let imp = instance.impl_();
226 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
227 let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
228
229 imp.path_for_child(wrap.unsafe_cast_ref(), &widget)
230 .to_glib_none()
231 .0
232 }
233
container_forall<T: ObjectSubclass>( ptr: *mut ffi::GtkContainer, include_internals: glib::ffi::gboolean, callback: ffi::GtkCallback, user_data: glib::ffi::gpointer, ) where T: ContainerImpl,234 unsafe extern "C" fn container_forall<T: ObjectSubclass>(
235 ptr: *mut ffi::GtkContainer,
236 include_internals: glib::ffi::gboolean,
237 callback: ffi::GtkCallback,
238 user_data: glib::ffi::gpointer,
239 ) where
240 T: ContainerImpl,
241 {
242 let instance = &*(ptr as *mut T::Instance);
243 let imp = instance.impl_();
244 let wrap: Borrowed<Container> = from_glib_borrow(ptr);
245 let callback = Callback {
246 callback,
247 user_data,
248 };
249
250 imp.forall(
251 wrap.unsafe_cast_ref(),
252 from_glib(include_internals),
253 &callback,
254 )
255 }
256
257 #[derive(Debug)]
258 pub struct Callback {
259 callback: ffi::GtkCallback,
260 user_data: glib::ffi::gpointer,
261 }
262
263 impl Callback {
call(&self, widget: &Widget)264 pub fn call(&self, widget: &Widget) {
265 unsafe {
266 if let Some(callback) = self.callback {
267 callback(widget.to_glib_none().0, self.user_data);
268 }
269 }
270 }
271 }
272
273 pub unsafe trait ContainerClassSubclassExt: ClassStruct {
274 #[doc(alias = "gtk_container_class_handle_border_width")]
handle_border_width(&mut self)275 fn handle_border_width(&mut self) {
276 unsafe {
277 let widget_class = self as *mut _ as *mut ffi::GtkContainerClass;
278 ffi::gtk_container_class_handle_border_width(widget_class);
279 }
280 }
281 }
282
283 unsafe impl<T: ClassStruct> ContainerClassSubclassExt for T where T::Type: ContainerImpl {}
284