diff --git a/Cargo.toml b/Cargo.toml index 63b011d5c8..7049169742 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ purge-lgpl-docs = ["gtk-rs-lgpl-docs", "gdk/purge-lgpl-docs"] embed-lgpl-docs = ["gtk-rs-lgpl-docs", "gdk/embed-lgpl-docs"] dox = ["gdk/dox", "gtk-sys/dox"] futures = ["futures-preview", "fragile", "gio/futures"] +subclassing = ["glib/subclassing", "gio/subclassing"] [target.'cfg(target_os = "macos")'.build-dependencies] cc = "^1.0" diff --git a/Gir.toml b/Gir.toml index e0d5bfefeb..4398570a45 100644 --- a/Gir.toml +++ b/Gir.toml @@ -426,6 +426,7 @@ status = "generate" name = "Gtk.Application" status = "generate" trait_name = "GtkApplicationExt" +subclassing = true manual_traits = ["gio::ApplicationExtManual"] [[object.function]] name = "new" diff --git a/src/lib.rs b/src/lib.rs index 6aee94ae5d..ebc293a0a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -272,6 +272,10 @@ mod tree_store; mod widget; mod window; +#[macro_use] +#[cfg(feature = "subclassing")] +pub mod subclass; + pub mod prelude; pub use auto::*; diff --git a/src/subclass/application.rs b/src/subclass/application.rs new file mode 100644 index 0000000000..a1eaa863f6 --- /dev/null +++ b/src/subclass/application.rs @@ -0,0 +1,81 @@ +use gtk_sys; + +use glib::translate::*; + +use glib::subclass::prelude::*; + +use Application; +use ApplicationClass; +use Window; + +pub trait ApplicationImpl: ApplicationImplExt + gio::subclass::prelude::ApplicationImpl + 'static { + fn window_added(&self, application: &Application, window: &Window) { + self.parent_window_added(application, window) + } + + fn window_removed(&self, application: &Application, window: &Window) { + self.parent_window_removed(application, window) + } +} + +pub trait ApplicationImplExt { + fn parent_window_added(&self, application: &Application, window: &Window); + fn parent_window_removed(&self, application: &Application, window: &Window); +} + +impl ApplicationImplExt for T { + fn parent_window_added(&self, application: &Application, window: &Window) { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut gtk_sys::GtkApplicationClass; + let f = (*parent_class) + .window_added + .expect("No parent class implementation for \"window_added\""); + f(application.to_glib_none().0, window.to_glib_none().0) + } + } + + fn parent_window_removed(&self, application: &Application, window: &Window) { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut gtk_sys::GtkApplicationClass; + let f = (*parent_class) + .window_removed + .expect("No parent class implementation for \"window_added\""); + f(application.to_glib_none().0, window.to_glib_none().0) + } + } +} + +unsafe impl IsSubclassable for ApplicationClass { + fn override_vfuncs(&mut self) { + >::override_vfuncs(self); + unsafe { + let klass = &mut *(self as *mut Self as *mut gtk_sys::GtkApplicationClass); + klass.window_added = Some(application_window_added::); + klass.window_removed = Some(application_window_removed::); + } + } +} + +unsafe extern "C" fn application_window_added(ptr: *mut gtk_sys::GtkApplication, wptr: *mut gtk_sys::GtkWindow) +where + T: ApplicationImpl, +{ + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Application = from_glib_borrow(ptr); + + imp.window_added(&wrap, &from_glib_borrow(wptr)) +} + +unsafe extern "C" fn application_window_removed(ptr: *mut gtk_sys::GtkApplication, wptr: *mut gtk_sys::GtkWindow) +where + T: ApplicationImpl, +{ + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Application = from_glib_borrow(ptr); + + imp.window_removed(&wrap, &from_glib_borrow(wptr)) +} diff --git a/src/subclass/mod.rs b/src/subclass/mod.rs new file mode 100644 index 0000000000..ffe689aeae --- /dev/null +++ b/src/subclass/mod.rs @@ -0,0 +1,5 @@ +// Copyright 2019, The Gtk-rs Project Developers. +// See the COPYRIGHT file at the top-level directory of this distribution. +// Licensed under the MIT license, see the LICENSE file or + +pub mod application;