| 1 | ## cell_renderer_image.py |
|---|
| 2 | ## |
|---|
| 3 | ## Contributors for this file: |
|---|
| 4 | ## - Yann Le Boulanger <asterix@lagaule.org> |
|---|
| 5 | ## - Nikos Kouremenos <kourem@gmail.com> |
|---|
| 6 | ## |
|---|
| 7 | ## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org> |
|---|
| 8 | ## Vincent Hanquez <tab@snarc.org> |
|---|
| 9 | ## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org> |
|---|
| 10 | ## Vincent Hanquez <tab@snarc.org> |
|---|
| 11 | ## Nikos Kouremenos <nkour@jabber.org> |
|---|
| 12 | ## Dimitur Kirov <dkirov@gmail.com> |
|---|
| 13 | ## Travis Shirk <travis@pobox.com> |
|---|
| 14 | ## Norman Rasmussen <norman@rasmussen.co.za> |
|---|
| 15 | ## |
|---|
| 16 | ## This program is free software; you can redistribute it and/or modify |
|---|
| 17 | ## it under the terms of the GNU General Public License as published |
|---|
| 18 | ## by the Free Software Foundation; version 2 only. |
|---|
| 19 | ## |
|---|
| 20 | ## This program is distributed in the hope that it will be useful, |
|---|
| 21 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 22 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 23 | ## GNU General Public License for more details. |
|---|
| 24 | ## |
|---|
| 25 | |
|---|
| 26 | import gtk |
|---|
| 27 | import gobject |
|---|
| 28 | |
|---|
| 29 | class CellRendererImage(gtk.GenericCellRenderer): |
|---|
| 30 | |
|---|
| 31 | __gproperties__ = { |
|---|
| 32 | 'image': (gobject.TYPE_OBJECT, 'Image', |
|---|
| 33 | 'Image', gobject.PARAM_READWRITE), |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | def __init__(self): |
|---|
| 37 | self.__gobject_init__() |
|---|
| 38 | self.image = None |
|---|
| 39 | self.iters = {} |
|---|
| 40 | |
|---|
| 41 | def do_set_property(self, pspec, value): |
|---|
| 42 | setattr(self, pspec.name, value) |
|---|
| 43 | |
|---|
| 44 | def do_get_property(self, pspec): |
|---|
| 45 | return getattr(self, pspec.name) |
|---|
| 46 | |
|---|
| 47 | def func(self, model, path, iter, (image, tree)): |
|---|
| 48 | if model.get_value(iter, 0) != image: |
|---|
| 49 | return |
|---|
| 50 | self.redraw = 1 |
|---|
| 51 | cell_area = tree.get_cell_area(path, tree.get_column(0)) |
|---|
| 52 | tree.queue_draw_area(cell_area.x, cell_area.y, |
|---|
| 53 | cell_area.width, cell_area.height) |
|---|
| 54 | |
|---|
| 55 | def animation_timeout(self, tree, image): |
|---|
| 56 | if image.get_storage_type() != gtk.IMAGE_ANIMATION: |
|---|
| 57 | return |
|---|
| 58 | self.redraw = 0 |
|---|
| 59 | iter = self.iters[image] |
|---|
| 60 | iter.advance() |
|---|
| 61 | model = tree.get_model() |
|---|
| 62 | model.foreach(self.func, (image, tree)) |
|---|
| 63 | if self.redraw: |
|---|
| 64 | gobject.timeout_add(iter.get_delay_time(), |
|---|
| 65 | self.animation_timeout, tree, image) |
|---|
| 66 | elif image in self.iters: |
|---|
| 67 | del self.iters[image] |
|---|
| 68 | |
|---|
| 69 | def on_render(self, window, widget, background_area, cell_area, |
|---|
| 70 | expose_area, flags): |
|---|
| 71 | if not self.image: |
|---|
| 72 | return |
|---|
| 73 | pix_rect = gtk.gdk.Rectangle() |
|---|
| 74 | pix_rect.x, pix_rect.y, pix_rect.width, pix_rect.height = \ |
|---|
| 75 | self.on_get_size(widget, cell_area) |
|---|
| 76 | |
|---|
| 77 | pix_rect.x += cell_area.x |
|---|
| 78 | pix_rect.y += cell_area.y |
|---|
| 79 | pix_rect.width -= 2 * self.get_property('xpad') |
|---|
| 80 | pix_rect.height -= 2 * self.get_property('ypad') |
|---|
| 81 | |
|---|
| 82 | draw_rect = cell_area.intersect(pix_rect) |
|---|
| 83 | draw_rect = expose_area.intersect(draw_rect) |
|---|
| 84 | |
|---|
| 85 | if self.image.get_storage_type() == gtk.IMAGE_ANIMATION: |
|---|
| 86 | if self.image not in self.iters: |
|---|
| 87 | animation = self.image.get_animation() |
|---|
| 88 | iter = animation.get_iter() |
|---|
| 89 | self.iters[self.image] = iter |
|---|
| 90 | gobject.timeout_add(iter.get_delay_time(), |
|---|
| 91 | self.animation_timeout, widget, self.image) |
|---|
| 92 | |
|---|
| 93 | pix = self.iters[self.image].get_pixbuf() |
|---|
| 94 | elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF: |
|---|
| 95 | pix = self.image.get_pixbuf() |
|---|
| 96 | else: |
|---|
| 97 | return |
|---|
| 98 | window.draw_pixbuf(widget.style.black_gc, pix, |
|---|
| 99 | draw_rect.x - pix_rect.x, |
|---|
| 100 | draw_rect.y - pix_rect.y, |
|---|
| 101 | draw_rect.x, draw_rect.y + 2, |
|---|
| 102 | draw_rect.width, draw_rect.height, |
|---|
| 103 | gtk.gdk.RGB_DITHER_NONE, 0, 0) |
|---|
| 104 | |
|---|
| 105 | def on_get_size(self, widget, cell_area): |
|---|
| 106 | if not self.image: |
|---|
| 107 | return 0, 0, 0, 0 |
|---|
| 108 | if self.image.get_storage_type() == gtk.IMAGE_ANIMATION: |
|---|
| 109 | animation = self.image.get_animation() |
|---|
| 110 | pix = animation.get_iter().get_pixbuf() |
|---|
| 111 | elif self.image.get_storage_type() == gtk.IMAGE_PIXBUF: |
|---|
| 112 | pix = self.image.get_pixbuf() |
|---|
| 113 | else: |
|---|
| 114 | return 0, 0, 0, 0 |
|---|
| 115 | pixbuf_width = pix.get_width() |
|---|
| 116 | pixbuf_height = pix.get_height() |
|---|
| 117 | calc_width = self.get_property('xpad') * 2 + pixbuf_width |
|---|
| 118 | calc_height = self.get_property('ypad') * 2 + pixbuf_height |
|---|
| 119 | x_offset = 0 |
|---|
| 120 | y_offset = 0 |
|---|
| 121 | if cell_area and pixbuf_width > 0 and pixbuf_height > 0: |
|---|
| 122 | x_offset = self.get_property('xalign') * \ |
|---|
| 123 | (cell_area.width - calc_width - \ |
|---|
| 124 | self.get_property('xpad')) |
|---|
| 125 | y_offset = self.get_property('yalign') * \ |
|---|
| 126 | (cell_area.height - calc_height - \ |
|---|
| 127 | self.get_property('ypad')) |
|---|
| 128 | return x_offset, y_offset, calc_width, calc_height |
|---|
| 129 | |
|---|
| 130 | if gtk.pygtk_version < (2, 8, 0): |
|---|
| 131 | gobject.type_register(CellRendererImage) |
|---|