[pygtk] re : adding buttons to ListStore rows
Laurent G.
lauranger at free.fr
Sat Aug 9 04:53:40 WST 2008
Hi
I don't know if you can get anything useful from what I send but here is
my class for color and toggle buttons I wrote for my gimp plugin.
Hth
Regards
Laurent G.
class ColorBtnCellRenderer(gtk.GenericCellRenderer):
__gsignals__ = {
'color-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT))
}
def __init__(self):
gtk.GenericCellRenderer.__init__(self)
self.__gobject_init__()
self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
self.xpad = 4; self.ypad = 3
self.xalign = 0.5; self.yalign = 0.5
self.gc = None
self.color = gtk.gdk.Color(100,100,100)
self.dialog = gtk.ColorSelectionDialog('')
self.active_area = None
self.sig_deac = 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 on_render(self, window, widget, background_area,
cell_area, expose_area, flags):
if not isinstance(window, gtk.gdk.Window):
print "not GdkWindow"
return
state = gtk.STATE_NORMAL
if flags & 128:
b = bool(flags & 64)
else:
b = not cmp_rects(self.active_area, cell_area)
shadow = gtk.SHADOW_OUT if b else gtk.SHADOW_IN
x_offset, y_offset, width, height = self.on_get_size(widget,
cell_area)
widget.style.paint_box(window,
state, shadow,
cell_area, widget, None,
cell_area.x,
cell_area.y,
cell_area.width, cell_area.height)
if self.gc is None:
self.bg = window.get_colormap().alloc_color(0xffff, 0, 0)
self.fg = window.get_colormap().alloc_color(0, 0xffff, 0)
self.gc = gtk.gdk.GC(window, self.fg, self.bg)
self.gc.set_rgb_fg_color(self.color)
window.draw_rectangle(self.gc, True, cell_area.x+x_offset,
cell_area.y+ y_offset, width, height)
def on_get_size(self, widget, cell_area):
if cell_area:
calc_width = cell_area.width - 2*self.xpad
calc_height = cell_area.height - 2*self.ypad
x_offset = int(self.xalign * (cell_area.width - calc_width))
x_offset = max(x_offset, 0)
y_offset = int(self.yalign * (cell_area.height - calc_height))
y_offset = max(y_offset, 0)
else:
x_offset = 0
y_offset = 0
calc_width = 20
calc_height = 16
return x_offset, y_offset, calc_width, calc_height
def on_activate(self, event, widget, path, background_area,
cell_area, flags):
if event and event.type == gtk.gdk.BUTTON_PRESS:
self.edit_color = self.color
self.sig_deac = widget.connect('button-release-event',
self.on_deactivate, cell_area, path)
self.sig_move = widget.connect('motion-notify-event',
self.on_mouse_move, cell_area, path)
self.active_area = cell_area
self.on_render(widget.get_bin_window(), widget, None,
cell_area, None, 3 << 6)
def on_deactivate(self, w, e, cell_area, path):
if self.sig_deac is not None: w.disconnect(self.sig_deac)
if self.sig_move is not None: w.disconnect(self.sig_move)
if ( cell_area.x <= int(e.x) <= cell_area.x + cell_area.width ) \
and ( cell_area.y <= int(e.y) <= cell_area.y +
cell_area.height):
self.dialog.colorsel.set_property('current-color',
self.edit_color)
ret = self.dialog.run()
if ret ==
self.dialog.get_response_for_widget(self.dialog.ok_button):
c = self.dialog.colorsel.get_property('current-color')
#self.edit_color = c
self.emit('color-changed', path, c)
self.color = self.edit_color
self.dialog.hide()
self.active_area = None
self.on_render(w.get_bin_window(), w, None, cell_area, None, 0)
def on_mouse_move(self, w, e, cell_area, path):
inside = 2 + int(cell_area.x <= e.x < cell_area.x +
cell_area.width \
and cell_area.y <= e.y < cell_area.y + cell_area.height)
self.color = self.edit_color
self.on_render(w.get_bin_window(), w, None, cell_area, None,
inside << 6)
gobject.type_register(ColorBtnCellRenderer)
class ButtonCellRenderer(gtk.GenericCellRenderer):
__gsignals__ = {
'toggled': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,))
}
def __init__(self):
gtk.GenericCellRenderer.__init__(self)
self.__gobject_init__()
self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
self.xpad = 1; self.ypad = 0
self.xalign = 0.5; self.yalign = 0.5
self.active_area = None
self.toggled = False
self.pango_l = None
self.text = ""
def do_set_property(self, pspec, value):
print "set prop ", pspec.name
setattr(self, pspec.name, value)
def do_get_property(self, pspec):
print "get prop ", pspec.name
return getattr(self, pspec.name)
def on_render(self, window, widget, background_area,
cell_area, expose_area, flags):
if not isinstance(window, gtk.gdk.Window):
#if not isinstance(window, gtk.gdk.Drawable):
return
if self.get_property('mode') != gtk.CELL_RENDERER_MODE_ACTIVATABLE:
state = gtk.STATE_INSENSITIVE
else:
state = gtk.STATE_NORMAL
concerned = cmp_rects(self.active_area, cell_area)
changing = self.active_area is not None
shadow = gtk.SHADOW_IN if (concerned and changing) ^
self.toggled else gtk.SHADOW_OUT
x_offset, y_offset, width, height = self.on_get_size(widget,
cell_area)
widget.style.paint_box(window,
state, shadow,
cell_area, widget, None,
cell_area.x + x_offset,
cell_area.y + y_offset,
width, height)
if self.pango_l is None:
context = widget.create_pango_context()
self.pango_l = pango.Layout(context)
self.pango_l.set_text(self.text)
w, h = self.pango_l.get_pixel_size()
widget.style.paint_layout(window, state, True,
cell_area, widget, None,
cell_area.x + x_offset + (width -w)/2,
cell_area.y + y_offset + (height -h)/2,
self.pango_l)
def on_get_size(self, widget, cell_area):
if cell_area:
calc_width = cell_area.width - 2*self.xpad
calc_height = cell_area.height - 2*self.ypad
if calc_width < calc_height:
calc_height = calc_width
else:
calc_width = calc_height
x_offset = int(self.xalign * (cell_area.width - calc_width))
x_offset = max(x_offset, 0)
y_offset = int(self.yalign * (cell_area.height - calc_height))
y_offset = max(y_offset, 0)
else:
x_offset = 0
y_offset = 0
calc_width = 20
calc_height = 16
return x_offset, y_offset, calc_width, calc_height
def on_activate(self, event, widget, path, background_area,
cell_area, flags):
self.sig_deac = widget.connect('button-release-event',
self.on_deactivate, cell_area, path)
self.active_area = cell_area
self.toggled = not self.toggled
def on_deactivate(self, w, e, cell_area, path):
w.disconnect(self.sig_deac)
if ( cell_area.x <= int(e.x) <= cell_area.x + cell_area.width ) \
and ( cell_area.y <= int(e.y) <= cell_area.y +
cell_area.height):
self.emit('toggled', path)
self.active_area = None
self.on_render(w.get_bin_window(), w, None, cell_area, None, 0)
More information about the pygtk
mailing list