Skip to main content

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::{ParamSpec, Value, translate::*};
9
10use crate::{
11    Buildable, CellArea, CellAreaContext, CellLayout, CellRenderer, CellRendererState,
12    DirectionType, SizeRequestMode, Snapshot, TreeIter, TreeModel, Widget, ffi, prelude::*,
13    subclass::prelude::*,
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    ///
249    /// # Deprecated since 4.10
250    ///
251    /// ## `context`
252    /// the [`CellArea`][crate::CellArea]Context for this row of data.
253    /// ## `widget`
254    /// the [`Widget`][crate::Widget] that @self is rendering to
255    /// ## `cell_area`
256    /// the @widget relative coordinates and size for @self
257    /// ## `background_area`
258    /// the @widget relative coordinates of the background area
259    /// ## `callback`
260    /// the `GtkCellAllocCallback` to call
261    /// ## `callback_data`
262    /// user provided data pointer
263    fn foreach_alloc<P: IsA<CellAreaContext>, W: IsA<Widget>>(
264        &self,
265        context: &P,
266        widget: &W,
267        area: &gdk::Rectangle,
268        bg_area: &gdk::Rectangle,
269        callback: &CellCallbackAllocate,
270    ) {
271        self.parent_foreach_alloc(context, widget, area, bg_area, callback)
272    }
273
274    /// Removes @renderer from @self.
275    ///
276    /// # Deprecated since 4.10
277    ///
278    /// ## `renderer`
279    /// the [`CellRenderer`][crate::CellRenderer] to remove from @self
280    fn remove<R: IsA<CellRenderer>>(&self, renderer: &R) {
281        self.parent_remove(renderer)
282    }
283
284    /// Returns whether the area can do anything when activated,
285    /// after applying new attributes to @self.
286    ///
287    /// # Deprecated since 4.10
288    ///
289    ///
290    /// # Returns
291    ///
292    /// whether @self can do anything when activated.
293    fn is_activatable(&self) -> bool {
294        self.parent_is_activatable()
295    }
296
297    /// This should be called by the @self’s owning layout widget
298    /// when focus is to be passed to @self, or moved within @self
299    /// for a given @direction and row data.
300    ///
301    /// Implementing [`CellArea`][crate::CellArea] classes should implement this
302    /// method to receive and navigate focus in its own way particular
303    /// to how it lays out cells.
304    ///
305    /// # Deprecated since 4.10
306    ///
307    /// ## `direction`
308    /// the [`DirectionType`][crate::DirectionType]
309    ///
310    /// # Returns
311    ///
312    /// [`true`] if focus remains inside @self as a result of this call.
313    fn focus(&self, direction_type: DirectionType) -> bool {
314        self.parent_focus(direction_type)
315    }
316
317    /// Gets whether the area prefers a height-for-width layout
318    /// or a width-for-height layout.
319    ///
320    /// # Deprecated since 4.10
321    ///
322    ///
323    /// # Returns
324    ///
325    /// The [`SizeRequestMode`][crate::SizeRequestMode] preferred by @self.
326    fn request_mode(&self) -> SizeRequestMode {
327        self.parent_request_mode()
328    }
329
330    /// Retrieves a cell area’s initial minimum and natural width.
331    ///
332    /// @self will store some geometrical information in @context along the way;
333    /// when requesting sizes over an arbitrary number of rows, it’s not important
334    /// to check the @minimum_width and @natural_width of this call but rather to
335    /// consult gtk_cell_area_context_get_preferred_width() after a series of
336    /// requests.
337    ///
338    /// # Deprecated since 4.10
339    ///
340    /// ## `context`
341    /// the [`CellArea`][crate::CellArea]Context to perform this request with
342    /// ## `widget`
343    /// the [`Widget`][crate::Widget] where @self will be rendering
344    ///
345    /// # Returns
346    ///
347    ///
348    /// ## `minimum_width`
349    /// location to store the minimum width
350    ///
351    /// ## `natural_width`
352    /// location to store the natural width
353    fn preferred_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
354        &self,
355        context: &P,
356        widget: &W,
357    ) -> (i32, i32) {
358        self.parent_preferred_width(context, widget)
359    }
360
361    /// Retrieves a cell area’s minimum and natural width if it would be given
362    /// the specified @height.
363    ///
364    /// @self stores some geometrical information in @context along the way
365    /// while calling gtk_cell_area_get_preferred_height(). It’s important to
366    /// perform a series of gtk_cell_area_get_preferred_height() requests with
367    /// @context first and then call gtk_cell_area_get_preferred_width_for_height()
368    /// on each cell area individually to get the height for width of each
369    /// fully requested row.
370    ///
371    /// If at some point, the height of a single row changes, it should be
372    /// requested with gtk_cell_area_get_preferred_height() again and then
373    /// the full height of the requested rows checked again with
374    /// gtk_cell_area_context_get_preferred_height().
375    ///
376    /// # Deprecated since 4.10
377    ///
378    /// ## `context`
379    /// the [`CellArea`][crate::CellArea]Context which has already been requested for widths.
380    /// ## `widget`
381    /// the [`Widget`][crate::Widget] where @self will be rendering
382    /// ## `height`
383    /// the height for which to check the width of this area
384    ///
385    /// # Returns
386    ///
387    ///
388    /// ## `minimum_width`
389    /// location to store the minimum width
390    ///
391    /// ## `natural_width`
392    /// location to store the natural width
393    fn preferred_width_for_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
394        &self,
395        context: &P,
396        widget: &W,
397        height: i32,
398    ) -> (i32, i32) {
399        self.parent_preferred_width_for_height(context, widget, height)
400    }
401
402    /// Retrieves a cell area’s initial minimum and natural height.
403    ///
404    /// @self will store some geometrical information in @context along the way;
405    /// when requesting sizes over an arbitrary number of rows, it’s not important
406    /// to check the @minimum_height and @natural_height of this call but rather to
407    /// consult gtk_cell_area_context_get_preferred_height() after a series of
408    /// requests.
409    ///
410    /// # Deprecated since 4.10
411    ///
412    /// ## `context`
413    /// the [`CellArea`][crate::CellArea]Context to perform this request with
414    /// ## `widget`
415    /// the [`Widget`][crate::Widget] where @self will be rendering
416    ///
417    /// # Returns
418    ///
419    ///
420    /// ## `minimum_height`
421    /// location to store the minimum height
422    ///
423    /// ## `natural_height`
424    /// location to store the natural height
425    fn preferred_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
426        &self,
427        context: &P,
428        widget: &W,
429    ) -> (i32, i32) {
430        self.parent_preferred_height(context, widget)
431    }
432
433    /// Retrieves a cell area’s minimum and natural height if it would be given
434    /// the specified @width.
435    ///
436    /// @self stores some geometrical information in @context along the way
437    /// while calling gtk_cell_area_get_preferred_width(). It’s important to
438    /// perform a series of gtk_cell_area_get_preferred_width() requests with
439    /// @context first and then call gtk_cell_area_get_preferred_height_for_width()
440    /// on each cell area individually to get the height for width of each
441    /// fully requested row.
442    ///
443    /// If at some point, the width of a single row changes, it should be
444    /// requested with gtk_cell_area_get_preferred_width() again and then
445    /// the full width of the requested rows checked again with
446    /// gtk_cell_area_context_get_preferred_width().
447    ///
448    /// # Deprecated since 4.10
449    ///
450    /// ## `context`
451    /// the [`CellArea`][crate::CellArea]Context which has already been requested for widths.
452    /// ## `widget`
453    /// the [`Widget`][crate::Widget] where @self will be rendering
454    /// ## `width`
455    /// the width for which to check the height of this area
456    ///
457    /// # Returns
458    ///
459    ///
460    /// ## `minimum_height`
461    /// location to store the minimum height
462    ///
463    /// ## `natural_height`
464    /// location to store the natural height
465    fn preferred_height_for_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
466        &self,
467        context: &P,
468        widget: &W,
469        width: i32,
470    ) -> (i32, i32) {
471        self.parent_preferred_height_for_width(context, widget, width)
472    }
473
474    /// Snapshots @self’s cells according to @self’s layout onto at
475    /// the given coordinates.
476    ///
477    /// # Deprecated since 4.10
478    ///
479    /// ## `context`
480    /// the [`CellArea`][crate::CellArea]Context for this row of data.
481    /// ## `widget`
482    /// the [`Widget`][crate::Widget] that @self is rendering to
483    /// ## `snapshot`
484    /// the [`Snapshot`][crate::Snapshot] to draw to
485    /// ## `background_area`
486    /// the @widget relative coordinates for @self’s background
487    /// ## `cell_area`
488    /// the @widget relative coordinates for @self
489    /// ## `flags`
490    /// the [`CellRenderer`][crate::CellRenderer]State for @self in this row.
491    /// ## `paint_focus`
492    /// whether @self should paint focus on focused cells for focused rows or not.
493    #[allow(clippy::too_many_arguments)]
494    fn snapshot<P: IsA<CellAreaContext>, W: IsA<Widget>>(
495        &self,
496        context: &P,
497        snapshot: &Snapshot,
498        widget: &W,
499        background_area: &gdk::Rectangle,
500        cellarea: &gdk::Rectangle,
501        flags: CellRendererState,
502        paint_focus: bool,
503    ) {
504        self.parent_snapshot(
505            context,
506            snapshot,
507            widget,
508            background_area,
509            cellarea,
510            flags,
511            paint_focus,
512        );
513    }
514}
515
516#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
517#[allow(deprecated)]
518pub trait CellAreaImplExt: CellAreaImpl {
519    // Returns true if the area was successfully activated
520    fn parent_activate<P: IsA<CellAreaContext>, W: IsA<Widget>>(
521        &self,
522        context: &P,
523        widget: &W,
524        area: &gdk::Rectangle,
525        flags: CellRendererState,
526        edit_only: bool,
527    ) -> bool {
528        unsafe {
529            let data = Self::type_data();
530            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
531            if let Some(f) = (*parent_class).activate {
532                from_glib(f(
533                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
534                    context.as_ref().to_glib_none().0,
535                    widget.as_ref().to_glib_none().0,
536                    area.to_glib_none().0,
537                    flags.into_glib(),
538                    edit_only.into_glib(),
539                ))
540            } else {
541                false
542            }
543        }
544    }
545
546    fn parent_add<R: IsA<CellRenderer>>(&self, renderer: &R) {
547        unsafe {
548            let data = Self::type_data();
549            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
550            if let Some(f) = (*parent_class).add {
551                f(
552                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
553                    renderer.as_ref().to_glib_none().0,
554                )
555            }
556        }
557    }
558
559    fn parent_apply_attributes<M: IsA<TreeModel>>(
560        &self,
561        tree_model: &M,
562        iter: &TreeIter,
563        is_expander: bool,
564        is_expanded: bool,
565    ) {
566        unsafe {
567            let data = Self::type_data();
568            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
569            if let Some(f) = (*parent_class).apply_attributes {
570                f(
571                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
572                    tree_model.as_ref().to_glib_none().0,
573                    iter.to_glib_none().0 as *mut _,
574                    is_expander.into_glib(),
575                    is_expanded.into_glib(),
576                )
577            }
578        }
579    }
580
581    fn parent_create_context(&self) -> Option<CellAreaContext> {
582        unsafe {
583            let data = Self::type_data();
584            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
585            let f = (*parent_class)
586                .create_context
587                .expect("No parent class impl for \"create_context\"");
588
589            let ret = f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0);
590            Some(from_glib_full(ret))
591        }
592    }
593
594    fn parent_copy_context<P: IsA<CellAreaContext>>(&self, context: &P) -> Option<CellAreaContext> {
595        unsafe {
596            let data = Self::type_data();
597            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
598            let f = (*parent_class)
599                .copy_context
600                .expect("No parent class impl for \"copy_context\"");
601
602            let ret = f(
603                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
604                context.as_ref().to_glib_none().0,
605            );
606            Some(from_glib_full(ret))
607        }
608    }
609
610    // returns true only if the event is handled
611    fn parent_event<W: IsA<Widget>, P: IsA<CellAreaContext>>(
612        &self,
613        context: &P,
614        widget: &W,
615        event: &gdk::Event,
616        area: &gdk::Rectangle,
617        flags: CellRendererState,
618    ) -> bool {
619        unsafe {
620            let data = Self::type_data();
621            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
622            if let Some(f) = (*parent_class).event {
623                from_glib(f(
624                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
625                    context.as_ref().to_glib_none().0,
626                    widget.as_ref().to_glib_none().0,
627                    event.to_glib_none().0,
628                    area.to_glib_none().0,
629                    flags.into_glib(),
630                ))
631            } else {
632                false
633            }
634        }
635    }
636
637    fn parent_foreach(&self, callback: &CellCallback) {
638        unsafe {
639            let data = Self::type_data();
640            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
641            if let Some(f) = (*parent_class).foreach {
642                f(
643                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
644                    callback.callback,
645                    callback.user_data,
646                )
647            }
648        }
649    }
650
651    fn parent_foreach_alloc<P: IsA<CellAreaContext>, W: IsA<Widget>>(
652        &self,
653        context: &P,
654        widget: &W,
655        area: &gdk::Rectangle,
656        bg_area: &gdk::Rectangle,
657        callback: &CellCallbackAllocate,
658    ) {
659        unsafe {
660            let data = Self::type_data();
661            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
662            if let Some(f) = (*parent_class).foreach_alloc {
663                f(
664                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
665                    context.as_ref().to_glib_none().0,
666                    widget.as_ref().to_glib_none().0,
667                    area.to_glib_none().0,
668                    bg_area.to_glib_none().0,
669                    callback.callback,
670                    callback.user_data,
671                )
672            }
673        }
674    }
675
676    fn parent_remove<R: IsA<CellRenderer>>(&self, renderer: &R) {
677        unsafe {
678            let data = Self::type_data();
679            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
680            if let Some(f) = (*parent_class).remove {
681                f(
682                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
683                    renderer.as_ref().to_glib_none().0,
684                )
685            }
686        }
687    }
688
689    // Whether the cell is activatable
690    fn parent_is_activatable(&self) -> bool {
691        unsafe {
692            let data = Self::type_data();
693            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
694            if let Some(f) = (*parent_class).is_activatable {
695                from_glib(f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0))
696            } else {
697                false
698            }
699        }
700    }
701
702    // TRUE if focus remains inside area as a result of this call.
703    fn parent_focus(&self, direction_type: DirectionType) -> bool {
704        unsafe {
705            let data = Self::type_data();
706            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
707            if let Some(f) = (*parent_class).focus {
708                from_glib(f(
709                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
710                    direction_type.into_glib(),
711                ))
712            } else {
713                false
714            }
715        }
716    }
717
718    fn parent_request_mode(&self) -> SizeRequestMode {
719        unsafe {
720            let data = Self::type_data();
721            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
722            let f = (*parent_class)
723                .get_request_mode
724                .expect("No parent class impl for \"get_request_mode\"");
725            from_glib(f(self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0))
726        }
727    }
728
729    fn parent_preferred_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
730        &self,
731        cell_area_context: &P,
732        widget: &W,
733    ) -> (i32, i32) {
734        unsafe {
735            let data = Self::type_data();
736            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
737            let f = (*parent_class).get_preferred_width.unwrap();
738
739            let mut minimum_size = mem::MaybeUninit::uninit();
740            let mut natural_size = mem::MaybeUninit::uninit();
741            f(
742                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
743                cell_area_context.as_ref().to_glib_none().0,
744                widget.as_ref().to_glib_none().0,
745                minimum_size.as_mut_ptr(),
746                natural_size.as_mut_ptr(),
747            );
748            (minimum_size.assume_init(), natural_size.assume_init())
749        }
750    }
751
752    fn parent_preferred_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
753        &self,
754        cell_area_context: &P,
755        widget: &W,
756    ) -> (i32, i32) {
757        unsafe {
758            let data = Self::type_data();
759            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
760            let f = (*parent_class).get_preferred_height.unwrap();
761
762            let mut minimum_size = mem::MaybeUninit::uninit();
763            let mut natural_size = mem::MaybeUninit::uninit();
764            f(
765                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
766                cell_area_context.as_ref().to_glib_none().0,
767                widget.as_ref().to_glib_none().0,
768                minimum_size.as_mut_ptr(),
769                natural_size.as_mut_ptr(),
770            );
771            (minimum_size.assume_init(), natural_size.assume_init())
772        }
773    }
774
775    fn parent_preferred_width_for_height<P: IsA<CellAreaContext>, W: IsA<Widget>>(
776        &self,
777        cell_area_context: &P,
778        widget: &W,
779        height: i32,
780    ) -> (i32, i32) {
781        unsafe {
782            let data = Self::type_data();
783            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
784            let f = (*parent_class).get_preferred_width_for_height.unwrap();
785
786            let mut minimum_size = mem::MaybeUninit::uninit();
787            let mut natural_size = mem::MaybeUninit::uninit();
788            f(
789                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
790                cell_area_context.as_ref().to_glib_none().0,
791                widget.as_ref().to_glib_none().0,
792                height,
793                minimum_size.as_mut_ptr(),
794                natural_size.as_mut_ptr(),
795            );
796            (minimum_size.assume_init(), natural_size.assume_init())
797        }
798    }
799
800    fn parent_preferred_height_for_width<P: IsA<CellAreaContext>, W: IsA<Widget>>(
801        &self,
802        cell_area_context: &P,
803        widget: &W,
804        width: i32,
805    ) -> (i32, i32) {
806        unsafe {
807            let data = Self::type_data();
808            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
809            let f = (*parent_class).get_preferred_height_for_width.unwrap();
810            let mut minimum_size = mem::MaybeUninit::uninit();
811            let mut natural_size = mem::MaybeUninit::uninit();
812            f(
813                self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
814                cell_area_context.as_ref().to_glib_none().0,
815                widget.as_ref().to_glib_none().0,
816                width,
817                minimum_size.as_mut_ptr(),
818                natural_size.as_mut_ptr(),
819            );
820            (minimum_size.assume_init(), natural_size.assume_init())
821        }
822    }
823
824    #[allow(clippy::too_many_arguments)]
825    fn parent_snapshot<P: IsA<CellAreaContext>, W: IsA<Widget>>(
826        &self,
827        context: &P,
828        snapshot: &Snapshot,
829        widget: &W,
830        background_area: &gdk::Rectangle,
831        cellarea: &gdk::Rectangle,
832        flags: CellRendererState,
833        paint_focus: bool,
834    ) {
835        unsafe {
836            let data = Self::type_data();
837            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellAreaClass;
838            if let Some(f) = (*parent_class).snapshot {
839                f(
840                    self.obj().unsafe_cast_ref::<CellArea>().to_glib_none().0,
841                    context.as_ref().to_glib_none().0,
842                    widget.as_ref().to_glib_none().0,
843                    snapshot.to_glib_none().0,
844                    background_area.to_glib_none().0,
845                    cellarea.to_glib_none().0,
846                    flags.into_glib(),
847                    paint_focus.into_glib(),
848                )
849            }
850        }
851    }
852}
853
854impl<T: CellAreaImpl> CellAreaImplExt for T {}
855
856unsafe impl<T: CellAreaImpl> IsSubclassable<T> for CellArea {
857    fn class_init(class: &mut glib::Class<Self>) {
858        Self::parent_class_init::<T>(class);
859        let klass = class.as_mut();
860
861        assert_initialized_main_thread!();
862
863        let pspecs = <T as CellAreaImpl>::cell_properties();
864        if !pspecs.is_empty() {
865            unsafe {
866                for (prop_id, pspec) in pspecs.iter().enumerate() {
867                    ffi::gtk_cell_area_class_install_cell_property(
868                        klass,
869                        prop_id as u32,
870                        pspec.to_glib_none().0,
871                    );
872                }
873            }
874        }
875        klass.activate = Some(cell_area_activate::<T>);
876        klass.add = Some(cell_area_add::<T>);
877        klass.apply_attributes = Some(cell_area_apply_attributes::<T>);
878        klass.create_context = Some(cell_area_create_context::<T>);
879        klass.copy_context = Some(cell_area_copy_context::<T>);
880        klass.event = Some(cell_area_event::<T>);
881        klass.foreach = Some(cell_area_foreach::<T>);
882        klass.foreach_alloc = Some(cell_area_foreach_alloc::<T>);
883        klass.remove = Some(cell_area_remove::<T>);
884        klass.is_activatable = Some(cell_area_is_activatable::<T>);
885        klass.focus = Some(cell_area_focus::<T>);
886        klass.get_request_mode = Some(cell_area_get_request_mode::<T>);
887        klass.get_preferred_width = Some(cell_area_get_preferred_width::<T>);
888        klass.get_preferred_width_for_height = Some(cell_area_get_preferred_width_for_height::<T>);
889        klass.get_preferred_height = Some(cell_area_get_preferred_height::<T>);
890        klass.get_preferred_height_for_width = Some(cell_area_get_preferred_height_for_width::<T>);
891        klass.snapshot = Some(cell_area_snapshot::<T>);
892        klass.set_cell_property = Some(cell_area_set_cell_property::<T>);
893        klass.get_cell_property = Some(cell_area_get_cell_property::<T>);
894    }
895}
896
897unsafe extern "C" fn cell_area_set_cell_property<T: CellAreaImpl>(
898    ptr: *mut ffi::GtkCellArea,
899    rendererptr: *mut ffi::GtkCellRenderer,
900    id: u32,
901    valueptr: *mut glib::gobject_ffi::GValue,
902    pspecptr: *mut glib::gobject_ffi::GParamSpec,
903) {
904    unsafe {
905        let instance = &*(ptr as *mut T::Instance);
906        let imp = instance.imp();
907        imp.set_cell_property(
908            &*from_glib_borrow::<_, CellRenderer>(rendererptr),
909            id as usize,
910            &*(valueptr as *mut Value),
911            &from_glib_borrow(pspecptr),
912        );
913    }
914}
915
916unsafe extern "C" fn cell_area_get_cell_property<T: CellAreaImpl>(
917    ptr: *mut ffi::GtkCellArea,
918    rendererptr: *mut ffi::GtkCellRenderer,
919    id: u32,
920    valueptr: *mut glib::gobject_ffi::GValue,
921    pspecptr: *mut glib::gobject_ffi::GParamSpec,
922) {
923    unsafe {
924        let instance = &*(ptr as *mut T::Instance);
925        let imp = instance.imp();
926
927        let value = imp.cell_property(
928            &*from_glib_borrow::<_, CellRenderer>(rendererptr),
929            id as usize,
930            &from_glib_borrow(pspecptr),
931        );
932
933        // See glib::subclass::ObjectImpl::property for the reasoning behind
934        glib::gobject_ffi::g_value_unset(valueptr);
935        let value = mem::ManuallyDrop::new(value);
936        std::ptr::write(valueptr, std::ptr::read(value.to_glib_none().0));
937    }
938}
939
940unsafe extern "C" fn cell_area_add<T: CellAreaImpl>(
941    ptr: *mut ffi::GtkCellArea,
942    rendererptr: *mut ffi::GtkCellRenderer,
943) {
944    unsafe {
945        let instance = &*(ptr as *mut T::Instance);
946        let imp = instance.imp();
947        let renderer: Borrowed<CellRenderer> = from_glib_borrow(rendererptr);
948
949        imp.add(&*renderer)
950    }
951}
952
953unsafe extern "C" fn cell_area_apply_attributes<T: CellAreaImpl>(
954    ptr: *mut ffi::GtkCellArea,
955    modelptr: *mut ffi::GtkTreeModel,
956    iterptr: *mut ffi::GtkTreeIter,
957    is_expander: glib::ffi::gboolean,
958    is_expanded: glib::ffi::gboolean,
959) {
960    unsafe {
961        let instance = &*(ptr as *mut T::Instance);
962        let imp = instance.imp();
963        let model: Borrowed<TreeModel> = from_glib_borrow(modelptr);
964        let iter: Borrowed<TreeIter> = from_glib_borrow(iterptr);
965
966        imp.apply_attributes(
967            &*model,
968            &iter,
969            from_glib(is_expander),
970            from_glib(is_expanded),
971        )
972    }
973}
974
975unsafe extern "C" fn cell_area_remove<T: CellAreaImpl>(
976    ptr: *mut ffi::GtkCellArea,
977    rendererptr: *mut ffi::GtkCellRenderer,
978) {
979    unsafe {
980        let instance = &*(ptr as *mut T::Instance);
981        let imp = instance.imp();
982        let renderer: Borrowed<CellRenderer> = from_glib_borrow(rendererptr);
983
984        imp.remove(&*renderer)
985    }
986}
987
988unsafe extern "C" fn cell_area_is_activatable<T: CellAreaImpl>(
989    ptr: *mut ffi::GtkCellArea,
990) -> glib::ffi::gboolean {
991    unsafe {
992        let instance = &*(ptr as *mut T::Instance);
993        let imp = instance.imp();
994
995        imp.is_activatable().into_glib()
996    }
997}
998
999unsafe extern "C" fn cell_area_focus<T: CellAreaImpl>(
1000    ptr: *mut ffi::GtkCellArea,
1001    directionptr: ffi::GtkDirectionType,
1002) -> glib::ffi::gboolean {
1003    unsafe {
1004        let instance = &*(ptr as *mut T::Instance);
1005        let imp = instance.imp();
1006
1007        imp.focus(from_glib(directionptr)).into_glib()
1008    }
1009}
1010
1011unsafe extern "C" fn cell_area_get_request_mode<T: CellAreaImpl>(
1012    ptr: *mut ffi::GtkCellArea,
1013) -> ffi::GtkSizeRequestMode {
1014    unsafe {
1015        let instance = &*(ptr as *mut T::Instance);
1016        let imp = instance.imp();
1017
1018        imp.request_mode().into_glib()
1019    }
1020}
1021
1022unsafe extern "C" fn cell_area_get_preferred_height<T: CellAreaImpl>(
1023    ptr: *mut ffi::GtkCellArea,
1024    contextptr: *mut ffi::GtkCellAreaContext,
1025    wdgtptr: *mut ffi::GtkWidget,
1026    minptr: *mut libc::c_int,
1027    natptr: *mut libc::c_int,
1028) {
1029    unsafe {
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_height(&*context, &*widget);
1036        if !minptr.is_null() {
1037            *minptr = min_size;
1038        }
1039        if !natptr.is_null() {
1040            *natptr = nat_size;
1041        }
1042    }
1043}
1044
1045unsafe extern "C" fn cell_area_get_preferred_width<T: CellAreaImpl>(
1046    ptr: *mut ffi::GtkCellArea,
1047    contextptr: *mut ffi::GtkCellAreaContext,
1048    wdgtptr: *mut ffi::GtkWidget,
1049    minptr: *mut libc::c_int,
1050    natptr: *mut libc::c_int,
1051) {
1052    unsafe {
1053        let instance = &*(ptr as *mut T::Instance);
1054        let imp = instance.imp();
1055        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1056        let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1057
1058        let (min_size, nat_size) = imp.preferred_width(&*context, &*widget);
1059        if !minptr.is_null() {
1060            *minptr = min_size;
1061        }
1062        if !natptr.is_null() {
1063            *natptr = nat_size;
1064        }
1065    }
1066}
1067
1068unsafe extern "C" fn cell_area_get_preferred_width_for_height<T: CellAreaImpl>(
1069    ptr: *mut ffi::GtkCellArea,
1070    contextptr: *mut ffi::GtkCellAreaContext,
1071    wdgtptr: *mut ffi::GtkWidget,
1072    height: i32,
1073    min_width_ptr: *mut libc::c_int,
1074    nat_width_ptr: *mut libc::c_int,
1075) {
1076    unsafe {
1077        let instance = &*(ptr as *mut T::Instance);
1078        let imp = instance.imp();
1079        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1080        let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1081
1082        let (min_width, nat_width) = imp.preferred_width_for_height(&*context, &*widget, height);
1083        if !min_width_ptr.is_null() {
1084            *min_width_ptr = min_width;
1085        }
1086        if !nat_width_ptr.is_null() {
1087            *nat_width_ptr = nat_width;
1088        }
1089    }
1090}
1091
1092unsafe extern "C" fn cell_area_get_preferred_height_for_width<T: CellAreaImpl>(
1093    ptr: *mut ffi::GtkCellArea,
1094    contextptr: *mut ffi::GtkCellAreaContext,
1095    wdgtptr: *mut ffi::GtkWidget,
1096    width: i32,
1097    min_height_ptr: *mut libc::c_int,
1098    nat_height_ptr: *mut libc::c_int,
1099) {
1100    unsafe {
1101        let instance = &*(ptr as *mut T::Instance);
1102        let imp = instance.imp();
1103        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1104        let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1105
1106        let (min_height, nat_height) = imp.preferred_height_for_width(&*context, &*widget, width);
1107        if !min_height_ptr.is_null() {
1108            *min_height_ptr = min_height;
1109        }
1110        if !nat_height_ptr.is_null() {
1111            *nat_height_ptr = nat_height;
1112        }
1113    }
1114}
1115
1116unsafe extern "C" fn cell_area_activate<T: CellAreaImpl>(
1117    ptr: *mut ffi::GtkCellArea,
1118    contextptr: *mut ffi::GtkCellAreaContext,
1119    wdgtptr: *mut ffi::GtkWidget,
1120    cellptr: *const gdk::ffi::GdkRectangle,
1121    flags: ffi::GtkCellRendererState,
1122    edit_only: glib::ffi::gboolean,
1123) -> glib::ffi::gboolean {
1124    unsafe {
1125        let instance = &*(ptr as *mut T::Instance);
1126        let imp = instance.imp();
1127        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1128        let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1129
1130        imp.activate(
1131            &*context,
1132            &*widget,
1133            &from_glib_borrow(cellptr),
1134            from_glib(flags),
1135            from_glib(edit_only),
1136        )
1137        .into_glib()
1138    }
1139}
1140
1141unsafe extern "C" fn cell_area_snapshot<T: CellAreaImpl>(
1142    ptr: *mut ffi::GtkCellArea,
1143    contextptr: *mut ffi::GtkCellAreaContext,
1144    wdgtptr: *mut ffi::GtkWidget,
1145    snapshotptr: *mut ffi::GtkSnapshot,
1146    bgptr: *const gdk::ffi::GdkRectangle,
1147    cellptr: *const gdk::ffi::GdkRectangle,
1148    flags: ffi::GtkCellRendererState,
1149    paint_focus: glib::ffi::gboolean,
1150) {
1151    unsafe {
1152        let instance = &*(ptr as *mut T::Instance);
1153        let imp = instance.imp();
1154        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1155        let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
1156        let snapshot: Borrowed<Snapshot> = from_glib_borrow(snapshotptr);
1157
1158        imp.snapshot(
1159            &*context,
1160            &snapshot,
1161            &*widget,
1162            &from_glib_borrow(bgptr),
1163            &from_glib_borrow(cellptr),
1164            from_glib(flags),
1165            from_glib(paint_focus),
1166        )
1167    }
1168}
1169
1170unsafe extern "C" fn cell_area_create_context<T: CellAreaImpl>(
1171    ptr: *mut ffi::GtkCellArea,
1172) -> *mut ffi::GtkCellAreaContext {
1173    unsafe {
1174        let instance = &*(ptr as *mut T::Instance);
1175        let imp = instance.imp();
1176
1177        imp.create_context().into_glib_ptr()
1178    }
1179}
1180
1181unsafe extern "C" fn cell_area_copy_context<T: CellAreaImpl>(
1182    ptr: *mut ffi::GtkCellArea,
1183    contextptr: *mut ffi::GtkCellAreaContext,
1184) -> *mut ffi::GtkCellAreaContext {
1185    unsafe {
1186        let instance = &*(ptr as *mut T::Instance);
1187        let imp = instance.imp();
1188        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1189
1190        imp.copy_context(&*context).into_glib_ptr()
1191    }
1192}
1193
1194unsafe extern "C" fn cell_area_event<T: CellAreaImpl>(
1195    ptr: *mut ffi::GtkCellArea,
1196    contextptr: *mut ffi::GtkCellAreaContext,
1197    widgetptr: *mut ffi::GtkWidget,
1198    eventptr: *mut gdk::ffi::GdkEvent,
1199    rectangleptr: *const gdk::ffi::GdkRectangle,
1200    flags: ffi::GtkCellRendererState,
1201) -> glib::ffi::gboolean {
1202    unsafe {
1203        let instance = &*(ptr as *mut T::Instance);
1204        let imp = instance.imp();
1205        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1206        let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
1207        let event: Borrowed<gdk::Event> = from_glib_borrow(eventptr);
1208        let rectangle: Borrowed<gdk::Rectangle> = from_glib_borrow(rectangleptr);
1209
1210        imp.event(&*context, &*widget, &event, &rectangle, from_glib(flags))
1211            .into_glib()
1212    }
1213}
1214
1215unsafe extern "C" fn cell_area_foreach<T: CellAreaImpl>(
1216    ptr: *mut ffi::GtkCellArea,
1217    callback: ffi::GtkCellCallback,
1218    user_data: glib::ffi::gpointer,
1219) {
1220    unsafe {
1221        let instance = &*(ptr as *mut T::Instance);
1222        let imp = instance.imp();
1223
1224        let callback = CellCallback {
1225            callback,
1226            user_data,
1227        };
1228
1229        imp.foreach(&callback)
1230    }
1231}
1232
1233unsafe extern "C" fn cell_area_foreach_alloc<T: CellAreaImpl>(
1234    ptr: *mut ffi::GtkCellArea,
1235    contextptr: *mut ffi::GtkCellAreaContext,
1236    widgetptr: *mut ffi::GtkWidget,
1237    areaptr: *const gdk::ffi::GdkRectangle,
1238    rectangleptr: *const gdk::ffi::GdkRectangle,
1239    callback: ffi::GtkCellAllocCallback,
1240    user_data: glib::ffi::gpointer,
1241) {
1242    unsafe {
1243        let instance = &*(ptr as *mut T::Instance);
1244        let imp = instance.imp();
1245        let context: Borrowed<CellAreaContext> = from_glib_borrow(contextptr);
1246        let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
1247        let rectangle: Borrowed<gdk::Rectangle> = from_glib_borrow(rectangleptr);
1248        let area: Borrowed<gdk::Rectangle> = from_glib_borrow(areaptr);
1249
1250        let callback = CellCallbackAllocate {
1251            callback,
1252            user_data,
1253        };
1254
1255        imp.foreach_alloc(&*context, &*widget, &area, &rectangle, &callback)
1256    }
1257}
1258
1259#[allow(clippy::missing_safety_doc)]
1260pub unsafe trait CellAreaClassExt: ClassStruct {
1261    /// Finds a cell property of a cell area class by name.
1262    ///
1263    /// # Deprecated since 4.10
1264    ///
1265    /// ## `property_name`
1266    /// the name of the child property to find
1267    ///
1268    /// # Returns
1269    ///
1270    /// the `GParamSpec` of the child property
1271    #[doc(alias = "gtk_cell_area_class_find_cell_property")]
1272    fn find_cell_property(&self, property_name: &str) -> Option<ParamSpec> {
1273        unsafe {
1274            let cell_area_class = self as *const _ as *mut ffi::GtkCellAreaClass;
1275            from_glib_none(ffi::gtk_cell_area_class_find_cell_property(
1276                cell_area_class,
1277                property_name.to_glib_none().0,
1278            ))
1279        }
1280    }
1281
1282    /// Returns all cell properties of a cell area class.
1283    ///
1284    /// # Deprecated since 4.10
1285    ///
1286    ///
1287    /// # Returns
1288    ///
1289    /// a newly
1290    ///     allocated [`None`]-terminated array of `GParamSpec`*.  The array
1291    ///     must be freed with g_free().
1292    #[doc(alias = "gtk_cell_area_class_list_cell_properties")]
1293    fn list_cell_properties(&self) -> Vec<ParamSpec> {
1294        unsafe {
1295            let cell_area_class = self as *const _ as *mut ffi::GtkCellAreaClass;
1296            let mut n_properties = std::mem::MaybeUninit::uninit();
1297            let props = ffi::gtk_cell_area_class_list_cell_properties(
1298                cell_area_class,
1299                n_properties.as_mut_ptr(),
1300            );
1301            FromGlibContainer::from_glib_none_num(props, n_properties.assume_init() as usize)
1302        }
1303    }
1304}
1305
1306unsafe impl<T: ClassStruct> CellAreaClassExt for T {}