[gnome-builder] meson-templates: added Gtk4 C template
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] meson-templates: added Gtk4 C template
- Date: Sun, 18 Jul 2021 17:12:07 +0000 (UTC)
commit 62f49ddbc54db46ad44cc5a9f1ff06e08b202adc
Author: Günther Wagner <info gunibert de>
Date: Sun Jul 18 16:38:57 2021 +0200
meson-templates: added Gtk4 C template
Introduce the first Gtk4 C template. Reworked also the example shown. It
contains a application menu, shortcuts window, about dialog.
.../meson-templates/meson-templates.gresource.xml | 5 +
src/plugins/meson-templates/meson_templates.py | 88 ++++++++++++++++-
src/plugins/meson-templates/resources/flatpak.json | 3 +
.../meson-templates/resources/src/application.c | 107 +++++++++++++++++++++
.../meson-templates/resources/src/application.h | 16 +++
.../resources/src/hello.gresource.xml | 3 +
.../meson-templates/resources/src/help-overlay.ui | 29 ++++++
.../meson-templates/resources/src/main-gtk4.c | 40 ++++++++
.../resources/src/meson-c-vala.build | 5 +
.../meson-templates/resources/src/window-gtk4.ui | 43 +++++++++
10 files changed, 336 insertions(+), 3 deletions(-)
---
diff --git a/src/plugins/meson-templates/meson-templates.gresource.xml
b/src/plugins/meson-templates/meson-templates.gresource.xml
index 5eff3df59..dbc7d1d2a 100644
--- a/src/plugins/meson-templates/meson-templates.gresource.xml
+++ b/src/plugins/meson-templates/meson-templates.gresource.xml
@@ -2,6 +2,8 @@
<gresources>
<gresource prefix="/plugins/meson_templates">
<file compressed="true">resources/src/window.ui</file>
+ <file compressed="true">resources/src/window-gtk4.ui</file>
+ <file compressed="true">resources/src/help-overlay.ui</file>
<file compressed="true">resources/src/window.js.tmpl</file>
<file compressed="true">resources/src/meson-py.build</file>
<file compressed="true">resources/src/window.h</file>
@@ -13,11 +15,14 @@
<file compressed="true">resources/src/meson-rs.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/__init__.py</file>
<file compressed="true">resources/src/meson-c-vala.build</file>
<file compressed="true">resources/src/meson-empty.build</file>
<file compressed="true">resources/src/main.js.tmpl</file>
<file compressed="true">resources/src/main.c</file>
+ <file compressed="true">resources/src/main-gtk4.c</file>
<file compressed="true">resources/src/main-cli.c</file>
<file compressed="true">resources/src/main.cpp</file>
<file compressed="true">resources/src/main-cli.cpp</file>
diff --git a/src/plugins/meson-templates/meson_templates.py b/src/plugins/meson-templates/meson_templates.py
index 0cb974b73..b2001e429 100644
--- a/src/plugins/meson-templates/meson_templates.py
+++ b/src/plugins/meson-templates/meson_templates.py
@@ -33,7 +33,8 @@ _ = Ide.gettext
class LibraryTemplateProvider(GObject.Object, Ide.TemplateProvider):
def do_get_project_templates(self):
- return [GnomeProjectTemplate(),
+ return [GnomeGTK4ProjectTemplate(),
+ GnomeProjectTemplate(),
LibraryProjectTemplate(),
CLIProjectTemplate(),
EmptyProjectTemplate()]
@@ -143,7 +144,8 @@ class MesonTemplate(Ide.TemplateBase, Ide.ProjectTemplate):
scope.get('PreFix').assign_string(PreFix)
scope.get('prefix_').assign_string(prefix_)
scope.get('PREFIX').assign_string(PREFIX)
-
+ scope.get('spaces').assign_string(" " * len(prefix_))
+ scope.get('Spaces').assign_string(" " * len(PreFix))
enable_gnome = isinstance(self, GnomeProjectTemplate)
scope.get('project_version').assign_string('0.1.0')
@@ -246,7 +248,7 @@ class GnomeProjectTemplate(MesonTemplate):
def __init__(self):
super().__init__(
'gnome-app',
- _('GNOME Application'),
+ _('GNOME Application GTK+-3.0'),
'pattern-gnome',
_('Create a new GNOME application'),
['C', 'C++', 'C♯', 'Python', 'JavaScript', 'Vala', 'Rust'],
@@ -320,6 +322,86 @@ class GnomeProjectTemplate(MesonTemplate):
files[meson_file] = 'src/meson.build'
+class GnomeGTK4ProjectTemplate(MesonTemplate):
+ def __init__(self):
+ super().__init__(
+ 'gnome-app-gtk4',
+ _('GNOME Application GTK4'),
+ 'pattern-gnome',
+ _('Create a new GNOME GTK4 application'),
+ ['C'],
+ 0
+ )
+
+ def prepare_files(self, files):
+ # Shared files
+ files['resources/flatpak.json'] = '%(appid)s.json'
+ files['resources/data/hello.desktop.in'] = 'data/%(appid)s.desktop.in'
+ files['resources/data/hello.appdata.xml.in'] = 'data/%(appid)s.appdata.xml.in'
+ files['resources/data/hello.gschema.xml'] = 'data/%(appid)s.gschema.xml'
+ files['resources/data/meson.build'] = 'data/meson.build'
+ files['resources/data/icons/meson.build'] = 'data/icons/meson.build'
+ files['resources/data/icons/hicolor/scalable/apps/hello.svg'] =
'data/icons/hicolor/scalable/apps/%(appid)s.svg'
+ files['resources/data/icons/hicolor/symbolic/apps/hello-symbolic.svg'] =
'data/icons/hicolor/symbolic/apps/%(appid)s-symbolic.svg'
+ files['resources/build-aux/meson/postinstall.py'] = 'build-aux/meson/postinstall.py'
+ files['resources/po/LINGUAS'] = 'po/LINGUAS'
+ files['resources/po/meson.build'] = 'po/meson.build'
+ files['resources/po/POTFILES'] = 'po/POTFILES'
+ files['resources/src/help-overlay.ui'] = 'src/gtk/help-overlay.ui'
+ window_ui_name = 'src/window.ui'
+ resource_name = 'src/%(prefix)s.gresource.xml'
+ meson_file = 'resources/src/meson-c-vala.build'
+
+ if self.language == 'c':
+ files['resources/src/main-gtk4.c'] = 'src/main.c'
+ files['resources/src/window.c'] = 'src/%(prefix)s-window.c'
+ files['resources/src/window.h'] = 'src/%(prefix)s-window.h'
+ files['resources/src/application.c'] = 'src/%(prefix)s-application.c'
+ files['resources/src/application.h'] = 'src/%(prefix)s-application.h'
+ window_ui_name = 'src/%(prefix)s-window.ui'
+ elif self.language == 'c++':
+ files['resources/src/main.cpp'] = 'src/main.cpp'
+ files['resources/src/window.cpp'] = 'src/%(prefix)s-window.cpp'
+ files['resources/src/window.hpp'] = 'src/%(prefix)s-window.h'
+ window_ui_name = 'src/%(prefix)s-window.ui'
+ elif self.language == 'c♯':
+ files['resources/src/main.cs'] = 'src/main.cs'
+ files['resources/src/application.in'] = 'src/%(exec_name)s.in'
+ files['resources/flatpak-gtksharp.json.tmpl'] = '%(appid)s.json'
+ meson_file = 'resources/src/meson-cs.build'
+ resource_name = None
+ window_ui_name = None
+ elif self.language == 'vala':
+ files['resources/src/main.vala'] = 'src/main.vala'
+ files['resources/src/window.vala'] = 'src/window.vala'
+ elif self.language == 'javascript':
+ files['resources/src/main.js.tmpl'] = 'src/main.js'
+ files['resources/src/hello.js.in'] = 'src/%(appid)s.in'
+ files['resources/src/window.js.tmpl'] = 'src/window.js'
+ files['resources/src/hello.src.gresource.xml'] = 'src/%(appid)s.src.gresource.xml'
+ resource_name = 'src/%(appid)s.data.gresource.xml'
+ meson_file = 'resources/src/meson-js.build'
+ elif self.language == 'python':
+ files['resources/src/hello.py.in'] = 'src/%(name)s.in'
+ files['resources/src/__init__.py'] = 'src/__init__.py'
+ files['resources/src/window.py'] = 'src/window.py'
+ 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/Cargo.lock'] = 'Cargo.lock'
+ files['resources/src/Cargo.toml'] = 'Cargo.toml'
+ files['resources/build-aux/cargo.sh'] = 'build-aux/cargo.sh'
+ meson_file = 'resources/src/meson-rs.build'
+
+ if resource_name:
+ files['resources/src/hello.gresource.xml'] = resource_name
+ if window_ui_name:
+ files['resources/src/window-gtk4.ui'] = window_ui_name
+
+ files[meson_file] = 'src/meson.build'
class LibraryProjectTemplate(MesonTemplate):
def __init__(self):
diff --git a/src/plugins/meson-templates/resources/flatpak.json
b/src/plugins/meson-templates/resources/flatpak.json
index 9574c9e09..9eba876b4 100644
--- a/src/plugins/meson-templates/resources/flatpak.json
+++ b/src/plugins/meson-templates/resources/flatpak.json
@@ -13,6 +13,9 @@
"--share=network",
"--share=ipc",
"--socket=fallback-x11",
+{{if template == "gnome-app-gtk4"}}
+ "--device=dri",
+{{endif}}
"--socket=wayland"
],
{{if language == "rust"}}
diff --git a/src/plugins/meson-templates/resources/src/application.c
b/src/plugins/meson-templates/resources/src/application.c
new file mode 100644
index 000000000..ae844bd22
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/application.c
@@ -0,0 +1,107 @@
+{{include "license.c"}}
+
+#include "{{prefix}}-application.h"
+#include "{{prefix}}-window.h"
+
+struct _{{PreFix}}Application
+{
+ GtkApplication parent_instance;
+};
+
+G_DEFINE_TYPE ({{PreFix}}Application, {{prefix_}}_application, GTK_TYPE_APPLICATION)
+
+{{PreFix}}Application *
+{{prefix_}}_application_new (gchar *application_id,
+{{spaces}} GApplicationFlags flags)
+{
+ return g_object_new ({{PREFIX}}_TYPE_APPLICATION,
+ "application-id", application_id,
+ "flags", flags,
+ NULL);
+}
+
+static void
+{{prefix_}}_application_finalize (GObject *object)
+{
+ {{PreFix}}Application *self = ({{PreFix}}Application *)object;
+
+ G_OBJECT_CLASS ({{prefix_}}_application_parent_class)->finalize (object);
+}
+
+static void
+{{prefix_}}_application_activate (GApplication *app)
+{
+ GtkWindow *window;
+
+ /* It's good practice to check your parameters at the beginning of the
+ * function. It helps catch errors early and in development instead of
+ * by your users.
+ */
+ g_assert (GTK_IS_APPLICATION (app));
+
+ /* Get the current window or create one if necessary. */
+ window = gtk_application_get_active_window (GTK_APPLICATION (app));
+ if (window == NULL)
+ window = g_object_new ({{PREFIX}}_TYPE_WINDOW,
+ "application", app,
+ "default-width", 600,
+ "default-height", 300,
+ NULL);
+
+ /* Ask the window manager/compositor to present the window. */
+ gtk_window_present (window);
+}
+
+
+static void
+{{prefix_}}_application_class_init ({{PreFix}}ApplicationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
+
+ object_class->finalize = {{prefix_}}_application_finalize;
+
+ /*
+ * 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.
+ */
+ app_class->activate = {{prefix_}}_application_activate;
+}
+
+static void
+{{prefix_}}_application_show_about (GSimpleAction *action,
+{{spaces}} GVariant *parameter,
+{{spaces}} gpointer user_data)
+{
+ {{PreFix}}Application *self = {{PREFIX}}_APPLICATION (user_data);
+ GtkWindow *window = NULL;
+ const gchar *authors[] = {"{{author}}", NULL};
+
+ g_return_if_fail ({{PREFIX}}_IS_APPLICATION (self));
+
+ window = gtk_application_get_active_window (GTK_APPLICATION (self));
+
+ gtk_show_about_dialog (window,
+ "program-name", "{{name}}",
+ "authors", authors,
+ "version", "{{project_version}}",
+ NULL);
+}
+
+
+static void
+{{prefix_}}_application_init ({{PreFix}}Application *self)
+{
+ GSimpleAction *quit_action = g_simple_action_new ("quit", NULL);
+ g_signal_connect_swapped (quit_action, "activate", G_CALLBACK (g_application_quit), self);
+ g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (quit_action));
+
+ GSimpleAction *about_action = g_simple_action_new ("about", NULL);
+ g_signal_connect (about_action, "activate", G_CALLBACK ({{prefix_}}_application_show_about), self);
+ g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (about_action));
+
+ const char *accels[] = {"<primary>q", NULL};
+ gtk_application_set_accels_for_action (GTK_APPLICATION (self), "app.quit", accels);
+}
diff --git a/src/plugins/meson-templates/resources/src/application.h
b/src/plugins/meson-templates/resources/src/application.h
new file mode 100644
index 000000000..d4a9bada0
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/application.h
@@ -0,0 +1,16 @@
+{{include "license.h"}}
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define {{PREFIX}}_TYPE_APPLICATION ({{prefix_}}_application_get_type())
+
+G_DECLARE_FINAL_TYPE ({{PreFix}}Application, {{prefix_}}_application, {{PREFIX}}, APPLICATION,
GtkApplication)
+
+{{PreFix}}Application *{{prefix_}}_application_new (gchar *application_id,
+{{Spaces}}{{spaces}} GApplicationFlags flags);
+
+G_END_DECLS
diff --git a/src/plugins/meson-templates/resources/src/hello.gresource.xml
b/src/plugins/meson-templates/resources/src/hello.gresource.xml
index ff0db9372..bc5275809 100644
--- a/src/plugins/meson-templates/resources/src/hello.gresource.xml
+++ b/src/plugins/meson-templates/resources/src/hello.gresource.xml
@@ -2,5 +2,8 @@
<gresources>
<gresource prefix="{{appid_path}}">
<file>{{ui_file}}</file>
+{{if template == "gnome-app-gtk4"}}
+ <file>gtk/help-overlay.ui</file>
+{{end}}
</gresource>
</gresources>
diff --git a/src/plugins/meson-templates/resources/src/help-overlay.ui
b/src/plugins/meson-templates/resources/src/help-overlay.ui
new file mode 100644
index 000000000..ef12f02e8
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/help-overlay.ui
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkShortcutsWindow" id="help_overlay">
+ <property name="modal">True</property>
+ <child>
+ <object class="GtkShortcutsSection">
+ <property name="section-name">shortcuts</property>
+ <property name="max-height">10</property>
+ <child>
+ <object class="GtkShortcutsGroup">
+ <property name="title" translatable="yes" context="shortcut window">General</property>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="title" translatable="yes" context="shortcut window">Show Shortcuts</property>
+ <property name="action-name">win.show-help-overlay</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="title" translatable="yes" context="shortcut window">Quit</property>
+ <property name="action-name">app.quit</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/plugins/meson-templates/resources/src/main-gtk4.c
b/src/plugins/meson-templates/resources/src/main-gtk4.c
new file mode 100644
index 000000000..5dd33a8db
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/main-gtk4.c
@@ -0,0 +1,40 @@
+{{include "license.c"}}
+
+#include <glib/gi18n.h>
+
+#include "{{prefix}}-config.h"
+#include "{{prefix}}-application.h"
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_autoptr({{PreFix}}Application) app = NULL;
+ int ret;
+
+ /* Set up gettext translations */
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ /*
+ * 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.
+ */
+ app = {{prefix_}}_application_new ("{{appid}}", G_APPLICATION_FLAGS_NONE);
+
+ /*
+ * 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.
+ *
+ * Since GtkApplication inherits from GApplication, we use the parent class
+ * method "run". But we need to cast, which is what the "G_APPLICATION()"
+ * macro does.
+ */
+ ret = g_application_run (G_APPLICATION (app), argc, argv);
+
+ return ret;
+}
diff --git a/src/plugins/meson-templates/resources/src/meson-c-vala.build
b/src/plugins/meson-templates/resources/src/meson-c-vala.build
index baf5414d4..a9abe1061 100644
--- a/src/plugins/meson-templates/resources/src/meson-c-vala.build
+++ b/src/plugins/meson-templates/resources/src/meson-c-vala.build
@@ -2,6 +2,9 @@
{{if language == "c"}}
'main.c',
'{{prefix}}-window.c',
+ {{if template == "gnome-app-gtk4"}}
+ '{{prefix}}-application.c',
+ {{end}}
{{else if language == "c++"}}
'main.cpp',
'{{prefix}}-window.cpp',
@@ -14,6 +17,8 @@
{{name_}}_deps = [
{{if language == "c++"}}
dependency('gtkmm-3.0', version: '>= 3.18'),
+{{else if template == "gnome-app-gtk4"}}
+ dependency('gtk4'),
{{else}}
dependency('gio-2.0', version: '>= 2.50'),
dependency('gtk+-3.0', version: '>= 3.22'),
diff --git a/src/plugins/meson-templates/resources/src/window-gtk4.ui
b/src/plugins/meson-templates/resources/src/window-gtk4.ui
new file mode 100644
index 000000000..27cbb075b
--- /dev/null
+++ b/src/plugins/meson-templates/resources/src/window-gtk4.ui
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="{{PreFix}}Window" parent="GtkApplicationWindow">
+ <property name="default-width">600</property>
+ <property name="default-height">300</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar" id="header_bar">
+ <child type="end">
+ <object class="GtkMenuButton">
+ <property name="icon-name">open-menu-symbolic</property>
+ <property name="menu-model">primary_menu</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="label">Hello, World!</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ </child>
+ </template>
+
+ <menu id="primary_menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Preferences</attribute>
+ <attribute name="action">app.preferences</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
+ <attribute name="action">win.show-help-overlay</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_About GTK Rust Template</attribute>
+ <attribute name="action">app.about</attribute>
+ </item>
+ </section>
+ </menu>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]