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`].
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: ObjectImpl + ObjectSubclass<Type: IsA<CellAreaContext>> {
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
118#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
119#[allow(deprecated)]
120pub trait CellAreaContextImplExt: CellAreaContextImpl {
121    fn parent_reset(&self) {
122        unsafe {
123            let data = Self::type_data();
124            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
125            if let Some(f) = (*parent_class).reset {
126                f(self
127                    .obj()
128                    .unsafe_cast_ref::<CellAreaContext>()
129                    .to_glib_none()
130                    .0)
131            }
132        }
133    }
134
135    fn parent_preferred_height_for_width(&self, width: i32) -> (i32, i32) {
136        unsafe {
137            let data = Self::type_data();
138            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
139            if let Some(f) = (*parent_class).get_preferred_height_for_width {
140                let mut minimum_size = MaybeUninit::uninit();
141                let mut natural_size = MaybeUninit::uninit();
142                f(
143                    self.obj()
144                        .unsafe_cast_ref::<CellAreaContext>()
145                        .to_glib_none()
146                        .0,
147                    width,
148                    minimum_size.as_mut_ptr(),
149                    natural_size.as_mut_ptr(),
150                );
151                (minimum_size.assume_init(), natural_size.assume_init())
152            } else {
153                (-1, -1)
154            }
155        }
156    }
157
158    fn parent_preferred_width_for_height(&self, height: i32) -> (i32, i32) {
159        unsafe {
160            let data = Self::type_data();
161            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
162            if let Some(f) = (*parent_class).get_preferred_width_for_height {
163                let mut minimum_size = MaybeUninit::uninit();
164                let mut natural_size = MaybeUninit::uninit();
165                f(
166                    self.obj()
167                        .unsafe_cast_ref::<CellAreaContext>()
168                        .to_glib_none()
169                        .0,
170                    height,
171                    minimum_size.as_mut_ptr(),
172                    natural_size.as_mut_ptr(),
173                );
174                (minimum_size.assume_init(), natural_size.assume_init())
175            } else {
176                (-1, -1)
177            }
178        }
179    }
180
181    fn parent_allocate(&self, width: i32, height: i32) {
182        unsafe {
183            let data = Self::type_data();
184            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaContextClass;
185            if let Some(f) = (*parent_class).allocate {
186                f(
187                    self.obj()
188                        .unsafe_cast_ref::<CellAreaContext>()
189                        .to_glib_none()
190                        .0,
191                    width,
192                    height,
193                )
194            }
195        }
196    }
197}
198
199impl<T: CellAreaContextImpl> CellAreaContextImplExt for T {}
200
201unsafe impl<T: CellAreaContextImpl> IsSubclassable<T> for CellAreaContext {
202    fn class_init(class: &mut glib::Class<Self>) {
203        Self::parent_class_init::<T>(class);
204
205        assert_initialized_main_thread!();
206
207        let klass = class.as_mut();
208        klass.reset = Some(cell_area_context_reset::<T>);
209        klass.get_preferred_height_for_width =
210            Some(cell_area_context_get_preferred_height_for_width::<T>);
211        klass.get_preferred_width_for_height =
212            Some(cell_area_context_get_preferred_width_for_height::<T>);
213        klass.allocate = Some(cell_area_context_allocate::<T>);
214    }
215}
216
217unsafe extern "C" fn cell_area_context_reset<T: CellAreaContextImpl>(
218    ptr: *mut ffi::GtkCellAreaContext,
219) {
220    let instance = &*(ptr as *mut T::Instance);
221    let imp = instance.imp();
222
223    imp.reset()
224}
225
226unsafe extern "C" fn cell_area_context_get_preferred_height_for_width<T: CellAreaContextImpl>(
227    ptr: *mut ffi::GtkCellAreaContext,
228    width: i32,
229    minimum_height: *mut libc::c_int,
230    natural_height: *mut libc::c_int,
231) {
232    let instance = &*(ptr as *mut T::Instance);
233    let imp = instance.imp();
234
235    let (min_height, nat_height) = imp.preferred_height_for_width(width);
236    *minimum_height = min_height;
237    *natural_height = nat_height;
238}
239
240unsafe extern "C" fn cell_area_context_get_preferred_width_for_height<T: CellAreaContextImpl>(
241    ptr: *mut ffi::GtkCellAreaContext,
242    height: i32,
243    minimum_width: *mut libc::c_int,
244    natural_width: *mut libc::c_int,
245) {
246    let instance = &*(ptr as *mut T::Instance);
247    let imp = instance.imp();
248
249    let (min_width, nat_width) = imp.preferred_width_for_height(height);
250    *minimum_width = min_width;
251    *natural_width = nat_width;
252}
253
254unsafe extern "C" fn cell_area_context_allocate<T: CellAreaContextImpl>(
255    ptr: *mut ffi::GtkCellAreaContext,
256    width: i32,
257    height: i32,
258) {
259    let instance = &*(ptr as *mut T::Instance);
260    let imp = instance.imp();
261
262    imp.allocate(width, height)
263}