Skip to content

Commit

Permalink
gtk4: Add convenience traits for binding template callbacks to classes
Browse files Browse the repository at this point in the history
  • Loading branch information
jf2048 committed Feb 21, 2022
1 parent cdfa2d2 commit 2f35ce3
Show file tree
Hide file tree
Showing 30 changed files with 93 additions and 42 deletions.
2 changes: 1 addition & 1 deletion book/listings/actions/5/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/actions/6/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/actions/7/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/composite_templates/1/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/composite_templates/2/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
4 changes: 2 additions & 2 deletions book/listings/composite_templates/3/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::bind_template_callbacks(klass);
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
4 changes: 2 additions & 2 deletions book/listings/composite_templates/4/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::bind_template_callbacks(klass);
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
4 changes: 2 additions & 2 deletions book/listings/composite_templates/5/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::bind_template_callbacks(klass);
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
4 changes: 2 additions & 2 deletions book/listings/composite_templates/6/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ impl ObjectSubclass for Window {
// Register `CustomButton`
CustomButton::ensure_type();

Self::bind_template(klass);
Self::bind_template_callbacks(klass);
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/css/6/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/css/7/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/css/8/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/css/9/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/1/todo_row/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ObjectSubclass for TodoRow {
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/1/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/2/todo_row/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl ObjectSubclass for TodoRow {
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/2/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/3/todo_row/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ObjectSubclass for TodoRow {
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
klass.set_css_name("todo-row");
}

Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/3/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/4/todo_row/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ObjectSubclass for TodoRow {
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/listings/todo_app/4/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl ObjectSubclass for Window {
type ParentType = gtk::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion book/src/composite_templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ This means that `handle_button_clicked` has a single parameter of type `&CustomB
{{#rustdoc_include ../listings/composite_templates/3/window/imp.rs:template_callbacks}}
```

Then we have to bind the template callbacks with [`bind_template_callbacks`](../docs/gtk4/subclass/widget/trait.CompositeTemplateCallbacks.html#method.bind_template_callbacks).
Then we have to bind the template callbacks with [`bind_template_callbacks`](../docs/gtk4/subclass/widget/trait.CompositeTemplateCallbacksClass.html#tymethod.bind_template_callbacks).

<span class="filename">Filename: listings/composite_templates/3/window/imp.rs</span>
```rust ,no_run,noplayground
Expand Down
2 changes: 1 addition & 1 deletion examples/composite_template/ex_application_window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl ObjectSubclass for ExApplicationWindow {
// The CompositeTemplate derive macro provides a convenience function
// bind_template() to set the template and bind all children at once.
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
UtilityCallbacks::bind_template_callbacks(klass);
}

Expand Down
4 changes: 2 additions & 2 deletions examples/composite_template/ex_menu_button/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ impl ObjectSubclass for ExMenuButton {
type ParentType = gtk::Widget;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::bind_template_callbacks(klass);
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_buildable/custom_buildable/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl ObjectSubclass for CustomBuildable {
type Interfaces = (gtk::Buildable,);

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();

// The layout manager determines how child widgets are laid out.
klass.set_layout_manager_type::<gtk::BinLayout>();
Expand Down
2 changes: 1 addition & 1 deletion examples/list_view_apps_launcher/application_row/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ObjectSubclass for ApplicationRow {
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down
2 changes: 1 addition & 1 deletion examples/video_player/video_player_window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl ObjectSubclass for VideoPlayerWindow {
}

fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
klass.bind_template();
klass.install_action(
"win.open",
None,
Expand Down
25 changes: 15 additions & 10 deletions gtk4-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ use syn::{parse_macro_input, DeriveInput};
/// type ParentType = gtk::Box;
///
/// fn class_init(klass: &mut Self::Class) {
/// Self::bind_template(klass);
/// klass.bind_template();
/// }
///
/// fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
Expand Down Expand Up @@ -100,12 +100,15 @@ pub fn composite_template_derive(input: TokenStream) -> TokenStream {
/// Widgets with [`CompositeTemplate`] can then make use of these callbacks from within their
/// template XML definition. The attribute must be applied to an `impl` statement of a struct.
/// Functions marked as callbacks within the `impl` will be stored in a static array. Then, in the
/// [`ObjectSubclass`] implementation you will need to call [`bind_template_callbacks`] in the
/// [`class_init`] function.
/// [`ObjectSubclass`] implementation you will need to call [`bind_template_callbacks`] and/or
/// [`bind_template_instance_callbacks`] in the [`class_init`] function.
///
/// Template callbacks can be specified on both a widget's public `impl` or on its private `impl`.
/// Template callbacks from other types can also be used. Care must be taken to call
/// `bind_template_callbacks` on each type in order to use its callbacks.
/// Template callbacks can be specified on both a widget's public wrapper `impl` or on its private
/// subclass `impl`, or from external types. If callbacks are specified on the public wrapper, then
/// `bind_template_instance_callbacks` must be called in `class_init`. If callbacks are specified
/// on the private subclass, then `bind_template_callbacks` must be called in `class_init`. To use
/// the callbacks from an external type, call [`T::bind_template_callbacks`] in `class_init`, where
/// `T` is the other type. See the example below for usage of all three.
///
/// These callbacks can be bound using the `<signal>` or `<closure>` tags in the template file.
/// Note that the arguments and return type will only be checked at run time when the method is
Expand Down Expand Up @@ -145,7 +148,9 @@ pub fn composite_template_derive(input: TokenStream) -> TokenStream {
/// [`glib::wrapper`]: ../glib/macro.wrapper.html
/// [`ObjectSubclass`]: ../glib/subclass/types/trait.ObjectSubclass.html
/// [`class_init`]: ../glib/subclass/types/trait.ObjectSubclass.html#method.class_init
/// [`bind_template_callbacks`]: ../gtk4/subclass/widget/trait.CompositeTemplateCallbacks.html#tymethod.bind_template_callbacks
/// [`bind_template_callbacks`]: ../gtk4/subclass/widget/trait.CompositeTemplateCallbacksClass.html#tymethod.bind_template_callbacks
/// [`bind_template_instance_callbacks`]: ../gtk4/subclass/widget/trait.CompositeTemplateInstanceCallbacksClass.html#tymethod.bind_template_instance_callbacks
/// [`T::bind_template_callbacks`]: ../gtk4/subclass/widget/trait.CompositeTemplateCallbacks.html#method.bind_template_callbacks
/// [`glib::FromValue`]: ../glib/value/trait.FromValue.html
/// [`glib::ToValue`]: ../glib/value/trait.ToValue.html
/// [`&glib::Value`]: ../glib/value/struct.Value.html
Expand Down Expand Up @@ -178,11 +183,11 @@ pub fn composite_template_derive(input: TokenStream) -> TokenStream {
/// type ParentType = gtk::Box;
///
/// fn class_init(klass: &mut Self::Class) {
/// Self::bind_template(klass);
/// klass.bind_template();
/// // Bind the private callbacks
/// Self::bind_template_callbacks(klass);
/// klass.bind_template_callbacks();
/// // Bind the public callbacks
/// Self::Type::bind_template_callbacks(klass);
/// klass.bind_template_instance_callbacks();
/// // Bind callbacks from another struct
/// super::Utility::bind_template_callbacks(klass);
/// }
Expand Down
3 changes: 3 additions & 0 deletions gtk4/src/subclass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ pub mod prelude {
pub use super::tree_view::{TreeViewImpl, TreeViewImplExt};
pub use super::widget::CompositeTemplate;
pub use super::widget::CompositeTemplateCallbacks;
pub use super::widget::CompositeTemplateCallbacksClass;
pub use super::widget::CompositeTemplateClass;
pub use super::widget::CompositeTemplateInstanceCallbacksClass;
pub use super::widget::TemplateChild;
pub use super::widget::WidgetClassSubclassExt;
pub use super::widget::{WidgetImpl, WidgetImplExt};
Expand Down
43 changes: 43 additions & 0 deletions gtk4/src/subclass/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1341,6 +1341,20 @@ pub trait CompositeTemplate: WidgetImpl {
fn bind_template(klass: &mut Self::Class);
}

pub trait CompositeTemplateClass {
fn bind_template(&mut self);
}

impl<T, U> CompositeTemplateClass for T
where
T: ClassStruct<Type = U>,
U: ObjectSubclass<Class = T> + CompositeTemplate,
{
fn bind_template(&mut self) {
<U as CompositeTemplate>::bind_template(self);
}
}

pub type TemplateCallback = (&'static str, fn(&[glib::Value]) -> Option<glib::Value>);

pub trait CompositeTemplateCallbacks {
Expand Down Expand Up @@ -1373,3 +1387,32 @@ pub trait CompositeTemplateCallbacks {
}
}
}

pub trait CompositeTemplateCallbacksClass {
fn bind_template_callbacks(&mut self);
}

impl<T, U> CompositeTemplateCallbacksClass for T
where
T: ClassStruct<Type = U> + WidgetClassSubclassExt,
U: ObjectSubclass<Class = T> + CompositeTemplateCallbacks,
{
fn bind_template_callbacks(&mut self) {
<U as CompositeTemplateCallbacks>::bind_template_callbacks(self);
}
}

pub trait CompositeTemplateInstanceCallbacksClass {
fn bind_template_instance_callbacks(&mut self);
}

impl<T, U, V> CompositeTemplateInstanceCallbacksClass for T
where
T: ClassStruct<Type = U> + WidgetClassSubclassExt,
U: ObjectSubclass<Class = T, Type = V>,
V: CompositeTemplateCallbacks,
{
fn bind_template_instance_callbacks(&mut self) {
<V as CompositeTemplateCallbacks>::bind_template_callbacks(self);
}
}

0 comments on commit 2f35ce3

Please sign in to comment.