Skip to content

Commit

Permalink
examples: Update composite_template to use template callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
jf2048 committed Nov 22, 2021
1 parent 39c97f2 commit 17de7d8
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,125 @@
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="valign">center</property>
<property name="spacing">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<child>
<object class="GtkLabel" id="label">
<property name="label">Composite Template</property>
<style>
<class name="large-title"/>
</style>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="valign">center</property>
<property name="vexpand">1</property>
<property name="spacing">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<child>
<object class="GtkLabel" id="label">
<property name="label">Composite Template</property>
<style>
<class name="large-title"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="subtitle_label">
<property name="wrap">True</property>
<property name="justify">center</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="subtitle_label">
<property name="wrap">True</property>
<property name="justify">center</property>
<style>
<class name="dim-label"/>
</style>
<object class="GtkGrid">
<property name="halign">center</property>
<property name="vexpand">1</property>
<property name="column-spacing">6</property>
<property name="row-spacing">6</property>
<child>
<object class="GtkEntry" id="entry_a">
<property name="text">Hello</property>
<property name="placeholder-text">First</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="entry_b">
<property name="text">World</property>
<property name="placeholder-text">Second</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="concat_strs">
<constant type="gchararray">Result: </constant>
<lookup type="GtkEntry" name="text">entry_a</lookup>
<constant type="gchararray"> </constant>
<lookup type="GtkEntry" name="text">entry_b</lookup>
</closure>
</binding>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="concat_strs">
<constant type="gchararray">Lengths: </constant>
<closure type="gchararray" function="to_string">
<closure type="guint64" function="strlen">
<lookup type="GtkEntry" name="text">entry_a</lookup>
</closure>
</closure>
<constant type="gchararray"> </constant>
<closure type="gchararray" function="to_string">
<closure type="guint64" function="strlen">
<lookup type="GtkEntry" name="text">entry_b</lookup>
</closure>
</closure>
</closure>
</binding>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Reset First</property>
<signal name="clicked" handler="reset_entry" object="entry_a" swapped="true"/>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Reset Second</property>
<signal name="clicked" handler="reset_entry" object="entry_b" swapped="true"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
</object>
</child>
</object>
Expand Down
35 changes: 35 additions & 0 deletions examples/composite_template/ex_application_window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()`.
Expand All @@ -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::<u64>() {
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]
fn concat_strs(#[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(method)]
fn reset_entry(entry: gtk::Entry) {
entry.set_text("Nothing");
}
}

impl ObjectImpl for ExApplicationWindow {
fn constructed(&self, obj: &Self::Type) {
obj.init_label();
Expand Down
2 changes: 2 additions & 0 deletions examples/composite_template/ex_menu_button/ex_menu_button.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
</property>
<child>
<object class="GtkToggleButton" id="toggle">
<signal name="toggled" handler="toggle_toggled" swapped="true"/>
<property name="child">
<object class="GtkBox">
<property name="spacing">6</property>
Expand All @@ -28,6 +29,7 @@
</child>
<child>
<object class="GtkPopover" id="popover">
<signal name="closed" handler="popover_closed" swapped="true"/>
<property name="child">
<object class="GtkLabel">
<property name="label">Hello from a custom child widget!</property>
Expand Down
31 changes: 14 additions & 17 deletions examples/composite_template/ex_menu_button/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,29 @@ 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<Self>) {
obj.init_template();
}
}

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(private)]
impl ExMenuButton {
#[template_callback]
fn toggle_toggled(&self, toggle: gtk::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.
Expand Down

0 comments on commit 17de7d8

Please sign in to comment.