new ImageCellRenderer to show pixbuf and pixbufAnimation in treeview (take less CPU time than the old method)
This commit is contained in:
parent
3dbb75f9db
commit
353b74c4ba
1 changed files with 110 additions and 41 deletions
|
@ -35,6 +35,81 @@ from dialogs import *
|
||||||
|
|
||||||
GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade'
|
GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade'
|
||||||
|
|
||||||
|
|
||||||
|
class ImageCellRenderer(gtk.GenericCellRenderer):
|
||||||
|
|
||||||
|
__gproperties__ = {
|
||||||
|
"image": (gobject.TYPE_OBJECT, "Image",
|
||||||
|
"Image", gobject.PARAM_READWRITE),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.__gobject_init__()
|
||||||
|
self.image = None
|
||||||
|
|
||||||
|
def do_set_property(self, pspec, value):
|
||||||
|
setattr(self, pspec.name, value)
|
||||||
|
|
||||||
|
def do_get_property(self, pspec):
|
||||||
|
return getattr(self, pspec.name)
|
||||||
|
|
||||||
|
def animation_timeout(self, tree, image):
|
||||||
|
if image.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
|
image.get_data('iter').advance()
|
||||||
|
gobject.timeout_add(image.get_data('iter').get_delay_time(), self.animation_timeout, tree, image)
|
||||||
|
tree.queue_draw()
|
||||||
|
# tree.queue_draw_area(16,32,16,340)
|
||||||
|
# tree.queue_draw_area(draw_rect.x, \
|
||||||
|
# draw_rect.y, pix.get_width(), pix.get_height())
|
||||||
|
|
||||||
|
def on_render(self, window, widget, background_area,cell_area, \
|
||||||
|
expose_area, flags):
|
||||||
|
pix_rect = gtk.gdk.Rectangle()
|
||||||
|
pix_rect.x, pix_rect.y, pix_rect.width, pix_rect.height = self.on_get_size(widget, cell_area)
|
||||||
|
|
||||||
|
pix_rect.x += cell_area.x
|
||||||
|
pix_rect.y += cell_area.y
|
||||||
|
pix_rect.width -= 2 * self.get_property("xpad")
|
||||||
|
pix_rect.height -= 2 * self.get_property("ypad")
|
||||||
|
|
||||||
|
draw_rect = cell_area.intersect(pix_rect)
|
||||||
|
draw_rect = expose_area.intersect(draw_rect)
|
||||||
|
|
||||||
|
if self.image.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
|
if not self.image.get_data('iter'):
|
||||||
|
animation = self.image.get_animation()
|
||||||
|
self.image.set_data('iter', animation.get_iter())
|
||||||
|
gobject.timeout_add(self.image.get_data('iter').get_delay_time(), self.animation_timeout, widget, self.image)
|
||||||
|
|
||||||
|
pix = self.image.get_data('iter').get_pixbuf()
|
||||||
|
elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF:
|
||||||
|
pix = self.image.get_pixbuf()
|
||||||
|
if pix:
|
||||||
|
window.draw_pixbuf(widget.style.black_gc, pix, \
|
||||||
|
draw_rect.x-pix_rect.x, draw_rect.y-pix_rect.y, draw_rect.x, \
|
||||||
|
draw_rect.y+2, draw_rect.width, draw_rect.height, \
|
||||||
|
gtk.gdk.RGB_DITHER_NONE, 0, 0)
|
||||||
|
|
||||||
|
def on_get_size(self, widget, cell_area):
|
||||||
|
if self.image.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
|
animation = self.image.get_animation()
|
||||||
|
pix = animation.get_iter().get_pixbuf()
|
||||||
|
elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF:
|
||||||
|
pix = self.image.get_pixbuf()
|
||||||
|
pixbuf_width = pix.get_width()
|
||||||
|
pixbuf_height = pix.get_height()
|
||||||
|
calc_width = self.get_property("xpad") * 2 + pixbuf_width
|
||||||
|
calc_height = self.get_property("ypad") * 2 + pixbuf_height
|
||||||
|
x_offset = 0
|
||||||
|
y_offset = 0
|
||||||
|
if cell_area and pixbuf_width > 0 and pixbuf_height > 0:
|
||||||
|
x_offset = self.get_property("xalign") * (cell_area.width - calc_width - self.get_property("xpad"))
|
||||||
|
y_offset = self.get_property("yalign") * (cell_area.height - calc_height - self.get_property("ypad"))
|
||||||
|
return x_offset, y_offset, calc_width, calc_height
|
||||||
|
|
||||||
|
gobject.type_register(ImageCellRenderer)
|
||||||
|
|
||||||
|
|
||||||
class user:
|
class user:
|
||||||
"""Informations concerning each users"""
|
"""Informations concerning each users"""
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
|
@ -147,11 +222,13 @@ class message_Window:
|
||||||
self.account = account
|
self.account = account
|
||||||
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Chat', APP)
|
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Chat', APP)
|
||||||
self.window = self.xml.get_widget('Chat')
|
self.window = self.xml.get_widget('Chat')
|
||||||
# hbox = xml.get_widget('hbox1')
|
|
||||||
# hbox.set_property('resize-mode', 2)
|
|
||||||
self.window.set_title('Chat with ' + user.name)
|
self.window.set_title('Chat with ' + user.name)
|
||||||
self.img = self.xml.get_widget('image')
|
self.img = self.xml.get_widget('image')
|
||||||
self.img.set_from_pixbuf(self.plugin.roster.pixbufs[user.show])
|
image = self.plugin.roster.pixbufs[user.show]
|
||||||
|
if image.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
|
self.img.set_from_animation(image.get_animation())
|
||||||
|
elif image.get_storage_type() == gtk.IMAGE_PIXBUF:
|
||||||
|
self.img.set_from_pixbuf(image.get_pixbuf())
|
||||||
self.xml.get_widget('button_contact').set_label(user.name + ' <'\
|
self.xml.get_widget('button_contact').set_label(user.name + ' <'\
|
||||||
+ user.jid + '>')
|
+ user.jid + '>')
|
||||||
self.xml.get_widget('button_contact').set_resize_mode(gtk.RESIZE_QUEUE)
|
self.xml.get_widget('button_contact').set_resize_mode(gtk.RESIZE_QUEUE)
|
||||||
|
@ -443,17 +520,6 @@ class roster_Window:
|
||||||
if model.iter_n_children(parent_i) == 0:
|
if model.iter_n_children(parent_i) == 0:
|
||||||
model.remove(parent_i)
|
model.remove(parent_i)
|
||||||
|
|
||||||
def update_anim(self, iteration, iter, jid, account):
|
|
||||||
"""Update animation in the treeview"""
|
|
||||||
if not self.plugin.queues[account].has_key(jid):
|
|
||||||
return
|
|
||||||
model = self.tree.get_model()
|
|
||||||
iteration.advance()
|
|
||||||
pix = iteration.get_pixbuf()
|
|
||||||
model.set_value(iter, 0, pix)
|
|
||||||
gobject.timeout_add(iteration.get_delay_time(), self.update_anim, \
|
|
||||||
iteration, iter, jid, account)
|
|
||||||
|
|
||||||
def redraw_jid(self, jid, account):
|
def redraw_jid(self, jid, account):
|
||||||
"""draw the correct pixbuf and name"""
|
"""draw the correct pixbuf and name"""
|
||||||
model = self.tree.get_model()
|
model = self.tree.get_model()
|
||||||
|
@ -472,15 +538,10 @@ class roster_Window:
|
||||||
show = u.show
|
show = u.show
|
||||||
for iter in iters:
|
for iter in iters:
|
||||||
if self.plugin.queues[account].has_key(jid):
|
if self.plugin.queues[account].has_key(jid):
|
||||||
pix = self.pixbufs['message']
|
img = self.pixbufs['message']
|
||||||
else:
|
else:
|
||||||
pix = self.pixbufs[show]
|
img = self.pixbufs[show]
|
||||||
if isinstance(pix, gtk.gdk.PixbufAnimation):
|
model.set_value(iter, 0, img)
|
||||||
iteration = pix.get_iter()
|
|
||||||
pix = iteration.get_pixbuf()
|
|
||||||
gobject.timeout_add(iteration.get_delay_time(), self.update_anim, \
|
|
||||||
iteration, iter, jid, account)
|
|
||||||
model.set_value(iter, 0, pix)
|
|
||||||
model.set_value(iter, 1, name)
|
model.set_value(iter, 1, name)
|
||||||
|
|
||||||
def mkmenu(self):
|
def mkmenu(self):
|
||||||
|
@ -589,8 +650,13 @@ class roster_Window:
|
||||||
if self.plugin.windows[account]['chats'].has_key(user.jid):
|
if self.plugin.windows[account]['chats'].has_key(user.jid):
|
||||||
#TODO: should show pibuf of the prioritest resource
|
#TODO: should show pibuf of the prioritest resource
|
||||||
if len(self.contacts[account][user.jid]) < 2:
|
if len(self.contacts[account][user.jid]) < 2:
|
||||||
|
img = self.pixbufs[show]
|
||||||
|
if img.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
self.plugin.windows[account]['chats'][user.jid].\
|
self.plugin.windows[account]['chats'][user.jid].\
|
||||||
img.set_from_pixbuf(self.pixbufs[show])
|
img = set_from_animation(img.get_animation())
|
||||||
|
elif img.get_storage_type() == gtk.IMAGE_PIXBUF:
|
||||||
|
self.plugin.windows[account]['chats'][user.jid].\
|
||||||
|
img = set_from_pixbuf(img.get_pixbuf())
|
||||||
name = user.name
|
name = user.name
|
||||||
if user.resource != '':
|
if user.resource != '':
|
||||||
name += '/'+user.resource
|
name += '/'+user.resource
|
||||||
|
@ -1092,21 +1158,24 @@ class roster_Window:
|
||||||
files.append(self.path + state + '.gif')
|
files.append(self.path + state + '.gif')
|
||||||
files.append(self.path + state + '.png')
|
files.append(self.path + state + '.png')
|
||||||
files.append(self.path + state + '.xpm')
|
files.append(self.path + state + '.xpm')
|
||||||
self.pixbufs[state] = None
|
image = gtk.Image()
|
||||||
|
image.show()
|
||||||
|
self.pixbufs[state] = image
|
||||||
for file in files:
|
for file in files:
|
||||||
if not os.path.exists(file):
|
if not os.path.exists(file):
|
||||||
continue
|
continue
|
||||||
fct = gtk.gdk.pixbuf_new_from_file
|
|
||||||
if file.find('.gif') != -1:
|
if file.find('.gif') != -1:
|
||||||
fct = gtk.gdk.PixbufAnimation
|
pix = gtk.gdk.PixbufAnimation(file)
|
||||||
pix = fct(file)
|
image.set_from_animation(pix)
|
||||||
self.pixbufs[state] = pix
|
else:
|
||||||
|
pix = gtk.gdk.pixbuf_new_from_file(file)
|
||||||
|
image.set_from_pixbuf(pix)
|
||||||
break
|
break
|
||||||
for state in ('online', 'away', 'xa', 'dnd', 'invisible', 'offline'):
|
for state in ('online', 'away', 'xa', 'dnd', 'invisible', 'offline'):
|
||||||
image = gtk.Image()
|
# image = gtk.Image()
|
||||||
image.set_from_pixbuf(self.pixbufs[state])
|
# image.set_from_pixbuf(self.pixbufs[state])
|
||||||
image.show()
|
# image.show()
|
||||||
self.xml.get_widget(state).set_image(image)
|
self.xml.get_widget(state).set_image(self.pixbufs[state])
|
||||||
|
|
||||||
def on_show_off(self, widget):
|
def on_show_off(self, widget):
|
||||||
"""when show offline option is changed :
|
"""when show offline option is changed :
|
||||||
|
@ -1178,7 +1247,7 @@ class roster_Window:
|
||||||
self.contacts[a] = {}
|
self.contacts[a] = {}
|
||||||
self.groups[a] = {}
|
self.groups[a] = {}
|
||||||
#(icon, name, type, jid, editable)
|
#(icon, name, type, jid, editable)
|
||||||
model = gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, \
|
model = gtk.TreeStore(gtk.Image, str, str, str, \
|
||||||
gobject.TYPE_BOOLEAN)
|
gobject.TYPE_BOOLEAN)
|
||||||
model.set_sort_func(1, self.compareIters)
|
model.set_sort_func(1, self.compareIters)
|
||||||
model.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
model.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
||||||
|
@ -1192,9 +1261,9 @@ class roster_Window:
|
||||||
#columns
|
#columns
|
||||||
col = gtk.TreeViewColumn()
|
col = gtk.TreeViewColumn()
|
||||||
self.tree.append_column(col)
|
self.tree.append_column(col)
|
||||||
render_pixbuf = gtk.CellRendererPixbuf()
|
render_pixbuf = ImageCellRenderer()
|
||||||
col.pack_start(render_pixbuf, expand = False)
|
col.pack_start(render_pixbuf, expand = False)
|
||||||
col.add_attribute(render_pixbuf, 'pixbuf', 0)
|
col.add_attribute(render_pixbuf, 'image', 0)
|
||||||
col.set_cell_data_func(render_pixbuf, self.iconCellDataFunc, None)
|
col.set_cell_data_func(render_pixbuf, self.iconCellDataFunc, None)
|
||||||
|
|
||||||
render_text = gtk.CellRendererText()
|
render_text = gtk.CellRendererText()
|
||||||
|
@ -1250,11 +1319,11 @@ class systray:
|
||||||
status = 'message'
|
status = 'message'
|
||||||
else:
|
else:
|
||||||
status = self.status
|
status = self.status
|
||||||
pix = self.plugin.roster.pixbufs[status]
|
image = self.plugin.roster.pixbufs[status]
|
||||||
if isinstance(pix, gtk.gdk.PixbufAnimation):
|
if image.get_storage_type() == gtk.IMAGE_ANIMATION:
|
||||||
self.img_tray.set_from_animation(pix)
|
self.img_tray.set_from_animation(image.get_animation())
|
||||||
else:
|
elif image.get_storage_type() == gtk.IMAGE_PIXBUF:
|
||||||
self.img_tray.set_from_pixbuf(pix)
|
self.img_tray.set_from_pixbuf(image.get_pixbuf())
|
||||||
|
|
||||||
def add_jid(self, jid, account):
|
def add_jid(self, jid, account):
|
||||||
list = [account, jid]
|
list = [account, jid]
|
||||||
|
|
Loading…
Add table
Reference in a new issue