From fcacd42efa5b9179a07c5794e1c0da2d7f9eee5e Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Tue, 3 May 2011 14:50:48 +0200 Subject: [PATCH] [sulfur] improve CellRendererStars rendering speed dramatically --- sulfur/src/sulfur/widgets.py | 110 +++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/sulfur/src/sulfur/widgets.py b/sulfur/src/sulfur/widgets.py index 38181d53d..71639b7e7 100644 --- a/sulfur/src/sulfur/widgets.py +++ b/sulfur/src/sulfur/widgets.py @@ -34,6 +34,7 @@ class CellRendererStars(gtk.GenericCellRenderer): self.__gobject_init__() self.value = -1 self.value_voted = 0.0 + self.__cache = {} def do_set_property(self, pspec, value): setattr(self, pspec.name, value) @@ -44,6 +45,9 @@ class CellRendererStars(gtk.GenericCellRenderer): def on_render(self, window, widget, background_area, cell_area, expose_area, flags): + if self.value == -1: + return + (x_offset, y_offset, width, height) = self.on_get_size(widget, cell_area) if isinstance(window, gtk.gdk.Window): @@ -54,55 +58,73 @@ class CellRendererStars(gtk.GenericCellRenderer): cell_area.x+x_offset, cell_area.y+y_offset, width, height) - if ((self.value > -1) and (self.value < 6)) or (self.value_voted > 0): - xt = widget.style.xthickness - empty = gtk.Image() - empty.set_from_file(const.empty_background) - try: - empty_buf = empty.get_pixbuf() - except ValueError: - return + xt = widget.style.xthickness - if self.value_voted: - star = gtk.Image() - star.set_from_file(const.star_selected_pixmap) + ## caching + cache_id = self.value + int_part = int(cache_id) # truncate + float_part = cache_id - int_part + if float_part < 0.6: + cache_id = float(int_part) + 0.5 + else: + cache_id = float(int_part) + 1.0 + + pixbuf = self.__cache.get((cache_id, self.value_voted)) + if pixbuf is not None: + window.draw_pixbuf(None, pixbuf, 0, 0, + cell_area.x+x_offset+xt, cell_area.y+y_offset+xt, -1, -1) + return + + empty = gtk.Image() + empty.set_from_file(const.empty_background) + try: + empty_buf = empty.get_pixbuf() + except ValueError: + return + + if self.value_voted: + star = gtk.Image() + star.set_from_file(const.star_selected_pixmap) + else: + star = gtk.Image() + star.set_from_file(const.star_normal_pixmap) + + star_empty = gtk.Image() + star_empty.set_from_file(const.star_empty_pixmap) + + star_half = gtk.Image() + star_half.set_from_file(const.star_half_pixmap) + + star_buf = star.get_pixbuf() + star_empty_buf = star_empty.get_pixbuf() + star_half_buf = star_half.get_pixbuf() + + w, h = star_buf.get_width(), star_buf.get_height() + myval = self.value + if self.value_voted: + myval = self.value_voted + empty_buf = empty_buf.scale_simple(w*5, h+12, gtk.gdk.INTERP_BILINEAR) + myvals = [0, w, w*2, w*3, w*4] + cnt = 0 + while myval > 0: + if (myval < 0.6): + star_half_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], + 6) else: - star = gtk.Image() - star.set_from_file(const.star_normal_pixmap) + star_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], 6) + myval -= 1 + cnt += 1 - star_empty = gtk.Image() - star_empty.set_from_file(const.star_empty_pixmap) + myval = 5 - cnt + while myval > 0: + star_empty_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], 6) + myval -= 1 + cnt += 1 - star_half = gtk.Image() - star_half.set_from_file(const.star_half_pixmap) - - star_buf = star.get_pixbuf() - star_empty_buf = star_empty.get_pixbuf() - star_half_buf = star_half.get_pixbuf() - - w, h = star_buf.get_width(), star_buf.get_height() - myval = self.value - if self.value_voted: - myval = self.value_voted - empty_buf = empty_buf.scale_simple(w*5, h+12, gtk.gdk.INTERP_BILINEAR) - myvals = [0, w, w*2, w*3, w*4] - cnt = 0 - while myval > 0: - if (myval < 0.6): - star_half_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], - 6) - else: - star_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], 6) - myval -= 1 - cnt += 1 - myval = 5 - cnt - while myval > 0: - star_empty_buf.copy_area(0, 0, w, h, empty_buf, myvals[cnt], 6) - myval -= 1 - cnt += 1 - - if empty_buf: window.draw_pixbuf(None, empty_buf, 0, 0, + if empty_buf: + self.__cache[(cache_id, self.value_voted)] = empty_buf + window.draw_pixbuf(None, empty_buf, 0, 0, cell_area.x+x_offset+xt, cell_area.y+y_offset+xt, -1, -1)