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

subclass: Add support for subclassing GtkDialog #880

Merged
merged 2 commits into from Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/subclass/dialog.rs
@@ -0,0 +1,84 @@
use gtk_sys;

use glib::translate::*;

use glib::subclass::prelude::*;

use super::window::WindowImpl;
use Dialog;
use DialogClass;
use ResponseType;

pub trait DialogImpl: DialogImplExt + WindowImpl + 'static {
fn response(&self, dialog: &Dialog, response: ResponseType) {
self.parent_response(dialog, response)
}

fn close(&self, dialog: &Dialog) {
self.parent_close(dialog)
}
}

pub trait DialogImplExt {
fn parent_response(&self, dialog: &Dialog, response: ResponseType);
fn parent_close(&self, dialog: &Dialog);
}

impl<T: DialogImpl + ObjectImpl> DialogImplExt for T {
fn parent_response(&self, dialog: &Dialog, response: ResponseType) {
unsafe {
let data = self.get_type_data();
let parent_class = data.as_ref().get_parent_class() as *mut gtk_sys::GtkDialogClass;
let f = (*parent_class)
.response
.expect("No parent class impl for \"response\"");
f(dialog.to_glib_none().0, response.to_glib())
}
}

fn parent_close(&self, dialog: &Dialog) {
unsafe {
let data = self.get_type_data();
let parent_class = data.as_ref().get_parent_class() as *mut gtk_sys::GtkDialogClass;
let f = (*parent_class)
.close
.expect("No parent class impl for \"close\"");
f(dialog.to_glib_none().0)
}
}
}

unsafe impl<T: ObjectSubclass + DialogImpl> IsSubclassable<T> for DialogClass {
fn override_vfuncs(&mut self) {
unsafe {
let klass = &mut *(self as *mut Self as *mut gtk_sys::GtkDialogClass);
klass.response = Some(dialog_response::<T>);
klass.close = Some(dialog_close::<T>);
}
}
}

unsafe extern "C" fn dialog_response<T: ObjectSubclass>(
ptr: *mut gtk_sys::GtkDialog,
responseptr: i32,
) where
T: DialogImpl,
{
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Dialog = from_glib_borrow(ptr);
let res: ResponseType = from_glib(responseptr);

imp.response(&wrap, res)
}

unsafe extern "C" fn dialog_close<T: ObjectSubclass>(ptr: *mut gtk_sys::GtkDialog)
where
T: DialogImpl,
{
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Dialog = from_glib_borrow(ptr);

imp.close(&wrap)
}
2 changes: 2 additions & 0 deletions src/subclass/mod.rs
Expand Up @@ -7,6 +7,7 @@ pub mod application_window;
pub mod bin;
pub mod box_;
pub mod container;
pub mod dialog;
pub mod event_box;
pub mod widget;
pub mod window;
Expand All @@ -17,6 +18,7 @@ pub mod prelude {
pub use super::bin::BinImpl;
pub use super::box_::BoxImpl;
pub use super::container::ContainerImpl;
pub use super::dialog::DialogImpl;
pub use super::event_box::EventBoxImpl;
pub use super::widget::WidgetImpl;
pub use super::window::WindowImpl;
Expand Down