[gnome-builder/gnome-builder-41] meson-templates: Add GTK4 Rust template
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-41] meson-templates: Add GTK4 Rust template
- Date: Tue, 16 Nov 2021 19:00:39 +0000 (UTC)
commit b2bd0ade91a98b051425c0b171c1e3439ad30a2f
Author: Marco Melorio <marco melorio protonmail com>
Date: Thu Oct 28 20:25:26 2021 +0200
meson-templates: Add GTK4 Rust template
This is based on the current GTK4 C template.
.../meson-templates/meson-templates.gresource.xml | 6 ++
src/plugins/meson-templates/meson_templates.py | 13 +--
.../meson-templates/resources/src/Cargo-gtk4.toml | 8 ++
.../meson-templates/resources/src/application.rs | 92 ++++++++++++++++++++++
.../resources/src/config-gtk4.rs.in | 4 +
.../meson-templates/resources/src/main-gtk4.rs | 35 ++++++++
.../resources/src/meson-rs-gtk4.build | 57 ++++++++++++++
.../meson-templates/resources/src/window-gtk4.rs | 50 ++++++++++++
8 files changed, 259 insertions(+), 6 deletions(-)
---
diff --git a/src/plugins/meson-templates/meson-templates.gresource.xml
b/src/plugins/meson-templates/meson-templates.gresource.xml
index 3f96c5871..57620d8ca 100644
--- a/src/plugins/meson-templates/meson-templates.gresource.xml
+++ b/src/plugins/meson-templates/meson-templates.gresource.xml
@@ -13,10 +13,12 @@
<file compressed="true">resources/src/meson-clib.build</file>
<file compressed="true">resources/src/meson-js.build</file>
<file compressed="true">resources/src/meson-rs.build</file>
+ <file compressed="true">resources/src/meson-rs-gtk4.build</file>
<file compressed="true">resources/src/hello.c</file>
<file compressed="true">resources/src/hello.h</file>
<file compressed="true">resources/src/application.c</file>
<file compressed="true">resources/src/application.h</file>
+ <file compressed="true">resources/src/application.rs</file>
<file compressed="true">resources/src/__init__.py</file>
<file compressed="true">resources/src/meson-c-vala.build</file>
<file compressed="true">resources/src/meson-empty.build</file>
@@ -33,17 +35,21 @@
<file compressed="true">resources/src/window.py</file>
<file compressed="true">resources/src/window.vala</file>
<file compressed="true">resources/src/config.rs.in</file>
+ <file compressed="true">resources/src/config-gtk4.rs.in</file>
<file compressed="true">resources/src/window.rs</file>
+ <file compressed="true">resources/src/window-gtk4.rs</file>
<file compressed="true">resources/src/main.vala</file>
<file compressed="true">resources/src/main-cli.vala</file>
<file compressed="true">resources/src/hello.py.in</file>
<file compressed="true">resources/src/main.py</file>
<file compressed="true">resources/src/main.rs</file>
+ <file compressed="true">resources/src/main-gtk4.rs</file>
<file compressed="true">resources/src/main-cli.rs</file>
<file compressed="true">resources/src/application.in</file>
<file compressed="true">resources/src/main.cs</file>
<file compressed="true">resources/src/Cargo.lock</file>
<file compressed="true">resources/src/Cargo.toml</file>
+ <file compressed="true">resources/src/Cargo-gtk4.toml</file>
<file compressed="true">resources/src/Cargo-cli.toml</file>
<file compressed="true">resources/src/meson-cs.build</file>
<file compressed="true">resources/build-aux/cargo.sh</file>
diff --git a/src/plugins/meson-templates/meson_templates.py b/src/plugins/meson-templates/meson_templates.py
index f4be02cb3..4f465b244 100644
--- a/src/plugins/meson-templates/meson_templates.py
+++ b/src/plugins/meson-templates/meson_templates.py
@@ -330,7 +330,7 @@ class GnomeGTK4ProjectTemplate(MesonTemplate):
_('GNOME Application'),
'pattern-gnome',
_('Create a GNOME application with GTK 4'),
- ['C'],
+ ['C', 'Rust'],
0
)
@@ -389,13 +389,14 @@ class GnomeGTK4ProjectTemplate(MesonTemplate):
files['resources/src/main.py'] = 'src/main.py'
meson_file = 'resources/src/meson-py.build'
elif self.language == 'rust':
- files['resources/src/config.rs.in'] = 'src/config.rs.in'
- files['resources/src/main.rs'] = 'src/main.rs'
- files['resources/src/window.rs'] = 'src/window.rs'
+ files['resources/src/application.rs'] = 'src/application.rs'
+ files['resources/src/config-gtk4.rs.in'] = 'src/config.rs.in'
+ files['resources/src/main-gtk4.rs'] = 'src/main.rs'
+ files['resources/src/window-gtk4.rs'] = 'src/window.rs'
files['resources/src/Cargo.lock'] = 'Cargo.lock'
- files['resources/src/Cargo.toml'] = 'Cargo.toml'
+ files['resources/src/Cargo-gtk4.toml'] = 'Cargo.toml'
files['resources/build-aux/cargo.sh'] = 'build-aux/cargo.sh'
- meson_file = 'resources/src/meson-rs.build'
+ meson_file = 'resources/src/meson-rs-gtk4.build'
if resource_name:
files['resources/src/hello.gresource.xml'] = resource_name
diff --git a/src/plugins/meson-templates/resources/src/Cargo-gtk4.toml
b/src/plugins/meson-templates/resources/src/Cargo-gtk4.toml
new file mode 100644
index 000000000..c8c9ce406
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/Cargo-gtk4.toml
@@ -0,0 +1,8 @@
+[package]
+name = "{{name}}"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+gettext-rs = { version = "0.7", features = ["gettext-system"] }
+gtk = { version = "0.3", package = "gtk4" }
diff --git a/src/plugins/meson-templates/resources/src/application.rs
b/src/plugins/meson-templates/resources/src/application.rs
new file mode 100644
index 000000000..1f13b37f6
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/application.rs
@@ -0,0 +1,92 @@
+use glib::clone;
+use gtk::prelude::*;
+use gtk::subclass::prelude::*;
+use gtk::{gio, glib};
+
+use crate::config::VERSION;
+use crate::{{PreFix}}Window;
+
+mod imp {
+ use super::*;
+
+ #[derive(Debug, Default)]
+ pub struct {{PreFix}}Application {}
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for {{PreFix}}Application {
+ const NAME: &'static str = "{{PreFix}}Application";
+ type Type = super::{{PreFix}}Application;
+ type ParentType = gtk::Application;
+ }
+
+ impl ObjectImpl for {{PreFix}}Application {
+ fn constructed(&self, obj: &Self::Type) {
+ self.parent_constructed(obj);
+
+ obj.setup_gactions();
+ obj.set_accels_for_action("app.quit", &["<primary>q"]);
+ }
+ }
+
+ impl ApplicationImpl for {{PreFix}}Application {
+ // We connect to the activate callback to create a window when the application
+ // has been launched. Additionally, this callback notifies us when the user
+ // tries to launch a "second instance" of the application. When they try
+ // to do that, we'll just present any existing window.
+ fn activate(&self, application: &Self::Type) {
+ // Get the current window or create one if necessary
+ let window = if let Some(window) = application.active_window() {
+ window
+ } else {
+ let window = {{PreFix}}Window::new(application);
+ window.set_default_size(600, 300);
+ window.upcast()
+ };
+
+ // Ask the window manager/compositor to present the window
+ window.present();
+ }
+ }
+
+ impl GtkApplicationImpl for {{PreFix}}Application {}
+}
+
+glib::wrapper! {
+ pub struct {{PreFix}}Application(ObjectSubclass<imp::{{PreFix}}Application>)
+ @extends gio::Application, gtk::Application,
+ @implements gio::ActionGroup, gio::ActionMap;
+}
+
+impl {{PreFix}}Application {
+ pub fn new(application_id: &str, flags: &gio::ApplicationFlags) -> Self {
+ glib::Object::new(&[("application-id", &application_id), ("flags", flags)])
+ .expect("Failed to create {{PreFix}}Application")
+ }
+
+ fn setup_gactions(&self) {
+ let quit_action = gio::SimpleAction::new("quit", None);
+ quit_action.connect_activate(clone!(@weak self as app => move |_, _| {
+ app.quit();
+ }));
+ self.add_action(&quit_action);
+
+ let about_action = gio::SimpleAction::new("about", None);
+ about_action.connect_activate(clone!(@weak self as app => move |_, _| {
+ app.show_about();
+ }));
+ self.add_action(&about_action);
+ }
+
+ fn show_about(&self) {
+ let window = self.active_window().unwrap();
+ let dialog = gtk::AboutDialogBuilder::new()
+ .transient_for(&window)
+ .modal(true)
+ .program_name("{{name}}")
+ .version(VERSION)
+ .authors(vec!["{{author}}".into()])
+ .build();
+
+ dialog.present();
+ }
+}
diff --git a/src/plugins/meson-templates/resources/src/config-gtk4.rs.in
b/src/plugins/meson-templates/resources/src/config-gtk4.rs.in
new file mode 100644
index 000000000..1a24858ed
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/config-gtk4.rs.in
@@ -0,0 +1,4 @@
+pub static VERSION: &str = @VERSION@;
+pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@;
+pub static LOCALEDIR: &str = @LOCALEDIR@;
+pub static PKGDATADIR: &str = @PKGDATADIR@;
diff --git a/src/plugins/meson-templates/resources/src/main-gtk4.rs
b/src/plugins/meson-templates/resources/src/main-gtk4.rs
new file mode 100644
index 000000000..abafbd171
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/main-gtk4.rs
@@ -0,0 +1,35 @@
+mod application;
+mod config;
+mod window;
+
+use self::application::{{PreFix}}Application;
+use self::window::{{PreFix}}Window;
+
+use config::{GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR};
+use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain};
+use gtk::gio;
+use gtk::prelude::*;
+
+fn main() {
+ // Set up gettext translations
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain");
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8")
+ .expect("Unable to set the text domain encoding");
+ textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain");
+
+ // Load resources
+ let resources = gio::Resource::load(PKGDATADIR.to_owned() + "/{{name}}.gresource")
+ .expect("Could not load resources");
+ gio::resources_register(&resources);
+
+ // Create a new GtkApplication. The application manages our main loop,
+ // application windows, integration with the window manager/compositor, and
+ // desktop features such as file opening and single-instance applications.
+ let app = {{PreFix}}Application::new("{{appid}}", &gio::ApplicationFlags::empty());
+
+ // Run the application. This function will block until the application
+ // exits. Upon return, we have our exit code to return to the shell. (This
+ // is the code you see when you do `echo $?` after running a command in a
+ // terminal.
+ std::process::exit(app.run());
+}
diff --git a/src/plugins/meson-templates/resources/src/meson-rs-gtk4.build
b/src/plugins/meson-templates/resources/src/meson-rs-gtk4.build
new file mode 100644
index 000000000..c3e937bb0
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/meson-rs-gtk4.build
@@ -0,0 +1,57 @@
+pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
+gnome = import('gnome')
+
+gnome.compile_resources('{{name}}',
+ '{{prefix}}.gresource.xml',
+ gresource_bundle: true,
+ install: true,
+ install_dir: pkgdatadir,
+)
+
+conf = configuration_data()
+conf.set_quoted('VERSION', meson.project_version())
+conf.set_quoted('GETTEXT_PACKAGE', '{{name}}')
+conf.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir')))
+conf.set_quoted('PKGDATADIR', pkgdatadir)
+
+configure_file(
+ input: 'config.rs.in',
+ output: 'config.rs',
+ configuration: conf
+)
+
+# Copy the config.rs output to the source directory.
+run_command(
+ 'cp',
+ join_paths(meson.build_root(), 'src', 'config.rs'),
+ join_paths(meson.source_root(), 'src', 'config.rs'),
+ check: true
+)
+
+rust_sources = files(
+ 'application.rs',
+ 'config.rs',
+ 'main.rs',
+ 'window.rs',
+)
+
+sources = [cargo_sources, rust_sources]
+
+cargo_script = find_program(join_paths(meson.source_root(), 'build-aux/cargo.sh'))
+cargo_release = custom_target(
+ 'cargo-build',
+ build_by_default: true,
+ input: sources,
+ output: meson.project_name(),
+ console: true,
+ install: true,
+ install_dir: get_option('bindir'),
+ command: [
+ cargo_script,
+ meson.build_root(),
+ meson.source_root(),
+ '@OUTPUT@',
+ get_option('buildtype'),
+ meson.project_name(),
+ ]
+)
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.rs
b/src/plugins/meson-templates/resources/src/window-gtk4.rs
new file mode 100644
index 000000000..0ef2d37c2
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.rs
@@ -0,0 +1,50 @@
+use gtk::prelude::*;
+use gtk::subclass::prelude::*;
+use gtk::{gio, glib, CompositeTemplate};
+
+mod imp {
+ use super::*;
+
+ #[derive(Debug, Default, CompositeTemplate)]
+ #[template(resource = "{{appid_path}}/{{ui_file}}")]
+ pub struct {{PreFix}}Window {
+ // Template widgets
+ #[template_child]
+ pub header_bar: TemplateChild<gtk::HeaderBar>,
+ #[template_child]
+ pub label: TemplateChild<gtk::Label>,
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for {{PreFix}}Window {
+ const NAME: &'static str = "{{PreFix}}Window";
+ type Type = super::{{PreFix}}Window;
+ type ParentType = gtk::ApplicationWindow;
+
+ fn class_init(klass: &mut Self::Class) {
+ Self::bind_template(klass);
+ }
+
+ fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
+ obj.init_template();
+ }
+ }
+
+ impl ObjectImpl for {{PreFix}}Window {}
+ impl WidgetImpl for {{PreFix}}Window {}
+ impl WindowImpl for {{PreFix}}Window {}
+ impl ApplicationWindowImpl for {{PreFix}}Window {}
+}
+
+glib::wrapper! {
+ pub struct {{PreFix}}Window(ObjectSubclass<imp::{{PreFix}}Window>)
+ @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow,
+ @implements gio::ActionGroup, gio::ActionMap;
+}
+
+impl {{PreFix}}Window {
+ pub fn new<P: glib::IsA<gtk::Application>>(application: &P) -> Self {
+ glib::Object::new(&[("application", application)])
+ .expect("Failed to create {{PreFix}}Window")
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]