Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/textbubble.py
diff options
context:
space:
mode:
Diffstat (limited to 'tutorius/textbubble.py')
-rw-r--r--tutorius/textbubble.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/tutorius/textbubble.py b/tutorius/textbubble.py
new file mode 100644
index 0000000..e09b298
--- /dev/null
+++ b/tutorius/textbubble.py
@@ -0,0 +1,109 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+This module represents TextBubble widget. Also, it aims to be a short example
+of drawing with Cairo.
+"""
+
+import gtk
+from math import pi as M_PI
+import cairo
+
+# FIXME set as subclass of gtk.Widget, not EventBox
+class TextBubble(gtk.EventBox):
+ def __init__(self, label):
+ gtk.EventBox.__init__(self)
+
+ ##self.set_app_paintable(True) # else may be blank
+ # FIXME ensure previous call does not interfere with widget stacking
+ self.label = label
+ self.lineWidth = 5
+
+ self.connect("expose-event", self._on_expose)
+
+ def __draw_with_cairo__(self, context):
+ """
+
+ """
+ pass
+
+ def _on_expose(self, widget, event):
+ """Redraw event callback."""
+ # TODO
+ ctx = self.window.cairo_create()
+
+ # set drawing region. Useless since this widget has its own window.
+ ##region = gtk.gdk.region_rectangle(self.allocation)
+ ##region.intersect(gtk.gdk.region_rectangle(event.area))
+ ##ctx.region(region)
+ ##ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
+ ##ctx.clip()
+
+ ##import pdb; pdb.set_trace()
+ ##ctx.set_operator(cairo.OPERATOR_CLEAR)
+ ##ctx.paint()
+ ##ctx.set_operator(cairo.OPERATOR_OVER)
+
+ width = self.allocation.width
+ height = self.allocation.height
+ xradius = width/2
+ yradius = height/2
+ width -= self.lineWidth
+ height -= self.lineWidth
+ ctx.move_to(self.lineWidth, yradius)
+ ctx.curve_to(self.lineWidth, self.lineWidth,
+ self.lineWidth, self.lineWidth, xradius, self.lineWidth)
+ ctx.curve_to(width, self.lineWidth,
+ width, self.lineWidth, width, yradius)
+ ctx.curve_to(width, height, width, height, xradius, height)
+ ctx.curve_to(self.lineWidth, height,
+ self.lineWidth, height, self.lineWidth, yradius)
+ ctx.set_source_rgb(1.0, 1.0, 1.0)
+ ctx.fill_preserve()
+ ctx.set_line_width(self.lineWidth)
+ ctx.set_source_rgb(0.0, 0.0, 0.0)
+ ctx.stroke()
+
+ _, _, textWidth, textHeight, _, _ = ctx.text_extents(self._label)
+ ctx.move_to(int((self.allocation.width-textWidth)/2),
+ int((self.allocation.height+textHeight)/2))
+ ctx.text_path(self._label)
+ ctx.fill()
+
+ return True
+
+
+ def _set_label(self, value):
+ """Sets the label and flags the widget to be redrawn."""
+ self._label = value
+ # FIXME hack to calculate size. necessary because may not have been
+ # realized
+ surf = cairo.SVGSurface("/dev/null", 0, 0)
+ ctx = cairo.Context(surf)
+ _, _, width, height, _, _ = ctx.text_extents(self._label)
+ del ctx, surf
+
+ # FIXME bogus values follows
+ self.set_size_request(int(width+20), int(height+40))
+ # TODO test changing a realized label
+
+ def _get_label(self):
+ """Getter method for the label property"""
+ return self._label
+
+ label = property(fget=_get_label, fset=_set_label,\
+ doc="Text label which is to be painted on the top of the widget")
+