gtk4/subclass/
layout_manager.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for subclassing [`LayoutManager`].
5
6use 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    // rustdoc-stripper-ignore-next
23    /// Only set if the child implemented LayoutChildImpl
24    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}