gtk4/subclass/
cell_renderer.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 [`CellRenderer`].
5
6use std::mem;
7
8use glib::{translate::*, GString};
9use libc::{c_char, c_int};
10
11use crate::{
12    ffi, prelude::*, subclass::prelude::*, CellEditable, CellRenderer, CellRendererState,
13    SizeRequestMode, Snapshot, Widget,
14};
15
16#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
17#[allow(deprecated)]
18pub trait CellRendererImpl: ObjectImpl + ObjectSubclass<Type: IsA<CellRenderer>> {
19    /// Passes an activate event to the cell renderer for possible processing.
20    /// Some cell renderers may use events; for example, [`CellRendererToggle`][crate::CellRendererToggle]
21    /// toggles when it gets a mouse click.
22    ///
23    /// # Deprecated since 4.10
24    ///
25    /// ## `event`
26    /// a [`gdk::Event`][crate::gdk::Event]
27    /// ## `widget`
28    /// widget that received the event
29    /// ## `path`
30    /// widget-dependent string representation of the event location;
31    ///    e.g. for [`TreeView`][crate::TreeView], a string representation of [`TreePath`][crate::TreePath]
32    /// ## `background_area`
33    /// background area as passed to gtk_cell_renderer_render()
34    /// ## `cell_area`
35    /// cell area as passed to gtk_cell_renderer_render()
36    /// ## `flags`
37    /// render flags
38    ///
39    /// # Returns
40    ///
41    /// [`true`] if the event was consumed/handled
42    fn activate<P: IsA<Widget>>(
43        &self,
44        event: Option<&gdk::Event>,
45        widget: &P,
46        path: &str,
47        background_area: &gdk::Rectangle,
48        cell_area: &gdk::Rectangle,
49        flags: CellRendererState,
50    ) -> bool {
51        self.parent_activate(event, widget, path, background_area, cell_area, flags)
52    }
53
54    /// Signal gets emitted when the user cancels the process of editing a cell.
55    fn editing_canceled(&self) {
56        self.parent_editing_canceled()
57    }
58
59    /// Signal gets emitted when a cell starts to be edited.
60    fn editing_started(&self, editable: &CellEditable, path: &str) {
61        self.parent_editing_started(editable, path)
62    }
63
64    /// Gets the aligned area used by @self inside @cell_area. Used for finding
65    /// the appropriate edit and focus rectangle.
66    ///
67    /// # Deprecated since 4.10
68    ///
69    /// ## `widget`
70    /// the [`Widget`][crate::Widget] this cell will be rendering to
71    /// ## `flags`
72    /// render flags
73    /// ## `cell_area`
74    /// cell area which would be passed to gtk_cell_renderer_render()
75    ///
76    /// # Returns
77    ///
78    ///
79    /// ## `aligned_area`
80    /// the return location for the space inside @cell_area
81    ///                that would actually be used to render.
82    #[doc(alias = "get_aligned_area")]
83    fn aligned_area<P: IsA<Widget>>(
84        &self,
85        widget: &P,
86        flags: CellRendererState,
87        cell_area: &gdk::Rectangle,
88    ) -> gdk::Rectangle {
89        self.parent_aligned_area(widget, flags, cell_area)
90    }
91
92    /// Retrieves a cell renderers’s minimum and natural height if it were rendered to
93    /// @widget with the specified @width.
94    ///
95    /// # Deprecated since 4.10
96    ///
97    /// ## `widget`
98    /// the [`Widget`][crate::Widget] this cell will be rendering to
99    /// ## `width`
100    /// the size which is available for allocation
101    ///
102    /// # Returns
103    ///
104    ///
105    /// ## `minimum_height`
106    /// location for storing the minimum size
107    ///
108    /// ## `natural_height`
109    /// location for storing the preferred size
110    #[doc(alias = "get_preferred_height_for_width")]
111    fn preferred_height_for_width<P: IsA<Widget>>(&self, widget: &P, width: i32) -> (i32, i32) {
112        self.parent_preferred_height_for_width(widget, width)
113    }
114
115    /// Retrieves a renderer’s natural size when rendered to @widget.
116    ///
117    /// # Deprecated since 4.10
118    ///
119    /// ## `widget`
120    /// the [`Widget`][crate::Widget] this cell will be rendering to
121    ///
122    /// # Returns
123    ///
124    ///
125    /// ## `minimum_size`
126    /// location to store the minimum size
127    ///
128    /// ## `natural_size`
129    /// location to store the natural size
130    #[doc(alias = "get_preferred_height")]
131    fn preferred_height<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
132        self.parent_preferred_height(widget)
133    }
134
135    /// Retrieves a cell renderers’s minimum and natural width if it were rendered to
136    /// @widget with the specified @height.
137    ///
138    /// # Deprecated since 4.10
139    ///
140    /// ## `widget`
141    /// the [`Widget`][crate::Widget] this cell will be rendering to
142    /// ## `height`
143    /// the size which is available for allocation
144    ///
145    /// # Returns
146    ///
147    ///
148    /// ## `minimum_width`
149    /// location for storing the minimum size
150    ///
151    /// ## `natural_width`
152    /// location for storing the preferred size
153    #[doc(alias = "get_preferred_width_for_height")]
154    fn preferred_width_for_height<P: IsA<Widget>>(&self, widget: &P, height: i32) -> (i32, i32) {
155        self.parent_preferred_width_for_height(widget, height)
156    }
157
158    /// Retrieves a renderer’s natural size when rendered to @widget.
159    ///
160    /// # Deprecated since 4.10
161    ///
162    /// ## `widget`
163    /// the [`Widget`][crate::Widget] this cell will be rendering to
164    ///
165    /// # Returns
166    ///
167    ///
168    /// ## `minimum_size`
169    /// location to store the minimum size
170    ///
171    /// ## `natural_size`
172    /// location to store the natural size
173    #[doc(alias = "get_preferred_width")]
174    fn preferred_width<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
175        self.parent_preferred_width(widget)
176    }
177
178    /// Gets whether the cell renderer prefers a height-for-width layout
179    /// or a width-for-height layout.
180    ///
181    /// # Deprecated since 4.10
182    ///
183    ///
184    /// # Returns
185    ///
186    /// The [`SizeRequestMode`][crate::SizeRequestMode] preferred by this renderer.
187    #[doc(alias = "get_request_mode")]
188    fn request_mode(&self) -> SizeRequestMode {
189        self.parent_request_mode()
190    }
191
192    /// Invokes the virtual render function of the [`CellRenderer`][crate::CellRenderer]. The three
193    /// passed-in rectangles are areas in @cr. Most renderers will draw within
194    /// @cell_area; the xalign, yalign, xpad, and ypad fields of the [`CellRenderer`][crate::CellRenderer]
195    /// should be honored with respect to @cell_area. @background_area includes the
196    /// blank space around the cell, and also the area containing the tree expander;
197    /// so the @background_area rectangles for all cells tile to cover the entire
198    /// @window.
199    ///
200    /// # Deprecated since 4.10
201    ///
202    /// ## `snapshot`
203    /// a [`Snapshot`][crate::Snapshot] to draw to
204    /// ## `widget`
205    /// the widget owning @window
206    /// ## `background_area`
207    /// entire cell area (including tree expanders and maybe
208    ///    padding on the sides)
209    /// ## `cell_area`
210    /// area normally rendered by a cell renderer
211    /// ## `flags`
212    /// flags that affect rendering
213    fn snapshot<P: IsA<Widget>>(
214        &self,
215        snapshot: &Snapshot,
216        widget: &P,
217        background_area: &gdk::Rectangle,
218        cell_area: &gdk::Rectangle,
219        flags: CellRendererState,
220    ) {
221        self.parent_snapshot(snapshot, widget, background_area, cell_area, flags);
222    }
223
224    /// Starts editing the contents of this @self, through a new [`CellEditable`][crate::CellEditable]
225    /// widget created by the [`CellRenderer`][crate::CellRenderer]Class.start_editing virtual function.
226    ///
227    /// # Deprecated since 4.10
228    ///
229    /// ## `event`
230    /// a [`gdk::Event`][crate::gdk::Event]
231    /// ## `widget`
232    /// widget that received the event
233    /// ## `path`
234    /// widget-dependent string representation of the event location;
235    ///    e.g. for [`TreeView`][crate::TreeView], a string representation of [`TreePath`][crate::TreePath]
236    /// ## `background_area`
237    /// background area as passed to gtk_cell_renderer_render()
238    /// ## `cell_area`
239    /// cell area as passed to gtk_cell_renderer_render()
240    /// ## `flags`
241    /// render flags
242    ///
243    /// # Returns
244    ///
245    /// A new [`CellEditable`][crate::CellEditable] for editing this
246    ///   @self, or [`None`] if editing is not possible
247    fn start_editing<P: IsA<Widget>>(
248        &self,
249        event: Option<&gdk::Event>,
250        widget: &P,
251        path: &str,
252        background_area: &gdk::Rectangle,
253        cell_area: &gdk::Rectangle,
254        flags: CellRendererState,
255    ) -> Option<CellEditable> {
256        self.parent_start_editing(event, widget, path, background_area, cell_area, flags)
257    }
258}
259
260#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
261#[allow(deprecated)]
262pub trait CellRendererImplExt: CellRendererImpl {
263    fn parent_request_mode(&self) -> SizeRequestMode {
264        unsafe {
265            let data = Self::type_data();
266            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
267            let f = (*parent_class).get_request_mode.unwrap();
268            from_glib(f(self
269                .obj()
270                .unsafe_cast_ref::<CellRenderer>()
271                .to_glib_none()
272                .0))
273        }
274    }
275
276    fn parent_preferred_width<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
277        unsafe {
278            let data = Self::type_data();
279            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
280            let f = (*parent_class).get_preferred_width.unwrap();
281
282            let mut minimum_size = mem::MaybeUninit::uninit();
283            let mut natural_size = mem::MaybeUninit::uninit();
284            f(
285                self.obj()
286                    .unsafe_cast_ref::<CellRenderer>()
287                    .to_glib_none()
288                    .0,
289                widget.as_ref().to_glib_none().0,
290                minimum_size.as_mut_ptr(),
291                natural_size.as_mut_ptr(),
292            );
293            (minimum_size.assume_init(), natural_size.assume_init())
294        }
295    }
296
297    fn parent_preferred_width_for_height<P: IsA<Widget>>(
298        &self,
299        widget: &P,
300        height: i32,
301    ) -> (i32, i32) {
302        unsafe {
303            let data = Self::type_data();
304            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
305            let f = (*parent_class).get_preferred_width_for_height.unwrap();
306
307            let mut minimum_size = mem::MaybeUninit::uninit();
308            let mut natural_size = mem::MaybeUninit::uninit();
309            f(
310                self.obj()
311                    .unsafe_cast_ref::<CellRenderer>()
312                    .to_glib_none()
313                    .0,
314                widget.as_ref().to_glib_none().0,
315                height,
316                minimum_size.as_mut_ptr(),
317                natural_size.as_mut_ptr(),
318            );
319            (minimum_size.assume_init(), natural_size.assume_init())
320        }
321    }
322    fn parent_preferred_height<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
323        unsafe {
324            let data = Self::type_data();
325            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
326            let f = (*parent_class).get_preferred_height.unwrap();
327            let mut minimum_size = mem::MaybeUninit::uninit();
328            let mut natural_size = mem::MaybeUninit::uninit();
329            f(
330                self.obj()
331                    .unsafe_cast_ref::<CellRenderer>()
332                    .to_glib_none()
333                    .0,
334                widget.as_ref().to_glib_none().0,
335                minimum_size.as_mut_ptr(),
336                natural_size.as_mut_ptr(),
337            );
338            (minimum_size.assume_init(), natural_size.assume_init())
339        }
340    }
341    fn parent_preferred_height_for_width<P: IsA<Widget>>(
342        &self,
343        widget: &P,
344        width: i32,
345    ) -> (i32, i32) {
346        unsafe {
347            let data = Self::type_data();
348            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
349            let f = (*parent_class).get_preferred_height_for_width.unwrap();
350            let mut minimum_size = mem::MaybeUninit::uninit();
351            let mut natural_size = mem::MaybeUninit::uninit();
352            f(
353                self.obj()
354                    .unsafe_cast_ref::<CellRenderer>()
355                    .to_glib_none()
356                    .0,
357                widget.as_ref().to_glib_none().0,
358                width,
359                minimum_size.as_mut_ptr(),
360                natural_size.as_mut_ptr(),
361            );
362            (minimum_size.assume_init(), natural_size.assume_init())
363        }
364    }
365
366    fn parent_aligned_area<P: IsA<Widget>>(
367        &self,
368        widget: &P,
369        flags: CellRendererState,
370        cell_area: &gdk::Rectangle,
371    ) -> gdk::Rectangle {
372        unsafe {
373            let data = Self::type_data();
374            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
375            let mut aligned_area = gdk::Rectangle::uninitialized();
376            let f = (*parent_class).get_aligned_area.unwrap();
377            f(
378                self.obj()
379                    .unsafe_cast_ref::<CellRenderer>()
380                    .to_glib_none()
381                    .0,
382                widget.as_ref().to_glib_none().0,
383                flags.into_glib(),
384                cell_area.to_glib_none().0,
385                aligned_area.to_glib_none_mut().0,
386            );
387            aligned_area
388        }
389    }
390
391    fn parent_snapshot<P: IsA<Widget>>(
392        &self,
393        snapshot: &Snapshot,
394        widget: &P,
395        background_area: &gdk::Rectangle,
396        cell_area: &gdk::Rectangle,
397        flags: CellRendererState,
398    ) {
399        unsafe {
400            let data = Self::type_data();
401            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
402            if let Some(f) = (*parent_class).snapshot {
403                f(
404                    self.obj()
405                        .unsafe_cast_ref::<CellRenderer>()
406                        .to_glib_none()
407                        .0,
408                    snapshot.to_glib_none().0,
409                    widget.as_ref().to_glib_none().0,
410                    background_area.to_glib_none().0,
411                    cell_area.to_glib_none().0,
412                    flags.into_glib(),
413                )
414            }
415        }
416    }
417
418    // Returns true if the event was consumed/handled
419    fn parent_activate<P: IsA<Widget>>(
420        &self,
421        event: Option<&gdk::Event>,
422        widget: &P,
423        path: &str,
424        background_area: &gdk::Rectangle,
425        cell_area: &gdk::Rectangle,
426        flags: CellRendererState,
427    ) -> bool {
428        unsafe {
429            let data = Self::type_data();
430            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
431            if let Some(f) = (*parent_class).activate {
432                from_glib(f(
433                    self.obj()
434                        .unsafe_cast_ref::<CellRenderer>()
435                        .to_glib_none()
436                        .0,
437                    mut_override(event.to_glib_none().0),
438                    widget.as_ref().to_glib_none().0,
439                    path.to_glib_none().0,
440                    background_area.to_glib_none().0,
441                    cell_area.to_glib_none().0,
442                    flags.into_glib(),
443                ))
444            } else {
445                false
446            }
447        }
448    }
449
450    fn parent_start_editing<P: IsA<Widget>>(
451        &self,
452        event: Option<&gdk::Event>,
453        widget: &P,
454        path: &str,
455        background_area: &gdk::Rectangle,
456        cell_area: &gdk::Rectangle,
457        flags: CellRendererState,
458    ) -> Option<CellEditable> {
459        unsafe {
460            let data = Self::type_data();
461            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
462            if let Some(f) = (*parent_class).start_editing {
463                from_glib_none(f(
464                    self.obj()
465                        .unsafe_cast_ref::<CellRenderer>()
466                        .to_glib_none()
467                        .0,
468                    mut_override(event.to_glib_none().0),
469                    widget.as_ref().to_glib_none().0,
470                    path.to_glib_none().0,
471                    background_area.to_glib_none().0,
472                    cell_area.to_glib_none().0,
473                    flags.into_glib(),
474                ))
475            } else {
476                None
477            }
478        }
479    }
480
481    fn parent_editing_canceled(&self) {
482        unsafe {
483            let data = Self::type_data();
484            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
485            if let Some(f) = (*parent_class).editing_canceled {
486                f(self
487                    .obj()
488                    .unsafe_cast_ref::<CellRenderer>()
489                    .to_glib_none()
490                    .0)
491            }
492        }
493    }
494
495    fn parent_editing_started(&self, editable: &CellEditable, path: &str) {
496        unsafe {
497            let data = Self::type_data();
498            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
499            if let Some(f) = (*parent_class).editing_started {
500                f(
501                    self.obj()
502                        .unsafe_cast_ref::<CellRenderer>()
503                        .to_glib_none()
504                        .0,
505                    editable.to_glib_none().0,
506                    path.to_glib_none().0,
507                )
508            }
509        }
510    }
511}
512
513impl<T: CellRendererImpl> CellRendererImplExt for T {}
514
515unsafe impl<T: CellRendererImpl> IsSubclassable<T> for CellRenderer {
516    fn class_init(class: &mut ::glib::Class<Self>) {
517        Self::parent_class_init::<T>(class);
518
519        assert_initialized_main_thread!();
520
521        let klass = class.as_mut();
522
523        klass.activate = Some(cell_renderer_activate::<T>);
524        klass.editing_canceled = Some(cell_renderer_editing_canceled::<T>);
525        klass.editing_started = Some(cell_renderer_editing_started::<T>);
526        klass.get_aligned_area = Some(cell_renderer_get_aligned_area::<T>);
527        klass.get_preferred_height_for_width =
528            Some(cell_renderer_get_preferred_height_for_width::<T>);
529        klass.get_preferred_height = Some(cell_renderer_get_preferred_height::<T>);
530        klass.get_preferred_width_for_height =
531            Some(cell_renderer_get_preferred_width_for_height::<T>);
532        klass.get_preferred_width = Some(cell_renderer_get_preferred_width::<T>);
533        klass.get_request_mode = Some(cell_renderer_get_request_mode::<T>);
534        klass.snapshot = Some(cell_renderer_snapshot::<T>);
535        klass.start_editing = Some(cell_renderer_start_editing::<T>);
536    }
537}
538
539unsafe extern "C" fn cell_renderer_activate<T: CellRendererImpl>(
540    ptr: *mut ffi::GtkCellRenderer,
541    evtptr: *mut gdk::ffi::GdkEvent,
542    wdgtptr: *mut ffi::GtkWidget,
543    pathptr: *const c_char,
544    bgptr: *const gdk::ffi::GdkRectangle,
545    cellptr: *const gdk::ffi::GdkRectangle,
546    flags: ffi::GtkCellRendererState,
547) -> glib::ffi::gboolean {
548    let instance = &*(ptr as *mut T::Instance);
549    let imp = instance.imp();
550    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
551    let evt: Borrowed<Option<gdk::Event>> = from_glib_borrow(evtptr);
552
553    imp.activate(
554        evt.as_ref().as_ref(),
555        &*widget,
556        &GString::from_glib_borrow(pathptr),
557        &from_glib_borrow(bgptr),
558        &from_glib_borrow(cellptr),
559        from_glib(flags),
560    )
561    .into_glib()
562}
563
564unsafe extern "C" fn cell_renderer_editing_canceled<T: CellRendererImpl>(
565    ptr: *mut ffi::GtkCellRenderer,
566) {
567    let instance = &*(ptr as *mut T::Instance);
568    let imp = instance.imp();
569
570    imp.editing_canceled();
571}
572
573unsafe extern "C" fn cell_renderer_editing_started<T: CellRendererImpl>(
574    ptr: *mut ffi::GtkCellRenderer,
575    editableptr: *mut ffi::GtkCellEditable,
576    pathptr: *const c_char,
577) {
578    let instance = &*(ptr as *mut T::Instance);
579    let imp = instance.imp();
580    let editable = from_glib_borrow(editableptr);
581
582    imp.editing_started(&editable, &GString::from_glib_borrow(pathptr));
583}
584
585unsafe extern "C" fn cell_renderer_get_aligned_area<T: CellRendererImpl>(
586    ptr: *mut ffi::GtkCellRenderer,
587    wdgtptr: *mut ffi::GtkWidget,
588    flags: ffi::GtkCellRendererState,
589    cellarea: *const gdk::ffi::GdkRectangle,
590    alignedptr: *mut gdk::ffi::GdkRectangle,
591) {
592    let instance = &*(ptr as *mut T::Instance);
593    let imp = instance.imp();
594    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
595
596    let rectangle = imp.aligned_area(&*widget, from_glib(flags), &from_glib_borrow(cellarea));
597    *alignedptr = *rectangle.to_glib_none().0;
598}
599
600unsafe extern "C" fn cell_renderer_get_preferred_height_for_width<T: CellRendererImpl>(
601    ptr: *mut ffi::GtkCellRenderer,
602    wdgtptr: *mut ffi::GtkWidget,
603    width: c_int,
604    min_height_ptr: *mut c_int,
605    nat_height_ptr: *mut c_int,
606) {
607    let instance = &*(ptr as *mut T::Instance);
608    let imp = instance.imp();
609    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
610
611    let (min_height, nat_height) = imp.preferred_height_for_width(&*widget, width);
612    if !min_height_ptr.is_null() {
613        *min_height_ptr = min_height;
614    }
615    if !nat_height_ptr.is_null() {
616        *nat_height_ptr = nat_height;
617    }
618}
619
620unsafe extern "C" fn cell_renderer_get_preferred_height<T: CellRendererImpl>(
621    ptr: *mut ffi::GtkCellRenderer,
622    wdgtptr: *mut ffi::GtkWidget,
623    minptr: *mut c_int,
624    natptr: *mut c_int,
625) {
626    let instance = &*(ptr as *mut T::Instance);
627    let imp = instance.imp();
628    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
629
630    let (min_size, nat_size) = imp.preferred_height(&*widget);
631    if !minptr.is_null() {
632        *minptr = min_size;
633    }
634    if !natptr.is_null() {
635        *natptr = nat_size;
636    }
637}
638
639unsafe extern "C" fn cell_renderer_get_preferred_width_for_height<T: CellRendererImpl>(
640    ptr: *mut ffi::GtkCellRenderer,
641    wdgtptr: *mut ffi::GtkWidget,
642    height: c_int,
643    min_width_ptr: *mut c_int,
644    nat_width_ptr: *mut c_int,
645) {
646    let instance = &*(ptr as *mut T::Instance);
647    let imp = instance.imp();
648    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
649
650    let (min_width, nat_width) = imp.preferred_width_for_height(&*widget, height);
651    if !min_width_ptr.is_null() {
652        *min_width_ptr = min_width;
653    }
654    if !nat_width_ptr.is_null() {
655        *nat_width_ptr = nat_width;
656    }
657}
658
659unsafe extern "C" fn cell_renderer_get_preferred_width<T: CellRendererImpl>(
660    ptr: *mut ffi::GtkCellRenderer,
661    wdgtptr: *mut ffi::GtkWidget,
662    minptr: *mut c_int,
663    natptr: *mut c_int,
664) {
665    let instance = &*(ptr as *mut T::Instance);
666    let imp = instance.imp();
667    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
668
669    let (min_size, nat_size) = imp.preferred_width(&*widget);
670    if !minptr.is_null() {
671        *minptr = min_size;
672    }
673    if !natptr.is_null() {
674        *natptr = nat_size;
675    }
676}
677
678unsafe extern "C" fn cell_renderer_get_request_mode<T: CellRendererImpl>(
679    ptr: *mut ffi::GtkCellRenderer,
680) -> ffi::GtkSizeRequestMode {
681    let instance = &*(ptr as *mut T::Instance);
682    let imp = instance.imp();
683
684    imp.request_mode().into_glib()
685}
686
687unsafe extern "C" fn cell_renderer_snapshot<T: CellRendererImpl>(
688    ptr: *mut ffi::GtkCellRenderer,
689    snapshotptr: *mut ffi::GtkSnapshot,
690    wdgtptr: *mut ffi::GtkWidget,
691    bgptr: *const gdk::ffi::GdkRectangle,
692    cellptr: *const gdk::ffi::GdkRectangle,
693    flags: ffi::GtkCellRendererState,
694) {
695    let instance = &*(ptr as *mut T::Instance);
696    let imp = instance.imp();
697    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
698    let snapshot: Borrowed<Snapshot> = from_glib_borrow(snapshotptr);
699
700    imp.snapshot(
701        &snapshot,
702        &*widget,
703        &from_glib_borrow(bgptr),
704        &from_glib_borrow(cellptr),
705        from_glib(flags),
706    );
707}
708
709unsafe extern "C" fn cell_renderer_start_editing<T: CellRendererImpl>(
710    ptr: *mut ffi::GtkCellRenderer,
711    evtptr: *mut gdk::ffi::GdkEvent,
712    wdgtptr: *mut ffi::GtkWidget,
713    pathptr: *const c_char,
714    bgptr: *const gdk::ffi::GdkRectangle,
715    cellptr: *const gdk::ffi::GdkRectangle,
716    flags: ffi::GtkCellRendererState,
717) -> *mut ffi::GtkCellEditable {
718    let instance = &*(ptr as *mut T::Instance);
719    let imp = instance.imp();
720    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
721    let evt: Borrowed<Option<gdk::Event>> = from_glib_borrow(evtptr);
722
723    imp.start_editing(
724        evt.as_ref().as_ref(),
725        &*widget,
726        &GString::from_glib_borrow(pathptr),
727        &from_glib_borrow(bgptr),
728        &from_glib_borrow(cellptr),
729        from_glib(flags),
730    )
731    .to_glib_none()
732    .0
733}