gtk4/subclass/
cell_area.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 [`CellArea`].
5
6use std::mem;
7
8use glib::{translate::*, ParamSpec, Value};
9
10use crate::{
11    ffi, prelude::*, subclass::prelude::*, Buildable, CellArea, CellAreaContext, CellLayout,
12    CellRenderer, CellRendererState, DirectionType, SizeRequestMode, Snapshot, TreeIter, TreeModel,
13    Widget,
14};
15
16#[derive(Debug)]
17pub struct CellCallback {
18    callback: ffi::GtkCellCallback,
19    user_data: glib::ffi::gpointer,
20}
21
22impl CellCallback {
23    pub fn call<R: IsA<CellRenderer>>(&self, cell_renderer: &R) -> glib::ControlFlow {
24        unsafe {
25            if let Some(callback) = self.callback {
26                from_glib(callback(
27                    cell_renderer.as_ref().to_glib_none().0,
28                    self.user_data,
29                ))
30            } else {
31                glib::ControlFlow::Break
32            }
33        }
34    }
35}
36
37#[derive(Debug)]
38pub struct CellCallbackAllocate {
39    callback: ffi::GtkCellAllocCallback,
40    user_data: glib::ffi::gpointer,
41}
42
43impl CellCallbackAllocate {
44    pub fn call<R: IsA<CellRenderer>>(
45        &self,
46        cell_renderer: &R,
47        cell_area: &gdk::Rectangle,
48        cell_background: &gdk::Rectangle,
49    ) -> glib::ControlFlow {
50        unsafe {
51            if let Some(callback) = self.callback {
52                from_glib(callback(
53                    cell_renderer.as_ref().to_glib_none().0,
54                    cell_area.to_glib_none().0,
55                    cell_background.to_glib_none().0,
56                    self.user_data,
57                ))
58            } else {
59                glib::ControlFlow::Break
60            }
61        }
62    }
63}
64
65#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
66#[allow(deprecated)]
67pub trait CellAreaImpl:
68    ObjectImpl + ObjectSubclass<Type: IsA<CellArea> + IsA<Buildable> + IsA<CellLayout>>
69{
70    fn cell_properties() -> &'static [ParamSpec] {
71        &[]
72    }
73
74    /// This should be implemented to handle changes in child
75    ///   cell properties for a given [`CellRenderer`][crate::CellRenderer] that were previously
76    ///   installed on the [`CellAreaClass`][crate::CellAreaClass] with gtk_cell_area_class_install_cell_property().
77    fn set_cell_property<R: IsA<CellRenderer>>(
78        &self,
79        _renderer: &R,
80        _id: usize,
81        _value: &Value,
82        _pspec: &ParamSpec,
83    ) {
84        unimplemented!()
85    }
86
87    /// This should be implemented to report the values of
88    ///   child cell properties for a given child [`CellRenderer`][crate::CellRenderer].
89    fn cell_property<R: IsA<CellRenderer>>(
90        &self,
91        _renderer: &R,
92        _id: usize,
93        _pspec: &ParamSpec,
94    ) -> Value {
95        unimplemented!()
96    }
97
98    /// Activates @self, usually by activating the currently focused
99    /// cell, however some subclasses which embed widgets in the area
100    /// can also activate a widget if it currently has the focus.
101    ///
102    /// # Deprecated since 4.10
103    ///
104    /// ## `context`
105    /// the [`CellArea`][crate::CellArea]Context in context with the current row data
106    /// ## `widget`
107    /// the [`Widget`][crate::Widget] that @self is rendering on
108    /// ## `cell_area`
109    /// the size and location of @self relative to @widget’s allocation
110    /// ## `flags`
111    /// the [`CellRenderer`][crate::CellRenderer]State flags for @self for this row of data.
112    /// ## `edit_only`
113    /// if [`true`] then only cell renderers that are [`CellRendererMode::Editable`][crate::CellRendererMode::Editable]
114    ///             will be activated.
115    ///
116    /// # Returns
117    ///
118    /// Whether @self was successfully activated.
119    fn activate<P: IsA<CellAreaContext>, W: IsA<Widget>>(
120        &self,
121        context: &P,
122        widget: &W,
123        area: &gdk::Rectangle,
124        flags: CellRendererState,
125        edit_only: bool,
126    ) -> bool {
127        self.parent_activate(context, widget, area, flags, edit_only)
128    }
129
130    /// Adds @renderer to @self with the default child cell properties.
131    ///
132    /// # Deprecated since 4.10
133    ///
134    /// ## `renderer`
135    /// the [`CellRenderer`][crate::CellRenderer] to add to @self
136    fn add<R: IsA<CellRenderer>>(&self, renderer: &R) {
137        self.parent_add(renderer)
138    }
139
140    /// Applies any connected attributes to the renderers in
141    /// @self by pulling the values from @tree_model.
142    ///
143    /// # Deprecated since 4.10
144    ///
145    /// ## `tree_model`
146    /// the [`TreeModel`][crate::TreeModel] to pull values from
147    /// ## `iter`
148    /// the [`TreeIter`][crate::TreeIter] in @tree_model to apply values for
149    /// ## `is_expander`
150    /// whether @iter has children
151    /// ## `is_expanded`
152    /// whether @iter is expanded in the view and
153    ///               children are visible
154    fn apply_attributes<M: IsA<TreeModel>>(
155        &self,
156        tree_model: &M,
157        iter: &TreeIter,
158        is_expander: bool,
159        is_expanded: bool,
160    ) {
161        self.parent_apply_attributes(tree_model, iter, is_expander, is_expanded)
162    }
163
164    /// Creates a [`CellArea`][crate::CellArea]Context to be used with @self for
165    /// all purposes. [`CellArea`][crate::CellArea]Context stores geometry information
166    /// for rows for which it was operated on, it is important to use
167    /// the same context for the same row of data at all times (i.e.
168    /// one should render and handle events with the same [`CellArea`][crate::CellArea]Context
169    /// which was used to request the size of those rows of data).
170    ///
171    /// # Deprecated since 4.10
172    ///
173    ///
174    /// # Returns
175    ///
176    /// a newly created [`CellArea`][crate::CellArea]Context which can be used with @self.
177    fn create_context(&self) -> Option<CellAreaContext> {
178        self.parent_create_context()
179    }
180
181    /// This is sometimes needed for cases where rows need to share
182    /// alignments in one orientation but may be separately grouped
183    /// in the opposing orientation.
184    ///
185    /// For instance, [`IconView`][crate::IconView] creates all icons (rows) to have
186    /// the same width and the cells theirin to have the same
187    /// horizontal alignments. However each row of icons may have
188    /// a separate collective height. [`IconView`][crate::IconView] uses this to
189    /// request the heights of each row based on a context which
190    /// was already used to request all the row widths that are
191    /// to be displayed.
192    ///
193    /// # Deprecated since 4.10
194    ///
195    /// ## `context`
196    /// the [`CellArea`][crate::CellArea]Context to copy
197    ///
198    /// # Returns
199    ///
200    /// a newly created [`CellArea`][crate::CellArea]Context copy of @context.
201    fn copy_context<P: IsA<CellAreaContext>>(&self, context: &P) -> Option<CellAreaContext> {
202        self.parent_copy_context(context)
203    }
204
205    /// Delegates event handling to a [`CellArea`][crate::CellArea].
206    ///
207    /// # Deprecated since 4.10
208    ///
209    /// ## `context`
210    /// the [`CellArea`][crate::CellArea]Context for this row of data.
211    /// ## `widget`
212    /// the [`Widget`][crate::Widget] that @self is rendering to
213    /// ## `event`
214    /// the [`gdk::Event`][crate::gdk::Event] to handle
215    /// ## `cell_area`
216    /// the @widget relative coordinates for @self
217    /// ## `flags`
218    /// the [`CellRenderer`][crate::CellRenderer]State for @self in this row.
219    ///
220    /// # Returns
221    ///
222    /// [`true`] if the event was handled by @self.
223    fn event<W: IsA<Widget>, P: IsA<CellAreaContext>>(
224        &self,
225        context: &P,
226        widget: &W,
227        event: &gdk::Event,
228        area: &gdk::Rectangle,
229        flags: CellRendererState,
230    ) -> bool {
231        self.parent_event(context, widget, event, area, flags)
232    }
233
234    /// Calls @callback for every [`CellRenderer`][crate::CellRenderer] in @self.
235    ///
236    /// # Deprecated since 4.10
237    ///
238    /// ## `callback`
239    /// the `GtkCellCallback` to call
240    /// ## `callback_data`
241    /// user provided data pointer
242    fn foreach(&self, callback: &CellCallback) {
243        self.parent_foreach(callback);
244    }
245
246    /// Calls @callback for every [`CellRenderer`][crate::CellRenderer] in @self with the
247    /// allocated rectangle inside @cell_area.
248    /// ## `context`
249    /// the [`CellArea`][crate::CellArea]Context for this row of data.
250    /// ## `widget`
251    /// the [`Widget`][crate::Widget] that @self is rendering to
252    /// ## `cell_area`
253    /// the @widget relative coordinates and size for @self
254    /// ## `background_area`
255    /// the @widget relative coordinates of the background area
256    /// ## `callback`
257    /// the `GtkCellAllocCallback` to call
258    /// ## `callback_data`
259    /// user provided data pointer
260    fn foreach_alloc<P: IsA<CellAreaContext>, W: IsA<Widget>>(
261        &self,
262        context: &P,
263        widget: &W,
264        area: &gdk::Rectangle,
265        bg_area: &gdk::Rectangle,
266        callback: &CellCallbackAllocate,
267    ) {
268        self.parent_foreach_alloc(context, widget, area, bg_area, callback)
269    }
270
271    /// Removes @renderer from @self.
272    ///
273    /// # Deprecated since 4.10
274    ///
275    /// ## `renderer`
276    /// the [`CellRenderer`][crate::CellRenderer] to remove from @self
277    fn remove<R: IsA<CellRenderer>>(&self, renderer: &R) {
278        self.parent_remove(renderer)
279    }
280
281    /// Returns whether the area can do anything when activated,
282    /// after applying new attributes to @self.
283    ///
284    /// # Deprecated since 4.10
285    ///
286    ///
287    /// # Returns
288    ///
289    /// whether @self can do anything when activated.
290    fn is_activatable(&self) -> bool {
291        self.parent_is_activatable()
292    }
293
294    /// This should be called by the @self’s owning layout widget
295    /// when focus is to be passed to @self, or moved within @self
296    /// for a given @direction and row data.
297    ///
298    /// Implementing [`CellArea`][crate::CellArea] classes should implement this
299    /// method to receive and navigate focus in its own way particular
300    /// to how it lays out cells.
301    ///
302    /// # Deprecated since 4.10
303    ///
304    /// ## `direction`
305    /// the [`DirectionType`][crate::DirectionType]
306    ///
307    /// # Returns
308    ///
309    /// [`true`] if focus remains inside @self as a result of this call.
310    fn focus(&self, direction_type: DirectionType) -> bool {
311        self.parent_focus(direction_type)
312    }
313
314    /// Gets whether the area prefers a height-for-width layout
315    /// or a width-for-height layout.
316    ///
317    /// # Returns
318    ///
319    /// The [`SizeRequestMode`][crate::SizeRequestMode] preferred by @self.
320    fn request_mode(&self) -> SizeRequestMode {
321        self.parent_request_mode()
322    }
323
324    /// Retrieves a cell area’s initial minimum and natural width.
325    ///
326    /// @self will store some geometrical information in @context along the way;
327    /// when requesting sizes over an arbitrary number of rows, it’s not important
328    /// to check the @minimum_width and @natural_width of this call but rather to
329    /// consult gtk_cell_area_context_get_preferred_width() after a series of
330    /// requests.
331    ///
332    /// # Deprecated since 4.10
333    ///
334    /// ## `context`
335    /// the [`CellArea`][crate::CellArea]Context to perform this request with
336    /// ## `widget`
337    /// the [`Widget`][crate::Widget] where @self will be rendering
338    ///
339    /// # Returns
340    ///
341    ///
342    /// ## `minimum_width`
343    /// location to store the minimum width
344    ///
345    /// ## `natural_width`
346    /// location to store the natural width
347    fn preferred_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
348        &self,
349        context: &P,
350        widget: &W,
351    ) -> (i32, i32) {
352        self.parent_preferred_width(context, widget)
353    }
354
355    /// Retrieves a cell area’s minimum and natural width if it would be given
356    /// the specified @height.
357    ///
358    /// @self stores some geometrical information in @context along the way
359    /// while calling gtk_cell_area_get_preferred_height(). It’s important to
360    /// perform a series of gtk_cell_area_get_preferred_height() requests with
361    /// @context first and then call gtk_cell_area_get_preferred_width_for_height()
362    /// on each cell area individually to get the height for width of each
363    /// fully requested row.
364    ///
365    /// If at some point, the height of a single row changes, it should be
366    /// requested with gtk_cell_area_get_preferred_height() again and then
367    /// the full height of the requested rows checked again with
368    /// gtk_cell_area_context_get_preferred_height().
369    ///
370    /// # Deprecated since 4.10
371    ///
372    /// ## `context`
373    /// the [`CellArea`][crate::CellArea]Context which has already been requested for widths.
374    /// ## `widget`
375    /// the [`Widget`][crate::Widget] where @self will be rendering
376    /// ## `height`
377    /// the height for which to check the width of this area
378    ///
379    /// # Returns
380    ///
381    ///
382    /// ## `minimum_width`
383    /// location to store the minimum width
384    ///
385    /// ## `natural_width`
386    /// location to store the natural width
387    fn preferred_width_for_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
388        &self,
389        context: &P,
390        widget: &W,
391        height: i32,
392    ) -> (i32, i32) {
393        self.parent_preferred_width_for_height(context, widget, height)
394    }
395
396    /// Retrieves a cell area’s initial minimum and natural height.
397    ///
398    /// @self will store some geometrical information in @context along the way;
399    /// when requesting sizes over an arbitrary number of rows, it’s not important
400    /// to check the @minimum_height and @natural_height of this call but rather to
401    /// consult gtk_cell_area_context_get_preferred_height() after a series of
402    /// requests.
403    ///
404    /// # Deprecated since 4.10
405    ///
406    /// ## `context`
407    /// the [`CellArea`][crate::CellArea]Context to perform this request with
408    /// ## `widget`
409    /// the [`Widget`][crate::Widget] where @self will be rendering
410    ///
411    /// # Returns
412    ///
413    ///
414    /// ## `minimum_height`
415    /// location to store the minimum height
416    ///
417    /// ## `natural_height`
418    /// location to store the natural height
419    fn preferred_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
420        &self,
421        context: &P,
422        widget: &W,
423    ) -> (i32, i32) {
424        self.parent_preferred_height(context, widget)
425    }
426
427    /// Retrieves a cell area’s minimum and natural height if it would be given
428    /// the specified @width.
429    ///
430    /// @self stores some geometrical information in @context along the way
431    /// while calling gtk_cell_area_get_preferred_width(). It’s important to
432    /// perform a series of gtk_cell_area_get_preferred_width() requests with
433    /// @context first and then call gtk_cell_area_get_preferred_height_for_width()
434    /// on each cell area individually to get the height for width of each
435    /// fully requested row.
436    ///
437    /// If at some point, the width of a single row changes, it should be
438    /// requested with gtk_cell_area_get_preferred_width() again and then
439    /// the full width of the requested rows checked again with
440    /// gtk_cell_area_context_get_preferred_width().
441    ///
442    /// # Deprecated since 4.10
443    ///
444    /// ## `context`
445    /// the [`CellArea`][crate::CellArea]Context which has already been requested for widths.
446    /// ## `widget`
447    /// the [`Widget`][crate::Widget] where @self will be rendering
448    /// ## `width`
449    /// the width for which to check the height of this area
450    ///
451    /// # Returns
452    ///
453    ///
454    /// ## `minimum_height`
455    /// location to store the minimum height
456    ///
457    /// ## `natural_height`
458    /// location to store the natural height
459    fn preferred_height_for_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
460        &self,
461        context: &P,
462        widget: &W,
463        width: i32,
464    ) -> (i32, i32) {
465        self.parent_preferred_height_for_width(context, widget, width)
466    }
467
468    /// Snapshots @self’s cells according to @self’s layout onto at
469    /// the given coordinates.
470    ///
471    /// # Deprecated since 4.10
472    ///
473    /// ## `context`
474    /// the [`CellArea`][crate::CellArea]Context for this row of data.
475    /// ## `widget`
476    /// the [`Widget`][crate::Widget] that @self is rendering to
477    /// ## `snapshot`
478    /// the [`Snapshot`][crate::Snapshot] to draw to
479    /// ## `background_area`
480    /// the @widget relative coordinates for @self’s background
481    /// ## `cell_area`
482    /// the @widget relative coordinates for @self
483    /// ## `flags`
484    /// the [`CellRenderer`][crate::CellRenderer]State for @self in this row.
485    /// ## `paint_focus`
486    /// whether @self should paint focus on focused cells for focused rows or not.
487    #[allow(clippy::too_many_arguments)]
488    fn snapshot<P: IsA<CellAreaContext>, W: IsA<Widget>>(
489        &self,
490        context: &P,
491        snapshot: &Snapshot,
492        widget: &W,
493        background_area: &gdk::Rectangle,
494        cellarea: &gdk::Rectangle,
495        flags: CellRendererState,
496        paint_focus: bool,
497    ) {
498        self.parent_snapshot(
499            context,
500            snapshot,
501            widget,
502            background_area,
503            cellarea,
504            flags,
505            paint_focus,
506        );
507    }
508}
509
510#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
511#[allow(deprecated)]
512pub trait CellAreaImplExt: CellAreaImpl {
513    // Returns true if the area was successfully activated
514    fn parent_activate<P: IsA<CellAreaContext>, W: IsA<Widget>>(
515        &self,
516        context: &P,
517        widget: &W,
518        area: &gdk::Rectangle,
519        flags: CellRendererState,
520        edit_only: bool,
521    ) -> bool {
522        unsafe {
523            let data = Self::type_data();
524            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
525            if let Some(f) = (*parent_class).activate {
526                from_glib(f(
527                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
528                    context.as_ref().to_glib_none().0,
529                    widget.as_ref().to_glib_none().0,
530                    area.to_glib_none().0,
531                    flags.into_glib(),
532                    edit_only.into_glib(),
533                ))
534            } else {
535                false
536            }
537        }
538    }
539
540    fn parent_add<R: IsA<CellRenderer>>(&self, renderer: &R) {
541        unsafe {
542            let data = Self::type_data();
543            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
544            if let Some(f) = (*parent_class).add {
545                f(
546                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
547                    renderer.as_ref().to_glib_none().0,
548                )
549            }
550        }
551    }
552
553    fn parent_apply_attributes<M: IsA<TreeModel>>(
554        &self,
555        tree_model: &M,
556        iter: &TreeIter,
557        is_expander: bool,
558        is_expanded: bool,
559    ) {
560        unsafe {
561            let data = Self::type_data();
562            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
563            if let Some(f) = (*parent_class).apply_attributes {
564                f(
565                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
566                    tree_model.as_ref().to_glib_none().0,
567                    iter.to_glib_none().0 as *mut _,
568                    is_expander.into_glib(),
569                    is_expanded.into_glib(),
570                )
571            }
572        }
573    }
574
575    fn parent_create_context(&self) -> Option<CellAreaContext> {
576        unsafe {
577            let data = Self::type_data();
578            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
579            let f = (*parent_class)
580                .create_context
581                .expect("No parent class impl for \"create_context\"");
582
583            let ret = f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0);
584            Some(from_glib_full(ret))
585        }
586    }
587
588    fn parent_copy_context<P: IsA<CellAreaContext>>(&self, context: &P) -> Option<CellAreaContext> {
589        unsafe {
590            let data = Self::type_data();
591            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
592            let f = (*parent_class)
593                .copy_context
594                .expect("No parent class impl for \"copy_context\"");
595
596            let ret = f(
597                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
598                context.as_ref().to_glib_none().0,
599            );
600            Some(from_glib_full(ret))
601        }
602    }
603
604    // returns true only if the event is handled
605    fn parent_event<W: IsA<Widget>, P: IsA<CellAreaContext>>(
606        &self,
607        context: &P,
608        widget: &W,
609        event: &gdk::Event,
610        area: &gdk::Rectangle,
611        flags: CellRendererState,
612    ) -> bool {
613        unsafe {
614            let data = Self::type_data();
615            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
616            if let Some(f) = (*parent_class).event {
617                from_glib(f(
618                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
619                    context.as_ref().to_glib_none().0,
620                    widget.as_ref().to_glib_none().0,
621                    event.to_glib_none().0,
622                    area.to_glib_none().0,
623                    flags.into_glib(),
624                ))
625            } else {
626                false
627            }
628        }
629    }
630
631    fn parent_foreach(&self, callback: &CellCallback) {
632        unsafe {
633            let data = Self::type_data();
634            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
635            if let Some(f) = (*parent_class).foreach {
636                f(
637                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
638                    callback.callback,
639                    callback.user_data,
640                )
641            }
642        }
643    }
644
645    fn parent_foreach_alloc<P: IsA<CellAreaContext>, W: IsA<Widget>>(
646        &self,
647        context: &P,
648        widget: &W,
649        area: &gdk::Rectangle,
650        bg_area: &gdk::Rectangle,
651        callback: &CellCallbackAllocate,
652    ) {
653        unsafe {
654            let data = Self::type_data();
655            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
656            if let Some(f) = (*parent_class).foreach_alloc {
657                f(
658                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
659                    context.as_ref().to_glib_none().0,
660                    widget.as_ref().to_glib_none().0,
661                    area.to_glib_none().0,
662                    bg_area.to_glib_none().0,
663                    callback.callback,
664                    callback.user_data,
665                )
666            }
667        }
668    }
669
670    fn parent_remove<R: IsA<CellRenderer>>(&self, renderer: &R) {
671        unsafe {
672            let data = Self::type_data();
673            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
674            if let Some(f) = (*parent_class).remove {
675                f(
676                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
677                    renderer.as_ref().to_glib_none().0,
678                )
679            }
680        }
681    }
682
683    // Whether the cell is activatable
684    fn parent_is_activatable(&self) -> bool {
685        unsafe {
686            let data = Self::type_data();
687            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
688            if let Some(f) = (*parent_class).is_activatable {
689                from_glib(f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0))
690            } else {
691                false
692            }
693        }
694    }
695
696    // TRUE if focus remains inside area as a result of this call.
697    fn parent_focus(&self, direction_type: DirectionType) -> bool {
698        unsafe {
699            let data = Self::type_data();
700            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
701            if let Some(f) = (*parent_class).focus {
702                from_glib(f(
703                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
704                    direction_type.into_glib(),
705                ))
706            } else {
707                false
708            }
709        }
710    }
711
712    fn parent_request_mode(&self) -> SizeRequestMode {
713        unsafe {
714            let data = Self::type_data();
715            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
716            let f = (*parent_class)
717                .get_request_mode
718                .expect("No parent class impl for \"get_request_mode\"");
719            from_glib(f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0))
720        }
721    }
722
723    fn parent_preferred_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
724        &self,
725        cell_area_context: &P,
726        widget: &W,
727    ) -> (i32, i32) {
728        unsafe {
729            let data = Self::type_data();
730            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
731            let f = (*parent_class).get_preferred_width.unwrap();
732
733            let mut minimum_size = mem::MaybeUninit::uninit();
734            let mut natural_size = mem::MaybeUninit::uninit();
735            f(
736                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
737                cell_area_context.as_ref().to_glib_none().0,
738                widget.as_ref().to_glib_none().0,
739                minimum_size.as_mut_ptr(),
740                natural_size.as_mut_ptr(),
741            );
742            (minimum_size.assume_init(), natural_size.assume_init())
743        }
744    }
745
746    fn parent_preferred_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
747        &self,
748        cell_area_context: &P,
749        widget: &W,
750    ) -> (i32, i32) {
751        unsafe {
752            let data = Self::type_data();
753            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
754            let f = (*parent_class).get_preferred_height.unwrap();
755
756            let mut minimum_size = mem::MaybeUninit::uninit();
757            let mut natural_size = mem::MaybeUninit::uninit();
758            f(
759                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
760                cell_area_context.as_ref().to_glib_none().0,
761                widget.as_ref().to_glib_none().0,
762                minimum_size.as_mut_ptr(),
763                natural_size.as_mut_ptr(),
764            );
765            (minimum_size.assume_init(), natural_size.assume_init())
766        }
767    }
768
769    fn parent_preferred_width_for_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
770        &self,
771        cell_area_context: &P,
772        widget: &W,
773        height: i32,
774    ) -> (i32, i32) {
775        unsafe {
776            let data = Self::type_data();
777            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
778            let f = (*parent_class).get_preferred_width_for_height.unwrap();
779
780            let mut minimum_size = mem::MaybeUninit::uninit();
781            let mut natural_size = mem::MaybeUninit::uninit();
782            f(
783                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
784                cell_area_context.as_ref().to_glib_none().0,
785                widget.as_ref().to_glib_none().0,
786                height,
787                minimum_size.as_mut_ptr(),
788                natural_size.as_mut_ptr(),
789            );
790            (minimum_size.assume_init(), natural_size.assume_init())
791        }
792    }
793
794    fn parent_preferred_height_for_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
795        &self,
796        cell_area_context: &P,
797        widget: &W,
798        width: i32,
799    ) -> (i32, i32) {
800        unsafe {
801            let data = Self::type_data();
802            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
803            let f = (*parent_class).get_preferred_height_for_width.unwrap();
804            let mut minimum_size = mem::MaybeUninit::uninit();
805            let mut natural_size = mem::MaybeUninit::uninit();
806            f(
807                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
808                cell_area_context.as_ref().to_glib_none().0,
809                widget.as_ref().to_glib_none().0,
810                width,
811                minimum_size.as_mut_ptr(),
812                natural_size.as_mut_ptr(),
813            );
814            (minimum_size.assume_init(), natural_size.assume_init())
815        }
816    }
817
818    #[allow(clippy::too_many_arguments)]
819    fn parent_snapshot<P: IsA<CellAreaContext>, W: IsA<Widget>>(
820        &self,
821        context: &P,
822        snapshot: &Snapshot,
823        widget: &W,
824        background_area: &gdk::Rectangle,
825        cellarea: &gdk::Rectangle,
826        flags: CellRendererState,
827        paint_focus: bool,
828    ) {
829        unsafe {
830            let data = Self::type_data();
831            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
832            if let Some(f) = (*parent_class).snapshot {
833                f(
834                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
835                    context.as_ref().to_glib_none().0,
836                    widget.as_ref().to_glib_none().0,
837                    snapshot.to_glib_none().0,
838                    background_area.to_glib_none().0,
839                    cellarea.to_glib_none().0,
840                    flags.into_glib(),
841                    paint_focus.into_glib(),
842                )
843            }
844        }
845    }
846}
847
848impl<T: CellAreaImpl> CellAreaImplExt for T {}
849
850unsafe impl<T: CellAreaImpl> IsSubclassable<T> for CellArea {
851    fn class_init(class: &mut glib::Class<Self>) {
852        Self::parent_class_init::<T>(class);
853        let klass = class.as_mut();
854
855        assert_initialized_main_thread!();
856
857        let pspecs = <T as CellAreaImpl>::cell_properties();
858        if !pspecs.is_empty() {
859            unsafe {
860                for (prop_id, pspec) in pspecs.iter().enumerate() {
861                    ffi::gtk_cell_area_class_install_cell_property(
862                        klass,
863                        prop_id as u32,
864                        pspec.to_glib_none().0,
865                    );
866                }
867            }
868        }
869        klass.activate = Some(cell_area_activate::<T>);
870        klass.add = Some(cell_area_add::<T>);
871        klass.apply_attributes = Some(cell_area_apply_attributes::<T>);
872        klass.create_context = Some(cell_area_create_context::<T>);
873        klass.copy_context = Some(cell_area_copy_context::<T>);
874        klass.event = Some(cell_area_event::<T>);
875        klass.foreach = Some(cell_area_foreach::<T>);
876        klass.foreach_alloc = Some(cell_area_foreach_alloc::<T>);
877        klass.remove = Some(cell_area_remove::<T>);
878        klass.is_activatable = Some(cell_area_is_activatable::<T>);
879        klass.focus = Some(cell_area_focus::<T>);
880        klass.get_request_mode = Some(cell_area_get_request_mode::<T>);
881        klass.get_preferred_width = Some(cell_area_get_preferred_width::<T>);
882        klass.get_preferred_width_for_height = Some(cell_area_get_preferred_width_for_height::<T>);
883        klass.get_preferred_height = Some(cell_area_get_preferred_height::<T>);
884        klass.get_preferred_height_for_width = Some(cell_area_get_preferred_height_for_width::<T>);
885        klass.snapshot = Some(cell_area_snapshot::<T>);
886        klass.set_cell_property = Some(cell_area_set_cell_property::<T>);
887        klass.get_cell_property = Some(cell_area_get_cell_property::<T>);
888    }
889}
890
891unsafe extern "C" fn cell_area_set_cell_property<T: CellAreaImpl>(
892    ptr: *mut ffi::GtkCellArea,
893    rendererptr: *mut ffi::GtkCellRenderer,
894    id: u32,
895    valueptr: *mut glib::gobject_ffi::GValue,
896    pspecptr: *mut glib::gobject_ffi::GParamSpec,
897) {
898    let instance = &*(ptr as *mut T::Instance);
899    let imp = instance.imp();
900    imp.set_cell_property(
901        &*from_glib_borrow::<_, CellRenderer>(rendererptr),
902        id as usize,
903        &*(valueptr as *mut Value),
904        &from_glib_borrow(pspecptr),
905    );
906}
907
908unsafe extern "C" fn cell_area_get_cell_property<T: CellAreaImpl>(
909    ptr: *mut ffi::GtkCellArea,
910    rendererptr: *mut ffi::GtkCellRenderer,
911    id: u32,
912    valueptr: *mut glib::gobject_ffi::GValue,
913    pspecptr: *mut glib::gobject_ffi::GParamSpec,
914) {
915    let instance = &*(ptr as *mut T::Instance);
916    let imp = instance.imp();
917
918    let value = imp.cell_property(
919        &*from_glib_borrow::<_, CellRenderer>(rendererptr),
920        id as usize,
921        &from_glib_borrow(pspecptr),
922    );
923
924    // See glib::subclass::ObjectImpl::property for the reasoning behind
925    glib::gobject_ffi::g_value_unset(valueptr);
926    let value = mem::ManuallyDrop::new(value);
927    std::ptr::write(valueptr, std::ptr::read(value.to_glib_none().0));
928}
929
930unsafe extern "C" fn cell_area_add<T: CellAreaImpl>(
931    ptr: *mut ffi::GtkCellArea,
932    rendererptr: *mut ffi::GtkCellRenderer,
933) {
934    let instance = &*(ptr as *mut T::Instance);
935    let imp = instance.imp();
936    let renderer: Borrowed<CellRenderer> = from_glib_borrow(rendererptr);
937
938    imp.add(&*renderer)
939}
940
941unsafe extern "C" fn cell_area_apply_attributes<T: CellAreaImpl>(
942    ptr: *mut ffi::GtkCellArea,
943    modelptr: *mut ffi::GtkTreeModel,
944    iterptr: *mut ffi::GtkTreeIter,
945    is_expander: glib::ffi::gboolean,
946    is_expanded: glib::ffi::gboolean,
947) {
948    let instance = &*(ptr as *mut T::Instance);
949    let imp = instance.imp();
950    let model: Borrowed<TreeModel> = from_glib_borrow(modelptr);
951    let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
952
953    imp.apply_attributes(
954        &*model,
955        &iter,
956        from_glib(is_expander),
957        from_glib(is_expanded),
958    )
959}
960
961unsafe extern "C" fn cell_area_remove<T: CellAreaImpl>(
962    ptr: *mut ffi::GtkCellArea,
963    rendererptr: *mut ffi::GtkCellRenderer,
964) {
965    let instance = &*(ptr as *mut T::Instance);
966    let imp = instance.imp();
967    let renderer: Borrowed<CellRenderer> = from_glib_borrow(rendererptr);
968
969    imp.remove(&*renderer)
970}
971
972unsafe extern "C" fn cell_area_is_activatable<T: CellAreaImpl>(
973    ptr: *mut ffi::GtkCellArea,
974) -> glib::ffi::gboolean {
975    let instance = &*(ptr as *mut T::Instance);
976    let imp = instance.imp();
977
978    imp.is_activatable().into_glib()
979}
980
981unsafe extern "C" fn cell_area_focus<T: CellAreaImpl>(
982    ptr: *mut ffi::GtkCellArea,
983    directionptr: ffi::GtkDirectionType,
984) -> glib::ffi::gboolean {
985    let instance = &*(ptr as *mut T::Instance);
986    let imp = instance.imp();
987
988    imp.focus(from_glib(directionptr)).into_glib()
989}
990
991unsafe extern "C" fn cell_area_get_request_mode<T: CellAreaImpl>(
992    ptr: *mut ffi::GtkCellArea,
993) -> ffi::GtkSizeRequestMode {
994    let instance = &*(ptr as *mut T::Instance);
995    let imp = instance.imp();
996
997    imp.request_mode().into_glib()
998}
999
1000unsafe extern "C" fn cell_area_get_preferred_height<T: CellAreaImpl>(
1001    ptr: *mut ffi::GtkCellArea,
1002    contextptr: *mut ffi::GtkCellAreaContext,
1003    wdgtptr: *mut ffi::GtkWidget,
1004    minptr: *mut libc::c_int,
1005    natptr: *mut libc::c_int,
1006) {
1007    let instance = &*(ptr as *mut T::Instance);
1008    let imp = instance.imp();
1009    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1010    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1011
1012    let (min_size, nat_size) = imp.preferred_height(&*context, &*widget);
1013    if !minptr.is_null() {
1014        *minptr = min_size;
1015    }
1016    if !natptr.is_null() {
1017        *natptr = nat_size;
1018    }
1019}
1020
1021unsafe extern "C" fn cell_area_get_preferred_width<T: CellAreaImpl>(
1022    ptr: *mut ffi::GtkCellArea,
1023    contextptr: *mut ffi::GtkCellAreaContext,
1024    wdgtptr: *mut ffi::GtkWidget,
1025    minptr: *mut libc::c_int,
1026    natptr: *mut libc::c_int,
1027) {
1028    let instance = &*(ptr as *mut T::Instance);
1029    let imp = instance.imp();
1030    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1031    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1032
1033    let (min_size, nat_size) = imp.preferred_width(&*context, &*widget);
1034    if !minptr.is_null() {
1035        *minptr = min_size;
1036    }
1037    if !natptr.is_null() {
1038        *natptr = nat_size;
1039    }
1040}
1041
1042unsafe extern "C" fn cell_area_get_preferred_width_for_height<T: CellAreaImpl>(
1043    ptr: *mut ffi::GtkCellArea,
1044    contextptr: *mut ffi::GtkCellAreaContext,
1045    wdgtptr: *mut ffi::GtkWidget,
1046    height: i32,
1047    min_width_ptr: *mut libc::c_int,
1048    nat_width_ptr: *mut libc::c_int,
1049) {
1050    let instance = &*(ptr as *mut T::Instance);
1051    let imp = instance.imp();
1052    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1053    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1054
1055    let (min_width, nat_width) = imp.preferred_width_for_height(&*context, &*widget, height);
1056    if !min_width_ptr.is_null() {
1057        *min_width_ptr = min_width;
1058    }
1059    if !nat_width_ptr.is_null() {
1060        *nat_width_ptr = nat_width;
1061    }
1062}
1063
1064unsafe extern "C" fn cell_area_get_preferred_height_for_width<T: CellAreaImpl>(
1065    ptr: *mut ffi::GtkCellArea,
1066    contextptr: *mut ffi::GtkCellAreaContext,
1067    wdgtptr: *mut ffi::GtkWidget,
1068    width: i32,
1069    min_height_ptr: *mut libc::c_int,
1070    nat_height_ptr: *mut libc::c_int,
1071) {
1072    let instance = &*(ptr as *mut T::Instance);
1073    let imp = instance.imp();
1074    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1075    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1076
1077    let (min_height, nat_height) = imp.preferred_height_for_width(&*context, &*widget, width);
1078    if !min_height_ptr.is_null() {
1079        *min_height_ptr = min_height;
1080    }
1081    if !nat_height_ptr.is_null() {
1082        *nat_height_ptr = nat_height;
1083    }
1084}
1085
1086unsafe extern "C" fn cell_area_activate<T: CellAreaImpl>(
1087    ptr: *mut ffi::GtkCellArea,
1088    contextptr: *mut ffi::GtkCellAreaContext,
1089    wdgtptr: *mut ffi::GtkWidget,
1090    cellptr: *const gdk::ffi::GdkRectangle,
1091    flags: ffi::GtkCellRendererState,
1092    edit_only: glib::ffi::gboolean,
1093) -> glib::ffi::gboolean {
1094    let instance = &*(ptr as *mut T::Instance);
1095    let imp = instance.imp();
1096    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1097    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1098
1099    imp.activate(
1100        &*context,
1101        &*widget,
1102        &from_glib_borrow(cellptr),
1103        from_glib(flags),
1104        from_glib(edit_only),
1105    )
1106    .into_glib()
1107}
1108
1109unsafe extern "C" fn cell_area_snapshot<T: CellAreaImpl>(
1110    ptr: *mut ffi::GtkCellArea,
1111    contextptr: *mut ffi::GtkCellAreaContext,
1112    wdgtptr: *mut ffi::GtkWidget,
1113    snapshotptr: *mut ffi::GtkSnapshot,
1114    bgptr: *const gdk::ffi::GdkRectangle,
1115    cellptr: *const gdk::ffi::GdkRectangle,
1116    flags: ffi::GtkCellRendererState,
1117    paint_focus: glib::ffi::gboolean,
1118) {
1119    let instance = &*(ptr as *mut T::Instance);
1120    let imp = instance.imp();
1121    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1122    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1123    let snapshot: Borrowed<Snapshot> = from_glib_borrow(snapshotptr);
1124
1125    imp.snapshot(
1126        &*context,
1127        &snapshot,
1128        &*widget,
1129        &from_glib_borrow(bgptr),
1130        &from_glib_borrow(cellptr),
1131        from_glib(flags),
1132        from_glib(paint_focus),
1133    )
1134}
1135
1136unsafe extern "C" fn cell_area_create_context<T: CellAreaImpl>(
1137    ptr: *mut ffi::GtkCellArea,
1138) -> *mut ffi::GtkCellAreaContext {
1139    let instance = &*(ptr as *mut T::Instance);
1140    let imp = instance.imp();
1141
1142    imp.create_context().into_glib_ptr()
1143}
1144
1145unsafe extern "C" fn cell_area_copy_context<T: CellAreaImpl>(
1146    ptr: *mut ffi::GtkCellArea,
1147    contextptr: *mut ffi::GtkCellAreaContext,
1148) -> *mut ffi::GtkCellAreaContext {
1149    let instance = &*(ptr as *mut T::Instance);
1150    let imp = instance.imp();
1151    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1152
1153    imp.copy_context(&*context).into_glib_ptr()
1154}
1155
1156unsafe extern "C" fn cell_area_event<T: CellAreaImpl>(
1157    ptr: *mut ffi::GtkCellArea,
1158    contextptr: *mut ffi::GtkCellAreaContext,
1159    widgetptr: *mut ffi::GtkWidget,
1160    eventptr: *mut gdk::ffi::GdkEvent,
1161    rectangleptr: *const gdk::ffi::GdkRectangle,
1162    flags: ffi::GtkCellRendererState,
1163) -> glib::ffi::gboolean {
1164    let instance = &*(ptr as *mut T::Instance);
1165    let imp = instance.imp();
1166    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1167    let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
1168    let event: Borrowed<gdk::Event> = from_glib_borrow(eventptr);
1169    let rectangle: Borrowed<gdk::Rectangle> = from_glib_borrow(rectangleptr);
1170
1171    imp.event(&*context, &*widget, &event, &rectangle, from_glib(flags))
1172        .into_glib()
1173}
1174
1175unsafe extern "C" fn cell_area_foreach<T: CellAreaImpl>(
1176    ptr: *mut ffi::GtkCellArea,
1177    callback: ffi::GtkCellCallback,
1178    user_data: glib::ffi::gpointer,
1179) {
1180    let instance = &*(ptr as *mut T::Instance);
1181    let imp = instance.imp();
1182
1183    let callback = CellCallback {
1184        callback,
1185        user_data,
1186    };
1187
1188    imp.foreach(&callback)
1189}
1190
1191unsafe extern "C" fn cell_area_foreach_alloc<T: CellAreaImpl>(
1192    ptr: *mut ffi::GtkCellArea,
1193    contextptr: *mut ffi::GtkCellAreaContext,
1194    widgetptr: *mut ffi::GtkWidget,
1195    areaptr: *const gdk::ffi::GdkRectangle,
1196    rectangleptr: *const gdk::ffi::GdkRectangle,
1197    callback: ffi::GtkCellAllocCallback,
1198    user_data: glib::ffi::gpointer,
1199) {
1200    let instance = &*(ptr as *mut T::Instance);
1201    let imp = instance.imp();
1202    let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1203    let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
1204    let rectangle: Borrowed<gdk::Rectangle> = from_glib_borrow(rectangleptr);
1205    let area: Borrowed<gdk::Rectangle> = from_glib_borrow(areaptr);
1206
1207    let callback = CellCallbackAllocate {
1208        callback,
1209        user_data,
1210    };
1211
1212    imp.foreach_alloc(&*context, &*widget, &area, &rectangle, &callback)
1213}
1214
1215#[allow(clippy::missing_safety_doc)]
1216pub unsafe trait CellAreaClassExt: ClassStruct {
1217    /// Finds a cell property of a cell area class by name.
1218    ///
1219    /// # Deprecated since 4.10
1220    ///
1221    /// ## `property_name`
1222    /// the name of the child property to find
1223    ///
1224    /// # Returns
1225    ///
1226    /// the `GParamSpec` of the child property
1227    #[doc(alias = "gtk_cell_area_class_find_cell_property")]
1228    fn find_cell_property(&self, property_name: &str) -> Option<ParamSpec> {
1229        unsafe {
1230            let cell_area_class = self as *const _ as *mut ffi::GtkCellAreaClass;
1231            from_glib_none(ffi::gtk_cell_area_class_find_cell_property(
1232                cell_area_class,
1233                property_name.to_glib_none().0,
1234            ))
1235        }
1236    }
1237
1238    /// Returns all cell properties of a cell area class.
1239    ///
1240    /// # Deprecated since 4.10
1241    ///
1242    ///
1243    /// # Returns
1244    ///
1245    /// a newly
1246    ///     allocated [`None`]-terminated array of `GParamSpec`*.  The array
1247    ///     must be freed with g_free().
1248    #[doc(alias = "gtk_cell_area_class_list_cell_properties")]
1249    fn list_cell_properties(&self) -> Vec<ParamSpec> {
1250        unsafe {
1251            let cell_area_class = self as *const _ as *mut ffi::GtkCellAreaClass;
1252            let mut n_properties = std::mem::MaybeUninit::uninit();
1253            let props = ffi::gtk_cell_area_class_list_cell_properties(
1254                cell_area_class,
1255                n_properties.as_mut_ptr(),
1256            );
1257            FromGlibContainer::from_glib_none_num(props, n_properties.assume_init() as usize)
1258        }
1259    }
1260}
1261
1262unsafe impl<T: ClassStruct> CellAreaClassExt for T {}