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}