Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request #863 from sdroege/widget-subclass-draw
Browse files Browse the repository at this point in the history
Add support for overriding Widget::draw() virtual method
  • Loading branch information
GuillaumeGomez committed Aug 8, 2019
2 parents 31fe389 + 9f8559f commit 65251bd
Showing 1 changed file with 39 additions and 4 deletions.
43 changes: 39 additions & 4 deletions src/subclass/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use glib::subclass::prelude::*;

use crate::Inhibit;
use crate::Orientation;
use cairo;
use cairo_sys;
use Widget;
use WidgetClass;

Expand Down Expand Up @@ -60,6 +62,10 @@ pub trait WidgetImpl: WidgetImplExt + ObjectImpl + 'static {
self.parent_button_release_event(widget, event)
}

fn draw(&self, widget: &Widget, cr: &cairo::Context) -> Inhibit {
self.parent_draw(widget, cr)
}

// fn can_activate_accel(&self, widget: &Widget, signal_id: u32) -> bool {
// self.parent_can_activate_accel(widget, signal_id)
// }
Expand Down Expand Up @@ -92,6 +98,8 @@ pub trait WidgetImplExt {
fn parent_button_press_event(&self, widget: &Widget, event: &gdk::EventButton) -> Inhibit;
fn parent_button_release_event(&self, widget: &Widget, event: &gdk::EventButton) -> Inhibit;
// fn parent_can_activate_accel(&self, widget: &Widget, signal_id: u32) -> bool;

fn parent_draw(&self, widget: &Widget, cr: &cairo::Context) -> Inhibit;
}

impl<T: WidgetImpl + ObjectImpl> WidgetImplExt for T {
Expand Down Expand Up @@ -178,7 +186,7 @@ impl<T: WidgetImpl + ObjectImpl> WidgetImplExt for T {
.button_press_event
.expect("No parent class impl for \"button_press_event\"");
let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
Inhibit(f(widget.to_glib_none().0, ev_glib) != 0)
Inhibit(from_glib(f(widget.to_glib_none().0, ev_glib)))
}
}

Expand All @@ -190,7 +198,7 @@ impl<T: WidgetImpl + ObjectImpl> WidgetImplExt for T {
.button_release_event
.expect("No parent class impl for \"button_release_event\"");
let ev_glib = glib::translate::mut_override(event.to_glib_none().0);
Inhibit(f(widget.to_glib_none().0, ev_glib) != 0)
Inhibit(from_glib(f(widget.to_glib_none().0, ev_glib)))
}
}

Expand All @@ -205,6 +213,17 @@ impl<T: WidgetImpl + ObjectImpl> WidgetImplExt for T {
// f(widget.to_glib_none().0, signal_id) != 0
// }
// }

fn parent_draw(&self, widget: &Widget, cr: &cairo::Context) -> Inhibit {
unsafe {
let data = self.get_type_data();
let parent_class = data.as_ref().get_parent_class() as *mut gtk_sys::GtkWidgetClass;
let f = (*parent_class)
.draw
.expect("No parent class impl for \"draw\"");
Inhibit(from_glib(f(widget.to_glib_none().0, cr.to_glib_none().0)))
}
}
}

unsafe impl<T: ObjectSubclass + WidgetImpl> IsSubclassable<T> for WidgetClass {
Expand All @@ -218,6 +237,7 @@ unsafe impl<T: ObjectSubclass + WidgetImpl> IsSubclassable<T> for WidgetClass {
klass.button_press_event = Some(widget_button_press_event::<T>);
klass.button_release_event = Some(widget_button_release_event::<T>);
// klass.can_activate_accel = Some(widget_can_activate_accel::<T>);
klass.draw = Some(widget_draw::<T>);
}
}
}
Expand Down Expand Up @@ -302,7 +322,7 @@ where
let wrap: Widget = from_glib_borrow(ptr);
let evwrap: gdk::EventButton = from_glib_borrow(btnptr);

imp.button_press_event(&wrap, &evwrap).0 as glib_sys::gboolean
imp.button_press_event(&wrap, &evwrap).to_glib()
}

unsafe extern "C" fn widget_button_release_event<T: ObjectSubclass>(
Expand All @@ -317,7 +337,7 @@ where
let wrap: Widget = from_glib_borrow(ptr);
let evwrap: gdk::EventButton = from_glib_borrow(btnptr);

imp.button_release_event(&wrap, &evwrap).0 as glib_sys::gboolean
imp.button_release_event(&wrap, &evwrap).to_glib()
}

// unsafe extern "C" fn widget_can_activate_accel<T: ObjectSubclass>(
Expand All @@ -332,3 +352,18 @@ where

// imp.can_activate_accel(&wrap, signal_id) as glib_sys::gboolean
// }

unsafe extern "C" fn widget_draw<T: ObjectSubclass>(
ptr: *mut gtk_sys::GtkWidget,
cr_ptr: *mut cairo_sys::cairo_t,
) -> glib_sys::gboolean
where
T: WidgetImpl,
{
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Widget = from_glib_borrow(ptr);
let cr: cairo::Context = from_glib_borrow(cr_ptr);

imp.draw(&wrap, &cr).to_glib()
}

0 comments on commit 65251bd

Please sign in to comment.