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