[libadwaita/wip/exalm/screenshots: 1/2] doc: Add a screenshot generator
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/screenshots: 1/2] doc: Add a screenshot generator
- Date: Thu, 16 Dec 2021 21:16:33 +0000 (UTC)
commit 97ab4fa38545c8670bffea237d01852376da23e2
Author: Adrien Plazas <kekun plazas laposte net>
Date: Fri Dec 17 00:33:08 2021 +0500
doc: Add a screenshot generator
doc/meson.build | 2 +
doc/tools/README.md | 7 ++
doc/tools/meson.build | 17 +++
doc/tools/screenshot.c | 211 ++++++++++++++++++++++++++++++++++++
doc/tools/screenshot.gresources.xml | 6 +
doc/tools/style.css | 0
6 files changed, 243 insertions(+)
---
diff --git a/doc/meson.build b/doc/meson.build
index b5ae25eb..46c49564 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -1,5 +1,7 @@
if get_option('gtk_doc')
+subdir('tools')
+
expand_content_md_files = [
'build-howto.md',
'migrating-between-development-versions.md',
diff --git a/doc/tools/README.md b/doc/tools/README.md
new file mode 100644
index 00000000..ea3b1f36
--- /dev/null
+++ b/doc/tools/README.md
@@ -0,0 +1,7 @@
+To regenerate doc screenshots, run:
+
+```c
+./doc/tools/screenshot ../doc/images/
+```
+
+from the build directory.
diff --git a/doc/tools/meson.build b/doc/tools/meson.build
new file mode 100644
index 00000000..b78296d6
--- /dev/null
+++ b/doc/tools/meson.build
@@ -0,0 +1,17 @@
+screenshot_resources = gnome.compile_resources(
+ 'screenshot-resources',
+ 'screenshot.gresources.xml',
+
+ c_name: 'adw',
+)
+
+screenshot_sources = [
+ screenshot_resources,
+ 'screenshot.c',
+ libadwaita_generated_headers,
+]
+
+screenshot = executable('screenshot'.format(apiversion),
+ screenshot_sources,
+ dependencies: libadwaita_dep,
+)
diff --git a/doc/tools/screenshot.c b/doc/tools/screenshot.c
new file mode 100644
index 00000000..aa00288b
--- /dev/null
+++ b/doc/tools/screenshot.c
@@ -0,0 +1,211 @@
+#include <adwaita.h>
+
+#define RESOURCE_PATH "/org/gnome/Adwaita/Screenshot/"
+
+static GMainLoop *loop;
+
+typedef struct {
+ GtkWidget *widget;
+ GdkPaintable *paintable;
+ char *name;
+ GtkCssProvider *provider;
+} ScreenshotData;
+
+static void
+screenshot_data_free (ScreenshotData *data)
+{
+ g_object_unref (data->paintable);
+ gtk_window_destroy (GTK_WINDOW (gtk_widget_get_root (data->widget)));
+ g_object_unref (data->provider);
+ g_free (data->name);
+ g_free (data);
+}
+
+static void
+draw_paintable (ScreenshotData *data)
+{
+ GtkSnapshot *snapshot;
+ GskRenderer *renderer;
+ g_autoptr (GdkTexture) texture = NULL;
+ g_autoptr (GskRenderNode) node = NULL;
+ int width, height;
+
+ g_signal_handlers_disconnect_by_func (data->paintable,
+ G_CALLBACK (draw_paintable),
+ data);
+
+ width = gtk_widget_get_allocated_width (data->widget);
+ height = gtk_widget_get_allocated_height (data->widget);
+
+ snapshot = gtk_snapshot_new ();
+ gdk_paintable_snapshot (data->paintable, snapshot, width, height);
+
+ node = gtk_snapshot_free_to_node (snapshot);
+ renderer = gtk_native_get_renderer (gtk_widget_get_native (data->widget));
+
+ texture = gsk_renderer_render_texture (renderer, node,
+ &GRAPHENE_RECT_INIT (0, 0, width, height));
+
+ gdk_texture_save_to_png (texture, data->name);
+
+ screenshot_data_free (data);
+
+ g_main_loop_quit (loop);
+}
+
+static GtkCssProvider *
+load_css (const char *name)
+{
+ GtkCssProvider *provider = gtk_css_provider_new ();
+ g_autofree char *path = g_strdup_printf (RESOURCE_PATH "%s.css", name);
+
+ gtk_css_provider_load_from_resource (provider, path);
+
+ gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ return provider;
+}
+
+static void
+take_screenshot (const char *name,
+ gboolean dark,
+ GFile *output_dir)
+{
+ g_autofree char *ui_path = NULL;
+ g_autofree char *output_name = NULL;
+ g_autoptr (GtkBuilder) builder = NULL;
+ g_autoptr (GFile) output_file = NULL;
+ GObject *object;
+ ScreenshotData *data;
+ GtkWidget *window;
+
+ ui_path = g_strdup_printf (RESOURCE_PATH "data/%s.ui", name);
+
+ if (dark)
+ output_name = g_strdup_printf ("%s-dark.png", name);
+ else
+ output_name = g_strdup_printf ("%s.png", name);
+
+ output_file = g_file_get_child (output_dir, output_name);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ if (dark)
+ adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
+ ADW_COLOR_SCHEME_FORCE_DARK);
+ else
+ adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
+ ADW_COLOR_SCHEME_FORCE_LIGHT);
+
+ builder = gtk_builder_new_from_resource (ui_path);
+ object = gtk_builder_get_object (builder, "widget");
+
+ g_assert (GTK_IS_WIDGET (object));
+
+ data = g_new (ScreenshotData, 1);
+ data->widget = GTK_WIDGET (object);
+
+ if (GTK_IS_WINDOW (object)) {
+ window = GTK_WIDGET (object);
+ } else {
+ window = gtk_window_new ();
+ gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
+ gtk_window_set_child (GTK_WINDOW (window), data->widget);
+ }
+
+ data->paintable = gtk_widget_paintable_new (data->widget);
+ data->name = g_file_get_path (output_file);
+ data->provider = load_css ("style");
+
+ g_signal_connect_swapped (data->paintable, "invalidate-contents",
+ G_CALLBACK (draw_paintable), data);
+
+ gtk_window_present (GTK_WINDOW (window));
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+}
+
+static inline char *
+get_shortname (const char *basename)
+{
+ const char *first_period = strstr (basename, ".");
+
+ if (first_period)
+ return g_strndup (basename, first_period - basename);
+
+ return g_strdup (basename);
+}
+
+static void
+init_libadwaita (void)
+{
+ adw_init ();
+
+ g_object_set (gtk_settings_get_default (),
+ "gtk-font-name", "Cantarell 11",
+ "gtk-icon-theme-name", "Adwaita",
+ "gtk-decoration-layout", ":close",
+ "gtk-hint-font-metrics", TRUE,
+ NULL);
+}
+
+static void
+run_screenshot (GFile *output_dir)
+{
+ g_autoptr (GError) error = NULL;
+ g_auto (GStrv) children = NULL;
+ int i = -1;
+
+ children =
+ g_resources_enumerate_children (RESOURCE_PATH "data",
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &error);
+ if (error) {
+ g_critical ("Couldn't enumerate children: %s", error->message);
+ return;
+ }
+
+ while (children[++i]) {
+ g_autofree char *shortname = get_shortname (children[i]);
+
+ g_print ("Processing %s\n", shortname);
+ take_screenshot (shortname, FALSE, output_dir);
+ take_screenshot (shortname, TRUE, output_dir);
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GOptionContext *context = g_option_context_new ("PATH");
+ g_autoptr (GFile) output_dir = NULL;
+ g_autoptr (GError) error = NULL;
+
+ g_option_context_parse (context, &argc, &argv, NULL);
+
+ if (argc < 2 || !argv[1]) {
+ g_printerr ("%s\n", g_option_context_get_help (context, FALSE, NULL));
+
+ return 1;
+ }
+
+ output_dir = g_file_new_for_path (argv[1]);
+
+ if (!g_file_query_exists (output_dir, NULL)) {
+ g_file_make_directory_with_parents (output_dir, NULL, &error);
+ if (G_UNLIKELY (error != NULL)) {
+ g_critical ("Failed to create output directory: %s", error->message);
+
+ return 1;
+ }
+ }
+
+ init_libadwaita ();
+ run_screenshot (output_dir);
+
+ return 0;
+}
diff --git a/doc/tools/screenshot.gresources.xml b/doc/tools/screenshot.gresources.xml
new file mode 100644
index 00000000..2df7b63a
--- /dev/null
+++ b/doc/tools/screenshot.gresources.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/Adwaita/Screenshot">
+ <file compressed="true">style.css</file>
+ </gresource>
+</gresources>
diff --git a/doc/tools/style.css b/doc/tools/style.css
new file mode 100644
index 00000000..e69de29b
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]