gtk4/subclass/
cell_area_context.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 [`CellAreaContext`](crate::CellAreaContext).
5
6use std::mem::MaybeUninit;
7
8use glib::translate::*;
9
10use crate::{ffi, prelude::*, subclass::prelude::*, CellAreaContext};
11
12#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
13#[allow(deprecated)]
14pub trait CellAreaContextImpl: CellAreaContextImplExt + ObjectImpl {
15    /// Resets any previously cached request and allocation
16    /// data.
17    ///
18    /// When underlying [`TreeModel`][crate::TreeModel] data changes its
19    /// important to reset the context if the content
20    /// size is allowed to shrink. If the content size
21    /// is only allowed to grow (this is usually an option
22    /// for views rendering large data stores as a measure
23    /// of optimization), then only the row that changed
24    /// or was inserted needs to be (re)requested with
25    /// gtk_cell_area_get_preferred_width().
26    ///
27    /// When the new overall size of the context requires
28    /// that the allocated size changes (or whenever this
29    /// allocation changes at all), the variable row
30    /// sizes need to be re-requested for every row.
31    ///
32    /// For instance, if the rows are displayed all with
33    /// the same width from top to bottom then a change
34    /// in the allocated width necessitates a recalculation
35    /// of all the displayed row heights using
36    /// gtk_cell_area_get_preferred_height_for_width().
37    ///
38    /// # Deprecated since 4.10
39    ///
40    /// This object will be removed in GTK 5
41    fn reset(&self) {
42        self.parent_reset()
43    }
44
45    /// Gets the accumulative preferred height for @width for all rows
46    /// which have been requested for the same said @width with this context.
47    ///
48    /// After gtk_cell_area_context_reset() is called and/or before ever
49    /// requesting the size of a [`CellArea`][crate::CellArea], the returned values are -1.
50    ///
51    /// # Deprecated since 4.10
52    ///
53    /// This object will be removed in GTK 5
54    /// ## `width`
55    /// a proposed width for allocation
56    ///
57    /// # Returns
58    ///
59    ///
60    /// ## `minimum_height`
61    /// location to store the minimum height
62    ///
63    /// ## `natural_height`
64    /// location to store the natural height
65    fn preferred_height_for_width(&self, width: i32) -> (i32, i32) {
66        self.parent_preferred_height_for_width(width)
67    }
68
69    /// Gets the accumulative preferred width for @height for all rows which
70    /// have been requested for the same said @height with this context.
71    ///
72    /// After gtk_cell_area_context_reset() is called and/or before ever
73    /// requesting the size of a [`CellArea`][crate::CellArea], the returned values are -1.
74    ///
75    /// # Deprecated since 4.10
76    ///
77    /// This object will be removed in GTK 5
78    /// ## `height`
79    /// a proposed height for allocation
80    ///
81    /// # Returns
82    ///
83    ///
84    /// ## `minimum_width`
85    /// location to store the minimum width
86    ///
87    /// ## `natural_width`
88    /// location to store the natural width
89    fn preferred_width_for_height(&self, height: i32) -> (i32, i32) {
90        self.parent_preferred_width_for_height(height)
91    }
92
93    /// Allocates a width and/or a height for all rows which are to be
94    /// rendered with @self.
95    ///
96    /// Usually allocation is performed only horizontally or sometimes
97    /// vertically since a group of rows are usually rendered side by
98    /// side vertically or horizontally and share either the same width
99    /// or the same height. Sometimes they are allocated in both horizontal
100    /// and vertical orientations producing a homogeneous effect of the
101    /// rows. This is generally the case for [`TreeView`][crate::TreeView] when
102    /// `GtkTreeView:fixed-height-mode` is enabled.
103    ///
104    /// # Deprecated since 4.10
105    ///
106    /// This object will be removed in GTK 5
107    /// ## `width`
108    /// the allocated width for all [`TreeModel`][crate::TreeModel] rows rendered
109    ///   with @self, or -1
110    /// ## `height`
111    /// the allocated height for all [`TreeModel`][crate::TreeModel] rows rendered
112    ///   with @self, or -1
113    fn allocate(&self, width: i32, height: i32) {
114        self.parent_allocate(width, height)
115    }
116}
117
118mod sealed {
119    pub trait Sealed {}
120    impl<T: super::CellAreaContextImplExt> Sealed for T {}
121}
122
123#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
124#[allow(deprecated)]
125pub trait CellAreaContextImplExt: sealed::Sealed + ObjectSubclass {
126    fn parent_reset(&self) {
127        unsafe {
128            let data = Self::type_data();
129            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
130            if let Some(f) = (*parent_class).reset {
131                f(self
132                    .obj()
133                    .unsafe_cast_ref::<CellAreaContext>()
134                    .to_glib_none()
135                    .0)
136            }
137        }
138    }
139
140    fn parent_preferred_height_for_width(&self, width: i32) -> (i32, i32) {
141        unsafe {
142            let data = Self::type_data();
143            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
144            if let Some(f) = (*parent_class).get_preferred_height_for_width {
145                let mut minimum_size = MaybeUninit::uninit();
146                let mut natural_size = MaybeUninit::uninit();
147                f(
148                    self.obj()
149                        .unsafe_cast_ref::<CellAreaContext>()
150                        .to_glib_none()
151                        .0,
152                    width,
153                    minimum_size.as_mut_ptr(),
154                    natural_size.as_mut_ptr(),
155                );
156                (minimum_size.assume_init(), natural_size.assume_init())
157            } else {
158                (-1, -1)
159            }
160        }
161    }
162
163    fn parent_preferred_width_for_height(&self, height: i32) -> (i32, i32) {
164        unsafe {
165            let data = Self::type_data();
166            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
167            if let Some(f) = (*parent_class).get_preferred_width_for_height {
168                let mut minimum_size = MaybeUninit::uninit();
169                let mut natural_size = MaybeUninit::uninit();
170                f(
171                    self.obj()
172                        .unsafe_cast_ref::<CellAreaContext>()
173                        .to_glib_none()
174                        .0,
175                    height,
176                    minimum_size.as_mut_ptr(),
177                    natural_size.as_mut_ptr(),
178                );
179                (minimum_size.assume_init(), natural_size.assume_init())
180            } else {
181                (-1, -1)
182            }
183        }
184    }
185
186    fn parent_allocate(&self, width: i32, height: i32) {
187        unsafe {
188            let data = Self::type_data();
189            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
190            if let Some(f) = (*parent_class).allocate {
191                f(
192                    self.obj()
193                        .unsafe_cast_ref::<CellAreaContext>()
194                        .to_glib_none()
195                        .0,
196                    width,
197                    height,
198                )
199            }
200        }
201    }
202}
203
204impl<T: CellAreaContextImpl> CellAreaContextImplExt for T {}
205
206unsafe impl<T: CellAreaContextImpl> IsSubclassable<T> for CellAreaContext {
207    fn class_init(class: &mut glib::Class<Self>) {
208        Self::parent_class_init::<T>(class);
209
210        assert_initialized_main_thread!();
211
212        let klass = class.as_mut();
213        klass.reset = Some(cell_area_context_reset::<T>);
214        klass.get_preferred_height_for_width =
215            Some(cell_area_context_get_preferred_height_for_width::<T>);
216        klass.get_preferred_width_for_height =
217            Some(cell_area_context_get_preferred_width_for_height::<T>);
218        klass.allocate = Some(cell_area_context_allocate::<T>);
219    }
220}
221
222unsafe extern "C" fn cell_area_context_reset<T: CellAreaContextImpl>(
223    ptr: *mut ffi::GtkCellAreaContext,
224) {
225    let instance = &*(ptr as *mut T::Instance);
226    let imp = instance.imp();
227
228    imp.reset()
229}
230
231unsafe extern "C" fn cell_area_context_get_preferred_height_for_width<T: CellAreaContextImpl>(
232    ptr: *mut ffi::GtkCellAreaContext,
233    width: i32,
234    minimum_height: *mut libc::c_int,
235    natural_height: *mut libc::c_int,
236) {
237    let instance = &*(ptr as *mut T::Instance);
238    let imp = instance.imp();
239
240    let (min_height, nat_height) = imp.preferred_height_for_width(width);
241    *minimum_height = min_height;
242    *natural_height = nat_height;
243}
244
245unsafe extern "C" fn cell_area_context_get_preferred_width_for_height<T: CellAreaContextImpl>(
246    ptr: *mut ffi::GtkCellAreaContext,
247    height: i32,
248    minimum_width: *mut libc::c_int,
249    natural_width: *mut libc::c_int,
250) {
251    let instance = &*(ptr as *mut T::Instance);
252    let imp = instance.imp();
253
254    let (min_width, nat_width) = imp.preferred_width_for_height(height);
255    *minimum_width = min_width;
256    *natural_width = nat_width;
257}
258
259unsafe extern "C" fn cell_area_context_allocate<T: CellAreaContextImpl>(
260    ptr: *mut ffi::GtkCellAreaContext,
261    width: i32,
262    height: i32,
263) {
264    let instance = &*(ptr as *mut T::Instance);
265    let imp = instance.imp();
266
267    imp.allocate(width, height)
268}