home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / serpentine / cairopiechart.py < prev    next >
Encoding:
Python Source  |  2006-08-23  |  4.0 KB  |  150 lines

  1. import gtk
  2. from math import cos, sin
  3. import math
  4.  
  5. TWO_PI = math.pi * 2
  6.  
  7.  
  8. X = 0
  9. Y = 1
  10. _getx = lambda x, radius, angle: x + cos(angle) * radius
  11. _gety = lambda y, radius, angle: y + sin(angle) * radius
  12. _getxy = lambda center, radius, angle: (_getx(center[X], radius, angle), _gety(center[Y], radius, angle))
  13.  
  14. def sketch_arc(ctx, center, radius, offset, apperture):
  15.     
  16.     angle1 = offset
  17.     angle2 = offset + apperture
  18.     corner1 = _getxy(center, radius, angle1)
  19.     corner2 = _getxy(center, radius, angle2)
  20.     
  21.     ctx.move_to(*center)
  22.     ctx.line_to(*corner1)
  23.     ctx.arc(center[X], center[Y], radius, angle1, angle2)
  24.     ctx.line_to(center[X], center[Y])
  25.  
  26. def sketch_radius(ctx, center, radius, angle):
  27.     ctx.move_to(*center)
  28.     ctx.line_to(*_getxy(center, radius, angle))
  29.  
  30.  
  31. class CairoPieChart(gtk.DrawingArea):
  32.     def __init__(self, values, getter):
  33.         super(CairoPieChart, self).__init__()
  34.         self.connect("expose-event", self._on_exposed)
  35.         self.values = values
  36.         self.selected = []
  37.         self.getter = getter
  38.         self.values = values
  39.     
  40.  
  41.     def _on_exposed(self, me, evt):
  42.         self.draw(evt)
  43.     
  44.     def draw_slice(self, center, radius, offset, percentage, color, ctx):
  45.         offset *= math.pi * 2
  46.         apperture = percentage * math.pi * 2
  47.         
  48.         ctx.set_source_color(color)
  49.         sketch_arc(ctx, center, radius, offset, apperture)
  50.         ctx.close_path()
  51.         ctx.fill()
  52.         
  53.         ctx.set_source_color(self.get_border_color())
  54.         sketch_radius(ctx, center, radius, offset)
  55.         ctx.stroke()
  56.  
  57.     def draw_background(self, center, radius, ctx):
  58.         ctx.set_source_color(self.style.bg[gtk.STATE_NORMAL])
  59.         ctx.arc(center[X], center[Y], radius, 0, TWO_PI)
  60.         ctx.fill()
  61.  
  62.     def draw_border(self, center, radius, ctx):
  63.         ctx.set_source_color(self.get_border_color())
  64.         ctx.arc(center[X], center[Y], radius, 0, TWO_PI)
  65.         ctx.stroke()
  66.  
  67.         
  68.     def get_border_color(self):
  69.         return self.style.dark[gtk.STATE_NORMAL]
  70.     
  71.     def get_normal_background_color(self):
  72.         return self.style.base[gtk.STATE_NORMAL]
  73.  
  74.     def get_selected_background_color(self):
  75.         return self.style.base[gtk.STATE_SELECTED]
  76.  
  77.     def get_empty_background_color(self):
  78.         return self.style.mid[gtk.STATE_NORMAL]
  79.  
  80.     def get_background_color(self):
  81.         return self.style.bg[gtk.STATE_NORMAL]
  82.  
  83.  
  84.        
  85.     def draw(self, evt):
  86.         rect = self.allocation
  87.         radius = min(rect.width / 2.0, rect.height / 2.0) - 5
  88.         if radius <= 0:
  89.             return
  90.         
  91.         x = rect.width / 2.0
  92.         y = rect.height / 2.0
  93.         center = (x, y)
  94.         
  95.         small_radius = radius * 0.20
  96.         self.total = float(self.total)
  97.         
  98.         ctx = self.window.cairo_create()
  99.         ctx.set_line_width(0.75)
  100.  
  101.         offset = 0.0
  102.         for index, val in enumerate(self.values):
  103.             apperture = self.getter(val) / self.total
  104.             selected = index in self.selected
  105.  
  106.             if selected:
  107.                 bg = self.get_selected_background_color()
  108.             else:
  109.                 bg = self.get_normal_background_color()
  110.                 
  111.                 
  112.             assert offset + apperture <= 1
  113.             self.draw_slice(center, radius, offset, apperture, bg, ctx)
  114.             offset += apperture
  115.         
  116.         if offset < 1:
  117.             bg = self.get_empty_background_color()
  118.             self.draw_slice(center, radius, offset, 1.0 - offset, bg, ctx)
  119.  
  120.         self.draw_background(center, small_radius, ctx)
  121.         self.draw_border(center, small_radius, ctx)
  122.         self.draw_border(center, radius, ctx)
  123.  
  124.  
  125.  
  126.  
  127. def main():
  128.     window = gtk.Window()
  129.     chart = CairoPieChart([10,12], lambda x: x)
  130.     chart.total = 22
  131.     chart.selected = [0]
  132.     chart.show()
  133.     chart.set_size_request(64, 64)
  134.  
  135.     btn = gtk.Button("Hi")
  136.     btn.show()
  137.     vbox = gtk.VBox()
  138.     vbox.show()
  139.     vbox.add(btn)
  140.     vbox.add(chart)
  141.     window.add(vbox)
  142.  
  143.     #window.add(chart)
  144.     window.connect("destroy", gtk.main_quit)
  145.     window.show()
  146.     gtk.main()
  147.  
  148. if __name__ == '__main__':
  149.     main()
  150.