[gimp/wip/jehan/icons: 2/3] app, libgimpwidgets: add gimp_icon_get_image() to create proper icons.
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/jehan/icons: 2/3] app, libgimpwidgets: add gimp_icon_get_image() to create proper icons.
- Date: Tue, 22 May 2018 14:39:22 +0000 (UTC)
commit 0f6a2257021d5ae0cfb4009bcf0fc32e37ae820f
Author: Jehan <jehan girinstud io>
Date: Mon May 21 04:13:40 2018 +0200
app, libgimpwidgets: add gimp_icon_get_image() to create proper icons.
Even though GTK+ has some support for symbolic icons, not all functions
taking an icon name is actually checking for symbolic variant, and if
color needs to be adapted to the background.
gtk_icon_info_load_symbolic() does adapt the symbolic icons to the
theme, but it generates a GdkPixbuf which on turn cannot sync with theme
changes and updated icon sizes. This new function should be our own
custom implementation to create icons with optional symbolic support,
background adaptation and theme/size syncing.
Using it for the toolbox, replacing code from previous commit.
app/widgets/gimptoolpalette.c | 111 ++++++++++++++++++++++++----------
libgimpwidgets/gimpicons.c | 133 +++++++++++++++++++++++++++++++++++++++++
libgimpwidgets/gimpicons.h | 10 +++-
3 files changed, 220 insertions(+), 34 deletions(-)
---
diff --git a/app/widgets/gimptoolpalette.c b/app/widgets/gimptoolpalette.c
index 508a7ef..92b0af7 100644
--- a/app/widgets/gimptoolpalette.c
+++ b/app/widgets/gimptoolpalette.c
@@ -49,6 +49,13 @@
#define TOOL_INFO_DATA_KEY "gimp-tool-info"
+enum
+{
+ PROP_0,
+ PROP_PIXEL_ICON_SIZE
+};
+
+
typedef struct _GimpToolPalettePrivate GimpToolPalettePrivate;
struct _GimpToolPalettePrivate
@@ -57,6 +64,8 @@ struct _GimpToolPalettePrivate
gint tool_rows;
gint tool_columns;
+
+ gint pixel_icon_size;
};
#define GET_PRIVATE(p) G_TYPE_INSTANCE_GET_PRIVATE (p, \
@@ -65,6 +74,14 @@ struct _GimpToolPalettePrivate
static void gimp_tool_palette_dispose (GObject *object);
+static void gimp_tool_palette_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_tool_palette_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
static GtkSizeRequestMode
gimp_tool_palette_get_request_mode (GtkWidget *widget);
@@ -110,7 +127,9 @@ gimp_tool_palette_class_init (GimpToolPaletteClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- object_class->dispose = gimp_tool_palette_dispose;
+ object_class->dispose = gimp_tool_palette_dispose;
+ object_class->get_property = gimp_tool_palette_get_property;
+ object_class->set_property = gimp_tool_palette_set_property;
widget_class->get_request_mode = gimp_tool_palette_get_request_mode;
widget_class->get_preferred_width = gimp_tool_palette_get_preferred_width;
@@ -119,6 +138,11 @@ gimp_tool_palette_class_init (GimpToolPaletteClass *klass)
widget_class->style_updated = gimp_tool_palette_style_updated;
widget_class->hierarchy_changed = gimp_tool_palette_hierarchy_changed;
+ g_object_class_install_property (object_class, PROP_PIXEL_ICON_SIZE,
+ g_param_spec_int ("pixel-icon-size", NULL, NULL,
+ 16, 200, 16,
+ GIMP_PARAM_READWRITE));
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_enum ("tool-icon-size",
NULL, NULL,
@@ -182,6 +206,46 @@ gimp_tool_palette_dispose (GObject *object)
}
static void
+gimp_tool_palette_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpToolPalettePrivate *priv = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_PIXEL_ICON_SIZE:
+ g_value_set_int (value, priv->pixel_icon_size);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_tool_palette_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpToolPalettePrivate *priv = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_PIXEL_ICON_SIZE:
+ priv->pixel_icon_size = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
gimp_tool_palette_get_preferred_height (GtkWidget *widget,
gint *min_height,
gint *pref_height)
@@ -379,45 +443,23 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
{
GimpToolInfo *tool_info = list->data;
GtkToolItem *item;
- GtkIconTheme *icon_theme;
- gchar *icon_name;
- GtkIconInfo *icon_info;
+ GtkWidget *image;
GtkIconSize icon_size;
gint icon_width;
gint icon_height;
- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (group));
- icon_name = g_strdup_printf ("%s-symbolic",
- gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)));
icon_size = gtk_tool_palette_get_icon_size (GTK_TOOL_PALETTE (palette));
gtk_icon_size_lookup (icon_size, &icon_width, &icon_height);
- icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name,
- MAX (icon_width, icon_height),
- GTK_ICON_LOOKUP_GENERIC_FALLBACK);
- g_free (icon_name);
-
item = gtk_radio_tool_button_new (item_group);
- if (icon_info)
- {
- GdkPixbuf *pixbuf;
- GtkWidget *image;
-
- pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info,
- gtk_widget_get_style_context (group),
- NULL, NULL);
- image = gtk_image_new_from_pixbuf (pixbuf);
- gtk_widget_show (image);
-
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), image);
-
- g_object_unref (icon_info);
- g_object_unref (pixbuf);
- }
+ image = gimp_icon_get_image (gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)),
+ group, MAX (icon_width, icon_height),
+ (GObject *) palette, "pixel-icon-size");
+ if (image)
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), image);
else
- {
- gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), icon_name);
- }
+ gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item),
+ gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)));
item_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
@@ -585,6 +627,8 @@ gimp_tool_palette_config_size_changed (GimpGuiConfig *config,
{
GimpIconSize size;
GtkIconSize tool_icon_size;
+ gint icon_width;
+ gint icon_height;
size = gimp_gui_config_detect_icon_size (config);
/* Match GimpIconSize with GtkIconSize for the toolbox icons. */
@@ -610,6 +654,9 @@ gimp_tool_palette_config_size_changed (GimpGuiConfig *config,
NULL);
break;
}
+ gtk_icon_size_lookup (tool_icon_size, &icon_width, &icon_height);
- gtk_tool_palette_set_icon_size (GTK_TOOL_PALETTE (palette), tool_icon_size);
+ g_object_set (palette,
+ "pixel-icon-size", MAX (icon_width, icon_height),
+ NULL);
}
diff --git a/libgimpwidgets/gimpicons.c b/libgimpwidgets/gimpicons.c
index 19e3f79..286ff67 100644
--- a/libgimpwidgets/gimpicons.c
+++ b/libgimpwidgets/gimpicons.c
@@ -180,6 +180,39 @@ gimp_icons_sanity_check (GFile *path,
return exists;
}
+static void
+gimp_prop_size_icon_notify (GObject *config,
+ GParamSpec *param_spec,
+ GtkWidget *image)
+{
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+ gchar *icon_name;
+ gint icon_size;
+
+ icon_name = g_object_get_data (G_OBJECT (image), "icon-name");
+ g_object_get (config,
+ param_spec->name, &icon_size,
+ NULL);
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (image));
+ icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, icon_size,
+ GTK_ICON_LOOKUP_GENERIC_FALLBACK);
+
+ if (icon_info)
+ {
+ /* Only update the image if we found it. */
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info,
+ gtk_widget_get_style_context (image),
+ NULL, NULL);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
+ g_object_unref (icon_info);
+ g_object_unref (pixbuf);
+ }
+}
+
void
gimp_icons_set_icon_theme (GFile *path)
{
@@ -314,3 +347,103 @@ gimp_icons_init (void)
initialized = TRUE;
}
+
+/**
+ * gimp_icons_get_image:
+ * @icon_name: the icon name (without "-symbolic" prefix).
+ * @parent: a parent from which styling will be derived.
+ * @icon_size: initial requested size for the icon.
+ * @config: optional object from which size can be synced.
+ * @property_name: Name of int property of @config from which size is
+ * synced.
+ *
+ * Lookup an icon in the current icon theme, possibly getting the
+ * symbolic version and matching the theme background (for instance in
+ * case of dark theme).
+ * @parent is used to determine the style information, and in particular
+ * this function does not add the image to @parent in any way.
+ *
+ * The returned image is synced to the theme and the displayed icon will
+ * be automatically updated if the theme changes.
+ *
+ * If @config and @property_name is set, the returned image's size will
+ * sync to this property (which must therefore be an int property).
+ * In such case @icon_size is useless and can be set to any value.
+ *
+ * Returns: a #GtkImage displaying @icon_name at @icon_size, or NULL if
+ * the lookup failed.
+ * gtk_widget_show() has been called already on the returned
+ * image, allowing to add it directly to a container.
+ */
+GtkWidget *
+gimp_icon_get_image (const gchar *icon_name,
+ GtkWidget *parent,
+ gint icon_size,
+ GObject *config,
+ const gchar *property_name)
+{
+ GtkWidget *image = NULL;
+ GParamSpec *param_spec = NULL;
+ GtkIconTheme *icon_theme;
+ gchar *symbolic_name;
+ GtkIconInfo *icon_info;
+
+ g_return_val_if_fail (icon_name != NULL, NULL);
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (icon_size >= 10 || (config && property_name), NULL);
+
+ if (config && property_name)
+ {
+ param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
+ property_name);
+
+ g_return_val_if_fail (param_spec != NULL, NULL);
+ g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec),
+ G_TYPE_PARAM_INT), NULL);
+
+ /* Override the icon size parameter with the current property
+ * value.
+ */
+ g_object_get (config,
+ property_name, &icon_size,
+ NULL);
+ }
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (parent));
+ symbolic_name = g_strdup_printf ("%s-symbolic", icon_name);
+
+ icon_info = gtk_icon_theme_lookup_icon (icon_theme, symbolic_name, icon_size,
+ GTK_ICON_LOOKUP_GENERIC_FALLBACK);
+
+ if (icon_info)
+ {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info,
+ gtk_widget_get_style_context (parent),
+ NULL, NULL);
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_widget_show (image);
+
+ g_object_set_data_full (G_OBJECT (image),
+ "icon-name", symbolic_name,
+ g_free);
+ g_object_unref (icon_info);
+ g_object_unref (pixbuf);
+
+ if (param_spec)
+ {
+ gchar *notify_name = g_strconcat ("notify::", property_name, NULL);
+
+ g_signal_connect_object (config, notify_name,
+ G_CALLBACK (gimp_prop_size_icon_notify),
+ image, 0);
+
+ g_free (notify_name);
+ }
+ }
+ else
+ g_free (symbolic_name);
+
+ return image;
+}
diff --git a/libgimpwidgets/gimpicons.h b/libgimpwidgets/gimpicons.h
index 27e79cd..1fb38b9 100644
--- a/libgimpwidgets/gimpicons.h
+++ b/libgimpwidgets/gimpicons.h
@@ -390,9 +390,15 @@ G_BEGIN_DECLS
#define GIMP_ICON_ZOOM_FOLLOW_WINDOW "gimp-zoom-follow-window"
-void gimp_icons_init (void);
+void gimp_icons_init (void);
-void gimp_icons_set_icon_theme (GFile *path);
+void gimp_icons_set_icon_theme (GFile *path);
+
+GtkWidget * gimp_icon_get_image (const gchar *icon_name,
+ GtkWidget *parent,
+ gint icon_size,
+ GObject *config,
+ const gchar *property_name);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]