From 22507c066ceee5488aa60ffd22bd544ce910406e Mon Sep 17 00:00:00 2001 From: Jason Francis Date: Mon, 8 Nov 2021 21:34:56 -0600 Subject: [PATCH] examples: Update composite_template to use template callbacks --- .../ex_application_window.ui | 132 +++++++++++++++--- .../ex_application_window/imp.rs | 35 +++++ .../ex_menu_button/ex_menu_button.ui | 2 + .../composite_template/ex_menu_button/imp.rs | 31 ++-- 4 files changed, 166 insertions(+), 34 deletions(-) diff --git a/examples/composite_template/ex_application_window/ex_application_window.ui b/examples/composite_template/ex_application_window/ex_application_window.ui index 262a7c55f6f7..4fefd32f36e0 100644 --- a/examples/composite_template/ex_application_window/ex_application_window.ui +++ b/examples/composite_template/ex_application_window/ex_application_window.ui @@ -17,27 +17,125 @@ vertical - center - 6 - 12 - 12 - 12 - 12 - - Composite Template - + + vertical + center + 1 + 6 + 12 + 12 + 12 + 12 + + + Composite Template + + + + + + True + center + + + - - True - center - + + center + 1 + 6 + 6 + + + Hello + First + + 0 + 0 + + + + + + World + Second + + 1 + 0 + + + + + + start + + + Result: + entry_a + + entry_b + + + + 0 + 1 + 2 + + + + + + start + + + Lengths: + + + entry_a + + + + + + entry_b + + + + + + 0 + 2 + 2 + + + + + + Reset First + + + 0 + 3 + + + + + + Reset Second + + + 1 + 3 + + + diff --git a/examples/composite_template/ex_application_window/imp.rs b/examples/composite_template/ex_application_window/imp.rs index ad8dfb711d53..b515e08a4e82 100644 --- a/examples/composite_template/ex_application_window/imp.rs +++ b/examples/composite_template/ex_application_window/imp.rs @@ -33,6 +33,7 @@ impl ObjectSubclass for ExApplicationWindow { // bind_template() to set the template and bind all children at once. fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); + UtilityCallbacks::bind_template_callbacks(klass); } // You must call `Widget`'s `init_template()` within `instance_init()`. @@ -41,6 +42,40 @@ impl ObjectSubclass for ExApplicationWindow { } } +struct UtilityCallbacks {} + +#[gtk::template_callbacks(functions)] +impl UtilityCallbacks { + #[template_callback] + fn to_string(value: &glib::Value) -> String { + if let Ok(value) = value.get::() { + value.to_string() + } else if let Ok(value) = value.get::<&str>() { + value.to_owned() + } else { + "".into() + } + } + #[template_callback] + fn strlen(s: &str) -> u64 { + s.len() as u64 + } + #[template_callback(name = "concat_strs")] + fn concat(#[rest] values: &[glib::Value]) -> String { + let mut res = String::new(); + for (index, value) in values.iter().enumerate() { + res.push_str(value.get::<&str>().unwrap_or_else(|e| { + panic!("Expected string value for argument {}: {}", index, e); + })); + } + res + } + #[template_callback(function = false, name = "reset_entry")] + fn reset(entry: >k::Entry) { + entry.set_text("Nothing"); + } +} + impl ObjectImpl for ExApplicationWindow { fn constructed(&self, obj: &Self::Type) { obj.init_label(); diff --git a/examples/composite_template/ex_menu_button/ex_menu_button.ui b/examples/composite_template/ex_menu_button/ex_menu_button.ui index b38458ed3fb1..a8d9048c1ba7 100644 --- a/examples/composite_template/ex_menu_button/ex_menu_button.ui +++ b/examples/composite_template/ex_menu_button/ex_menu_button.ui @@ -6,6 +6,7 @@ + 6 @@ -28,6 +29,7 @@ + Hello from a custom child widget! diff --git a/examples/composite_template/ex_menu_button/imp.rs b/examples/composite_template/ex_menu_button/imp.rs index f85b6c4e3bc0..c38db3bf7562 100644 --- a/examples/composite_template/ex_menu_button/imp.rs +++ b/examples/composite_template/ex_menu_button/imp.rs @@ -19,6 +19,7 @@ impl ObjectSubclass for ExMenuButton { fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); + Self::bind_template_callbacks(klass); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -26,25 +27,21 @@ impl ObjectSubclass for ExMenuButton { } } -impl ObjectImpl for ExMenuButton { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); - - let popover = &*self.popover; - self.toggle - .connect_toggled(glib::clone!(@weak popover => move |toggle| { - if toggle.is_active() { - popover.popup(); - } - })); - - let toggle = &*self.toggle; - self.popover - .connect_closed(glib::clone!(@weak toggle => move |_| { - toggle.set_active(false); - })); +#[gtk::template_callbacks(subclass)] +impl ExMenuButton { + #[template_callback] + fn toggle_toggled(&self, toggle: >k::ToggleButton) { + if toggle.is_active() { + self.popover.popup(); + } } + #[template_callback(name = "popover_closed")] + fn unset_toggle(&self) { + self.toggle.set_active(false); + } +} +impl ObjectImpl for ExMenuButton { // Needed for direct subclasses of GtkWidget; // Here you need to unparent all direct children // of your template.