mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 05:50:10 +00:00
Support 'symbolic' themed icons
Add gtk_icon_info_load_symbolic() to load symbolic icons, and theme their background/foreground colours to match the colours used in the theme. Adds the gtk_icon_info_load_symbolic() function, explicit support in GtkImage and GtkCellRendererPixbuf, and test cases for those 2 widgets. With help from Bastien Nocera <hadess@hadess.net> https://bugzilla.gnome.org/show_bug.cgi?id=614711
This commit is contained in:
parent
3cc9575323
commit
6b939d57c7
@ -317,6 +317,7 @@ do_images (GtkWidget *do_widget)
|
|||||||
GtkWidget *align;
|
GtkWidget *align;
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
GIcon *gicon;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
@ -415,6 +416,26 @@ do_images (GtkWidget *do_widget)
|
|||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
|
/* Symbolic icon */
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Symbolic themed icon</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
/* The alignment keeps the frame from growing when users resize
|
||||||
|
* the window
|
||||||
|
*/
|
||||||
|
align = gtk_alignment_new (0.5, 0.5, 0, 0);
|
||||||
|
gtk_container_add (GTK_CONTAINER (align), frame);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
gicon = g_themed_icon_new_with_default_fallbacks ("battery-critical-charging-symbolic");
|
||||||
|
image = gtk_image_new_from_gicon (gicon, GTK_ICON_SIZE_DIALOG);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
/* Progressive */
|
/* Progressive */
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ enum
|
|||||||
COLUMN_SEVERITY,
|
COLUMN_SEVERITY,
|
||||||
COLUMN_DESCRIPTION,
|
COLUMN_DESCRIPTION,
|
||||||
COLUMN_PULSE,
|
COLUMN_PULSE,
|
||||||
|
COLUMN_ICON,
|
||||||
COLUMN_ACTIVE,
|
COLUMN_ACTIVE,
|
||||||
|
COLUMN_SENSITIVE,
|
||||||
NUM_COLUMNS
|
NUM_COLUMNS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,11 +94,24 @@ create_model (void)
|
|||||||
G_TYPE_STRING,
|
G_TYPE_STRING,
|
||||||
G_TYPE_STRING,
|
G_TYPE_STRING,
|
||||||
G_TYPE_UINT,
|
G_TYPE_UINT,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_BOOLEAN,
|
||||||
G_TYPE_BOOLEAN);
|
G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
/* add data to the list store */
|
/* add data to the list store */
|
||||||
for (i = 0; i < G_N_ELEMENTS (data); i++)
|
for (i = 0; i < G_N_ELEMENTS (data); i++)
|
||||||
{
|
{
|
||||||
|
gchar *icon_name;
|
||||||
|
gboolean sensitive;
|
||||||
|
|
||||||
|
if (i == 1 || i == 3)
|
||||||
|
icon_name = "battery-critical-charging-symbolic";
|
||||||
|
else
|
||||||
|
icon_name = NULL;
|
||||||
|
if (i == 3)
|
||||||
|
sensitive = FALSE;
|
||||||
|
else
|
||||||
|
sensitive = TRUE;
|
||||||
gtk_list_store_append (store, &iter);
|
gtk_list_store_append (store, &iter);
|
||||||
gtk_list_store_set (store, &iter,
|
gtk_list_store_set (store, &iter,
|
||||||
COLUMN_FIXED, data[i].fixed,
|
COLUMN_FIXED, data[i].fixed,
|
||||||
@ -104,7 +119,9 @@ create_model (void)
|
|||||||
COLUMN_SEVERITY, data[i].severity,
|
COLUMN_SEVERITY, data[i].severity,
|
||||||
COLUMN_DESCRIPTION, data[i].description,
|
COLUMN_DESCRIPTION, data[i].description,
|
||||||
COLUMN_PULSE, 0,
|
COLUMN_PULSE, 0,
|
||||||
|
COLUMN_ICON, icon_name,
|
||||||
COLUMN_ACTIVE, FALSE,
|
COLUMN_ACTIVE, FALSE,
|
||||||
|
COLUMN_SENSITIVE, sensitive,
|
||||||
-1);
|
-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +216,19 @@ add_columns (GtkTreeView *treeview)
|
|||||||
NULL);
|
NULL);
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_PULSE);
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_PULSE);
|
||||||
gtk_tree_view_append_column (treeview, column);
|
gtk_tree_view_append_column (treeview, column);
|
||||||
|
|
||||||
|
/* column for symbolic icon */
|
||||||
|
renderer = gtk_cell_renderer_pixbuf_new ();
|
||||||
|
g_object_set (G_OBJECT (renderer), "follow-state", TRUE, NULL);
|
||||||
|
column = gtk_tree_view_column_new_with_attributes ("Symbolic icon",
|
||||||
|
renderer,
|
||||||
|
"icon-name",
|
||||||
|
COLUMN_ICON,
|
||||||
|
"sensitive",
|
||||||
|
COLUMN_SENSITIVE,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_ICON);
|
||||||
|
gtk_tree_view_append_column (treeview, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -6684,6 +6684,7 @@ gtk_icon_info_get_base_size
|
|||||||
gtk_icon_info_get_filename
|
gtk_icon_info_get_filename
|
||||||
gtk_icon_info_get_builtin_pixbuf
|
gtk_icon_info_get_builtin_pixbuf
|
||||||
gtk_icon_info_load_icon
|
gtk_icon_info_load_icon
|
||||||
|
gtk_icon_info_load_symbolic
|
||||||
gtk_icon_info_set_raw_coordinates
|
gtk_icon_info_set_raw_coordinates
|
||||||
gtk_icon_info_get_embedded_rect
|
gtk_icon_info_get_embedded_rect
|
||||||
gtk_icon_info_get_attach_points
|
gtk_icon_info_get_attach_points
|
||||||
|
@ -1965,6 +1965,7 @@ gtk_icon_info_get_filename_utf8
|
|||||||
#endif
|
#endif
|
||||||
gtk_icon_info_get_type G_GNUC_CONST
|
gtk_icon_info_get_type G_GNUC_CONST
|
||||||
gtk_icon_info_load_icon
|
gtk_icon_info_load_icon
|
||||||
|
gtk_icon_info_load_symbolic
|
||||||
gtk_icon_info_set_raw_coordinates
|
gtk_icon_info_set_raw_coordinates
|
||||||
gtk_icon_theme_add_builtin_icon
|
gtk_icon_theme_add_builtin_icon
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
|
@ -497,6 +497,7 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
|
|||||||
GtkIconTheme *icon_theme;
|
GtkIconTheme *icon_theme;
|
||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
GtkIconInfo *info;
|
||||||
|
|
||||||
priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
|
priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
|
||||||
|
|
||||||
@ -519,29 +520,140 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->icon_name)
|
if (priv->icon_name)
|
||||||
cellpixbuf->pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
info = gtk_icon_theme_lookup_icon (icon_theme,
|
||||||
priv->icon_name,
|
priv->icon_name,
|
||||||
MIN (width, height),
|
MIN (width, height),
|
||||||
GTK_ICON_LOOKUP_USE_BUILTIN,
|
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||||
NULL);
|
|
||||||
else if (priv->gicon)
|
else if (priv->gicon)
|
||||||
{
|
info = gtk_icon_theme_lookup_by_gicon (icon_theme,
|
||||||
GtkIconInfo *info;
|
priv->gicon,
|
||||||
|
MIN (width, height),
|
||||||
|
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||||
|
else
|
||||||
|
info = NULL;
|
||||||
|
|
||||||
info = gtk_icon_theme_lookup_by_gicon (icon_theme,
|
if (info)
|
||||||
priv->gicon,
|
{
|
||||||
MIN (width, height),
|
GdkColor error_color, warning_color, success_color;
|
||||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
GdkColor *error_ptr, *warning_ptr, *success_ptr;
|
||||||
if (info)
|
GtkStyle *style;
|
||||||
{
|
|
||||||
cellpixbuf->pixbuf = gtk_icon_info_load_icon (info, NULL);
|
style = gtk_widget_get_style (GTK_WIDGET (widget));
|
||||||
gtk_icon_info_free (info);
|
if (!gtk_style_lookup_color (style, "error_color", &error_color))
|
||||||
}
|
error_ptr = NULL;
|
||||||
|
else
|
||||||
|
error_ptr = &error_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
|
||||||
|
warning_ptr = NULL;
|
||||||
|
else
|
||||||
|
warning_ptr = &warning_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "success_color", &success_color))
|
||||||
|
success_ptr = NULL;
|
||||||
|
else
|
||||||
|
success_ptr = &success_color;
|
||||||
|
|
||||||
|
cellpixbuf->pixbuf = gtk_icon_info_load_symbolic (info,
|
||||||
|
&style->fg[GTK_STATE_NORMAL],
|
||||||
|
success_ptr,
|
||||||
|
warning_ptr,
|
||||||
|
error_ptr,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
gtk_icon_info_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
|
g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
create_symbolic_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GdkColor *fg)
|
||||||
|
{
|
||||||
|
GtkCellRendererPixbufPrivate *priv;
|
||||||
|
GdkScreen *screen;
|
||||||
|
GtkIconTheme *icon_theme;
|
||||||
|
GtkSettings *settings;
|
||||||
|
gint width, height;
|
||||||
|
GtkIconInfo *info;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
|
priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
|
||||||
|
|
||||||
|
/* Not a named symbolic icon? */
|
||||||
|
if (priv->icon_name) {
|
||||||
|
if (!g_str_has_suffix (priv->icon_name, "-symbolic"))
|
||||||
|
return NULL;
|
||||||
|
} else if (priv->gicon) {
|
||||||
|
const gchar * const *names;
|
||||||
|
if (!G_IS_THEMED_ICON (priv->gicon))
|
||||||
|
return NULL;
|
||||||
|
names = g_themed_icon_get_names (G_THEMED_ICON (priv->gicon));
|
||||||
|
if (names == NULL || !g_str_has_suffix (names[0], "-symbolic"))
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen = gtk_widget_get_screen (GTK_WIDGET (widget));
|
||||||
|
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||||
|
settings = gtk_settings_get_for_screen (screen);
|
||||||
|
|
||||||
|
if (!gtk_icon_size_lookup_for_settings (settings,
|
||||||
|
priv->stock_size,
|
||||||
|
&width, &height))
|
||||||
|
{
|
||||||
|
g_warning ("Invalid icon size %u\n", priv->stock_size);
|
||||||
|
width = height = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (priv->icon_name)
|
||||||
|
info = gtk_icon_theme_lookup_icon (icon_theme,
|
||||||
|
priv->icon_name,
|
||||||
|
MIN (width, height),
|
||||||
|
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||||
|
else if (priv->gicon)
|
||||||
|
info = gtk_icon_theme_lookup_by_gicon (icon_theme,
|
||||||
|
priv->gicon,
|
||||||
|
MIN (width, height),
|
||||||
|
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
GdkColor error_color, warning_color, success_color;
|
||||||
|
GdkColor *error_ptr, *warning_ptr, *success_ptr;
|
||||||
|
GtkStyle *style;
|
||||||
|
|
||||||
|
style = gtk_widget_get_style (GTK_WIDGET (widget));
|
||||||
|
if (!gtk_style_lookup_color (style, "error_color", &error_color))
|
||||||
|
error_ptr = NULL;
|
||||||
|
else
|
||||||
|
error_ptr = &error_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
|
||||||
|
warning_ptr = NULL;
|
||||||
|
else
|
||||||
|
warning_ptr = &warning_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "success_color", &success_color))
|
||||||
|
success_ptr = NULL;
|
||||||
|
else
|
||||||
|
success_ptr = &success_color;
|
||||||
|
|
||||||
|
pixbuf = gtk_icon_info_load_symbolic (info,
|
||||||
|
fg,
|
||||||
|
success_ptr,
|
||||||
|
warning_ptr,
|
||||||
|
error_ptr,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
gtk_icon_info_free (info);
|
||||||
|
return pixbuf;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
create_colorized_pixbuf (GdkPixbuf *src,
|
create_colorized_pixbuf (GdkPixbuf *src,
|
||||||
GdkColor *new_color)
|
GdkColor *new_color)
|
||||||
@ -678,6 +790,7 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
|||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GdkPixbuf *invisible = NULL;
|
GdkPixbuf *invisible = NULL;
|
||||||
GdkPixbuf *colorized = NULL;
|
GdkPixbuf *colorized = NULL;
|
||||||
|
GdkPixbuf *symbolic = NULL;
|
||||||
GdkRectangle pix_rect;
|
GdkRectangle pix_rect;
|
||||||
GdkRectangle draw_rect;
|
GdkRectangle draw_rect;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
@ -755,10 +868,15 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
|||||||
else
|
else
|
||||||
state = GTK_STATE_PRELIGHT;
|
state = GTK_STATE_PRELIGHT;
|
||||||
|
|
||||||
colorized = create_colorized_pixbuf (pixbuf,
|
symbolic = create_symbolic_pixbuf (cellpixbuf, widget, &widget->style->fg[state]);
|
||||||
&widget->style->base[state]);
|
if (!symbolic) {
|
||||||
|
colorized = create_colorized_pixbuf (pixbuf,
|
||||||
|
&widget->style->base[state]);
|
||||||
|
|
||||||
pixbuf = colorized;
|
pixbuf = colorized;
|
||||||
|
} else {
|
||||||
|
pixbuf = symbolic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cr = gdk_cairo_create (window);
|
cr = gdk_cairo_create (window);
|
||||||
@ -774,6 +892,9 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
|||||||
|
|
||||||
if (colorized)
|
if (colorized)
|
||||||
g_object_unref (colorized);
|
g_object_unref (colorized);
|
||||||
|
|
||||||
|
if (symbolic)
|
||||||
|
g_object_unref (symbolic);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __GTK_CELL_RENDERER_PIXBUF_C__
|
#define __GTK_CELL_RENDERER_PIXBUF_C__
|
||||||
|
@ -3079,6 +3079,142 @@ gtk_icon_info_load_icon (GtkIconInfo *icon_info,
|
|||||||
return g_object_ref (icon_info->pixbuf);
|
return g_object_ref (icon_info->pixbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
gdk_color_to_css (GdkColor *color)
|
||||||
|
{
|
||||||
|
return g_strdup_printf ("rgb(%d,%d,%d)",
|
||||||
|
color->red >> 8,
|
||||||
|
color->green >> 8,
|
||||||
|
color->blue >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_icon_info_load_symbolic:
|
||||||
|
* @info: a #GtkIconInfo
|
||||||
|
* @fg: a #GdkColor representing the foreground color of the icon
|
||||||
|
* @success_color: (allow-none): a #GdkColor representing the warning color of the icon
|
||||||
|
* or %NULL to use the default color
|
||||||
|
* @warning_color: (allow-none): a #GdkColor representing the warning color of the icon
|
||||||
|
* or %NULL to use the default color
|
||||||
|
* @error_color: (allow-none): a #GdkColor representing the error color of the icon
|
||||||
|
* or %NULL to use the default color (allow-none)
|
||||||
|
* @was_symbolic: (allow-none): a #gboolean, returns whether the loaded icon was a symbolic
|
||||||
|
* one and whether the @fg color was applied to it.
|
||||||
|
* @error: (allow-none): location to store error information on failure, or %NULL.
|
||||||
|
*
|
||||||
|
* Loads an icon, modifying it to match the system colours for the foreground,
|
||||||
|
* success, warning and error colors provided. If the icon is not a symbolic one,
|
||||||
|
* the function will return the result from gtk_icon_info_load_icon().
|
||||||
|
*
|
||||||
|
* This allows loading symbolic icons that will match the system theme.
|
||||||
|
*
|
||||||
|
* Unless you are implementing a widget, you will want to use
|
||||||
|
* g_themed_icon_new_with_default_fallbacks() to load the icon.
|
||||||
|
*
|
||||||
|
* As implementation details, the icon loaded needs to be of SVG type,
|
||||||
|
* contain the "symbolic" term as the last chunk of the icon name,
|
||||||
|
* and use the fg, success, warning and error styles in the SVG file itself.
|
||||||
|
* See the <a ulink url="http://www.freedesktop.org/wiki/SymbolicIcons">Symbolic Icons spec</ulink>
|
||||||
|
* for more information about symbolic icons.
|
||||||
|
*
|
||||||
|
* Return value: a #GdkPixbuf representing the loaded icon
|
||||||
|
*
|
||||||
|
* Since: 2.22
|
||||||
|
**/
|
||||||
|
GdkPixbuf *
|
||||||
|
gtk_icon_info_load_symbolic (GtkIconInfo *info,
|
||||||
|
GdkColor *fg,
|
||||||
|
GdkColor *success_color,
|
||||||
|
GdkColor *warning_color,
|
||||||
|
GdkColor *error_color,
|
||||||
|
gboolean *was_symbolic,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
GInputStream *stream;
|
||||||
|
gchar *data;
|
||||||
|
gchar *css_fg;
|
||||||
|
gchar *css_success;
|
||||||
|
gchar *css_warning;
|
||||||
|
gchar *css_error;
|
||||||
|
|
||||||
|
g_return_val_if_fail (fg != NULL, NULL);
|
||||||
|
|
||||||
|
if (!info->filename || !g_str_has_suffix (info->filename, "-symbolic.svg"))
|
||||||
|
{
|
||||||
|
if (was_symbolic)
|
||||||
|
*was_symbolic = FALSE;
|
||||||
|
return gtk_icon_info_load_icon (info, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (was_symbolic)
|
||||||
|
*was_symbolic = TRUE;
|
||||||
|
|
||||||
|
css_fg = gdk_color_to_css (fg);
|
||||||
|
if (!warning_color)
|
||||||
|
{
|
||||||
|
GdkColor warning_default_color = { 0, 0xf500, 0x7900, 0x3e00 };
|
||||||
|
css_warning = gdk_color_to_css (&warning_default_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
css_warning = gdk_color_to_css (warning_color);
|
||||||
|
if (!error_color)
|
||||||
|
{
|
||||||
|
GdkColor error_default_color = { 0, 0xcc00, 0x0000, 0x0000 };
|
||||||
|
css_error = gdk_color_to_css (&error_default_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
css_error = gdk_color_to_css (error_color);
|
||||||
|
if (!success_color)
|
||||||
|
{
|
||||||
|
GdkColor success_default_color = { 0, 0x4e00, 0x9a00, 0x0600 };
|
||||||
|
css_success = gdk_color_to_css (&success_default_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
css_success = gdk_color_to_css (success_color);
|
||||||
|
|
||||||
|
data = g_strconcat (
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||||
|
"<svg version=\"1.1\"\n"
|
||||||
|
" xmlns=\"http://www.w3.org/2000/svg\"\n"
|
||||||
|
" xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n"
|
||||||
|
" width=\"16\"\n"
|
||||||
|
" height=\"16\">\n"
|
||||||
|
" <style type=\"text/css\">\n"
|
||||||
|
" rect,path {\n"
|
||||||
|
" fill: ", css_fg," !important;\n"
|
||||||
|
" }\n"
|
||||||
|
" .warning {\n"
|
||||||
|
" fill: ", css_warning," !important;\n"
|
||||||
|
" }\n"
|
||||||
|
" .error {\n"
|
||||||
|
" fill: ", css_error," !important;\n"
|
||||||
|
" }\n"
|
||||||
|
" .success {\n"
|
||||||
|
" fill: ", css_success," !important;\n"
|
||||||
|
" }\n"
|
||||||
|
" </style>\n"
|
||||||
|
" <xi:include href=\"", info->filename, "\"/>\n"
|
||||||
|
"</svg>",
|
||||||
|
NULL);
|
||||||
|
g_free (css_fg);
|
||||||
|
g_free (css_warning);
|
||||||
|
g_free (css_success);
|
||||||
|
g_free (css_error);
|
||||||
|
|
||||||
|
stream = g_memory_input_stream_new_from_data (data, -1, g_free);
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
||||||
|
info->desired_size,
|
||||||
|
info->desired_size,
|
||||||
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
error);
|
||||||
|
g_object_unref (stream);
|
||||||
|
|
||||||
|
return pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_icon_info_set_raw_coordinates:
|
* gtk_icon_info_set_raw_coordinates:
|
||||||
* @icon_info: a #GtkIconInfo
|
* @icon_info: a #GtkIconInfo
|
||||||
|
@ -179,6 +179,13 @@ G_CONST_RETURN gchar *gtk_icon_info_get_filename (GtkIconInfo *icon_info
|
|||||||
GdkPixbuf * gtk_icon_info_get_builtin_pixbuf (GtkIconInfo *icon_info);
|
GdkPixbuf * gtk_icon_info_get_builtin_pixbuf (GtkIconInfo *icon_info);
|
||||||
GdkPixbuf * gtk_icon_info_load_icon (GtkIconInfo *icon_info,
|
GdkPixbuf * gtk_icon_info_load_icon (GtkIconInfo *icon_info,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
GdkPixbuf * gtk_icon_info_load_symbolic (GtkIconInfo *icon_info,
|
||||||
|
GdkColor *fg,
|
||||||
|
GdkColor *success_color,
|
||||||
|
GdkColor *warning_color,
|
||||||
|
GdkColor *error_color,
|
||||||
|
gboolean *was_symbolic,
|
||||||
|
GError **error);
|
||||||
void gtk_icon_info_set_raw_coordinates (GtkIconInfo *icon_info,
|
void gtk_icon_info_set_raw_coordinates (GtkIconInfo *icon_info,
|
||||||
gboolean raw_coordinates);
|
gboolean raw_coordinates);
|
||||||
|
|
||||||
|
137
gtk/gtkimage.c
137
gtk/gtkimage.c
@ -134,6 +134,11 @@ struct _GtkImagePrivate
|
|||||||
/* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
|
/* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
|
|
||||||
|
/* a GtkStateType, with -1 meaning an invalid state,
|
||||||
|
* only used with GTK_IMAGE_GICON, GTK_IMAGE_ICON_NAME */
|
||||||
|
gint last_rendered_state;
|
||||||
|
gboolean was_symbolic;
|
||||||
|
|
||||||
gint pixel_size;
|
gint pixel_size;
|
||||||
guint need_calc_size : 1;
|
guint need_calc_size : 1;
|
||||||
};
|
};
|
||||||
@ -1628,6 +1633,10 @@ animation_timeout (gpointer data)
|
|||||||
static void
|
static void
|
||||||
icon_theme_changed (GtkImage *image)
|
icon_theme_changed (GtkImage *image)
|
||||||
{
|
{
|
||||||
|
GtkImagePrivate *priv;
|
||||||
|
|
||||||
|
priv = GTK_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
if (image->storage_type == GTK_IMAGE_ICON_NAME)
|
if (image->storage_type == GTK_IMAGE_ICON_NAME)
|
||||||
{
|
{
|
||||||
if (image->data.name.pixbuf)
|
if (image->data.name.pixbuf)
|
||||||
@ -1647,7 +1656,8 @@ icon_theme_changed (GtkImage *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ensure_pixbuf_for_icon_name (GtkImage *image)
|
ensure_pixbuf_for_icon_name (GtkImage *image,
|
||||||
|
GtkStateType state)
|
||||||
{
|
{
|
||||||
GtkImagePrivate *priv;
|
GtkImagePrivate *priv;
|
||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
@ -1655,8 +1665,8 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
|
|||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint *sizes, *s, dist;
|
gint *sizes, *s, dist;
|
||||||
|
GtkIconInfo *info;
|
||||||
GtkIconLookupFlags flags;
|
GtkIconLookupFlags flags;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_NAME);
|
g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_NAME);
|
||||||
|
|
||||||
@ -1665,8 +1675,15 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
|
|||||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||||
settings = gtk_settings_get_for_screen (screen);
|
settings = gtk_settings_get_for_screen (screen);
|
||||||
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
|
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
|
||||||
if (image->data.name.pixbuf == NULL)
|
if (image->data.name.pixbuf == NULL ||
|
||||||
|
(priv->was_symbolic && priv->last_rendered_state != state))
|
||||||
{
|
{
|
||||||
|
priv->last_rendered_state = state;
|
||||||
|
if (image->data.name.pixbuf)
|
||||||
|
{
|
||||||
|
g_object_unref (image->data.name.pixbuf);
|
||||||
|
image->data.name.pixbuf = NULL;
|
||||||
|
}
|
||||||
if (priv->pixel_size != -1)
|
if (priv->pixel_size != -1)
|
||||||
{
|
{
|
||||||
width = height = priv->pixel_size;
|
width = height = priv->pixel_size;
|
||||||
@ -1714,24 +1731,57 @@ ensure_pixbuf_for_icon_name (GtkImage *image)
|
|||||||
width = height = 24;
|
width = height = 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image->data.name.pixbuf =
|
|
||||||
gtk_icon_theme_load_icon (icon_theme,
|
info = gtk_icon_theme_lookup_icon (icon_theme,
|
||||||
image->data.name.icon_name,
|
image->data.name.icon_name,
|
||||||
MIN (width, height), flags, &error);
|
MIN (width, height), flags);
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
GdkColor error_color, warning_color, success_color;
|
||||||
|
GdkColor *error_ptr, *warning_ptr, *success_ptr;
|
||||||
|
GtkStyle *style;
|
||||||
|
gboolean was_symbolic;
|
||||||
|
|
||||||
|
style = gtk_widget_get_style (GTK_WIDGET (image));
|
||||||
|
if (!gtk_style_lookup_color (style, "error_color", &error_color))
|
||||||
|
error_ptr = NULL;
|
||||||
|
else
|
||||||
|
error_ptr = &error_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
|
||||||
|
warning_ptr = NULL;
|
||||||
|
else
|
||||||
|
warning_ptr = &warning_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "success_color", &success_color))
|
||||||
|
success_ptr = NULL;
|
||||||
|
else
|
||||||
|
success_ptr = &success_color;
|
||||||
|
|
||||||
|
image->data.name.pixbuf = gtk_icon_info_load_symbolic (info,
|
||||||
|
&style->fg[state],
|
||||||
|
success_ptr,
|
||||||
|
warning_ptr,
|
||||||
|
error_ptr,
|
||||||
|
&was_symbolic,
|
||||||
|
NULL);
|
||||||
|
priv->was_symbolic = was_symbolic;
|
||||||
|
gtk_icon_info_free (info);
|
||||||
|
}
|
||||||
|
|
||||||
if (image->data.name.pixbuf == NULL)
|
if (image->data.name.pixbuf == NULL)
|
||||||
{
|
{
|
||||||
g_error_free (error);
|
|
||||||
image->data.name.pixbuf =
|
image->data.name.pixbuf =
|
||||||
gtk_widget_render_icon (GTK_WIDGET (image),
|
gtk_widget_render_icon (GTK_WIDGET (image),
|
||||||
GTK_STOCK_MISSING_IMAGE,
|
GTK_STOCK_MISSING_IMAGE,
|
||||||
image->icon_size,
|
image->icon_size,
|
||||||
NULL);
|
NULL);
|
||||||
|
priv->was_symbolic = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ensure_pixbuf_for_gicon (GtkImage *image)
|
ensure_pixbuf_for_gicon (GtkImage *image,
|
||||||
|
GtkStateType state)
|
||||||
{
|
{
|
||||||
GtkImagePrivate *priv;
|
GtkImagePrivate *priv;
|
||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
@ -1748,8 +1798,15 @@ ensure_pixbuf_for_gicon (GtkImage *image)
|
|||||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||||
settings = gtk_settings_get_for_screen (screen);
|
settings = gtk_settings_get_for_screen (screen);
|
||||||
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
|
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
|
||||||
if (image->data.gicon.pixbuf == NULL)
|
if (image->data.gicon.pixbuf == NULL ||
|
||||||
|
(priv->was_symbolic && priv->last_rendered_state != state))
|
||||||
{
|
{
|
||||||
|
priv->last_rendered_state = state;
|
||||||
|
if (image->data.gicon.pixbuf)
|
||||||
|
{
|
||||||
|
g_object_unref (image->data.gicon.pixbuf);
|
||||||
|
image->data.gicon.pixbuf = NULL;
|
||||||
|
}
|
||||||
if (priv->pixel_size != -1)
|
if (priv->pixel_size != -1)
|
||||||
{
|
{
|
||||||
width = height = priv->pixel_size;
|
width = height = priv->pixel_size;
|
||||||
@ -1773,7 +1830,33 @@ ensure_pixbuf_for_gicon (GtkImage *image)
|
|||||||
MIN (width, height), flags);
|
MIN (width, height), flags);
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
image->data.gicon.pixbuf = gtk_icon_info_load_icon (info, NULL);
|
GdkColor error_color, warning_color, success_color;
|
||||||
|
GdkColor *error_ptr, *warning_ptr, *success_ptr;
|
||||||
|
GtkStyle *style;
|
||||||
|
gboolean was_symbolic;
|
||||||
|
|
||||||
|
style = gtk_widget_get_style (GTK_WIDGET (image));
|
||||||
|
if (!gtk_style_lookup_color (style, "error_color", &error_color))
|
||||||
|
error_ptr = NULL;
|
||||||
|
else
|
||||||
|
error_ptr = &error_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "warning_color", &warning_color))
|
||||||
|
warning_ptr = NULL;
|
||||||
|
else
|
||||||
|
warning_ptr = &warning_color;
|
||||||
|
if (!gtk_style_lookup_color (style, "success_color", &success_color))
|
||||||
|
success_ptr = NULL;
|
||||||
|
else
|
||||||
|
success_ptr = &success_color;
|
||||||
|
|
||||||
|
image->data.gicon.pixbuf = gtk_icon_info_load_symbolic (info,
|
||||||
|
&style->fg[state],
|
||||||
|
success_ptr,
|
||||||
|
warning_ptr,
|
||||||
|
error_ptr,
|
||||||
|
&was_symbolic,
|
||||||
|
NULL);
|
||||||
|
priv->was_symbolic = was_symbolic;
|
||||||
gtk_icon_info_free (info);
|
gtk_icon_info_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1784,6 +1867,7 @@ ensure_pixbuf_for_gicon (GtkImage *image)
|
|||||||
GTK_STOCK_MISSING_IMAGE,
|
GTK_STOCK_MISSING_IMAGE,
|
||||||
image->icon_size,
|
image->icon_size,
|
||||||
NULL);
|
NULL);
|
||||||
|
priv->was_symbolic = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1845,6 +1929,7 @@ gtk_image_expose (GtkWidget *widget,
|
|||||||
gint x, y, mask_x, mask_y;
|
gint x, y, mask_x, mask_y;
|
||||||
GdkBitmap *mask;
|
GdkBitmap *mask;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
GtkStateType state;
|
||||||
gboolean needs_state_transform;
|
gboolean needs_state_transform;
|
||||||
|
|
||||||
image = GTK_IMAGE (widget);
|
image = GTK_IMAGE (widget);
|
||||||
@ -2012,7 +2097,18 @@ gtk_image_expose (GtkWidget *widget,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_ICON_NAME:
|
case GTK_IMAGE_ICON_NAME:
|
||||||
ensure_pixbuf_for_icon_name (image);
|
state = gtk_widget_get_state (widget);
|
||||||
|
if (state == GTK_STATE_INSENSITIVE)
|
||||||
|
{
|
||||||
|
ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensure_pixbuf_for_icon_name (image, state);
|
||||||
|
/* Already done by the loading function? */
|
||||||
|
if (priv->was_symbolic)
|
||||||
|
needs_state_transform = FALSE;
|
||||||
|
}
|
||||||
pixbuf = image->data.name.pixbuf;
|
pixbuf = image->data.name.pixbuf;
|
||||||
if (pixbuf)
|
if (pixbuf)
|
||||||
{
|
{
|
||||||
@ -2023,7 +2119,18 @@ gtk_image_expose (GtkWidget *widget,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_GICON:
|
case GTK_IMAGE_GICON:
|
||||||
ensure_pixbuf_for_gicon (image);
|
state = gtk_widget_get_state (widget);
|
||||||
|
if (state == GTK_STATE_INSENSITIVE)
|
||||||
|
{
|
||||||
|
ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensure_pixbuf_for_gicon (image, state);
|
||||||
|
/* Already done by the loading function? */
|
||||||
|
if (priv->was_symbolic)
|
||||||
|
needs_state_transform = FALSE;
|
||||||
|
}
|
||||||
pixbuf = image->data.gicon.pixbuf;
|
pixbuf = image->data.gicon.pixbuf;
|
||||||
if (pixbuf)
|
if (pixbuf)
|
||||||
{
|
{
|
||||||
@ -2325,12 +2432,12 @@ gtk_image_calc_size (GtkImage *image)
|
|||||||
NULL);
|
NULL);
|
||||||
break;
|
break;
|
||||||
case GTK_IMAGE_ICON_NAME:
|
case GTK_IMAGE_ICON_NAME:
|
||||||
ensure_pixbuf_for_icon_name (image);
|
ensure_pixbuf_for_icon_name (image, GTK_STATE_NORMAL);
|
||||||
pixbuf = image->data.name.pixbuf;
|
pixbuf = image->data.name.pixbuf;
|
||||||
if (pixbuf) g_object_ref (pixbuf);
|
if (pixbuf) g_object_ref (pixbuf);
|
||||||
break;
|
break;
|
||||||
case GTK_IMAGE_GICON:
|
case GTK_IMAGE_GICON:
|
||||||
ensure_pixbuf_for_gicon (image);
|
ensure_pixbuf_for_gicon (image, GTK_STATE_NORMAL);
|
||||||
pixbuf = image->data.gicon.pixbuf;
|
pixbuf = image->data.gicon.pixbuf;
|
||||||
if (pixbuf)
|
if (pixbuf)
|
||||||
g_object_ref (pixbuf);
|
g_object_ref (pixbuf);
|
||||||
|
Loading…
Reference in New Issue
Block a user