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) {
16 self.parent_allocate(widget, width, height, baseline)
17 }
18
19 fn create_layout_child(&self, widget: &Widget, for_child: &Widget) -> LayoutChild {
20 self.parent_create_layout_child(widget, for_child)
21 }
22 fn layout_child_type() -> Option<glib::Type> {
25 None
26 }
27
28 #[doc(alias = "get_request_mode")]
29 fn request_mode(&self, widget: &Widget) -> SizeRequestMode {
30 self.parent_request_mode(widget)
31 }
32
33 fn measure(
34 &self,
35 widget: &Widget,
36 orientation: Orientation,
37 for_size: i32,
38 ) -> (i32, i32, i32, i32) {
39 self.parent_measure(widget, orientation, for_size)
40 }
41
42 fn root(&self) {
43 self.parent_root()
44 }
45
46 fn unroot(&self) {
47 self.parent_unroot()
48 }
49}
50
51pub trait LayoutManagerImplExt: LayoutManagerImpl {
52 fn parent_allocate(&self, widget: &Widget, width: i32, height: i32, baseline: i32) {
53 unsafe {
54 let data = Self::type_data();
55 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
56 if let Some(f) = (*parent_class).allocate {
57 f(
58 self.obj()
59 .unsafe_cast_ref::<LayoutManager>()
60 .to_glib_none()
61 .0,
62 widget.to_glib_none().0,
63 width,
64 height,
65 baseline,
66 )
67 }
68 }
69 }
70
71 fn parent_create_layout_child(&self, widget: &Widget, for_child: &Widget) -> LayoutChild {
72 unsafe {
73 let data = Self::type_data();
74 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
75 let f = (*parent_class)
76 .create_layout_child
77 .expect("No parent class impl for \"create_layout_child\"");
78 from_glib_none(f(
79 self.obj()
80 .unsafe_cast_ref::<LayoutManager>()
81 .to_glib_none()
82 .0,
83 widget.to_glib_none().0,
84 for_child.to_glib_none().0,
85 ))
86 }
87 }
88
89 fn parent_request_mode(&self, widget: &Widget) -> SizeRequestMode {
90 unsafe {
91 let data = Self::type_data();
92 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
93 let f = (*parent_class)
94 .get_request_mode
95 .expect("No parent class impl for \"get_request_mode\"");
96 from_glib(f(
97 self.obj()
98 .unsafe_cast_ref::<LayoutManager>()
99 .to_glib_none()
100 .0,
101 widget.to_glib_none().0,
102 ))
103 }
104 }
105
106 fn parent_measure(
107 &self,
108 widget: &Widget,
109 orientation: Orientation,
110 for_size: i32,
111 ) -> (i32, i32, i32, i32) {
112 unsafe {
113 let data = Self::type_data();
114 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
115 let f = (*parent_class)
116 .measure
117 .expect("No parent class impl for \"measure\"");
118
119 let mut minimum = 0;
120 let mut natural = 0;
121 let mut minimum_baseline = -1;
122 let mut natural_baseline = -1;
123 f(
124 self.obj()
125 .unsafe_cast_ref::<LayoutManager>()
126 .to_glib_none()
127 .0,
128 widget.to_glib_none().0,
129 orientation.into_glib(),
130 for_size,
131 &mut minimum,
132 &mut natural,
133 &mut minimum_baseline,
134 &mut natural_baseline,
135 );
136 (minimum, natural, minimum_baseline, natural_baseline)
137 }
138 }
139
140 fn parent_root(&self) {
141 unsafe {
142 let data = Self::type_data();
143 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
144 if let Some(f) = (*parent_class).root {
145 f(self
146 .obj()
147 .unsafe_cast_ref::<LayoutManager>()
148 .to_glib_none()
149 .0)
150 }
151 }
152 }
153
154 fn parent_unroot(&self) {
155 unsafe {
156 let data = Self::type_data();
157 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkLayoutManagerClass;
158 if let Some(f) = (*parent_class).unroot {
159 f(self
160 .obj()
161 .unsafe_cast_ref::<LayoutManager>()
162 .to_glib_none()
163 .0)
164 }
165 }
166 }
167}
168
169impl<T: LayoutManagerImpl> LayoutManagerImplExt for T {}
170
171unsafe impl<T: LayoutManagerImpl> IsSubclassable<T> for LayoutManager {
172 fn class_init(class: &mut glib::Class<Self>) {
173 Self::parent_class_init::<T>(class);
174
175 assert_initialized_main_thread!();
176
177 let klass = class.as_mut();
178 klass.allocate = Some(layout_manager_allocate::<T>);
179 klass.create_layout_child = Some(layout_manager_create_layout_child::<T>);
180 if let Some(type_) = T::layout_child_type() {
181 klass.layout_child_type = type_.into_glib();
182 }
183 klass.get_request_mode = Some(layout_manager_get_request_mode::<T>);
184 klass.measure = Some(layout_manager_measure::<T>);
185 klass.root = Some(layout_manager_root::<T>);
186 klass.unroot = Some(layout_manager_unroot::<T>);
187 }
188}
189
190unsafe extern "C" fn layout_manager_allocate<T: LayoutManagerImpl>(
191 ptr: *mut ffi::GtkLayoutManager,
192 widgetptr: *mut ffi::GtkWidget,
193 width: i32,
194 height: i32,
195 baseline: i32,
196) {
197 let instance = &*(ptr as *mut T::Instance);
198 let imp = instance.imp();
199
200 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
201
202 imp.allocate(&widget, width, height, baseline)
203}
204
205unsafe extern "C" fn layout_manager_create_layout_child<T: LayoutManagerImpl>(
206 ptr: *mut ffi::GtkLayoutManager,
207 widgetptr: *mut ffi::GtkWidget,
208 for_childptr: *mut ffi::GtkWidget,
209) -> *mut ffi::GtkLayoutChild {
210 let instance = &*(ptr as *mut T::Instance);
211 let imp = instance.imp();
212 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
213 let for_child: Borrowed<Widget> = from_glib_borrow(for_childptr);
214
215 imp.create_layout_child(&widget, &for_child).into_glib_ptr()
216}
217
218unsafe extern "C" fn layout_manager_get_request_mode<T: LayoutManagerImpl>(
219 ptr: *mut ffi::GtkLayoutManager,
220 widgetptr: *mut ffi::GtkWidget,
221) -> ffi::GtkSizeRequestMode {
222 let instance = &*(ptr as *mut T::Instance);
223 let imp = instance.imp();
224 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
225
226 imp.request_mode(&widget).into_glib()
227}
228
229unsafe extern "C" fn layout_manager_measure<T: LayoutManagerImpl>(
230 ptr: *mut ffi::GtkLayoutManager,
231 widgetptr: *mut ffi::GtkWidget,
232 orientation: ffi::GtkOrientation,
233 for_size: i32,
234 minimum_ptr: *mut c_int,
235 natural_ptr: *mut c_int,
236 minimum_baseline_ptr: *mut c_int,
237 natural_baseline_ptr: *mut c_int,
238) {
239 let instance = &*(ptr as *mut T::Instance);
240 let imp = instance.imp();
241 let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
242
243 let (minimum, natural, minimum_baseline, natural_baseline) =
244 imp.measure(&widget, from_glib(orientation), for_size);
245 if !minimum_ptr.is_null() {
246 *minimum_ptr = minimum;
247 }
248 if !natural_ptr.is_null() {
249 *natural_ptr = natural;
250 }
251 if !minimum_baseline_ptr.is_null() {
252 *minimum_baseline_ptr = minimum_baseline;
253 }
254 if !natural_baseline_ptr.is_null() {
255 *natural_baseline_ptr = natural_baseline;
256 }
257}
258
259unsafe extern "C" fn layout_manager_root<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
260 let instance = &*(ptr as *mut T::Instance);
261 let imp = instance.imp();
262
263 imp.root()
264}
265
266unsafe extern "C" fn layout_manager_unroot<T: LayoutManagerImpl>(ptr: *mut ffi::GtkLayoutManager) {
267 let instance = &*(ptr as *mut T::Instance);
268 let imp = instance.imp();
269
270 imp.unroot()
271}