diff options
author | Eben Eliason <eben@laptop.org> | 2007-11-12 17:50:39 (GMT) |
---|---|---|
committer | Eben Eliason <eben@laptop.org> | 2007-11-12 17:50:39 (GMT) |
commit | e7259e0eb77912badafdacfc305383672193b048 (patch) | |
tree | 3ec1d4162cfc1bbdb8010e46f994a6858f406176 | |
parent | 6818b2d30cd6297e5765514e95bc38bb1772fb2f (diff) | |
parent | 6a7df34ff944484a0ecd52aa46216a195b822ed2 (diff) |
Merge branch 'master' of git+ssh://eben@dev.laptop.org/git/artwork
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | gtk/engine/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/engine/sugar-style.c | 78 | ||||
-rw-r--r-- | gtk/engine/sugar-utils.c | 114 | ||||
-rw-r--r-- | gtk/engine/sugar-utils.h | 24 |
5 files changed, 225 insertions, 0 deletions
@@ -1,3 +1,10 @@ +Snapshot 0763fefc48 + +* #4610 Prevent a division by zero while making icons insensitive. (benzea) + +Snapshot 9bc8be4d48 + +* #4568 Implement a better effect for insensitive icons [may need more tweaking] (benzea) * Added tray-hide/show icons (eben) * Added a zoom-original button for returning to actual size (eben) * Updated the full media button set to the new design spec (eben) diff --git a/gtk/engine/Makefile.am b/gtk/engine/Makefile.am index 34bd007..eb720ff 100644 --- a/gtk/engine/Makefile.am +++ b/gtk/engine/Makefile.am @@ -15,6 +15,8 @@ libsugar_la_SOURCES = \ sugar-style.c \ sugar-info.h \ sugar-info.c \ + sugar-utils.h \ + sugar-utils.c \ sugar-drawing.h \ sugar-drawing.c diff --git a/gtk/engine/sugar-style.c b/gtk/engine/sugar-style.c index e3ca9e6..97a3062 100644 --- a/gtk/engine/sugar-style.c +++ b/gtk/engine/sugar-style.c @@ -25,6 +25,7 @@ #include "sugar-rc-style.h" #include "sugar-info.h" #include "sugar-drawing.h" +#include "sugar-utils.h" #define SANITIZE_SIZE g_return_if_fail (width >= -1 && height >= -1); \ if (width == -1 && height == -1) { \ @@ -776,6 +777,81 @@ sugar_style_draw_layout(GtkStyle *style, gdk_gc_set_clip_rectangle (gc, NULL); } +/* Based on the GTK+ implementation. */ +static GdkPixbuf* +sugar_style_render_icon (GtkStyle *style, + const GtkIconSource *source, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const gchar *detail) +{ + gint width = 1; + gint height = 1; + GdkPixbuf *scaled; + GdkPixbuf *stated; + GdkPixbuf *base_pixbuf; + GdkScreen *screen; + GtkSettings *settings; + + /* Oddly, style can be NULL in this function, because + * GtkIconSet can be used without a style and if so + * it uses this function. + */ + + base_pixbuf = gtk_icon_source_get_pixbuf (source); + + g_return_val_if_fail (base_pixbuf != NULL, NULL); + + if (widget && gtk_widget_has_screen (widget)) { + screen = gtk_widget_get_screen (widget); + settings = gtk_settings_get_for_screen (screen); + } else if (style && style->colormap) { + screen = gdk_colormap_get_screen (style->colormap); + settings = gtk_settings_get_for_screen (screen); + } else { + settings = gtk_settings_get_default (); + g_warning ("Using the default screen to get the icon sizes"); + } + + if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, 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 = sugar_pixbuf_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_INSENSITIVE) { + guint base = 127; + + if (style) { + GdkColor *color = &style->bg[GTK_STATE_INSENSITIVE]; + base = (color->red >> 8) + (color->green >> 8) + (color->blue >> 8); + base = base / 3; + } + + stated = sugar_get_insensitive_icon (scaled, 25, 127); + + /* Unref the scaled one. */ + g_object_unref (scaled); + } else { + stated = scaled; + } + } else + stated = scaled; + + return stated; +} + static void sugar_style_class_init (SugarStyleClass *klass) { @@ -798,6 +874,8 @@ sugar_style_class_init (SugarStyleClass *klass) style_class->draw_option = sugar_style_draw_option; style_class->draw_check = sugar_style_draw_check; style_class->draw_layout = sugar_style_draw_layout; + + style_class->render_icon = sugar_style_render_icon; } diff --git a/gtk/engine/sugar-utils.c b/gtk/engine/sugar-utils.c new file mode 100644 index 0000000..f5525ea --- /dev/null +++ b/gtk/engine/sugar-utils.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007, Benjamin Berg + * + * 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 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "sugar-utils.h" + +GdkPixbuf* +sugar_pixbuf_scale_or_ref (GdkPixbuf *pixbuf, + gint width, + gint height) +{ + gint pixbuf_width = gdk_pixbuf_get_width (pixbuf); + gint pixbuf_height = gdk_pixbuf_get_height (pixbuf); + + if ((pixbuf_width != width) || (pixbuf_height != height)) { + return gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR); + } else { + g_object_ref (pixbuf); + return pixbuf; + } +} + +#define RED 0 +#define GREEN 1 +#define BLUE 2 +#define ALPHA 3 + +GdkPixbuf* +sugar_get_insensitive_icon (GdkPixbuf *icon, + guint range, + guint base) +{ + GdkPixbuf *result = gdk_pixbuf_copy (icon); + guint x, y, rowstride, height, width; + guint n_channels; + guint8 *pixel, *pixels; + guint min_color_value = G_MAXUINT8; + guint max_color_value = 0; + guint mult; + gboolean has_alpha; + + width = gdk_pixbuf_get_width (result); + height = gdk_pixbuf_get_height (result); + rowstride = gdk_pixbuf_get_rowstride (result); + n_channels = gdk_pixbuf_get_n_channels (result); + pixels = gdk_pixbuf_get_pixels (result); + + for (y = 0; y < height; y++) { + pixel = pixels + y*rowstride; + for (x = 0; x < width; x++) { + if (n_channels == 4 && pixel[ALPHA] == 0) { + pixel += n_channels; + continue; + } + + min_color_value = MIN (min_color_value, pixel[RED]); + max_color_value = MAX (max_color_value, pixel[RED]); + + min_color_value = MIN (min_color_value, pixel[GREEN]); + max_color_value = MAX (max_color_value, pixel[GREEN]); + + min_color_value = MIN (min_color_value, pixel[BLUE]); + max_color_value = MAX (max_color_value, pixel[BLUE]); + + pixel += n_channels; + } + } + + /* Shift the base value to the lower side of the range */ + + if (max_color_value - min_color_value > 0) { + base = base - range / 2; + mult = (range << 8) / (max_color_value - min_color_value); + } else { + /* There is only one color, just fill everything with base. + * Se setting mult to 0 means that the old pixel value will just + * be discarted. */ + mult = 0; + } + + for (y = 0; y < height; y++) { + pixel = pixels + y*rowstride; + for (x = 0; x < width; x++) { + pixel[RED] = ((((guint) (pixel[RED] - min_color_value)) * mult) >> 8) + base; + pixel[GREEN] = ((((guint) (pixel[GREEN] - min_color_value)) * mult) >> 8) + base; + pixel[BLUE] = ((((guint) (pixel[BLUE] - min_color_value)) * mult) >> 8) + base; + + pixel += n_channels; + } + } + + return result; +} + +#undef RED +#undef GREEN +#undef BLUE +#undef ALPHA + diff --git a/gtk/engine/sugar-utils.h b/gtk/engine/sugar-utils.h new file mode 100644 index 0000000..d80a389 --- /dev/null +++ b/gtk/engine/sugar-utils.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2007, Benjamin Berg + * + * 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 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gdk/gdk.h> + +G_GNUC_INTERNAL GdkPixbuf* sugar_pixbuf_scale_or_ref (GdkPixbuf *pixbuf, gint width, gint height); +G_GNUC_INTERNAL GdkPixbuf* sugar_get_insensitive_icon (GdkPixbuf *icon, guint range, guint base); + |