diff options
-rw-r--r-- | widgets/table/e-cell-toggle.c | 178 |
1 files changed, 130 insertions, 48 deletions
diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c index 4f30093921..a42d7dbd1a 100644 --- a/widgets/table/e-cell-toggle.c +++ b/widgets/table/e-cell-toggle.c @@ -30,18 +30,22 @@ #include <libgnomeui/gnome-canvas.h> #include "e-cell-toggle.h" #include "gal/util/e-util.h" +#include "gal/widgets/e-hsv-utils.h" #include "e-table-item.h" #define PARENT_TYPE e_cell_get_type () typedef struct { - ECellView cell_view; - GdkGC *gc; - GnomeCanvas *canvas; + ECellView cell_view; + GdkGC *gc; + GnomeCanvas *canvas; + GdkPixmap **pixmap_cache; } ECellToggleView; static ECellClass *parent_class; +#define CACHE_SEQ_COUNT 6 + /* * ECell::realize method */ @@ -51,11 +55,16 @@ etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1); ETableItem *eti = E_TABLE_ITEM (e_table_item_view); GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + ECellToggle *etog = E_CELL_TOGGLE (ecell); + int i; toggle_view->cell_view.ecell = ecell; toggle_view->cell_view.e_table_model = table_model; toggle_view->cell_view.e_table_item_view = e_table_item_view; toggle_view->canvas = canvas; + toggle_view->pixmap_cache = g_new (GdkPixmap *, etog->n_states * CACHE_SEQ_COUNT); + for (i = 0; i < etog->n_states * CACHE_SEQ_COUNT; i++) + toggle_view->pixmap_cache[i] = NULL; return (ECellView *) toggle_view; } @@ -63,6 +72,13 @@ etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) static void etog_kill_view (ECellView *ecell_view) { + ECellToggle *etog = E_CELL_TOGGLE (ecell_view->ecell); + ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; + int i; + + for (i = 0; i < etog->n_states * CACHE_SEQ_COUNT; i++) + if (toggle_view->pixmap_cache[i]) + gdk_pixmap_unref (toggle_view->pixmap_cache[i]); g_free (ecell_view); } @@ -86,6 +102,81 @@ etog_unrealize (ECellView *ecv) toggle_view->gc = NULL; } +#define PIXMAP_CACHE(toggle_view, cache_seq, image_seq) ((toggle_view)->pixmap_cache[(cache_seq) * E_CELL_TOGGLE (((ECellView *) (toggle_view))->ecell)->n_states + (image_seq)]) + +#define RGB_COLOR(color) (((color).red & 0xff00) << 8 | \ + ((color).green & 0xff00) | \ + ((color).blue & 0xff00) >> 8) + +static void +check_cache (ECellToggleView *toggle_view, int image_seq, int cache_seq) +{ + ECellView *ecell_view = (ECellView *) toggle_view; + ECellToggle *etog = E_CELL_TOGGLE (ecell_view->ecell); + + if (PIXMAP_CACHE (toggle_view, cache_seq, image_seq) == NULL) { + GdkPixbuf *image = etog->images[image_seq]; + GdkPixbuf *flat; + guint32 color = 0xffffff; + int width = gdk_pixbuf_get_width (image); + int height = gdk_pixbuf_get_height (image); + + PIXMAP_CACHE (toggle_view, cache_seq, image_seq) = + gdk_pixmap_new (toggle_view->canvas->layout.bin_window, width, height, + gtk_widget_get_visual (GTK_WIDGET (toggle_view->canvas))->depth); + + + switch (cache_seq % 3) { + case 0: + color = RGB_COLOR (GTK_WIDGET (toggle_view->canvas)->style->bg [GTK_STATE_SELECTED]); + break; + case 1: + color = RGB_COLOR (GTK_WIDGET (toggle_view->canvas)->style->bg [GTK_STATE_ACTIVE]); + break; + case 2: + color = RGB_COLOR (GTK_WIDGET (toggle_view->canvas)->style->base [GTK_STATE_NORMAL]); + break; + } + + if (cache_seq >= 3) { + double r, g, b, h, s, v; + r = ((color >> 16) & 0xff) / 255.0f; + g = ((color >> 8) & 0xff) / 255.0f; + b = (color & 0xff) / 255.0f; + + e_rgb_to_hsv (r, g, b, &h, &s, &v); + + if (v - 0.05f < 0) { + v += 0.05f; + } else { + v -= 0.05f; + } + + e_hsv_to_rgb (h, s, v, &r, &g, &b); + + color = ((((int)(r * 255.0f)) & 0xff) << 16) + + ((((int)(g * 255.0f)) & 0xff) << 8) + + (((int)(b * 255.0f)) & 0xff); + } + + flat = gdk_pixbuf_composite_color_simple (image, + width, height, + GDK_INTERP_BILINEAR, + 255, + 1, + color, color); + + gdk_pixbuf_render_to_drawable (flat, PIXMAP_CACHE (toggle_view, cache_seq, image_seq), + toggle_view->gc, + 0, 0, + 0, 0, + width, height, + GDK_RGB_DITHER_NORMAL, + 0, 0); + gdk_pixbuf_unref (flat); + } +} + /* * ECell::draw method */ @@ -96,11 +187,11 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, { ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell); gboolean selected; -#if 0 ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; -#endif + GdkPixmap *pixmap; GdkPixbuf *image; int x, y, width, height; + int cache_seq; const int value = GPOINTER_TO_INT ( e_table_model_value_at (ecell_view->e_table_model, model_col, row)); @@ -113,7 +204,21 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, return; } - image = toggle->images [value]; + if (flags & E_CELL_SELECTED) { + if (GTK_WIDGET_HAS_FOCUS (toggle_view->canvas)) + cache_seq = 0; + else + cache_seq = 1; + } else + cache_seq = 2; + + if (E_TABLE_ITEM (ecell_view->e_table_item_view)->alternating_row_colors && (row % 2) == 0) + cache_seq += 3; + + check_cache (toggle_view, value, cache_seq); + + pixmap = PIXMAP_CACHE (toggle_view, cache_seq, value); + image = toggle->images[value]; if ((x2 - x1) < gdk_pixbuf_get_width (image)){ x = x1; @@ -131,44 +236,11 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, height = gdk_pixbuf_get_height (image); } -#if 0 /* do alpha */ - if (gdk_pixbuf_get_has_alpha (image)) { - flat = gdk_pixbuf_composite_color_simple ( - image, - gdk_pixbuf_get_width (image), - gdk_pixbuf_get_height (image), - GDK_INTERP_NEAREST, - 255, - 32, - 0xffffff, 0xffffff); - - gdk_pixbuf_render_to_drawable (flat, drawable, - toggle_view->gc, - 0, 0, - x, y, - width, height, - GDK_RGB_DITHER_NORMAL, - 0, 0); - gdk_pixbuf_unref (flat); - } else { - gdk_pixbuf_render_to_drawable (image, drawable, - toggle_view->gc, - 0, 0, - x, y, - width, height, - GDK_RGB_DITHER_NORMAL, - 0, 0); - } -#else - gdk_pixbuf_render_to_drawable_alpha (image, drawable, - 0, 0, - x, y, - width, height, - GDK_PIXBUF_ALPHA_BILEVEL, - 128, - GDK_RGB_DITHER_NORMAL, - x, y); -#endif + gdk_draw_pixmap (drawable, toggle_view->gc, + pixmap, + 0, 0, + x, y, + width, height); } static void @@ -260,6 +332,9 @@ etog_destroy (GtkObject *object) g_free (etog->images); + etog->images = NULL; + etog->n_states = 0; + GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -282,7 +357,16 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) parent_class = gtk_type_class (PARENT_TYPE); } -E_MAKE_TYPE(e_cell_toggle, "ECellToggle", ECellToggle, e_cell_toggle_class_init, NULL, PARENT_TYPE); +static void +e_cell_toggle_init (GtkObject *object) +{ + ECellToggle *etog = (ECellToggle *) object; + + etog->images = NULL; + etog->n_states = 0; +} + +E_MAKE_TYPE(e_cell_toggle, "ECellToggle", ECellToggle, e_cell_toggle_class_init, e_cell_toggle_init, PARENT_TYPE); /** * e_cell_toggle_construct: @@ -310,7 +394,7 @@ e_cell_toggle_construct (ECellToggle *etog, int border, int n_states, GdkPixbuf gdk_pixbuf_ref (images [i]); if (gdk_pixbuf_get_height (images [i]) > max_height) - max_height = gdk_pixbuf_get_height (images [i]); + max_height = gdk_pixbuf_get_height (images [i]); } etog->height = max_height; @@ -339,5 +423,3 @@ e_cell_toggle_new (int border, int n_states, GdkPixbuf **images) return (ECell *) etog; } - - |