From b88ac0890eaeb4294d41ba409cbd8460d575fcad Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 17 Apr 2022 11:19:07 -0400 Subject: [PATCH 1/3] gtk-builder-tool: Small reshuffle Move the display check into the preview command. --- tools/gtk-builder-tool-preview.c | 6 ++++++ tools/gtk-builder-tool.c | 14 ++------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tools/gtk-builder-tool-preview.c b/tools/gtk-builder-tool-preview.c index db345c7bca..df6e29976f 100644 --- a/tools/gtk-builder-tool-preview.c +++ b/tools/gtk-builder-tool-preview.c @@ -180,6 +180,12 @@ do_preview (int *argc, }; GError *error = NULL; + if (gdk_display_get_default () == NULL) + { + g_printerr ("Could not initialize windowing system\n"); + exit (1); + } + context = g_option_context_new (NULL); g_option_context_set_help_enabled (context, FALSE); g_option_context_add_main_entries (context, entries, NULL); diff --git a/tools/gtk-builder-tool.c b/tools/gtk-builder-tool.c index b62773738a..7de50fc283 100644 --- a/tools/gtk-builder-tool.c +++ b/tools/gtk-builder-tool.c @@ -109,13 +109,11 @@ log_writer_func (GLogLevelFlags level, int main (int argc, const char *argv[]) { - gboolean has_display; - g_set_prgname ("gtk-builder-tool"); g_log_set_writer_func (log_writer_func, NULL, NULL); - has_display = gtk_init_check (); + gtk_init_check (); gtk_test_register_all_types (); @@ -135,15 +133,7 @@ main (int argc, const char *argv[]) else if (strcmp (argv[0], "enumerate") == 0) do_enumerate (&argc, &argv); else if (strcmp (argv[0], "preview") == 0) - { - if (!has_display) - { - g_printerr ("Could not initialize windowing system\n"); - return 1; - } - - do_preview (&argc, &argv); - } + do_preview (&argc, &argv); else usage (); From c5e26dd591d558890cfa41392924078b0ac7e334 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 17 Apr 2022 11:59:06 -0400 Subject: [PATCH 2/3] gtk-builder-tool: Reshuffle --help Use GOptionContext better. --- po/POTFILES.in | 3 +++ tools/gtk-builder-tool-enumerate.c | 40 +++++++++++++++++++++++++++--- tools/gtk-builder-tool-preview.c | 12 ++++++--- tools/gtk-builder-tool-simplify.c | 24 +++++++++++------- tools/gtk-builder-tool-validate.c | 30 ++++++++++++++++++++-- tools/gtk-builder-tool.c | 17 ++++--------- 6 files changed, 96 insertions(+), 30 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 0e56e619c6..99c2034b9a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -403,6 +403,9 @@ modules/printbackends/gtkprintbackendlpr.c modules/printbackends/gtkprintercups.c tools/encodesymbolic.c tools/gtk-builder-tool.c +tools/gtk-builder-tool-enumerate.c +tools/gtk-builder-tool-preview.c tools/gtk-builder-tool-simplify.c +tools/gtk-builder-tool-validate.c tools/gtk-launch.c tools/updateiconcache.c diff --git a/tools/gtk-builder-tool-enumerate.c b/tools/gtk-builder-tool-enumerate.c index feb3758cc5..f0c6c8dc7e 100644 --- a/tools/gtk-builder-tool-enumerate.c +++ b/tools/gtk-builder-tool-enumerate.c @@ -17,6 +17,8 @@ * Author: Matthias Clasen */ +#include "config.h" + #include #include #include @@ -46,12 +48,42 @@ do_enumerate (int *argc, const char ***argv) GSList *list, *l; GObject *object; const char *name; - const char *filename; + char **filenames = NULL; + GOptionContext *context; + const GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, + { NULL, } + }; - filename = (*argv)[1]; + g_set_prgname ("gtk4-builder-tool enumerate"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("List all named objects.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + if (filenames == NULL) + { + g_printerr ("No .ui file specified\n"); + exit (1); + } + + if (g_strv_length (filenames) > 1) + { + g_printerr ("Can only enumerate a single .ui file\n"); + exit (1); + } builder = gtk_builder_new (); - ret = gtk_builder_add_from_file (builder, filename, &error); + ret = gtk_builder_add_from_file (builder, filenames[0], &error); if (ret == 0) { @@ -72,4 +104,6 @@ do_enumerate (int *argc, const char ***argv) g_slist_free (list); g_object_unref (builder); + + g_strfreev (filenames); } diff --git a/tools/gtk-builder-tool-preview.c b/tools/gtk-builder-tool-preview.c index df6e29976f..6c7473d80e 100644 --- a/tools/gtk-builder-tool-preview.c +++ b/tools/gtk-builder-tool-preview.c @@ -17,6 +17,8 @@ * Author: Matthias Clasen */ +#include "config.h" + #include #include #include @@ -173,9 +175,9 @@ do_preview (int *argc, char *css = NULL; char **filenames = NULL; const GOptionEntry entries[] = { - { "id", 0, 0, G_OPTION_ARG_STRING, &id, NULL, NULL }, - { "css", 0, 0, G_OPTION_ARG_FILENAME, &css, NULL, NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, NULL }, + { "id", 0, 0, G_OPTION_ARG_STRING, &id, N_("Preview only the named object"), N_("ID") }, + { "css", 0, 0, G_OPTION_ARG_FILENAME, &css, N_("Use style from CSS file"), N_("FILE") }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, { NULL, } }; GError *error = NULL; @@ -186,9 +188,11 @@ do_preview (int *argc, exit (1); } + g_set_prgname ("gtk4-builder-tool preview"); context = g_option_context_new (NULL); - g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Preview the file.")); if (!g_option_context_parse (context, argc, (char ***)argv, &error)) { diff --git a/tools/gtk-builder-tool-simplify.c b/tools/gtk-builder-tool-simplify.c index fb3acdde40..21dcfa2dc6 100644 --- a/tools/gtk-builder-tool-simplify.c +++ b/tools/gtk-builder-tool-simplify.c @@ -17,6 +17,8 @@ * Author: Matthias Clasen */ +#include "config.h" + #include #include #include @@ -2351,28 +2353,30 @@ do_simplify (int *argc, gboolean replace = FALSE; gboolean convert3to4 = FALSE; char **filenames = NULL; - GOptionContext *ctx; + GOptionContext *context; const GOptionEntry entries[] = { - { "replace", 0, 0, G_OPTION_ARG_NONE, &replace, NULL, NULL }, - { "3to4", 0, 0, G_OPTION_ARG_NONE, &convert3to4, NULL, NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, NULL }, + { "replace", 0, 0, G_OPTION_ARG_NONE, &replace, N_("Replace the file"), NULL }, + { "3to4", 0, 0, G_OPTION_ARG_NONE, &convert3to4, N_("Convert from GTK 3 to GTK 4"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, { NULL, } }; GError *error = NULL; int i; - ctx = g_option_context_new (NULL); - g_option_context_set_help_enabled (ctx, FALSE); - g_option_context_add_main_entries (ctx, entries, NULL); + g_set_prgname ("gtk4-builder-tool simplify"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Simplify the file.")); - if (!g_option_context_parse (ctx, argc, (char ***)argv, &error)) + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) { g_printerr ("%s\n", error->message); g_error_free (error); exit (1); } - g_option_context_free (ctx); + g_option_context_free (context); if (filenames == NULL) { @@ -2391,4 +2395,6 @@ do_simplify (int *argc, if (!simplify_file (filenames[i], replace, convert3to4)) exit (1); } + + g_strfreev (filenames); } diff --git a/tools/gtk-builder-tool-validate.c b/tools/gtk-builder-tool-validate.c index 8551231730..aa4069fd36 100644 --- a/tools/gtk-builder-tool-validate.c +++ b/tools/gtk-builder-tool-validate.c @@ -17,6 +17,8 @@ * Author: Matthias Clasen */ +#include "config.h" + #include #include #include @@ -150,11 +152,35 @@ validate_file (const char *filename) void do_validate (int *argc, const char ***argv) { + GError *error = NULL; + char **filenames = NULL; + GOptionContext *context; + const GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, + { NULL, } + }; int i; - for (i = 1; i < *argc; i++) + g_set_prgname ("gtk4-builder-tool validate"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Validate the file.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) { - if (!validate_file ((*argv)[i])) + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + for (i = 0; filenames[i]; i++) + { + if (!validate_file (filenames[i])) exit (1); } + + g_strfreev (filenames); } diff --git a/tools/gtk-builder-tool.c b/tools/gtk-builder-tool.c index 7de50fc283..ff47e81bd3 100644 --- a/tools/gtk-builder-tool.c +++ b/tools/gtk-builder-tool.c @@ -34,21 +34,14 @@ usage (void) g_print (_("Usage:\n" " gtk-builder-tool [COMMAND] [OPTION…] FILE\n" "\n" + "Perform various tasks on GtkBuilder .ui files.\n" + "\n" "Commands:\n" " validate Validate the file\n" " simplify Simplify the file\n" " enumerate List all named objects\n" " preview Preview the file\n" - "\n" - "Simplify Options:\n" - " --replace Replace the file\n" - " --3to4 Convert from GTK 3 to GTK 4\n" - "\n" - "Preview Options:\n" - " --id=ID Preview only the named object\n" - " --css=FILE Use style from CSS file\n" - "\n" - "Perform various tasks on GtkBuilder .ui files.\n")); + "\n")); exit (1); } @@ -117,10 +110,10 @@ main (int argc, const char *argv[]) gtk_test_register_all_types (); - if (argc < 3) + if (argc < 2) usage (); - if (strcmp (argv[2], "--help") == 0) + if (strcmp (argv[1], "--help") == 0) usage (); argv++; From 499687a11d67352b787ef61764d19b900fd4c3a3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 17 Apr 2022 00:26:25 -0400 Subject: [PATCH 3/3] gtk-builder-tool: Add a screenshot command This is an obvious variation of the preview command. It can save a .ui file as either .png or .node. --- docs/reference/gtk/gtk4-builder-tool.rst | 30 +- po/POTFILES.in | 1 + tools/gtk-builder-tool-screenshot.c | 362 +++++++++++++++++++++++ tools/gtk-builder-tool.c | 5 + tools/gtk-builder-tool.h | 9 +- tools/meson.build | 1 + 6 files changed, 403 insertions(+), 5 deletions(-) create mode 100644 tools/gtk-builder-tool-screenshot.c diff --git a/docs/reference/gtk/gtk4-builder-tool.rst b/docs/reference/gtk/gtk4-builder-tool.rst index 80998a9d96..9e011a330f 100644 --- a/docs/reference/gtk/gtk4-builder-tool.rst +++ b/docs/reference/gtk/gtk4-builder-tool.rst @@ -16,6 +16,7 @@ SYNOPSIS | **gtk4-builder-tool** enumerate | **gtk4-builder-tool** simplify [OPTIONS...] | **gtk4-builder-tool** preview [OPTIONS...] +| **gtk4-builder-tool** screenshot [OPTIONS...] DESCRIPTION ----------- @@ -41,7 +42,7 @@ definition file. Preview ^^^^^^^ -The ``preview`` command displays the UI dfinition file. +The ``preview`` command displays the UI definition file. This command accepts options to specify the ID of the toplevel object and a CSS file to use. @@ -55,6 +56,33 @@ file to use. Load style information from the given CSS file. +Screenshot +^^^^^^^^^^ + +The ``screenshot`` command saves a rendering of the UI definition file +as a png image or node file. The name of the file to write can be specified as +a second FILE argument. + +This command accepts options to specify the ID of the toplevel object and a CSS +file to use. + +``--id=ID`` + + The ID of the object to preview. If not specified, gtk4-builder-tool will + choose a suitable object on its own. + +``--css=FILE`` + + Load style information from the given CSS file. + +``--node`` + + Write a serialized node file instead of a png image. + +``--force`` + + Overwrite an existing file. + Simplification ^^^^^^^^^^^^^^ diff --git a/po/POTFILES.in b/po/POTFILES.in index 99c2034b9a..0f408e8b7c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -405,6 +405,7 @@ tools/encodesymbolic.c tools/gtk-builder-tool.c tools/gtk-builder-tool-enumerate.c tools/gtk-builder-tool-preview.c +tools/gtk-builder-tool-screenshot.c tools/gtk-builder-tool-simplify.c tools/gtk-builder-tool-validate.c tools/gtk-launch.c diff --git a/tools/gtk-builder-tool-screenshot.c b/tools/gtk-builder-tool-screenshot.c new file mode 100644 index 0000000000..81bf22bd9a --- /dev/null +++ b/tools/gtk-builder-tool-screenshot.c @@ -0,0 +1,362 @@ +/* Copyright 2015 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtkbuilderprivate.h" +#include "gtk-builder-tool.h" + +static gboolean +quit_when_idle (gpointer loop) +{ + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static GMainLoop *loop; + +static void +draw_paintable (GdkPaintable *paintable, + gpointer out_texture) +{ + GtkSnapshot *snapshot; + GskRenderNode *node; + GdkTexture *texture; + GskRenderer *renderer; + + snapshot = gtk_snapshot_new (); + gdk_paintable_snapshot (paintable, + snapshot, + gdk_paintable_get_intrinsic_width (paintable), + gdk_paintable_get_intrinsic_height (paintable)); + node = gtk_snapshot_free_to_node (snapshot); + + /* If the window literally draws nothing, we assume it hasn't been mapped yet and as such + * the invalidations were only side effects of resizes. + */ + if (node == NULL) + return; + + renderer = gtk_native_get_renderer ( + gtk_widget_get_native ( + gtk_widget_paintable_get_widget (GTK_WIDGET_PAINTABLE (paintable)))); + texture = gsk_renderer_render_texture (renderer, + node, + &GRAPHENE_RECT_INIT ( + 0, 0, + gdk_paintable_get_intrinsic_width (paintable), + gdk_paintable_get_intrinsic_height (paintable) + )); + g_object_set_data_full (G_OBJECT (texture), + "source-render-node", + node, + (GDestroyNotify) gsk_render_node_unref); + + g_signal_handlers_disconnect_by_func (paintable, draw_paintable, out_texture); + + *(GdkTexture **) out_texture = texture; + + g_idle_add (quit_when_idle, loop); +} + +static GdkTexture * +snapshot_widget (GtkWidget *widget) +{ + GdkPaintable *paintable; + GdkTexture *texture = NULL; + + g_assert_true (gtk_widget_get_realized (widget)); + + loop = g_main_loop_new (NULL, FALSE); + + /* We wait until the widget is drawn for the first time. + * + * We also use an inhibit mechanism, to give module functions a chance + * to delay the snapshot. + */ + paintable = gtk_widget_paintable_new (widget); + g_signal_connect (paintable, "invalidate-contents", G_CALLBACK (draw_paintable), &texture); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (paintable); + gtk_window_destroy (GTK_WINDOW (widget)); + + return texture; +} + +static void +set_window_title (GtkWindow *window, + const char *filename, + const char *id) +{ + char *name; + char *title; + + name = g_path_get_basename (filename); + + if (id) + title = g_strdup_printf ("%s in %s", id, name); + else + title = g_strdup (name); + + gtk_window_set_title (window, title); + + g_free (title); + g_free (name); +} + +static char * +get_save_filename (const char *filename, + gboolean as_node) +{ + int length = strlen (filename); + const char *extension = as_node ? ".node" : ".png"; + char *result; + + if (strcmp (filename + (length - 3), ".ui") == 0) + { + char *basename = g_strndup (filename, length - 3); + result = g_strconcat (basename, extension, NULL); + g_free (basename); + } + else + result = g_strconcat (filename, extension, NULL); + + return result; +} + +static void +screenshot_file (const char *filename, + const char *id, + const char *cssfile, + const char *save_file, + gboolean as_node, + gboolean force) +{ + GtkBuilder *builder; + GError *error = NULL; + GObject *object; + GtkWidget *window; + GdkTexture *texture; + char *save_to; + GBytes *bytes; + + if (cssfile) + { + GtkCssProvider *provider; + + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_path (provider, cssfile); + + gtk_style_context_add_provider_for_display (gdk_display_get_default (), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + + builder = gtk_builder_new (); + if (!gtk_builder_add_from_file (builder, filename, &error)) + { + g_printerr ("%s\n", error->message); + exit (1); + } + + object = NULL; + + if (id) + { + object = gtk_builder_get_object (builder, id); + } + else + { + GSList *objects, *l; + + objects = gtk_builder_get_objects (builder); + for (l = objects; l; l = l->next) + { + GObject *obj = l->data; + + if (GTK_IS_WINDOW (obj)) + { + object = obj; + break; + } + else if (GTK_IS_WIDGET (obj)) + { + if (object == NULL) + object = obj; + } + } + g_slist_free (objects); + } + + if (object == NULL) + { + if (id) + g_printerr ("No object with ID '%s' found\n", id); + else + g_printerr ("No object found\n"); + exit (1); + } + + if (!GTK_IS_WIDGET (object)) + { + g_printerr ("Objects of type %s can't be screenshot\n", G_OBJECT_TYPE_NAME (object)); + exit (1); + } + + if (GTK_IS_WINDOW (object)) + window = GTK_WIDGET (object); + else + { + GtkWidget *widget = GTK_WIDGET (object); + + window = gtk_window_new (); + + if (GTK_IS_BUILDABLE (object)) + id = gtk_buildable_get_buildable_id (GTK_BUILDABLE (object)); + + set_window_title (GTK_WINDOW (window), filename, id); + + g_object_ref (widget); + if (gtk_widget_get_parent (widget) != NULL) + gtk_box_remove (GTK_BOX (gtk_widget_get_parent (widget)), widget); + gtk_window_set_child (GTK_WINDOW (window), widget); + g_object_unref (widget); + } + + gtk_widget_show (window); + + texture = snapshot_widget (window); + + g_object_unref (builder); + + save_to = (char *)save_file; + + if (save_to == NULL) + save_to = get_save_filename (filename, as_node); + + if (g_file_test (save_to, G_FILE_TEST_EXISTS) && !force) + { + g_printerr ("File %s exists.\n" + "Use --force to overwrite.\n", save_to); + exit (1); + } + + if (as_node) + { + GskRenderNode *node; + + node = (GskRenderNode *) g_object_get_data (G_OBJECT (texture), "source-render-node"); + bytes = gsk_render_node_serialize (node); + } + else + { + bytes = gdk_texture_save_to_png_bytes (texture); + } + + if (g_file_set_contents (save_to, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + &error)) + { + g_print ("Output written to %s.\n", save_to); + } + else + { + g_printerr ("Failed to save %s: %s\n", save_to, error->message); + exit (1); + } + + g_bytes_unref (bytes); + + if (save_to != save_file) + g_free (save_to); + + g_object_unref (texture); +} + +void +do_screenshot (int *argc, + const char ***argv) +{ + GOptionContext *context; + char *id = NULL; + char *css = NULL; + char **filenames = NULL; + gboolean as_node = FALSE; + gboolean force = FALSE; + const GOptionEntry entries[] = { + { "id", 0, 0, G_OPTION_ARG_STRING, &id, N_("Screenshot only the named object"), N_("ID") }, + { "css", 0, 0, G_OPTION_ARG_FILENAME, &css, N_("Use style from CSS file"), N_("FILE") }, + { "node", 0, 0, G_OPTION_ARG_NONE, &as_node, N_("Save as node file instead of png"), NULL }, + { "force", 0, 0, G_OPTION_ARG_NONE, &force, N_("Overwrite existing file"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, + { NULL, } + }; + GError *error = NULL; + + if (gdk_display_get_default () == NULL) + { + g_printerr ("Could not initialize windowing system\n"); + exit (1); + } + + g_set_prgname ("gtk4-builder-tool screenshot"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Take a screenshot of the file.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + if (filenames == NULL) + { + g_printerr ("No .ui file specified\n"); + exit (1); + } + + if (g_strv_length (filenames) > 2) + { + g_printerr ("Can only screenshot a single .ui file and a single output file\n"); + exit (1); + } + + screenshot_file (filenames[0], id, css, filenames[1], as_node, force); + + g_strfreev (filenames); + g_free (id); + g_free (css); +} diff --git a/tools/gtk-builder-tool.c b/tools/gtk-builder-tool.c index ff47e81bd3..278d3fb4db 100644 --- a/tools/gtk-builder-tool.c +++ b/tools/gtk-builder-tool.c @@ -17,6 +17,8 @@ * Author: Matthias Clasen */ +#include "config.h" + #include #include #include @@ -41,6 +43,7 @@ usage (void) " simplify Simplify the file\n" " enumerate List all named objects\n" " preview Preview the file\n" + " screenshot Take a screenshot of the file\n" "\n")); exit (1); } @@ -127,6 +130,8 @@ main (int argc, const char *argv[]) do_enumerate (&argc, &argv); else if (strcmp (argv[0], "preview") == 0) do_preview (&argc, &argv); + else if (strcmp (argv[0], "screenshot") == 0) + do_screenshot (&argc, &argv); else usage (); diff --git a/tools/gtk-builder-tool.h b/tools/gtk-builder-tool.h index 3d895d83bb..0f2575f5a5 100644 --- a/tools/gtk-builder-tool.h +++ b/tools/gtk-builder-tool.h @@ -2,9 +2,10 @@ #ifndef __GTK_BUILDER_TOOL_H__ #define __GTK_BUILDER_TOOL_H__ -void do_simplify (int *argc, const char ***argv); -void do_validate (int *argc, const char ***argv); -void do_enumerate (int *argc, const char ***argv); -void do_preview (int *argc, const char ***argv); +void do_simplify (int *argc, const char ***argv); +void do_validate (int *argc, const char ***argv); +void do_enumerate (int *argc, const char ***argv); +void do_preview (int *argc, const char ***argv); +void do_screenshot (int *argc, const char ***argv); #endif diff --git a/tools/meson.build b/tools/meson.build index 1811b6969e..52afd5433d 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -28,6 +28,7 @@ gtk_tools = [ 'gtk-builder-tool-simplify.c', 'gtk-builder-tool-validate.c', 'gtk-builder-tool-enumerate.c', + 'gtk-builder-tool-screenshot.c', 'gtk-builder-tool-preview.c'], [libgtk_dep] ], ['gtk4-update-icon-cache', ['updateiconcache.c'] + extra_update_icon_cache_objs, [ libgtk_static_dep ] ], ['gtk4-encode-symbolic-svg', ['encodesymbolic.c'], [ libgtk_static_dep ] ],