Below is the file 'scribbler.py' from this revision. You can also download the file.
#!/usr/bin/env python import gobject import cairo import math import gtk import sys import os def ScribblerFactory(scribble_function): class Scribbler(gobject.GObjectMeta): def __new__(cls, name, bases, dict): def expose_handler(widget, event): context = widget.window.cairo_create() context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) context.clip() scribble_function(widget, context, widget.get_allocation()) return False def our_init(self, *args, **kwargs): super(self.__class__, self).__init__(*args, **kwargs) self.connect_after("expose-event", expose_handler) dict['__init__'] = our_init return type.__new__(cls, name, bases, dict) return Scribbler def draw_circle(widget, context, allocation): x = allocation.x + allocation.width / 2 y = allocation.y + allocation.height / 2 radius = min(allocation.width / 2, allocation.height / 2) - 5 context.arc(x, y, radius, 0, 2 * math.pi) context.set_source_rgb(0, 0, 0) context.stroke() def draw_flagamo(widget, context, allocation): context.set_source_rgb(1, 0, 0) context.set_line_width(5) context.rectangle(allocation.x + 5, allocation.y+ 5, allocation.width - 10, allocation.height - 10) context.move_to(allocation.x, allocation.y) context.line_to(allocation.x+allocation.width, allocation.y+allocation.height) context.move_to(allocation.x, allocation.y+allocation.height) context.line_to(allocation.x+allocation.width, allocation.y) context.stroke() def draw_brand(widget, context, allocation): context.set_source_rgba(0.5, 0.5, 1, 0.5) context.select_font_face("Serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) context.set_font_size(32) brand = '<branded by angry goats>' xb, yb, fw, fh = context.text_extents(brand)[:4] context.move_to(allocation.x + ((allocation.width - fw) / 2 - xb), allocation.y + ((allocation.height - fh) / 2 - yb)) context.show_text(brand) class BoxedTable(gtk.Table): __metaclass__ = ScribblerFactory(draw_flagamo) class WindowCircle(gtk.Window): __metaclass__ = ScribblerFactory(draw_circle) class ButtonCircle(gtk.Button): __metaclass__ = ScribblerFactory(draw_circle) class LabelCircle(gtk.Label): __metaclass__ = ScribblerFactory(draw_circle) class BrandedWindow(gtk.Window): __metaclass__ = ScribblerFactory(draw_brand) if __name__ == '__main__': window = BrandedWindow() vbox = BoxedTable(2, 2) for i in xrange(4): vbox.attach(ButtonCircle("Button %d" % i), (i%2), (i%2)+1, (i/2), (i/2)+1) window.add(vbox) window.show_all() gtk.main()