From 49d109c29e86dc9839560e8c405b85c48cd84b8f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 27 Aug 2021 23:33:56 +0200 Subject: [PATCH] gtk: Add the GtkSymbolicPaintable interface --- gtk/gtk.h | 1 + gtk/gtksymbolicpaintable.c | 112 +++++++++++++++++++++++++++++++++++++ gtk/gtksymbolicpaintable.h | 70 +++++++++++++++++++++++ gtk/meson.build | 2 + 4 files changed, 185 insertions(+) create mode 100644 gtk/gtksymbolicpaintable.c create mode 100644 gtk/gtksymbolicpaintable.h diff --git a/gtk/gtk.h b/gtk/gtk.h index 4d5dc5902d..0d4521e4ac 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -248,6 +248,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtksymbolicpaintable.c b/gtk/gtksymbolicpaintable.c new file mode 100644 index 0000000000..f33d63c837 --- /dev/null +++ b/gtk/gtksymbolicpaintable.c @@ -0,0 +1,112 @@ +/* + * Copyright © 2021 Benjamin Otte + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library. If not, see . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gtksymbolicpaintable.h" + +/** + * GtkSymbolicPaintable: + * + * `GtkSymbolicPaintable` is an interface that support symbolic colors in + * paintables. + * + * `GdkPaintable`s implementing the interface will have the + * [vfunc@Gtk.SymbolicPaintable.snapshot_symbolic] function called and + * have the colors for drawing symbolic icons passed. At least 4 colors are guaranteed + * to be passed every time. + * + * These 4 colors are the foreground color, and the colors to use for errors, warnings + * and success information in that order. + * + * More colors may be added in the future. + */ + +G_DEFINE_INTERFACE (GtkSymbolicPaintable, gtk_symbolic_paintable, GDK_TYPE_PAINTABLE) + +static void +gtk_symbolic_paintable_default_snapshot_symbolic (GtkSymbolicPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height, + const GdkRGBA *colors, + gsize n_colors) +{ + gdk_paintable_snapshot (GDK_PAINTABLE (paintable), snapshot, width, height); +} + +static void +gtk_symbolic_paintable_default_init (GtkSymbolicPaintableInterface *iface) +{ + iface->snapshot_symbolic = gtk_symbolic_paintable_default_snapshot_symbolic; +} + +/** + * gtk_symbolic_paintable_snapshot_symbolic + * @paintable: a `GtkSymbolicPaintable` + * @snapshot: a `GdkSnapshot` to snapshot to + * @width: width to snapshot in + * @height: height to snapshot in + * @colors: (array length=n_colors): a pointer to an array of colors + * @n_colors: The number of colors + * + * Snapshots the paintable with the given colors. + * + * If not at least 4 colors are provided, GTK will pad the array with default + * colors. + */ +void +gtk_symbolic_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height, + const GdkRGBA *colors, + gsize n_colors) +{ + GtkSymbolicPaintableInterface *iface; + + g_return_if_fail (GTK_IS_SYMBOLIC_PAINTABLE (paintable)); + g_return_if_fail (snapshot != NULL); + g_return_if_fail (colors != NULL || n_colors == 0); + + if (width <= 0.0 || height <= 0.0) + return; + + iface = GTK_SYMBOLIC_PAINTABLE_GET_IFACE (paintable); + + if (n_colors >= 4) + { + iface->snapshot_symbolic (paintable, snapshot, width, height, colors, n_colors); + } + else + { + /* Taken from GTK3, no idea where it got those from */ + GdkRGBA fg_default = { 0.7450980392156863, 0.7450980392156863, 0.7450980392156863, 1.0 }; + GdkRGBA error_default = { 0.796887159533074, 0, 0, 1.0 }; + GdkRGBA warning_default = {0.9570458533607996, 0.47266346227206835, 0.2421911955443656, 1.0 }; + GdkRGBA success_default = { 0.3046921492332342,0.6015716792553597, 0.023437857633325704, 1.0 }; + + iface->snapshot_symbolic (paintable, snapshot, width, height, (GdkRGBA[4]) { + n_colors > 0 ? colors[0] : fg_default, + n_colors > 1 ? colors[1] : error_default, + n_colors > 2 ? colors[2] : warning_default, + success_default, + }, 4); + } +} diff --git a/gtk/gtksymbolicpaintable.h b/gtk/gtksymbolicpaintable.h new file mode 100644 index 0000000000..67d787fc46 --- /dev/null +++ b/gtk/gtksymbolicpaintable.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2021 Benjamin Otte + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library. If not, see . + * + * Authors: Benjamin Otte + */ + +#ifndef __GTK_SYMBOLIC_PAINTABLE_H__ +#define __GTK_SYMBOLIC_PAINTABLE_H__ + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SYMBOLIC_PAINTABLE (gtk_symbolic_paintable_get_type ()) + +GDK_AVAILABLE_IN_4_6 +G_DECLARE_INTERFACE (GtkSymbolicPaintable, gtk_symbolic_paintable, GTK, SYMBOLIC_PAINTABLE, GdkPaintable) + +/** + * GtkSymbolicPaintableInterface: + * @snapshot_symbolic: Snapshot the paintable using the given colors. + * See `GtkSymbolicPaintable::snapshot_symbolic()` for details. + * If this function is not implemented, [vfunc@Gdk.Paintable.snapshot] + * will be called. + * + * The list of virtual functions for the `GtkSymbolicPaintable` interface. + * No function must be implemented, default implementations exist for each one. + */ +struct _GtkSymbolicPaintableInterface +{ + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + void (* snapshot_symbolic) (GtkSymbolicPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height, + const GdkRGBA *colors, + gsize n_colors); +}; + +GDK_AVAILABLE_IN_4_6 +void gtk_symbolic_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height, + const GdkRGBA *colors, + gsize n_colors); + +G_END_DECLS + +#endif /* __GTK_SYMBOLIC_PAINTABLE_H__ */ diff --git a/gtk/meson.build b/gtk/meson.build index bfb5105fe5..a4cdfabecc 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -391,6 +391,7 @@ gtk_public_sources = files([ 'gtkstylecontext.c', 'gtkstyleprovider.c', 'gtkswitch.c', + 'gtksymbolicpaintable.c', 'gtktestatcontext.c', 'gtktestutils.c', 'gtktext.c', @@ -663,6 +664,7 @@ gtk_public_headers = files([ 'gtkstylecontext.h', 'gtkstyleprovider.h', 'gtkswitch.h', + 'gtksymbolicpaintable.h', 'gtktestatcontext.h', 'gtktestutils.h', 'gtktext.h',