1use glib::translate::*;
7use libc::c_int;
8
9use crate::{
10 LayoutChild, LayoutManager, Orientation, SizeRequestMode, Widget, ffi, prelude::*,
11 subclass::prelude::*,
12};
13
14pub trait LayoutManagerImpl: ObjectImpl + ObjectSubclass<Type: IsA<LayoutManager>> {
15 fn allocate(&self, widget: &Widget, width: i32, height: i32, baseline: i32) {
27 self.parent_allocate(widget, width, height, baseline)
28 }
29
30 fn create_layout_child(&self, widget: &Widget, for_child: &Widget) -> LayoutChild {
40 self.parent_create_layout_child(widget, for_child)
41 }
42 fn layout_child_type() -> Option<glib::Type> {
45 None
46 }
47
48 #[doc(alias = "get_request_mode")]
52 fn request_mode(&self, widget: &Widget) -> SizeRequestMode {
53 self.parent_request_mode(widget)
54 }
55
56 fn measure(
92 &self,
93 widget: &Widget,
94 orientation: Orientation,
95 for_size: i32,
96 ) -> (i32, i32, i32, i32) {
97 self.parent_measure(widget, orientation, for_size)
98 }
99
100 fn root(&self) {
103 self.parent_root()
104 }
105
106 fn unroot(&self) {
109 self.parent_unroot()
110 }
111}
112
113pub trait LayoutManagerImplExt: LayoutManagerImpl {
114 fn parent_allocate(&self, widget: &Widget, width: i32, height: i32, baseline: i32) {
115 unsafe {
116 let data = Self::type_data();
117 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
118 if let Some(f) = (*parent_class).allocate {
119 f(
120 self.obj()
121 .unsafe_cast_ref::<LayoutManager>()
122 .to_glib_none()
123 .0,
124 widget.to_glib_none().0,
125 width,
126 height,
127 baseline,
128 )
129 }
130 }
131 }
132
133 fn parent_create_layout_child(&self, widget: &Widget, for_child: &Widget) -> LayoutChild {
134 unsafe {
135 let data = Self::type_data();
136 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
137 let f = (*parent_class)
138 .create_layout_child
139 .expect("No parent class impl for \"create_layout_child\"");
140 from_glib_none(f(
141 self.obj()
142 .unsafe_cast_ref::<LayoutManager>()
143 .to_glib_none()
144 .0,
145 widget.to_glib_none().0,
146 for_child.to_glib_none().0,
147 ))
148 }
149 }
150
151 fn parent_request_mode(&self, widget: &Widget) -> SizeRequestMode {
152 unsafe {
153 let data = Self::type_data();
154 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
155 let f = (*parent_class)
156 .get_request_mode
157 .expect("No parent class impl for \"get_request_mode\"");
158 from_glib(f(
159 self.obj()
160 .unsafe_cast_ref::<LayoutManager>()
161 .to_glib_none()
162 .0,
163 widget.to_glib_none().0,
164 ))
165 }
166 }
167
168 fn parent_measure(
169 &self,
170 widget: &Widget,
171 orientation: Orientation,
172 for_size: i32,
173 ) -> (i32, i32, i32, i32) {
174 unsafe {
175 let data = Self::type_data();
176 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
177 let f = (*parent_class)
178 .measure
179 .expect("No parent class impl for \"measure\"");
180
181 let mut minimum = 0;
182 let mut natural = 0;
183 let mut minimum_baseline = -1;
184 let mut natural_baseline = -1;
185 f(
186 self.obj()
187 .unsafe_cast_ref::<LayoutManager>()
188 .to_glib_none()
189 .0,
190 widget.to_glib_none().0,
191 orientation.into_glib(),
192 for_size,
193 &mut minimum,
194 &mut natural,
195 &mut minimum_baseline,
196 &mut natural_baseline,
197 );
198 (minimum, natural, minimum_baseline, natural_baseline)
199 }
200 }
201
202 fn parent_root(&self) {
203 unsafe {
204 let data = Self::type_data();
205 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
206 if let Some(f) = (*parent_class).root {
207 f(self
208 .obj()
209 .unsafe_cast_ref::<LayoutManager>()
210 .to_glib_none()
211 .0)
212 }
213 }
214 }
215
216 fn parent_unroot(&self) {
217 unsafe {
218 let data = Self::type_data();
219 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
220 if let Some(f) = (*parent_class).unroot {
221 f(self
222 .obj()
223 .unsafe_cast_ref::<LayoutManager>()
224 .to_glib_none()
225 .0)
226 }
227 }
228 }
229}
230
231impl<T: LayoutManagerImpl> LayoutManagerImplExt for T {}
232
233unsafe impl<T: LayoutManagerImpl> IsSubclassable<T> for LayoutManager {
234 fn class_init(class: &mut glib::Class<Self>) {
235 Self::parent_class_init::<T>(class);
236
237 assert_initialized_main_thread!();
238
239 let klass = class.as_mut();
240 klass.allocate = Some(layout_manager_allocate::<T>);
241 klass.create_layout_child = Some(layout_manager_create_layout_child::<T>);
242 if let Some(type_) = T::layout_child_type() {
243 klass.layout_child_type = type_.into_glib();
244 }
245 klass.get_request_mode = Some(layout_manager_get_request_mode::<T>);
246 klass.measure = Some(layout_manager_measure::<T>);
247 klass.root = Some(layout_manager_root::<T>);
248 klass.unroot = Some(layout_manager_unroot::<T>);
249 }
250}
251
252unsafe extern "C" fn layout_manager_allocate<T: LayoutManagerImpl>(
253 ptr: *mut ffi::GtkLayoutManager,
254 widgetptr: *mut ffi::GtkWidget,
255 width: i32,
256 height: i32,
257 baseline: i32,
258) {
259 unsafe {
260 let instance = &*(ptr as *mut T::Instance);
261 let imp = instance.imp();
262
263 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
264
265 imp.allocate(&widget, width, height, baseline)
266 }
267}
268
269unsafe extern "C" fn layout_manager_create_layout_child<T: LayoutManagerImpl>(
270 ptr: *mut ffi::GtkLayoutManager,
271 widgetptr: *mut ffi::GtkWidget,
272 for_childptr: *mut ffi::GtkWidget,
273) -> *mut ffi::GtkLayoutChild {
274 unsafe {
275 let instance = &*(ptr as *mut T::Instance);
276 let imp = instance.imp();
277 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
278 let for_child: Borrowed<Widget> = from_glib_borrow(for_childptr);
279
280 imp.create_layout_child(&widget, &for_child).into_glib_ptr()
281 }
282}
283
284unsafe extern "C" fn layout_manager_get_request_mode<T: LayoutManagerImpl>(
285 ptr: *mut ffi::GtkLayoutManager,
286 widgetptr: *mut ffi::GtkWidget,
287) -> ffi::GtkSizeRequestMode {
288 unsafe {
289 let instance = &*(ptr as *mut T::Instance);
290 let imp = instance.imp();
291 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
292
293 imp.request_mode(&widget).into_glib()
294 }
295}
296
297unsafe extern "C" fn layout_manager_measure<T: LayoutManagerImpl>(
298 ptr: *mut ffi::GtkLayoutManager,
299 widgetptr: *mut ffi::GtkWidget,
300 orientation: ffi::GtkOrientation,
301 for_size: i32,
302 minimum_ptr: *mut c_int,
303 natural_ptr: *mut c_int,
304 minimum_baseline_ptr: *mut c_int,
305 natural_baseline_ptr: *mut c_int,
306) {
307 unsafe {
308 let instance = &*(ptr as *mut T::Instance);
309 let imp = instance.imp();
310 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
311
312 let (minimum, natural, minimum_baseline, natural_baseline) =
313 imp.measure(&widget, from_glib(orientation), for_size);
314 if !minimum_ptr.is_null() {
315 *minimum_ptr = minimum;
316 }
317 if !natural_ptr.is_null() {
318 *natural_ptr = natural;
319 }
320 if !minimum_baseline_ptr.is_null() {
321 *minimum_baseline_ptr = minimum_baseline;
322 }
323 if !natural_baseline_ptr.is_null() {
324 *natural_baseline_ptr = natural_baseline;
325 }
326 }
327}
328
329unsafe extern "C" fn layout_manager_root<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
330 unsafe {
331 let instance = &*(ptr as *mut T::Instance);
332 let imp = instance.imp();
333
334 imp.root()
335 }
336}
337
338unsafe extern "C" fn layout_manager_unroot<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
339 unsafe {
340 let instance = &*(ptr as *mut T::Instance);
341 let imp = instance.imp();
342
343 imp.unroot()
344 }
345}