summaryrefslogtreecommitdiffstats
path: root/src/fringlib/fringrenderer.py
diff options
context:
space:
mode:
authorFrederic Back <fredericback@gmail.com>2006-09-22 13:40:20 +0000
committerFrederic Back <fredericback@gmail.com>2006-09-22 13:40:20 +0000
commit39a9e678c2bb3d8a93b1e86377d0d334c5306348 (patch)
tree50276cd4157da88c5a1f1e3a9ce0f5698e0e26c6 /src/fringlib/fringrenderer.py
parente62c4666f06a4e1e9370c68ceefa21af43482f25 (diff)
* Made a first python package
git-svn-id: file:///home/lennart/svn/public/fring/trunk@4 d0d2c35f-0a1e-0410-abeb-dabff30a67ee
Diffstat (limited to 'src/fringlib/fringrenderer.py')
-rw-r--r--src/fringlib/fringrenderer.py221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/fringlib/fringrenderer.py b/src/fringlib/fringrenderer.py
new file mode 100644
index 0000000..a0d5a4b
--- /dev/null
+++ b/src/fringlib/fringrenderer.py
@@ -0,0 +1,221 @@
+import cairo
+import pango
+from math import *
+from fringwalker import sum_list
+import os
+
+class Hotspot:
+
+ def __init__(self, minpos, maxpos, folder):
+ self.minx,self.miny = minpos
+ self.maxx,self.maxy = maxpos
+ self.folder = folder
+
+
+class FringRenderer:
+
+ def __init__(self):
+ self.MAX_LEVEL = 1
+ self.WIDTH, HEIGHT = 1024, 768
+ self.WIDTH, HEIGHT = 1024, 768
+ self.INNER_RADIUS = 100
+ self.RING_RADIUS = 60
+ self.RING_SPACE = 0
+ self.RINGS_MAX = 4
+ self.LINE_WIDTH = .5
+ self.LEG_LINE_WIDTH = 1
+
+ self.LABEL_UNTIL_RING = 0
+
+ self.hotspots = []
+
+ def prepare_layouts(self,ctx):
+ self.linklayout = ctx.create_layout()
+ self.linklayout.set_font_description(pango.FontDescription("sans 10"))
+
+ def draw_segment(self,ctx, ring, start_angle, end_angle, start_hue, end_hue, data, previouspath=""):
+
+ assert isinstance(data, sum_list)
+
+ CENTERX, CENTERY = self.WIDTH/2, self.HEIGHT/2
+ ctx.move_to(CENTERX, CENTERY)
+
+ if ring == 0:
+ self._draw_centered_text(ctx, self._pretty_size(data.the_sum))
+
+ n = len(data.data)
+ i = 0
+
+ accumulated = 0
+ last = start_angle
+
+ for fn, d in data.data:
+ start = last
+ value = self._list_value(d)
+ accumulated += value
+
+ end = start_angle+(end_angle - start_angle)*1.0*accumulated/data.the_sum
+
+ if end-start >= .01:
+
+ v = start_hue + (end_hue-start_hue)*1.0*i/n
+ color = self._choose_color(start_hue + (end_hue-start_hue)*1.0*i/n, ring)
+
+ r = self.INNER_RADIUS + ring * (self.RING_RADIUS + self.RING_SPACE)
+
+ ctx.move_to(CENTERX+r*cos(start*2*pi), CENTERY+r*sin(start*2*pi))
+ ctx.arc(CENTERX, CENTERY, r+self.RING_RADIUS, start*2*pi, end*2*pi)
+ ctx.arc_negative(CENTERX, CENTERY, r, end*2*pi, start*2*pi)
+ ctx.close_path()
+
+ ctx.set_line_width(self.LINE_WIDTH)
+ ctx.set_source_rgb(*color)
+ ctx.fill_preserve()
+
+ ctx.set_source_rgb(0, 0, 0)
+ ctx.stroke()
+
+ if isinstance(d, sum_list) and ring+1 < self.RINGS_MAX:
+ self.draw_segment(ctx, ring+1, start, end, v,
+ start_hue + (end_hue-start_hue)*1.0*(i+1)/n, d,
+ previouspath+os.sep+fn)
+
+ r += self.RING_RADIUS/2
+ middle = CENTERX+r*cos((start+end)*pi), CENTERY+r*sin((start+end)*pi)
+
+ if ring <= 0:
+ ctx.move_to(*middle)
+
+ leg_radius = self.INNER_RADIUS + (self.RINGS_MAX+1) * (self.RING_RADIUS + self.RING_SPACE)
+ leg_radius -= (self.RING_RADIUS + self.RING_SPACE) / 2
+
+ ctx.line_to(CENTERX+leg_radius*cos((start+end)*pi), CENTERY+leg_radius*sin((start+end)*pi))
+
+ if cos((start+end)*pi) >= 0:
+ x = self.WIDTH/2 + leg_radius
+ align_x = 1
+ else:
+ x = self.WIDTH/2 - leg_radius
+ align_x = 0
+
+ # get line target point
+ y = CENTERY+leg_radius*sin((start+end)*pi)
+ xmod = 2*(align_x*2-1)
+
+ # draw line
+ ctx.line_to(x, y)
+ ctx.set_source_rgb(.5, .5, .5)
+ ctx.set_line_width(self.LEG_LINE_WIDTH)
+ ctx.stroke()
+
+ # write folder name and register a hotspot
+ ctx.move_to(x+xmod,y)
+
+ # register a hotspot ONLY if directory
+ if isinstance(d, sum_list):
+ ctx.set_source_rgb(0,0,1)
+ width,height = self._draw_centered_text(ctx, fn, align_x)
+ link = previouspath+os.sep+fn
+ if align_x == 0: width *= -1
+ self.__register_hotspot(link,x,y+(height/2),x+(width),y-(height/2))
+
+ else:
+ ctx.set_source_rgb(0.5,0.5,0.5)
+ width,height = self._draw_centered_text(ctx, fn, align_x)
+
+
+ if ring <= self.LABEL_UNTIL_RING:
+ ctx.move_to(*middle)
+ ctx.set_source_rgb(0, 0, 0)
+
+ # write relative and absolute disk usage
+ self._draw_centered_text2(ctx, "%.0f%%" % ((end-start)*100), self._pretty_size(value))
+
+ last = end
+ i += 1
+
+ def get_hotspot_at(self,x,y):
+ for h in self.hotspots:
+ if x >= h.minx and x <= h.maxx and \
+ y >= h.miny and y <= h.maxy:
+ return h.folder
+
+ def __register_hotspot(self,folder,x0,y0,x1,y1):
+ if x1 < x0: x0,x1 = x1,x0 # swap
+ if y1 < y0: y0,y1 = y1,y0
+ self.hotspots.append(Hotspot( (x0,y0), (x1,y1), folder ))
+
+
+ def hsv2rgb(self,h,s,v):
+ if s<=0:
+ return 255*v,255*v,255*v
+
+ h=6.0*(h%1.0)
+ f=h-int(h)
+ p=int(255*v*(1.0-s))
+ q=int(255*v*(1.0-(s*f)))
+ t=int(255*v*(1.0-(s*(1.0-f))))
+ v=int(255*v)
+
+ return ((v,t,p),
+ (q,v,p),
+ (p,v,t),
+ (p,q,v),
+ (t,p,v),
+ (v,p,q))[int(h)]
+
+ def _list_value(self,l):
+ if isinstance(l, sum_list):
+ return l.the_sum
+ return l
+
+
+ def _pretty_size(self,size):
+ if size >= 1024*1024*1024:
+ return "%.1f GiB" % round(size/1024/1024/1024.0)
+ elif size >= 1024*1024:
+ return "%.1f MiB" % round(size/1024/1024.0)
+ elif size >= 1024:
+ return "%.1f KiB" % round(size/1024.0)
+ else:
+ return "%u B" % size
+
+
+ def _choose_color(self,v, ring):
+ color = self.hsv2rgb(v, .61, 1-ring*0.1)
+ return color[0]/256.0, color[1]/256.0, color[2]/256.0,
+
+
+ def _draw_centered_text(self,ctx, text, align_x = .5, align_y = .5):
+ try: text = unicode(text)
+ except: return
+
+ self.linklayout.set_text(text)
+ width,height = self.linklayout.get_pixel_size()
+ ctx.rel_move_to(-width*(1-align_x), -height*align_y)
+ ctx.show_layout(self.linklayout)
+ return width,height
+
+
+ def _draw_centered_text2(self,ctx, text1, text2):
+ try:
+ text1 = unicode(text1)
+ text2 = unicode(text2)
+ except: return
+
+ extents1 = ctx.text_extents(text1)
+ extents2 = ctx.text_extents(text2)
+
+ h = max((extents1[3], extents2[3]))
+
+ p = ctx.get_current_point()
+ ctx.rel_move_to(-extents1[2]/2, -1)
+ ctx.show_text(text1)
+
+ ctx.move_to(*p)
+ ctx.rel_move_to(-extents2[2]/2, h+1)
+ ctx.show_text(text2)
+
+
+
+