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