The unified diff between revisions [3660e007..] and [297332e4..] is displayed below. It can also be downloaded as a raw diff.

#
#
# add_file "metaclass.py"
#  content [c82d3a748cfcf7c6256f82dbc7198dfb54867824]
#
#   set "metaclass.py"
#  attr "mtn:execute"
# value "true"
#
============================================================
--- metaclass.py	c82d3a748cfcf7c6256f82dbc7198dfb54867824
+++ metaclass.py	c82d3a748cfcf7c6256f82dbc7198dfb54867824
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+import gobject
+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(self, 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(context, self.get_allocation())
+				return False
+
+			def our_init(self, *args, **kwargs):
+				super(self.__class__, self).__init__(*args, **kwargs)
+				self.connect_after("expose-event", lambda w, e: expose_handler(self, w, e))
+
+			dict['__init__']  = our_init
+			return type.__new__(cls, name, bases, dict)
+	return Scribbler
+
+def draw_circle(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()
+
+class WindowCircle(gtk.Window):
+	__metaclass__ = ScribblerFactory(draw_circle)
+
+class ButtonCircle(gtk.Button):
+	__metaclass__ = ScribblerFactory(draw_circle)
+
+class LabelCircle(gtk.Label):
+	__metaclass__ = ScribblerFactory(draw_circle)
+
+if __name__ == '__main__':
+	window = WindowCircle()
+	vbox = gtk.VBox()
+	vbox.add(ButtonCircle("This is a Button."))
+	vbox.add(LabelCircle("This is a label."))
+	window.add(vbox)
+	window.show_all()
+	gtk.main()
+