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`](crate::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: CellRendererImplExt + ObjectImpl {
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
260mod sealed {
261    pub trait Sealed {}
262    impl<T: super::CellRendererImplExt> Sealed for T {}
263}
264
265#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
266#[allow(deprecated)]
267pub trait CellRendererImplExt: sealed::Sealed + ObjectSubclass {
268    fn parent_request_mode(&self) -> SizeRequestMode {
269        unsafe {
270            let data = Self::type_data();
271            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
272            let f = (*parent_class).get_request_mode.unwrap();
273            from_glib(f(self
274                .obj()
275                .unsafe_cast_ref::<CellRenderer>()
276                .to_glib_none()
277                .0))
278        }
279    }
280
281    fn parent_preferred_width<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
282        unsafe {
283            let data = Self::type_data();
284            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
285            let f = (*parent_class).get_preferred_width.unwrap();
286
287            let mut minimum_size = mem::MaybeUninit::uninit();
288            let mut natural_size = mem::MaybeUninit::uninit();
289            f(
290                self.obj()
291                    .unsafe_cast_ref::<CellRenderer>()
292                    .to_glib_none()
293                    .0,
294                widget.as_ref().to_glib_none().0,
295                minimum_size.as_mut_ptr(),
296                natural_size.as_mut_ptr(),
297            );
298            (minimum_size.assume_init(), natural_size.assume_init())
299        }
300    }
301
302    fn parent_preferred_width_for_height<P: IsA<Widget>>(
303        &self,
304        widget: &P,
305        height: i32,
306    ) -> (i32, i32) {
307        unsafe {
308            let data = Self::type_data();
309            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
310            let f = (*parent_class).get_preferred_width_for_height.unwrap();
311
312            let mut minimum_size = mem::MaybeUninit::uninit();
313            let mut natural_size = mem::MaybeUninit::uninit();
314            f(
315                self.obj()
316                    .unsafe_cast_ref::<CellRenderer>()
317                    .to_glib_none()
318                    .0,
319                widget.as_ref().to_glib_none().0,
320                height,
321                minimum_size.as_mut_ptr(),
322                natural_size.as_mut_ptr(),
323            );
324            (minimum_size.assume_init(), natural_size.assume_init())
325        }
326    }
327    fn parent_preferred_height<P: IsA<Widget>>(&self, widget: &P) -> (i32, i32) {
328        unsafe {
329            let data = Self::type_data();
330            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
331            let f = (*parent_class).get_preferred_height.unwrap();
332            let mut minimum_size = mem::MaybeUninit::uninit();
333            let mut natural_size = mem::MaybeUninit::uninit();
334            f(
335                self.obj()
336                    .unsafe_cast_ref::<CellRenderer>()
337                    .to_glib_none()
338                    .0,
339                widget.as_ref().to_glib_none().0,
340                minimum_size.as_mut_ptr(),
341                natural_size.as_mut_ptr(),
342            );
343            (minimum_size.assume_init(), natural_size.assume_init())
344        }
345    }
346    fn parent_preferred_height_for_width<P: IsA<Widget>>(
347        &self,
348        widget: &P,
349        width: i32,
350    ) -> (i32, i32) {
351        unsafe {
352            let data = Self::type_data();
353            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
354            let f = (*parent_class).get_preferred_height_for_width.unwrap();
355            let mut minimum_size = mem::MaybeUninit::uninit();
356            let mut natural_size = mem::MaybeUninit::uninit();
357            f(
358                self.obj()
359                    .unsafe_cast_ref::<CellRenderer>()
360                    .to_glib_none()
361                    .0,
362                widget.as_ref().to_glib_none().0,
363                width,
364                minimum_size.as_mut_ptr(),
365                natural_size.as_mut_ptr(),
366            );
367            (minimum_size.assume_init(), natural_size.assume_init())
368        }
369    }
370
371    fn parent_aligned_area<P: IsA<Widget>>(
372        &self,
373        widget: &P,
374        flags: CellRendererState,
375        cell_area: &gdk::Rectangle,
376    ) -> gdk::Rectangle {
377        unsafe {
378            let data = Self::type_data();
379            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
380            let mut aligned_area = gdk::Rectangle::uninitialized();
381            let f = (*parent_class).get_aligned_area.unwrap();
382            f(
383                self.obj()
384                    .unsafe_cast_ref::<CellRenderer>()
385                    .to_glib_none()
386                    .0,
387                widget.as_ref().to_glib_none().0,
388                flags.into_glib(),
389                cell_area.to_glib_none().0,
390                aligned_area.to_glib_none_mut().0,
391            );
392            aligned_area
393        }
394    }
395
396    fn parent_snapshot<P: IsA<Widget>>(
397        &self,
398        snapshot: &Snapshot,
399        widget: &P,
400        background_area: &gdk::Rectangle,
401        cell_area: &gdk::Rectangle,
402        flags: CellRendererState,
403    ) {
404        unsafe {
405            let data = Self::type_data();
406            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
407            if let Some(f) = (*parent_class).snapshot {
408                f(
409                    self.obj()
410                        .unsafe_cast_ref::<CellRenderer>()
411                        .to_glib_none()
412                        .0,
413                    snapshot.to_glib_none().0,
414                    widget.as_ref().to_glib_none().0,
415                    background_area.to_glib_none().0,
416                    cell_area.to_glib_none().0,
417                    flags.into_glib(),
418                )
419            }
420        }
421    }
422
423    // Returns true if the event was consumed/handled
424    fn parent_activate<P: IsA<Widget>>(
425        &self,
426        event: Option<&gdk::Event>,
427        widget: &P,
428        path: &str,
429        background_area: &gdk::Rectangle,
430        cell_area: &gdk::Rectangle,
431        flags: CellRendererState,
432    ) -> bool {
433        unsafe {
434            let data = Self::type_data();
435            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
436            if let Some(f) = (*parent_class).activate {
437                from_glib(f(
438                    self.obj()
439                        .unsafe_cast_ref::<CellRenderer>()
440                        .to_glib_none()
441                        .0,
442                    mut_override(event.to_glib_none().0),
443                    widget.as_ref().to_glib_none().0,
444                    path.to_glib_none().0,
445                    background_area.to_glib_none().0,
446                    cell_area.to_glib_none().0,
447                    flags.into_glib(),
448                ))
449            } else {
450                false
451            }
452        }
453    }
454
455    fn parent_start_editing<P: IsA<Widget>>(
456        &self,
457        event: Option<&gdk::Event>,
458        widget: &P,
459        path: &str,
460        background_area: &gdk::Rectangle,
461        cell_area: &gdk::Rectangle,
462        flags: CellRendererState,
463    ) -> Option<CellEditable> {
464        unsafe {
465            let data = Self::type_data();
466            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
467            if let Some(f) = (*parent_class).start_editing {
468                from_glib_none(f(
469                    self.obj()
470                        .unsafe_cast_ref::<CellRenderer>()
471                        .to_glib_none()
472                        .0,
473                    mut_override(event.to_glib_none().0),
474                    widget.as_ref().to_glib_none().0,
475                    path.to_glib_none().0,
476                    background_area.to_glib_none().0,
477                    cell_area.to_glib_none().0,
478                    flags.into_glib(),
479                ))
480            } else {
481                None
482            }
483        }
484    }
485
486    fn parent_editing_canceled(&self) {
487        unsafe {
488            let data = Self::type_data();
489            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
490            if let Some(f) = (*parent_class).editing_canceled {
491                f(self
492                    .obj()
493                    .unsafe_cast_ref::<CellRenderer>()
494                    .to_glib_none()
495                    .0)
496            }
497        }
498    }
499
500    fn parent_editing_started(&self, editable: &CellEditable, path: &str) {
501        unsafe {
502            let data = Self::type_data();
503            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkCellRendererClass;
504            if let Some(f) = (*parent_class).editing_started {
505                f(
506                    self.obj()
507                        .unsafe_cast_ref::<CellRenderer>()
508                        .to_glib_none()
509                        .0,
510                    editable.to_glib_none().0,
511                    path.to_glib_none().0,
512                )
513            }
514        }
515    }
516}
517
518impl<T: CellRendererImpl> CellRendererImplExt for T {}
519
520unsafe impl<T: CellRendererImpl> IsSubclassable<T> for CellRenderer {
521    fn class_init(class: &mut ::glib::Class<Self>) {
522        Self::parent_class_init::<T>(class);
523
524        assert_initialized_main_thread!();
525
526        let klass = class.as_mut();
527
528        klass.activate = Some(cell_renderer_activate::<T>);
529        klass.editing_canceled = Some(cell_renderer_editing_canceled::<T>);
530        klass.editing_started = Some(cell_renderer_editing_started::<T>);
531        klass.get_aligned_area = Some(cell_renderer_get_aligned_area::<T>);
532        klass.get_preferred_height_for_width =
533            Some(cell_renderer_get_preferred_height_for_width::<T>);
534        klass.get_preferred_height = Some(cell_renderer_get_preferred_height::<T>);
535        klass.get_preferred_width_for_height =
536            Some(cell_renderer_get_preferred_width_for_height::<T>);
537        klass.get_preferred_width = Some(cell_renderer_get_preferred_width::<T>);
538        klass.get_request_mode = Some(cell_renderer_get_request_mode::<T>);
539        klass.snapshot = Some(cell_renderer_snapshot::<T>);
540        klass.start_editing = Some(cell_renderer_start_editing::<T>);
541    }
542}
543
544unsafe extern "C" fn cell_renderer_activate<T: CellRendererImpl>(
545    ptr: *mut ffi::GtkCellRenderer,
546    evtptr: *mut gdk::ffi::GdkEvent,
547    wdgtptr: *mut ffi::GtkWidget,
548    pathptr: *const c_char,
549    bgptr: *const gdk::ffi::GdkRectangle,
550    cellptr: *const gdk::ffi::GdkRectangle,
551    flags: ffi::GtkCellRendererState,
552) -> glib::ffi::gboolean {
553    let instance = &*(ptr as *mut T::Instance);
554    let imp = instance.imp();
555    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
556    let evt: Borrowed<Option<gdk::Event>> = from_glib_borrow(evtptr);
557
558    imp.activate(
559        evt.as_ref().as_ref(),
560        &*widget,
561        &GString::from_glib_borrow(pathptr),
562        &from_glib_borrow(bgptr),
563        &from_glib_borrow(cellptr),
564        from_glib(flags),
565    )
566    .into_glib()
567}
568
569unsafe extern "C" fn cell_renderer_editing_canceled<T: CellRendererImpl>(
570    ptr: *mut ffi::GtkCellRenderer,
571) {
572    let instance = &*(ptr as *mut T::Instance);
573    let imp = instance.imp();
574
575    imp.editing_canceled();
576}
577
578unsafe extern "C" fn cell_renderer_editing_started<T: CellRendererImpl>(
579    ptr: *mut ffi::GtkCellRenderer,
580    editableptr: *mut ffi::GtkCellEditable,
581    pathptr: *const c_char,
582) {
583    let instance = &*(ptr as *mut T::Instance);
584    let imp = instance.imp();
585    let editable = from_glib_borrow(editableptr);
586
587    imp.editing_started(&editable, &GString::from_glib_borrow(pathptr));
588}
589
590unsafe extern "C" fn cell_renderer_get_aligned_area<T: CellRendererImpl>(
591    ptr: *mut ffi::GtkCellRenderer,
592    wdgtptr: *mut ffi::GtkWidget,
593    flags: ffi::GtkCellRendererState,
594    cellarea: *const gdk::ffi::GdkRectangle,
595    alignedptr: *mut gdk::ffi::GdkRectangle,
596) {
597    let instance = &*(ptr as *mut T::Instance);
598    let imp = instance.imp();
599    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
600
601    let rectangle = imp.aligned_area(&*widget, from_glib(flags), &from_glib_borrow(cellarea));
602    *alignedptr = *rectangle.to_glib_none().0;
603}
604
605unsafe extern "C" fn cell_renderer_get_preferred_height_for_width<T: CellRendererImpl>(
606    ptr: *mut ffi::GtkCellRenderer,
607    wdgtptr: *mut ffi::GtkWidget,
608    width: c_int,
609    min_height_ptr: *mut c_int,
610    nat_height_ptr: *mut c_int,
611) {
612    let instance = &*(ptr as *mut T::Instance);
613    let imp = instance.imp();
614    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
615
616    let (min_height, nat_height) = imp.preferred_height_for_width(&*widget, width);
617    if !min_height_ptr.is_null() {
618        *min_height_ptr = min_height;
619    }
620    if !nat_height_ptr.is_null() {
621        *nat_height_ptr = nat_height;
622    }
623}
624
625unsafe extern "C" fn cell_renderer_get_preferred_height<T: CellRendererImpl>(
626    ptr: *mut ffi::GtkCellRenderer,
627    wdgtptr: *mut ffi::GtkWidget,
628    minptr: *mut c_int,
629    natptr: *mut c_int,
630) {
631    let instance = &*(ptr as *mut T::Instance);
632    let imp = instance.imp();
633    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
634
635    let (min_size, nat_size) = imp.preferred_height(&*widget);
636    if !minptr.is_null() {
637        *minptr = min_size;
638    }
639    if !natptr.is_null() {
640        *natptr = nat_size;
641    }
642}
643
644unsafe extern "C" fn cell_renderer_get_preferred_width_for_height<T: CellRendererImpl>(
645    ptr: *mut ffi::GtkCellRenderer,
646    wdgtptr: *mut ffi::GtkWidget,
647    height: c_int,
648    min_width_ptr: *mut c_int,
649    nat_width_ptr: *mut c_int,
650) {
651    let instance = &*(ptr as *mut T::Instance);
652    let imp = instance.imp();
653    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
654
655    let (min_width, nat_width) = imp.preferred_width_for_height(&*widget, height);
656    if !min_width_ptr.is_null() {
657        *min_width_ptr = min_width;
658    }
659    if !nat_width_ptr.is_null() {
660        *nat_width_ptr = nat_width;
661    }
662}
663
664unsafe extern "C" fn cell_renderer_get_preferred_width<T: CellRendererImpl>(
665    ptr: *mut ffi::GtkCellRenderer,
666    wdgtptr: *mut ffi::GtkWidget,
667    minptr: *mut c_int,
668    natptr: *mut c_int,
669) {
670    let instance = &*(ptr as *mut T::Instance);
671    let imp = instance.imp();
672    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
673
674    let (min_size, nat_size) = imp.preferred_width(&*widget);
675    if !minptr.is_null() {
676        *minptr = min_size;
677    }
678    if !natptr.is_null() {
679        *natptr = nat_size;
680    }
681}
682
683unsafe extern "C" fn cell_renderer_get_request_mode<T: CellRendererImpl>(
684    ptr: *mut ffi::GtkCellRenderer,
685) -> ffi::GtkSizeRequestMode {
686    let instance = &*(ptr as *mut T::Instance);
687    let imp = instance.imp();
688
689    imp.request_mode().into_glib()
690}
691
692unsafe extern "C" fn cell_renderer_snapshot<T: CellRendererImpl>(
693    ptr: *mut ffi::GtkCellRenderer,
694    snapshotptr: *mut ffi::GtkSnapshot,
695    wdgtptr: *mut ffi::GtkWidget,
696    bgptr: *const gdk::ffi::GdkRectangle,
697    cellptr: *const gdk::ffi::GdkRectangle,
698    flags: ffi::GtkCellRendererState,
699) {
700    let instance = &*(ptr as *mut T::Instance);
701    let imp = instance.imp();
702    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
703    let snapshot: Borrowed<Snapshot> = from_glib_borrow(snapshotptr);
704
705    imp.snapshot(
706        &snapshot,
707        &*widget,
708        &from_glib_borrow(bgptr),
709        &from_glib_borrow(cellptr),
710        from_glib(flags),
711    );
712}
713
714unsafe extern "C" fn cell_renderer_start_editing<T: CellRendererImpl>(
715    ptr: *mut ffi::GtkCellRenderer,
716    evtptr: *mut gdk::ffi::GdkEvent,
717    wdgtptr: *mut ffi::GtkWidget,
718    pathptr: *const c_char,
719    bgptr: *const gdk::ffi::GdkRectangle,
720    cellptr: *const gdk::ffi::GdkRectangle,
721    flags: ffi::GtkCellRendererState,
722) -> *mut ffi::GtkCellEditable {
723    let instance = &*(ptr as *mut T::Instance);
724    let imp = instance.imp();
725    let widget: Borrowed<Widget> = from_glib_borrow(wdgtptr);
726    let evt: Borrowed<Option<gdk::Event>> = from_glib_borrow(evtptr);
727
728    imp.start_editing(
729        evt.as_ref().as_ref(),
730        &*widget,
731        &GString::from_glib_borrow(pathptr),
732        &from_glib_borrow(bgptr),
733        &from_glib_borrow(cellptr),
734        from_glib(flags),
735    )
736    .to_glib_none()
737    .0
738}