Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEben Eliason <eben@laptop.org>2007-11-12 17:50:39 (GMT)
committer Eben Eliason <eben@laptop.org>2007-11-12 17:50:39 (GMT)
commite7259e0eb77912badafdacfc305383672193b048 (patch)
tree3ec1d4162cfc1bbdb8010e46f994a6858f406176
parent6818b2d30cd6297e5765514e95bc38bb1772fb2f (diff)
parent6a7df34ff944484a0ecd52aa46216a195b822ed2 (diff)
Merge branch 'master' of git+ssh://eben@dev.laptop.org/git/artwork
-rw-r--r--NEWS7
-rw-r--r--gtk/engine/Makefile.am2
-rw-r--r--gtk/engine/sugar-style.c78
-rw-r--r--gtk/engine/sugar-utils.c114
-rw-r--r--gtk/engine/sugar-utils.h24
5 files changed, 225 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 13601a0..61e6f29 100644
--- a/NEWS
+++ b/NEWS
@@ -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);
+