-
-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Examples: Dialog's response signal handling (#1514)
* example of a dialog's response signal handling * Apply suggestions Remove comment and one-time use statements Co-authored-by: Bilal Elmoussaoui <[email protected]> * Remove one-time use statement * Remove useless part of ObjectImpl implement statement. * Add gtk::Dialog in ui xml file. Remove old instance from code. Allow deprecated use of gtk::Dialog. * Apply suggestions group import, remove unused comment and blank lines. Co-authored-by: Bilal Elmoussaoui <[email protected]> * Replace redundant statements as suggested. Co-authored-by: Bilal Elmoussaoui <[email protected]> * Rename gtk::Dialog. Fix multiple identical call in match statement. * Comment details about types used in callback handler for signal response. * Rename callback handler popup_dialog in on_counter_notify * Update examples/composite_dialog/my_app_window/mod.rs Co-authored-by: jobale <[email protected]> * Update examples/composite_dialog/my_app_window/mod.rs --------- Co-authored-by: Bilal Elmoussaoui <[email protected]>
- Loading branch information
1 parent
234b1db
commit d48338f
Showing
7 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
mod my_app_window; | ||
|
||
use gtk::{glib, 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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::cell::Cell; | ||
|
||
use gtk::{glib, prelude::*, subclass::prelude::*}; | ||
|
||
#[derive(Default, gtk::CompositeTemplate, glib::Properties)] | ||
#[template(file = "window.ui")] | ||
#[properties(wrapper_type = super::MyAppWindow)] | ||
pub struct MyAppWindow { | ||
#[property(get, set)] | ||
counter: Cell<i32>, | ||
#[template_child] | ||
pub count_label: TemplateChild<gtk::Label>, | ||
#[template_child] | ||
pub plus: TemplateChild<gtk::Button>, | ||
#[template_child] | ||
pub minus: TemplateChild<gtk::Button>, | ||
#[template_child] | ||
pub dialog: TemplateChild<gtk::Dialog>, | ||
} | ||
|
||
#[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<Self>) { | ||
obj.init_template(); | ||
} | ||
} | ||
|
||
#[glib::derived_properties] | ||
impl ObjectImpl for MyAppWindow {} | ||
impl WidgetImpl for MyAppWindow {} | ||
impl WindowImpl for MyAppWindow {} | ||
impl ApplicationWindowImpl for MyAppWindow {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// 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::*}; | ||
|
||
glib::wrapper! { | ||
pub struct MyAppWindow(ObjectSubclass<imp::MyAppWindow>) | ||
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow; | ||
} | ||
|
||
#[gtk::template_callbacks] | ||
impl MyAppWindow { | ||
pub fn new<P: IsA<gtk::Application>>(app: &P) -> Self { | ||
glib::Object::builder().property("application", app).build() | ||
} | ||
|
||
/// 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 on_counter_notify(&self, _p: &glib::ParamSpec) { | ||
// Check counter property and create a Dialog. | ||
if self.counter() == 3 { | ||
self.imp().dialog.present(); | ||
} | ||
} | ||
|
||
/// 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. | ||
/// | ||
/// 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); | ||
|
||
match gtk::ResponseType::from(response) { | ||
gtk::ResponseType::Ok => self.set_counter(0), | ||
gtk::ResponseType::Other(35) => self.set_counter(6), | ||
gtk::ResponseType::DeleteEvent => (), | ||
_ => unimplemented!(), | ||
} | ||
} | ||
|
||
/// 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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?xml version='1.0' encoding='UTF-8'?> | ||
<interface> | ||
<template class="MyAppWindow" parent="GtkApplicationWindow"> | ||
<property name="default-height">300</property> | ||
<property name="default-width">400</property> | ||
<property name="hexpand">True</property> | ||
<property name="show-menubar">True</property> | ||
<property name="title">Composite Template Dialog</property> | ||
<property name="vexpand">True</property> | ||
<signal name="notify::counter" handler="on_counter_notify" swapped="true"/> | ||
<child> | ||
<object class="GtkBox"> | ||
<property name="halign">center</property> | ||
<property name="margin-top">10</property> | ||
<property name="spacing">5</property> | ||
<property name="orientation">vertical</property> | ||
<child> | ||
<object class="GtkLabel"> | ||
<property name="label">Click until you reach 3</property> | ||
<style> | ||
<class name="large-title"/> | ||
</style> | ||
</object> | ||
</child> | ||
<child> | ||
<object class="GtkBox"> | ||
<property name="halign">center</property> | ||
<property name="valign">center</property> | ||
<property name="spacing">10</property> | ||
<child> | ||
<object class="GtkButton" id="plus"> | ||
<signal name="clicked" handler="add_to_counter" swapped="true"/> | ||
<property name="label">+</property> | ||
<property name="focus-on-click">True</property> | ||
</object> | ||
</child> | ||
<child> | ||
<object class="GtkButton" id="minus"> | ||
<signal name="clicked" handler="sub_to_counter" swapped="true"/> | ||
<property name="label">-</property> | ||
<property name="focus-on-click">True</property> | ||
</object> | ||
</child> | ||
</object> | ||
</child> | ||
<child> | ||
<object class="GtkLabel" id="count_label"> | ||
<property name="label" | ||
bind-source="MyAppWindow" | ||
bind-property="counter" | ||
bind-flags="sync-create"/> | ||
<property name="justify">center</property> | ||
<property name="margin-end">5</property> | ||
<property name="margin-start">5</property> | ||
<property name="margin-top">20</property> | ||
<property name="margin-bottom">5</property> | ||
</object> | ||
</child> | ||
</object> | ||
</child> | ||
</template> | ||
<object class="GtkDialog" id="dialog"> | ||
<property name="transient-for">MyAppWindow</property> | ||
<property name="title">Counter reach 3</property> | ||
<property name="modal">True</property> | ||
<signal name="response" handler="counter_choice" swapped="true"/> | ||
<child type="action"> | ||
<object class="GtkButton" id="button_six"> | ||
<property name="visible">True</property> | ||
<property name="label">Set counter to 6</property> | ||
</object> | ||
</child> | ||
<child type="action"> | ||
<object class="GtkButton" id="button_reset"> | ||
<property name="visible">True</property> | ||
<property name="label">Reset counter</property> | ||
</object> | ||
</child> | ||
<action-widgets> | ||
<action-widget response="35">button_six</action-widget> | ||
<action-widget response="ok">button_reset</action-widget> | ||
</action-widgets> | ||
</object> | ||
</interface> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.