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