# A CSplit is a Clock-shaped split: the children are grouped in a circle. # The numbering is a little different from a real clock: the 12 o'clock # position is called 0, not 12. This is a little easier since Python # usually counts from zero. (BTW, there needn't be exactly 12 children.) from math import pi, sin, cos from Split import Split class CSplit(Split): # def getminsize(self, (m, (width, height))): # Since things look best if the children are spaced evenly # along the circle (and often all children have the same # size anyway) we compute the max child size and assume # this is each child's size. for child in self.children: wi, he = child.getminsize(m, (0, 0)) width = max(width, wi) height = max(height, he) # In approximation, the diameter of the circle we need is # (diameter of box) * (#children) / pi. # We approximate pi by 3 (so we slightly overestimate # our minimal size requirements -- not so bad). # Because the boxes stick out of the circle we add the # box size to each dimension. # Because we really deal with ellipses, do everything # separate in each dimension. n = len(self.children) return width + (width*n + 2)/3, height + (height*n + 2)/3 # def getbounds(self): return self.bounds # def setbounds(self, bounds): self.bounds = bounds # Place the children. This involves some math. # Compute center positions for children as if they were # ellipses with a diameter about 1/N times the # circumference of the big ellipse. # (There is some rounding involved to make it look # reasonable for small and large N alike.) # XXX One day Python will have automatic conversions... n = len(self.children) fn = float(n) if n = 0: return (left, top), (right, bottom) = bounds width, height = right-left, bottom-top child_width, child_height = width*3/(n+4), height*3/(n+4) half_width, half_height = \ float(width-child_width)/2.0, \ float(height-child_height)/2.0 center_h, center_v = center = (left+right)/2, (top+bottom)/2 fch, fcv = float(center_h), float(center_v) alpha = 2.0 * pi / fn for i in range(n): child = self.children[i] fi = float(i) fh, fv = \ fch + half_width*sin(fi*alpha), \ fcv - half_height*cos(fi*alpha) left, top = \ int(fh) - child_width/2, \ int(fv) - child_height/2 right, bottom = \ left + child_width, \ top + child_height child.setbounds((left, top), (right, bottom)) #