[gnome-themes-standard] adwaita: override render_icon_pixbuf() not to apply the checkboard



commit 1d5ad685cd857ed57b0c8966783e75ba72c05dc4
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sat Mar 5 15:25:56 2011 -0500

    adwaita: override render_icon_pixbuf() not to apply the checkboard
    
    Insensitive images are now dimmed with a 50% black alpha layer.

 src/adwaita_engine.c |  154 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)
---
diff --git a/src/adwaita_engine.c b/src/adwaita_engine.c
index c5820cc..0a32b7f 100644
--- a/src/adwaita_engine.c
+++ b/src/adwaita_engine.c
@@ -1361,6 +1361,159 @@ adwaita_engine_render_handle (GtkThemingEngine *engine,
 	}
 }
 
+/* taken from gtkthemingengine.c */
+static GdkPixbuf *
+scale_or_ref (GdkPixbuf *src,
+              gint       width,
+              gint       height)
+{
+	if (width == gdk_pixbuf_get_width (src) &&
+	    height == gdk_pixbuf_get_height (src)) {
+		return g_object_ref (src);
+	} else {
+		return gdk_pixbuf_scale_simple (src,
+						width, height,
+						GDK_INTERP_BILINEAR);
+	}
+}
+
+static gboolean
+lookup_icon_size (GtkThemingEngine *engine,
+		  GtkIconSize       size,
+		  gint             *width,
+		  gint             *height)
+{
+	GdkScreen *screen;
+	GtkSettings *settings;
+
+	screen = gtk_theming_engine_get_screen (engine);
+	settings = gtk_settings_get_for_screen (screen);
+
+	return gtk_icon_size_lookup_for_settings (settings, size, width, height);
+}
+
+/* Kudos to the gnome-panel guys. */
+static void
+colorshift_pixbuf (GdkPixbuf *src,
+                   GdkPixbuf *dest,
+                   gint       shift)
+{
+	gint i, j;
+	gint width, height, has_alpha, src_rowstride, dest_rowstride;
+	guchar *target_pixels;
+	guchar *original_pixels;
+	guchar *pix_src;
+	guchar *pix_dest;
+	int val;
+	guchar r, g, b;
+
+	has_alpha       = gdk_pixbuf_get_has_alpha (src);
+	width           = gdk_pixbuf_get_width (src);
+	height          = gdk_pixbuf_get_height (src);
+	src_rowstride   = gdk_pixbuf_get_rowstride (src);
+	dest_rowstride  = gdk_pixbuf_get_rowstride (dest);
+	original_pixels = gdk_pixbuf_get_pixels (src);
+	target_pixels   = gdk_pixbuf_get_pixels (dest);
+
+	for (i = 0; i < height; i++) {
+		pix_dest = target_pixels   + i * dest_rowstride;
+		pix_src  = original_pixels + i * src_rowstride;
+
+		for (j = 0; j < width; j++) {
+			r = *(pix_src++);
+			g = *(pix_src++);
+			b = *(pix_src++);
+
+			val = r + shift;
+			*(pix_dest++) = CLAMP (val, 0, 255);
+
+			val = g + shift;
+			*(pix_dest++) = CLAMP (val, 0, 255);
+
+			val = b + shift;
+			*(pix_dest++) = CLAMP (val, 0, 255);
+
+			if (has_alpha) {
+				*(pix_dest++) = *(pix_src++);
+			}
+		}
+	}
+}
+
+static GdkPixbuf *
+adwaita_engine_render_icon_pixbuf (GtkThemingEngine    *engine,
+				   const GtkIconSource *source,
+				   GtkIconSize          size)
+{
+	GdkPixbuf *base_pixbuf;
+	GdkPixbuf *scaled;
+	GdkPixbuf *stated;
+	GtkStateFlags state;
+	gint width = 1;
+	gint height = 1;
+
+	cairo_surface_t *stated_surface;
+	cairo_t *cr;
+
+	base_pixbuf = gtk_icon_source_get_pixbuf (source);
+	state = gtk_theming_engine_get_state (engine);
+
+	g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+	if (size != (GtkIconSize) -1 &&
+	    !lookup_icon_size (engine, size, &width, &height)) {
+		g_warning (G_STRLOC ": invalid icon size '%d'", size);
+		return NULL;
+	}
+
+	/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+	 * leave it alone.
+	 */
+	if (size != (GtkIconSize) -1 &&
+	    gtk_icon_source_get_size_wildcarded (source)) {
+		scaled = scale_or_ref (base_pixbuf, width, height);
+	} else {
+		scaled = g_object_ref (base_pixbuf);
+	}
+
+	/* If the state was wildcarded, then generate a state. */
+	if (gtk_icon_source_get_state_wildcarded (source)) {
+		if (state & GTK_STATE_FLAG_INSENSITIVE) {
+			/* dim the pixbuf with a 0.5 alpha black layer */
+			stated_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+								     gdk_pixbuf_get_width (scaled),
+								     gdk_pixbuf_get_height (scaled));
+			cr = cairo_create (stated_surface);
+
+			gdk_cairo_set_source_pixbuf (cr, scaled, 0, 0);
+			cairo_paint (cr);
+
+			cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
+			cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
+			cairo_paint (cr);
+
+			stated = gdk_pixbuf_get_from_surface (stated_surface,
+							      0, 0,
+							      cairo_image_surface_get_width (stated_surface),
+							      cairo_image_surface_get_height (stated_surface));
+
+			g_object_unref (scaled);
+			cairo_destroy (cr);
+			cairo_surface_destroy (stated_surface);
+		} else if (state & GTK_STATE_FLAG_PRELIGHT) {
+			stated = gdk_pixbuf_copy (scaled);
+			colorshift_pixbuf (scaled, stated, 30);
+			g_object_unref (scaled);
+		} else {
+			stated = scaled;
+		}
+	} else {
+		stated = scaled;
+	}
+
+	return stated;
+}
+
 static void
 adwaita_engine_class_init (AdwaitaEngineClass *klass)
 {
@@ -1377,6 +1530,7 @@ adwaita_engine_class_init (AdwaitaEngineClass *klass)
 	engine_class->render_activity = adwaita_engine_render_activity;
 	engine_class->render_slider = adwaita_engine_render_slider;
 	engine_class->render_handle = adwaita_engine_render_handle;
+	engine_class->render_icon_pixbuf = adwaita_engine_render_icon_pixbuf;
 
 	gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
 					      g_param_spec_boxed ("focus-border-color",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]