Skip to main content

gtk/subclass/
cell_renderer.rs

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