summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2006-09-22 20:13:06 +0000
committerLennart Poettering <lennart@poettering.net>2006-09-22 20:13:06 +0000
commit6a9fcd2bc707969699db05c0be61865124661973 (patch)
tree11d80b7975b101639a9714af57184ecef5441312
parent85f43c4b6ff43f45d8ee4df1c1ec7f0b4f227034 (diff)
add a hotspot for each pie segment
git-svn-id: file:///home/lennart/svn/public/fring/trunk@12 d0d2c35f-0a1e-0410-abeb-dabff30a67ee
-rw-r--r--src/fringlib/fringrenderer.py92
-rw-r--r--src/fringlib/fringui.py3
2 files changed, 80 insertions, 15 deletions
diff --git a/src/fringlib/fringrenderer.py b/src/fringlib/fringrenderer.py
index a0d5a4b..fb9a876 100644
--- a/src/fringlib/fringrenderer.py
+++ b/src/fringlib/fringrenderer.py
@@ -6,18 +6,28 @@ import os
class Hotspot:
- def __init__(self, minpos, maxpos, folder):
+ def __init__(self, minpos, maxpos, path, size, percentage):
self.minx,self.miny = minpos
self.maxx,self.maxy = maxpos
- self.folder = folder
+ self.path = path
+ self.size = size
+ self.percentage = percentage
+class Segment:
+ def __init__(self, start, end, path, size):
+ self.start, self.end = start, end
+ self.path = path
+ self.size = size
+
+ def percentage(self):
+ return self.end - self.start
+
class FringRenderer:
def __init__(self):
self.MAX_LEVEL = 1
- self.WIDTH, HEIGHT = 1024, 768
- self.WIDTH, HEIGHT = 1024, 768
+ self.WIDTH, self.HEIGHT = 1024, 768
self.INNER_RADIUS = 100
self.RING_RADIUS = 60
self.RING_SPACE = 0
@@ -28,6 +38,7 @@ class FringRenderer:
self.LABEL_UNTIL_RING = 0
self.hotspots = []
+ self.lookup_data = []
def prepare_layouts(self,ctx):
self.linklayout = ctx.create_layout()
@@ -37,6 +48,13 @@ class FringRenderer:
assert isinstance(data, sum_list)
+ if ring == 0:
+ self.lookup_data = []
+ self.hotspots = []
+
+ while len(self.lookup_data) <= ring:
+ self.lookup_data.append([])
+
CENTERX, CENTERY = self.WIDTH/2, self.HEIGHT/2
ctx.move_to(CENTERX, CENTERY)
@@ -55,14 +73,16 @@ class FringRenderer:
accumulated += value
end = start_angle+(end_angle - start_angle)*1.0*accumulated/data.the_sum
-
+
if end-start >= .01:
+ p = previouspath+os.sep+fn
+ self.lookup_data[ring].append(Segment(start, end, p, value))
+
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)
@@ -108,16 +128,15 @@ class FringRenderer:
ctx.set_line_width(self.LEG_LINE_WIDTH)
ctx.stroke()
- # write folder name and register a hotspot
+ # write path 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))
+ self.__register_hotspot(p,value,end-start,x,y+(height/2),x+(width),y-(height/2))
else:
ctx.set_source_rgb(0.5,0.5,0.5)
@@ -138,13 +157,60 @@ class FringRenderer:
for h in self.hotspots:
if x >= h.minx and x <= h.maxx and \
y >= h.miny and y <= h.maxy:
- return h.folder
+ return (h.path, h.size, h.percentage)
+
+ def sqr(x):
+ return x*x
- def __register_hotspot(self,folder,x0,y0,x1,y1):
+ CENTERX, CENTERY = self.WIDTH/2, self.HEIGHT/2
+ radius = sqrt(sqr(x - CENTERX) + sqr(y - CENTERY))
+ angle = atan2(y - CENTERY, x - CENTERX)
+ v = angle/(2*pi)
+
+ if v < 0:
+ v+=1
+
+ if radius <= self.INNER_RADIUS:
+ return None
+
+ # A simple bisection algorithm
+
+ ring = int((radius - self.INNER_RADIUS)/(self.RING_RADIUS + self.RING_SPACE))
+ try:
+ data = self.lookup_data[ring]
+ except IndexError:
+ return None
+
+ minidx, maxidx = 0, len(data)-1
+ p = int(maxidx*v) # Initial estimation
+
+ while True:
+ assert p >= minidx
+ assert p <= maxidx
+
+ d = data[p]
+
+ if v <= d.start:
+ maxidx = p-1
+ elif v <= d.end:
+ return (d.path, d.size, d.percentage())
+ else:
+ minidx = p+1
+
+ if minidx > maxidx:
+ return None
+
+ np = int((minidx+maxidx))/2
+
+ if np == p:
+ return None
+
+ p = np
+
+ def __register_hotspot(self,path,size,percentage,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 ))
-
+ self.hotspots.append(Hotspot( (x0,y0), (x1,y1), path, size, percentage ))
def hsv2rgb(self,h,s,v):
if s<=0:
diff --git a/src/fringlib/fringui.py b/src/fringlib/fringui.py
index 592176c..cf94eaa 100644
--- a/src/fringlib/fringui.py
+++ b/src/fringlib/fringui.py
@@ -198,7 +198,6 @@ class UI( gtk.Window ):
self.renderer.LABEL_UNTIL_RING = int(self.zoomfactor - 0.4)
if self.zoomfactor < 0.8: self.renderer.LABEL_UNTIL_RING = -1
- self.renderer.hotspots = []
self.renderer.draw_segment(self.ctx, 0, 0, 1, 0, 1, self.data, self.path)
self.image.queue_draw()
self.__show_busy_cursor(-1)
@@ -255,7 +254,7 @@ class UI( gtk.Window ):
def __click_event(self, widget, event):
f = self.renderer.get_hotspot_at(event.x, event.y)
- if f is not None: self.open_folder(f)
+ if f is not None: self.open_folder(f[0])
def __scroll_event(self, widget, event):
if event.direction is gtk.gdk.SCROLL_UP: