From f12dfd3fa15c33b9c2cad442e223e49aa1fc1b52 Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 13:21:37 +0200 Subject: [PATCH 01/12] example of a dialog's response signal handling --- examples/Cargo.toml | 5 +- examples/composite_dialog/README.md | 6 ++ examples/composite_dialog/main.rs | 17 ++++ .../composite_dialog/my_app_window/imp.rs | 55 ++++++++++++ .../composite_dialog/my_app_window/mod.rs | 80 ++++++++++++++++++ .../composite_dialog/my_app_window/window.ui | 62 ++++++++++++++ examples/composite_dialog/screenshot.png | Bin 0 -> 12807 bytes 7 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 examples/composite_dialog/README.md create mode 100644 examples/composite_dialog/main.rs create mode 100644 examples/composite_dialog/my_app_window/imp.rs create mode 100644 examples/composite_dialog/my_app_window/mod.rs create mode 100755 examples/composite_dialog/my_app_window/window.ui create mode 100644 examples/composite_dialog/screenshot.png diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 99a7e256f0af..9d0b1f509afd 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -57,6 +57,10 @@ path = "column_view_datagrid/main.rs" name = "composite_template" path = "composite_template/main.rs" +[[bin]] +name = "composite_dialog" +path = "composite_dialog/main.rs" + [[bin]] name = "confetti_snapshot_animation" path = "confetti_snapshot_animation/main.rs" @@ -187,4 +191,3 @@ path = "video_player/main.rs" [[bin]] name = "virtual_methods" path = "virtual_methods/main.rs" - diff --git a/examples/composite_dialog/README.md b/examples/composite_dialog/README.md new file mode 100644 index 000000000000..52f5b92e4f92 --- /dev/null +++ b/examples/composite_dialog/README.md @@ -0,0 +1,6 @@ +# Composite Template Dialog + +This example shows the use of callbacks, custom and bind property, notify and response signal in a composite +template situation. + +![Screenshot](screenshot.png) \ No newline at end of file diff --git a/examples/composite_dialog/main.rs b/examples/composite_dialog/main.rs new file mode 100644 index 000000000000..edd661c64977 --- /dev/null +++ b/examples/composite_dialog/main.rs @@ -0,0 +1,17 @@ +mod my_app_window; + +use gtk::glib; +use gtk::prelude::*; +use my_app_window::MyAppWindow; + +fn main() -> glib::ExitCode { + let application = gtk::Application::builder() + .application_id("com.github.gtk-rs.examples.composite_dialog") + .build(); + + application.connect_activate(|app| { + let win = MyAppWindow::new(app); + win.present(); + }); + application.run() +} diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs new file mode 100644 index 000000000000..725f78438ecf --- /dev/null +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -0,0 +1,55 @@ +use std::cell::Cell; + +use gtk::{ + glib::{self, Properties}, + prelude::*, + subclass::prelude::*, + CompositeTemplate, +}; + +// Object holding the state +#[derive(Default, CompositeTemplate, Properties)] +#[template(file = "window.ui")] +#[properties(wrapper_type = super::MyAppWindow)] +pub struct MyAppWindow { + #[property(get, set)] + counter: Cell, + #[template_child] + pub count_label: TemplateChild, + #[template_child] + pub plus: TemplateChild, + #[template_child] + pub minus: TemplateChild, +} + +// The central trait for subclassing a GObject +#[glib::object_subclass] +impl ObjectSubclass for MyAppWindow { + const NAME: &'static str = "MyAppWindow"; + type Type = super::MyAppWindow; + type ParentType = gtk::ApplicationWindow; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + klass.bind_template_instance_callbacks(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } +} + +// Trait shared by all GObjects +#[glib::derived_properties] +impl ObjectImpl for MyAppWindow { + fn constructed(&self) { + self.parent_constructed(); + + // Bind property to a label + // self.obj().bind_counter_to_count(); + } +} + +impl WidgetImpl for MyAppWindow {} +impl WindowImpl for MyAppWindow {} +impl ApplicationWindowImpl for MyAppWindow {} diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs new file mode 100644 index 000000000000..d7ecb0969bad --- /dev/null +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -0,0 +1,80 @@ +mod imp; + +use gtk::{ + glib::{self, ParamSpec}, + prelude::*, + ResponseType, +}; + +glib::wrapper! { + pub struct MyAppWindow(ObjectSubclass) + @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow; +} + +#[gtk::template_callbacks] +impl MyAppWindow { + pub fn new>(app: &P) -> Self { + glib::Object::builder().property("application", app).build() + } + + /// Callback handler for notify::label signal. + /// + /// When counter property reach 3, a dialog pops up and present the user + /// with 2 choices: Set the counter to 6 or reset the counter to 0. + #[allow(deprecated)] + #[template_callback] + fn popup_dialog(&self, _p: &ParamSpec) { + // Check counter property and create a Dialog. + if self.counter() == 3 { + let dial = gtk::Dialog::with_buttons( + Some("Counter value is 3"), + Some(self), + gtk::DialogFlags::MODAL, + &[ + ("Set counter to 6", ResponseType::Other(35)), + ("Reset counter", ResponseType::Ok), + ], + ); + dial.set_transient_for(Some(self)); + + let app = self.clone(); + + // Closure handling response signal from gtk::Dialog. + // The signature of the function differ from the documentation for response signal. + // gtk-rs use an i32 instead of a [`gtk::ResponseType`] as a response signal. + dial.connect_closure( + "response", + false, + glib::closure_local!(move |d: >k::Dialog, response: i32| { + match ResponseType::from(response) { + ResponseType::Other(35) => { + app.set_counter(6); + d.close(); + } + ResponseType::Ok => { + app.set_counter(0); + d.close(); + } + _ => (), + } + }), + ); + + dial.present(); + } + } + + /// Callback handler for gtk::Button plus. + #[template_callback] + fn add_to_counter(&self, _button: >k::Button) { + let n = self.counter() + 1; + self.set_counter(n); + } + + /// Callback handler for gtk::Button minus. + #[template_callback] + fn sub_to_counter(&self, _button: >k::Button) { + let n = self.counter() - 1; + self.set_counter(n); + } +} diff --git a/examples/composite_dialog/my_app_window/window.ui b/examples/composite_dialog/my_app_window/window.ui new file mode 100755 index 000000000000..357f284b903f --- /dev/null +++ b/examples/composite_dialog/my_app_window/window.ui @@ -0,0 +1,62 @@ + + + + diff --git a/examples/composite_dialog/screenshot.png b/examples/composite_dialog/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b2671ff8cbc614353b75305111991ad041b31bee GIT binary patch literal 12807 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 xxjcGMr8I_17y&nA9Kx&e;o*P(`hI*q+PdDbStX Date: Mon, 16 Oct 2023 16:59:36 +0200 Subject: [PATCH 02/12] Apply suggestions Remove comment and one-time use statements Co-authored-by: Bilal Elmoussaoui --- examples/composite_dialog/my_app_window/imp.rs | 3 +-- examples/composite_dialog/my_app_window/mod.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index 725f78438ecf..ea63ae13fcd9 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -8,7 +8,7 @@ use gtk::{ }; // Object holding the state -#[derive(Default, CompositeTemplate, Properties)] +#[derive(Default, gtk::CompositeTemplate, glib::Properties)] #[template(file = "window.ui")] #[properties(wrapper_type = super::MyAppWindow)] pub struct MyAppWindow { @@ -39,7 +39,6 @@ impl ObjectSubclass for MyAppWindow { } } -// Trait shared by all GObjects #[glib::derived_properties] impl ObjectImpl for MyAppWindow { fn constructed(&self) { diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index d7ecb0969bad..dbec04198960 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -13,7 +13,7 @@ glib::wrapper! { #[gtk::template_callbacks] impl MyAppWindow { - pub fn new>(app: &P) -> Self { + pub fn new>(app: &P) -> Self { glib::Object::builder().property("application", app).build() } From f01dc9dc489b8962831e7e1b6a4dd36451ced3b5 Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 17:04:24 +0200 Subject: [PATCH 03/12] Remove one-time use statement --- examples/composite_dialog/my_app_window/imp.rs | 7 +------ examples/composite_dialog/my_app_window/mod.rs | 8 ++------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index ea63ae13fcd9..6bedd92563fc 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -1,11 +1,6 @@ use std::cell::Cell; -use gtk::{ - glib::{self, Properties}, - prelude::*, - subclass::prelude::*, - CompositeTemplate, -}; +use gtk::{glib, prelude::*, subclass::prelude::*}; // Object holding the state #[derive(Default, gtk::CompositeTemplate, glib::Properties)] diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index dbec04198960..271a982ab50c 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -1,10 +1,6 @@ mod imp; -use gtk::{ - glib::{self, ParamSpec}, - prelude::*, - ResponseType, -}; +use gtk::{glib, prelude::*, subclass::prelude::ObjectSubclassIsExt}; glib::wrapper! { pub struct MyAppWindow(ObjectSubclass) @@ -23,7 +19,7 @@ impl MyAppWindow { /// with 2 choices: Set the counter to 6 or reset the counter to 0. #[allow(deprecated)] #[template_callback] - fn popup_dialog(&self, _p: &ParamSpec) { + fn popup_dialog(&self, _p: &glib::ParamSpec) { // Check counter property and create a Dialog. if self.counter() == 3 { let dial = gtk::Dialog::with_buttons( From b8ac363509c3f8843187b73d40a3cbb900b89b7d Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 17:08:28 +0200 Subject: [PATCH 04/12] Remove useless part of ObjectImpl implement statement. --- examples/composite_dialog/my_app_window/imp.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index 6bedd92563fc..3e85c04c00f4 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -35,14 +35,7 @@ impl ObjectSubclass for MyAppWindow { } #[glib::derived_properties] -impl ObjectImpl for MyAppWindow { - fn constructed(&self) { - self.parent_constructed(); - - // Bind property to a label - // self.obj().bind_counter_to_count(); - } -} +impl ObjectImpl for MyAppWindow {} impl WidgetImpl for MyAppWindow {} impl WindowImpl for MyAppWindow {} From 899721bac6fac068a00a1158398aac9c029659da Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 17:27:19 +0200 Subject: [PATCH 05/12] Add gtk::Dialog in ui xml file. Remove old instance from code. Allow deprecated use of gtk::Dialog. --- .../composite_dialog/my_app_window/imp.rs | 3 +- .../composite_dialog/my_app_window/mod.rs | 58 ++++++++----------- .../composite_dialog/my_app_window/window.ui | 22 +++++++ 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index 3e85c04c00f4..036ded7632f0 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -15,9 +15,10 @@ pub struct MyAppWindow { pub plus: TemplateChild, #[template_child] pub minus: TemplateChild, + #[template_child] + pub popup: TemplateChild, } -// The central trait for subclassing a GObject #[glib::object_subclass] impl ObjectSubclass for MyAppWindow { const NAME: &'static str = "MyAppWindow"; diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index 271a982ab50c..cb6d3deb052a 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -1,3 +1,5 @@ +// Since Gtk4 v4.10 gtk4::Dialog is deprecated and gtk4-rs's examples minimum version is v4.10 +#[allow(deprecated)] mod imp; use gtk::{glib, prelude::*, subclass::prelude::ObjectSubclassIsExt}; @@ -17,46 +19,32 @@ impl MyAppWindow { /// /// When counter property reach 3, a dialog pops up and present the user /// with 2 choices: Set the counter to 6 or reset the counter to 0. - #[allow(deprecated)] #[template_callback] fn popup_dialog(&self, _p: &glib::ParamSpec) { // Check counter property and create a Dialog. if self.counter() == 3 { - let dial = gtk::Dialog::with_buttons( - Some("Counter value is 3"), - Some(self), - gtk::DialogFlags::MODAL, - &[ - ("Set counter to 6", ResponseType::Other(35)), - ("Reset counter", ResponseType::Ok), - ], - ); - dial.set_transient_for(Some(self)); - - let app = self.clone(); - - // Closure handling response signal from gtk::Dialog. - // The signature of the function differ from the documentation for response signal. - // gtk-rs use an i32 instead of a [`gtk::ResponseType`] as a response signal. - dial.connect_closure( - "response", - false, - glib::closure_local!(move |d: >k::Dialog, response: i32| { - match ResponseType::from(response) { - ResponseType::Other(35) => { - app.set_counter(6); - d.close(); - } - ResponseType::Ok => { - app.set_counter(0); - d.close(); - } - _ => (), - } - }), - ); + self.imp().popup.present(); + } + } - dial.present(); + /// Handler for popup dialog's response. + /// + /// In the callback handler, response type is i32 instead of gtk::ResponseType. + #[template_callback] + fn counter_choice(&self, response: i32) { + match gtk::ResponseType::from(response) { + gtk::ResponseType::Ok => { + self.set_counter(0); + self.imp().popup.set_visible(false); + } + gtk::ResponseType::Other(35) => { + self.set_counter(6); + self.imp().popup.set_visible(false); + } + gtk::ResponseType::DeleteEvent => { + self.imp().popup.set_visible(false); + } + _ => unimplemented!(), } } diff --git a/examples/composite_dialog/my_app_window/window.ui b/examples/composite_dialog/my_app_window/window.ui index 357f284b903f..432dac5450c3 100755 --- a/examples/composite_dialog/my_app_window/window.ui +++ b/examples/composite_dialog/my_app_window/window.ui @@ -59,4 +59,26 @@ + + MyAppWindow + Counter reach 3 + True + + + + True + Set counter to 6 + + + + + True + Reset counter + + + + button_six + button_reset + + From e9841d3fa519974eab2458695a29f560043bd022 Mon Sep 17 00:00:00 2001 From: jobale Date: Mon, 16 Oct 2023 18:02:44 +0200 Subject: [PATCH 06/12] Apply suggestions group import, remove unused comment and blank lines. Co-authored-by: Bilal Elmoussaoui --- examples/composite_dialog/main.rs | 3 +-- examples/composite_dialog/my_app_window/imp.rs | 2 -- examples/composite_dialog/my_app_window/mod.rs | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/composite_dialog/main.rs b/examples/composite_dialog/main.rs index edd661c64977..7fcd319ed4f3 100644 --- a/examples/composite_dialog/main.rs +++ b/examples/composite_dialog/main.rs @@ -1,7 +1,6 @@ mod my_app_window; -use gtk::glib; -use gtk::prelude::*; +use gtk::{glib, prelude::*}; use my_app_window::MyAppWindow; fn main() -> glib::ExitCode { diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index 036ded7632f0..5b3ac0e14206 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -2,7 +2,6 @@ use std::cell::Cell; use gtk::{glib, prelude::*, subclass::prelude::*}; -// Object holding the state #[derive(Default, gtk::CompositeTemplate, glib::Properties)] #[template(file = "window.ui")] #[properties(wrapper_type = super::MyAppWindow)] @@ -37,7 +36,6 @@ impl ObjectSubclass for MyAppWindow { #[glib::derived_properties] impl ObjectImpl for MyAppWindow {} - impl WidgetImpl for MyAppWindow {} impl WindowImpl for MyAppWindow {} impl ApplicationWindowImpl for MyAppWindow {} diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index cb6d3deb052a..25b0b50c8d57 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -2,7 +2,7 @@ #[allow(deprecated)] mod imp; -use gtk::{glib, prelude::*, subclass::prelude::ObjectSubclassIsExt}; +use gtk::{glib, prelude::*, subclass::prelude::*}; glib::wrapper! { pub struct MyAppWindow(ObjectSubclass) From 5b0603f624756327d7f1734af0a60777e9b7a030 Mon Sep 17 00:00:00 2001 From: jobale Date: Mon, 16 Oct 2023 18:19:29 +0200 Subject: [PATCH 07/12] Replace redundant statements as suggested. Co-authored-by: Bilal Elmoussaoui --- examples/composite_dialog/my_app_window/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index 25b0b50c8d57..af3d17108df8 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -32,17 +32,15 @@ impl MyAppWindow { /// In the callback handler, response type is i32 instead of gtk::ResponseType. #[template_callback] fn counter_choice(&self, response: i32) { + self.imp().popup.set_visible(false); match gtk::ResponseType::from(response) { gtk::ResponseType::Ok => { self.set_counter(0); - self.imp().popup.set_visible(false); } gtk::ResponseType::Other(35) => { self.set_counter(6); - self.imp().popup.set_visible(false); } gtk::ResponseType::DeleteEvent => { - self.imp().popup.set_visible(false); } _ => unimplemented!(), } From e04f60b864482cb663d1bac1314d03b8658d0413 Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 19:08:30 +0200 Subject: [PATCH 08/12] Rename gtk::Dialog. Fix multiple identical call in match statement. --- examples/composite_dialog/my_app_window/imp.rs | 2 +- examples/composite_dialog/my_app_window/mod.rs | 16 ++++++---------- .../composite_dialog/my_app_window/window.ui | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/examples/composite_dialog/my_app_window/imp.rs b/examples/composite_dialog/my_app_window/imp.rs index 5b3ac0e14206..f760dd423422 100644 --- a/examples/composite_dialog/my_app_window/imp.rs +++ b/examples/composite_dialog/my_app_window/imp.rs @@ -15,7 +15,7 @@ pub struct MyAppWindow { #[template_child] pub minus: TemplateChild, #[template_child] - pub popup: TemplateChild, + pub dialog: TemplateChild, } #[glib::object_subclass] diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index af3d17108df8..3bf98dc1dba7 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -23,7 +23,7 @@ impl MyAppWindow { fn popup_dialog(&self, _p: &glib::ParamSpec) { // Check counter property and create a Dialog. if self.counter() == 3 { - self.imp().popup.present(); + self.imp().dialog.present(); } } @@ -32,16 +32,12 @@ impl MyAppWindow { /// In the callback handler, response type is i32 instead of gtk::ResponseType. #[template_callback] fn counter_choice(&self, response: i32) { - self.imp().popup.set_visible(false); + self.imp().dialog.set_visible(false); + match gtk::ResponseType::from(response) { - gtk::ResponseType::Ok => { - self.set_counter(0); - } - gtk::ResponseType::Other(35) => { - self.set_counter(6); - } - gtk::ResponseType::DeleteEvent => { - } + gtk::ResponseType::Ok => self.set_counter(0), + gtk::ResponseType::Other(35) => self.set_counter(6), + gtk::ResponseType::DeleteEvent => (), _ => unimplemented!(), } } diff --git a/examples/composite_dialog/my_app_window/window.ui b/examples/composite_dialog/my_app_window/window.ui index 432dac5450c3..d44c1a2cb82f 100755 --- a/examples/composite_dialog/my_app_window/window.ui +++ b/examples/composite_dialog/my_app_window/window.ui @@ -59,7 +59,7 @@ - + MyAppWindow Counter reach 3 True From 01e32565526861b6fb95884e9dec017accd4de03 Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 19:13:34 +0200 Subject: [PATCH 09/12] Comment details about types used in callback handler for signal response. --- examples/composite_dialog/my_app_window/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index 3bf98dc1dba7..ec0ac497f66c 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -27,9 +27,17 @@ impl MyAppWindow { } } - /// Handler for popup dialog's response. + /// Handler for dialog's response. /// /// In the callback handler, response type is i32 instead of gtk::ResponseType. + /// As the bindings replaces the original i32 to an enum that makes more sense in + /// Rust. Although, the template callback can't be changed. + /// + /// In the callback handler if we try to use a gtk::ResponseType as response's type, a runtime error is thrown + /// when a button's dialog is clicked (a.k.a dialog emits the signal response) with the following message: + /// + /// *Wrong type for argument 1 in template callback \`counter_choice\`: + /// ValueTypeMismatchError { actual: gint, requested: GtkResponseType }* #[template_callback] fn counter_choice(&self, response: i32) { self.imp().dialog.set_visible(false); From f059cfdd9292c773b4c3743ea5291cacf1ab911c Mon Sep 17 00:00:00 2001 From: joceran Date: Mon, 16 Oct 2023 19:14:59 +0200 Subject: [PATCH 10/12] Rename callback handler popup_dialog in on_counter_notify --- examples/composite_dialog/my_app_window/mod.rs | 4 ++-- examples/composite_dialog/my_app_window/window.ui | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index ec0ac497f66c..dba2d4db56c5 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -15,12 +15,12 @@ impl MyAppWindow { glib::Object::builder().property("application", app).build() } - /// Callback handler for notify::label signal. + /// Callback handler for `notify::counter` signal. /// /// When counter property reach 3, a dialog pops up and present the user /// with 2 choices: Set the counter to 6 or reset the counter to 0. #[template_callback] - fn popup_dialog(&self, _p: &glib::ParamSpec) { + fn on_counter_notify(&self, _p: &glib::ParamSpec) { // Check counter property and create a Dialog. if self.counter() == 3 { self.imp().dialog.present(); diff --git a/examples/composite_dialog/my_app_window/window.ui b/examples/composite_dialog/my_app_window/window.ui index d44c1a2cb82f..b40046ab237c 100755 --- a/examples/composite_dialog/my_app_window/window.ui +++ b/examples/composite_dialog/my_app_window/window.ui @@ -7,7 +7,7 @@ True Composite Template Dialog True - + center From d6759b6cde44e98856625a6968b1bd825acf1203 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Sun, 28 Jan 2024 11:02:24 +0100 Subject: [PATCH 11/12] Update examples/composite_dialog/my_app_window/mod.rs Co-authored-by: jobale --- examples/composite_dialog/my_app_window/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index dba2d4db56c5..4f60b1f0d653 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -33,11 +33,14 @@ impl MyAppWindow { /// As the bindings replaces the original i32 to an enum that makes more sense in /// Rust. Although, the template callback can't be changed. /// - /// In the callback handler if we try to use a gtk::ResponseType as response's type, a runtime error is thrown - /// when a button's dialog is clicked (a.k.a dialog emits the signal response) with the following message: - /// - /// *Wrong type for argument 1 in template callback \`counter_choice\`: - /// ValueTypeMismatchError { actual: gint, requested: GtkResponseType }* +/// To illustrate this, we can replace `i32` with `gtk::ResponseType` in this handler's signature +/// and compile. +/// However, at runtime, a crash would occur when the dialog emits a signal response (when clicking +/// a dialog's button): This handler signature ask for a `gtk::ResponseType` but receive a `i32`. +/// The error message details this discrepancy: +/// +/// *Wrong type for argument 1 in template callback \`counter_choice\`: +/// ValueTypeMismatchError { actual: gint, requested: GtkResponseType }* #[template_callback] fn counter_choice(&self, response: i32) { self.imp().dialog.set_visible(false); From 8c146c26d5d99966f2261a1751a8e604c38eb722 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Sun, 28 Jan 2024 11:02:24 +0100 Subject: [PATCH 12/12] Update examples/composite_dialog/my_app_window/mod.rs --- examples/composite_dialog/my_app_window/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/composite_dialog/my_app_window/mod.rs b/examples/composite_dialog/my_app_window/mod.rs index dba2d4db56c5..36c2dce3dc6c 100644 --- a/examples/composite_dialog/my_app_window/mod.rs +++ b/examples/composite_dialog/my_app_window/mod.rs @@ -33,8 +33,11 @@ impl MyAppWindow { /// As the bindings replaces the original i32 to an enum that makes more sense in /// Rust. Although, the template callback can't be changed. /// - /// In the callback handler if we try to use a gtk::ResponseType as response's type, a runtime error is thrown - /// when a button's dialog is clicked (a.k.a dialog emits the signal response) with the following message: + /// To illustrate this, we can replace `i32` with `gtk::ResponseType` in this handler's signature + /// and compile. + /// However, at runtime, a crash would occur when the dialog emits a signal response (when clicking + /// a dialog's button): This handler signature ask for a `gtk::ResponseType` but receive a `i32`. + /// The error message details this discrepancy: /// /// *Wrong type for argument 1 in template callback \`counter_choice\`: /// ValueTypeMismatchError { actual: gint, requested: GtkResponseType }*