summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2005-01-20 19:12:49 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2005-01-20 19:12:49 +0000
commit9726395dd6d15830444cecbad98ebca7d9e3978a (patch)
treec523cc8b10e18b672ce98f816c0628f68b42bedc /gtk
parent889e66decd2acf4cecf07b2fc51b6dd25670d3b4 (diff)
downloadgdk-pixbuf-9726395dd6d15830444cecbad98ebca7d9e3978a.tar.gz
Support tinting in GtkCellRendererPixbuf (#162903, Jorn Baayen):
2005-01-20 Matthias Clasen <mclasen@redhat.com> Support tinting in GtkCellRendererPixbuf (#162903, Jorn Baayen): * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_class_init) Add a follow-state property which when TRUE causes the pixbuf to be tinted according to state. * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render): Use follow-state and colorize the pixbuf when appropriate.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkcellrendererpixbuf.c129
1 files changed, 114 insertions, 15 deletions
diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c
index 0cdbb3c3e..0fe48c016 100644
--- a/gtk/gtkcellrendererpixbuf.c
+++ b/gtk/gtkcellrendererpixbuf.c
@@ -60,7 +60,8 @@ enum {
PROP_PIXBUF_EXPANDER_CLOSED,
PROP_STOCK_ID,
PROP_STOCK_SIZE,
- PROP_STOCK_DETAIL
+ PROP_STOCK_DETAIL,
+ PROP_FOLLOW_STATE
};
static gpointer parent_class;
@@ -74,6 +75,7 @@ struct _GtkCellRendererPixbufPrivate
gchar *stock_id;
GtkIconSize stock_size;
gchar *stock_detail;
+ gboolean follow_state;
};
@@ -183,6 +185,24 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
NULL,
G_PARAM_READWRITE));
+ /**
+ * GtkCellRendererPixbuf:follow-state:
+ *
+ * Specifies whether the rendered pixbuf should be colorized
+ * according to the #GtkCellRendererState.
+ *
+ * Since: 2.8
+ */
+ g_object_class_install_property (object_class,
+ PROP_FOLLOW_STATE,
+ g_param_spec_boolean ("follow_state",
+ P_("Follow State"),
+ P_("Whether the rendered pixbuf should be "
+ "colorized according to the state"),
+ FALSE,
+ G_PARAM_READWRITE));
+
+
g_type_class_add_private (object_class, sizeof (GtkCellRendererPixbufPrivate));
}
@@ -240,6 +260,9 @@ gtk_cell_renderer_pixbuf_get_property (GObject *object,
case PROP_STOCK_DETAIL:
g_value_set_string (value, priv->stock_detail);
break;
+ case PROP_FOLLOW_STATE:
+ g_value_set_boolean (value, priv->follow_state);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -305,6 +328,9 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
g_free (priv->stock_detail);
priv->stock_detail = g_strdup (g_value_get_string (value));
break;
+ case PROP_FOLLOW_STATE:
+ priv->follow_state = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -353,6 +379,53 @@ gtk_cell_renderer_pixbuf_create_stock_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
priv->stock_detail);
}
+static GdkPixbuf *
+create_colorized_pixbuf (GdkPixbuf *src,
+ GdkColor *new_color)
+{
+ gint i, j;
+ gint width, height, has_alpha, src_row_stride, dst_row_stride;
+ gint red_value, green_value, blue_value;
+ guchar *target_pixels;
+ guchar *original_pixels;
+ guchar *pixsrc;
+ guchar *pixdest;
+ GdkPixbuf *dest;
+
+ red_value = new_color->red / 255.0;
+ green_value = new_color->green / 255.0;
+ blue_value = new_color->blue / 255.0;
+
+ dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
+ gdk_pixbuf_get_has_alpha (src),
+ gdk_pixbuf_get_bits_per_sample (src),
+ gdk_pixbuf_get_width (src),
+ gdk_pixbuf_get_height (src));
+
+ has_alpha = gdk_pixbuf_get_has_alpha (src);
+ width = gdk_pixbuf_get_width (src);
+ height = gdk_pixbuf_get_height (src);
+ src_row_stride = gdk_pixbuf_get_rowstride (src);
+ dst_row_stride = gdk_pixbuf_get_rowstride (dest);
+ target_pixels = gdk_pixbuf_get_pixels (dest);
+ original_pixels = gdk_pixbuf_get_pixels (src);
+
+ for (i = 0; i < height; i++) {
+ pixdest = target_pixels + i*dst_row_stride;
+ pixsrc = original_pixels + i*src_row_stride;
+ for (j = 0; j < width; j++) {
+ *pixdest++ = (*pixsrc++ * red_value) >> 8;
+ *pixdest++ = (*pixsrc++ * green_value) >> 8;
+ *pixdest++ = (*pixsrc++ * blue_value) >> 8;
+ if (has_alpha) {
+ *pixdest++ = *pixsrc++;
+ }
+ }
+ }
+ return dest;
+}
+
+
static void
gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
@@ -434,6 +507,7 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
GtkCellRendererPixbufPrivate *priv;
GdkPixbuf *pixbuf;
GdkPixbuf *invisible = NULL;
+ GdkPixbuf *colorized = NULL;
GdkRectangle pix_rect;
GdkRectangle draw_rect;
gboolean stock_pixbuf = FALSE;
@@ -470,6 +544,10 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
pix_rect.width -= cell->xpad * 2;
pix_rect.height -= cell->ypad * 2;
+ if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
+ !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
+ return;
+
if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cell->sensitive)
{
GtkIconSource *source;
@@ -496,22 +574,43 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
pixbuf = invisible;
}
+ else if (priv->follow_state &&
+ (flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_PRELIT) != 0))
+ {
+ GtkStateType state;
+
+ if (flags & GTK_CELL_RENDERER_SELECTED != 0)
+ {
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ state = GTK_STATE_SELECTED;
+ else
+ state = GTK_STATE_ACTIVE;
+ }
+ else
+ state = GTK_STATE_PRELIGHT;
+
+ colorized = create_colorized_pixbuf (pixbuf,
+ &widget->style->base[state]);
+
+ pixbuf = colorized;
+ }
- if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) &&
- gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
- gdk_draw_pixbuf (window,
- widget->style->black_gc,
- pixbuf,
- /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
- draw_rect.x - pix_rect.x,
- draw_rect.y - pix_rect.y,
- draw_rect.x,
- draw_rect.y,
- draw_rect.width,
- draw_rect.height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
+ gdk_draw_pixbuf (window,
+ widget->style->black_gc,
+ pixbuf,
+ /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
+ draw_rect.x - pix_rect.x,
+ draw_rect.y - pix_rect.y,
+ draw_rect.x,
+ draw_rect.y,
+ draw_rect.width,
+ draw_rect.height,
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
if (invisible)
g_object_unref (invisible);
+
+ if (colorized)
+ g_object_unref (colorized);
}