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: 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 let instance = &*(ptr as *mut T::Instance);
260 let imp = instance.imp();
261
262 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
263
264 imp.allocate(&widget, width, height, baseline)
265}
266
267unsafe extern "C" fn layout_manager_create_layout_child<T: LayoutManagerImpl>(
268 ptr: *mut ffi::GtkLayoutManager,
269 widgetptr: *mut ffi::GtkWidget,
270 for_childptr: *mut ffi::GtkWidget,
271) -> *mut ffi::GtkLayoutChild {
272 let instance = &*(ptr as *mut T::Instance);
273 let imp = instance.imp();
274 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
275 let for_child: Borrowed<Widget> = from_glib_borrow(for_childptr);
276
277 imp.create_layout_child(&widget, &for_child).into_glib_ptr()
278}
279
280unsafe extern "C" fn layout_manager_get_request_mode<T: LayoutManagerImpl>(
281 ptr: *mut ffi::GtkLayoutManager,
282 widgetptr: *mut ffi::GtkWidget,
283) -> ffi::GtkSizeRequestMode {
284 let instance = &*(ptr as *mut T::Instance);
285 let imp = instance.imp();
286 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
287
288 imp.request_mode(&widget).into_glib()
289}
290
291unsafe extern "C" fn layout_manager_measure<T: LayoutManagerImpl>(
292 ptr: *mut ffi::GtkLayoutManager,
293 widgetptr: *mut ffi::GtkWidget,
294 orientation: ffi::GtkOrientation,
295 for_size: i32,
296 minimum_ptr: *mut c_int,
297 natural_ptr: *mut c_int,
298 minimum_baseline_ptr: *mut c_int,
299 natural_baseline_ptr: *mut c_int,
300) {
301 let instance = &*(ptr as *mut T::Instance);
302 let imp = instance.imp();
303 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
304
305 let (minimum, natural, minimum_baseline, natural_baseline) =
306 imp.measure(&widget, from_glib(orientation), for_size);
307 if !minimum_ptr.is_null() {
308 *minimum_ptr = minimum;
309 }
310 if !natural_ptr.is_null() {
311 *natural_ptr = natural;
312 }
313 if !minimum_baseline_ptr.is_null() {
314 *minimum_baseline_ptr = minimum_baseline;
315 }
316 if !natural_baseline_ptr.is_null() {
317 *natural_baseline_ptr = natural_baseline;
318 }
319}
320
321unsafe extern "C" fn layout_manager_root<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
322 let instance = &*(ptr as *mut T::Instance);
323 let imp = instance.imp();
324
325 imp.root()
326}
327
328unsafe extern "C" fn layout_manager_unroot<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
329 let instance = &*(ptr as *mut T::Instance);
330 let imp = instance.imp();
331
332 imp.unroot()
333}