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