Files
tryton/tryton/common/cellrendererbinary.py
T
2012-01-27 01:45:08 +01:00

160 lines
6.1 KiB
Python

#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import gtk
import gobject
import pango
BUTTON_BORDER = 10
BUTTON_SPACING = 2
class CellRendererBinary(gtk.GenericCellRenderer):
__gproperties__ = {
'visible': (gobject.TYPE_INT, 'Visible', 'Visible', 0, 10, 0,
gobject.PARAM_READWRITE),
'editable': (gobject.TYPE_INT, 'Editable', 'Editable', 0, 10, 0,
gobject.PARAM_READWRITE),
'size': (gobject.TYPE_STRING, 'Size', 'Size', '',
gobject.PARAM_READWRITE),
}
__gsignals__ = {
'new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,)),
'open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,)),
'save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,)),
'clear': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,)),
}
def __init__(self, use_filename):
self.__gobject_init__()
self.visible = True
self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE)
self.use_filename = use_filename
if use_filename:
self.buttons = ('new', 'open', 'save', 'clear')
else:
self.buttons = ('new', 'save', 'clear')
self.clicking = ''
self.images = {}
widget = gtk.Button()
for key, stock_name in (
('new', 'tryton-find'),
('open', 'tryton-open'),
('save', 'tryton-save-as'),
('clear', 'tryton-clear')):
# hack to get gtk.gdk.Image from stock icon
img_sensitive = widget.render_icon(stock_name,
gtk.ICON_SIZE_SMALL_TOOLBAR)
img_insensitive = img_sensitive.copy()
img_sensitive.saturate_and_pixelate(img_insensitive, 0, False)
width = img_sensitive.get_width()
height = img_sensitive.get_height()
self.images[key] = (img_sensitive, img_insensitive, width, height)
def do_set_property(self, pspec, value):
setattr(self, pspec.name, value)
def do_get_property(self, pspec):
return getattr(self, pspec.name)
def button_width(self):
return (sum(width for _, _, width, _ in self.images.itervalues())
+ (2 * (BUTTON_BORDER + BUTTON_SPACING) * len(self.buttons))
- 2 * BUTTON_SPACING)
def on_get_size(self, widget, cell_area=None):
if cell_area is None:
return (0, 0, 30, 18)
else:
return (cell_area.x, cell_area.y,
cell_area.width, cell_area.height)
def on_start_editing(self, event, widget, path, background_area,
cell_area, flags):
if event is None:
return
button_width = self.button_width()
for index, button_name in enumerate(self.buttons):
_, _, pxbf_width, _ = self.images[button_name]
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING) * index)
x_button = cell_area.x + x_offset
if x_button < event.x < (x_button + pxbf_width
+ (2 * BUTTON_BORDER)):
break
else:
button_name = None
if not self.visible or not button_name:
return
if not self.editable and button_name in ('new', 'clear'):
return
if not self.size and button_name == 'save':
return
if event.type == gtk.gdk.BUTTON_PRESS:
self.clicking = button_name
self.emit(button_name, path)
def timeout(self, widget):
self.clicking = ''
widget.queue_draw()
gobject.timeout_add(60, timeout, self, widget)
def on_render(self, window, widget, background_area, cell_area,
expose_area, flags):
if not self.visible:
return
# Handle Pixmap window as pygtk failed
if type(window) == gtk.gdk.Pixmap:
return
button_width = self.button_width()
# display size
layout = widget.create_pango_layout(self.size)
layout.set_font_description(widget.style.font_desc)
w, h = layout.get_size()
x = int(cell_area.x + cell_area.width - button_width - w / pango.SCALE
- BUTTON_SPACING)
y = int(cell_area.y + (cell_area.height - h / pango.SCALE) / 2)
layout.set_width(((cell_area.width / 2) - 2) * pango.SCALE)
state = gtk.STATE_NORMAL
if flags & gtk.CELL_RENDERER_SELECTED:
state = gtk.STATE_ACTIVE
if x >= cell_area.x:
widget.style.paint_layout(window, state, True, expose_area,
widget, "cellrendererbinary", x, y, layout)
# display buttons
for index, button_name in enumerate(self.buttons):
state = gtk.STATE_NORMAL
shadow = gtk.SHADOW_OUT
pxbf_sens, pxbf_insens, pxbf_width, pxbf_height = \
self.images[button_name]
if (self.clicking == button_name
and flags & gtk.CELL_RENDERER_SELECTED):
state = gtk.STATE_ACTIVE
shadow = gtk.SHADOW_IN
if (not self.editable and button_name in ('new', 'clear')
or not self.size and button_name in ('open', 'save')):
state = gtk.STATE_INSENSITIVE
pixbuf = pxbf_insens
else:
pixbuf = pxbf_sens
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING) * index)
if x_offset < 0:
continue
widget.style.paint_box(window, state, shadow,
None, widget, "button", cell_area.x + x_offset, cell_area.y,
pxbf_width + (2 * BUTTON_BORDER), cell_area.height)
window.draw_pixbuf(widget.style.black_gc,
pixbuf, 0, 0,
cell_area.x + x_offset + BUTTON_BORDER,
cell_area.y + (cell_area.height - pxbf_height) / 2)
gobject.type_register(CellRendererBinary)