Add a GdkPixmap * cache of rendered toggle images. This should
2002-03-15 Christopher James Lahey <clahey@ximian.com> * e-cell-toggle.c: Add a GdkPixmap * cache of rendered toggle images. This should considerably speed up over the wire performance of ECellToggle. svn path=/trunk/; revision=16177
This commit is contained in:

committed by
Chris Lahey

parent
524e5c62c0
commit
95c4e2623b
@ -30,18 +30,22 @@
|
|||||||
#include <libgnomeui/gnome-canvas.h>
|
#include <libgnomeui/gnome-canvas.h>
|
||||||
#include "e-cell-toggle.h"
|
#include "e-cell-toggle.h"
|
||||||
#include "gal/util/e-util.h"
|
#include "gal/util/e-util.h"
|
||||||
|
#include "gal/widgets/e-hsv-utils.h"
|
||||||
#include "e-table-item.h"
|
#include "e-table-item.h"
|
||||||
|
|
||||||
#define PARENT_TYPE e_cell_get_type ()
|
#define PARENT_TYPE e_cell_get_type ()
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ECellView cell_view;
|
ECellView cell_view;
|
||||||
GdkGC *gc;
|
GdkGC *gc;
|
||||||
GnomeCanvas *canvas;
|
GnomeCanvas *canvas;
|
||||||
|
GdkPixmap **pixmap_cache;
|
||||||
} ECellToggleView;
|
} ECellToggleView;
|
||||||
|
|
||||||
static ECellClass *parent_class;
|
static ECellClass *parent_class;
|
||||||
|
|
||||||
|
#define CACHE_SEQ_COUNT 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ECell::realize method
|
* 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);
|
ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
|
||||||
ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
|
ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
|
||||||
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
|
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.ecell = ecell;
|
||||||
toggle_view->cell_view.e_table_model = table_model;
|
toggle_view->cell_view.e_table_model = table_model;
|
||||||
toggle_view->cell_view.e_table_item_view = e_table_item_view;
|
toggle_view->cell_view.e_table_item_view = e_table_item_view;
|
||||||
toggle_view->canvas = canvas;
|
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;
|
return (ECellView *) toggle_view;
|
||||||
}
|
}
|
||||||
@ -63,6 +72,13 @@ etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view)
|
|||||||
static void
|
static void
|
||||||
etog_kill_view (ECellView *ecell_view)
|
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);
|
g_free (ecell_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +102,81 @@ etog_unrealize (ECellView *ecv)
|
|||||||
toggle_view->gc = NULL;
|
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
|
* ECell::draw method
|
||||||
*/
|
*/
|
||||||
@ -96,11 +187,11 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
|
|||||||
{
|
{
|
||||||
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
|
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
|
||||||
gboolean selected;
|
gboolean selected;
|
||||||
#if 0
|
|
||||||
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
|
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
|
||||||
#endif
|
GdkPixmap *pixmap;
|
||||||
GdkPixbuf *image;
|
GdkPixbuf *image;
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
|
int cache_seq;
|
||||||
|
|
||||||
const int value = GPOINTER_TO_INT (
|
const int value = GPOINTER_TO_INT (
|
||||||
e_table_model_value_at (ecell_view->e_table_model, model_col, row));
|
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;
|
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)){
|
if ((x2 - x1) < gdk_pixbuf_get_width (image)){
|
||||||
x = x1;
|
x = x1;
|
||||||
@ -131,44 +236,11 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
|
|||||||
height = gdk_pixbuf_get_height (image);
|
height = gdk_pixbuf_get_height (image);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* do alpha */
|
gdk_draw_pixmap (drawable, toggle_view->gc,
|
||||||
if (gdk_pixbuf_get_has_alpha (image)) {
|
pixmap,
|
||||||
flat = gdk_pixbuf_composite_color_simple (
|
0, 0,
|
||||||
image,
|
x, y,
|
||||||
gdk_pixbuf_get_width (image),
|
width, height);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -260,6 +332,9 @@ etog_destroy (GtkObject *object)
|
|||||||
|
|
||||||
g_free (etog->images);
|
g_free (etog->images);
|
||||||
|
|
||||||
|
etog->images = NULL;
|
||||||
|
etog->n_states = 0;
|
||||||
|
|
||||||
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
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);
|
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:
|
* 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]);
|
gdk_pixbuf_ref (images [i]);
|
||||||
|
|
||||||
if (gdk_pixbuf_get_height (images [i]) > max_height)
|
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;
|
etog->height = max_height;
|
||||||
@ -339,5 +423,3 @@ e_cell_toggle_new (int border, int n_states, GdkPixbuf **images)
|
|||||||
|
|
||||||
return (ECell *) etog;
|
return (ECell *) etog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user