Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 1 | # A CSplit is a Clock-shaped split: the children are grouped in a circle. |
| 2 | # The numbering is a little different from a real clock: the 12 o'clock |
| 3 | # position is called 0, not 12. This is a little easier since Python |
| 4 | # usually counts from zero. (BTW, there needn't be exactly 12 children.) |
| 5 | |
| 6 | |
| 7 | from math import pi, sin, cos |
| 8 | from Split import Split |
| 9 | |
| 10 | class CSplit() = Split(): |
| 11 | # |
| 12 | def minsize(self, m): |
| 13 | # Since things look best if the children are spaced evenly |
| 14 | # along the circle (and often all children have the same |
| 15 | # size anyway) we compute the max child size and assume |
| 16 | # this is each child's size. |
| 17 | width, height = 0, 0 |
| 18 | for child in self.children: |
| 19 | wi, he = child.minsize(m) |
| 20 | width = max(width, wi) |
| 21 | height = max(height, he) |
| 22 | # In approximation, the diameter of the circle we need is |
| 23 | # (diameter of box) * (#children) / pi. |
| 24 | # We approximate pi by 3 (so we slightly overestimate |
| 25 | # our minimal size requirements -- not so bad). |
| 26 | # Because the boxes stick out of the circle we add the |
| 27 | # box size to each dimension. |
| 28 | # Because we really deal with ellipses, do everything |
| 29 | # separate in each dimension. |
| 30 | n = len(self.children) |
| 31 | return width + (width*n + 2)/3, height + (height*n + 2)/3 |
| 32 | # |
| 33 | def getbounds(self): |
| 34 | return self.bounds |
| 35 | # |
| 36 | def setbounds(self, bounds): |
| 37 | self.bounds = bounds |
| 38 | # Place the children. This involves some math. |
| 39 | # Compute center positions for children as if they were |
| 40 | # ellipses with a diameter about 1/N times the |
| 41 | # circumference of the big ellipse. |
| 42 | # (There is some rounding involved to make it look |
| 43 | # reasonable for small and large N alike.) |
| 44 | # XXX One day Python will have automatic conversions... |
| 45 | n = len(self.children) |
| 46 | fn = float(n) |
| 47 | if n = 0: return |
| 48 | (left, top), (right, bottom) = bounds |
| 49 | width, height = right-left, bottom-top |
| 50 | child_width, child_height = width*3/(n+4), height*3/(n+4) |
| 51 | half_width, half_height = \ |
| 52 | float(width-child_width)/2.0, \ |
| 53 | float(height-child_height)/2.0 |
| 54 | center_h, center_v = center = (left+right)/2, (top+bottom)/2 |
| 55 | fch, fcv = float(center_h), float(center_v) |
| 56 | alpha = 2.0 * pi / fn |
| 57 | for i in range(n): |
| 58 | child = self.children[i] |
| 59 | fi = float(i) |
| 60 | fh, fv = \ |
| 61 | fch + half_width*sin(fi*alpha), \ |
| 62 | fcv - half_height*cos(fi*alpha) |
| 63 | left, top = \ |
| 64 | int(fh) - child_width/2, \ |
| 65 | int(fv) - child_height/2 |
| 66 | right, bottom = \ |
| 67 | left + child_width, \ |
| 68 | top + child_height |
| 69 | child.setbounds((left, top), (right, bottom)) |
| 70 | # |