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 | |
Guido van Rossum | ce08448 | 1991-12-26 13:06:29 +0000 | [diff] [blame] | 10 | class CSplit(Split): |
Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 11 | # |
Guido van Rossum | ca197b5 | 1991-08-16 13:05:37 +0000 | [diff] [blame] | 12 | def getminsize(self, (m, (width, height))): |
Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 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. |
Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 17 | for child in self.children: |
Guido van Rossum | ca197b5 | 1991-08-16 13:05:37 +0000 | [diff] [blame] | 18 | wi, he = child.getminsize(m, (0, 0)) |
Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 19 | width = max(width, wi) |
| 20 | height = max(height, he) |
| 21 | # In approximation, the diameter of the circle we need is |
| 22 | # (diameter of box) * (#children) / pi. |
| 23 | # We approximate pi by 3 (so we slightly overestimate |
| 24 | # our minimal size requirements -- not so bad). |
| 25 | # Because the boxes stick out of the circle we add the |
| 26 | # box size to each dimension. |
| 27 | # Because we really deal with ellipses, do everything |
| 28 | # separate in each dimension. |
| 29 | n = len(self.children) |
| 30 | return width + (width*n + 2)/3, height + (height*n + 2)/3 |
| 31 | # |
| 32 | def getbounds(self): |
| 33 | return self.bounds |
| 34 | # |
| 35 | def setbounds(self, bounds): |
| 36 | self.bounds = bounds |
| 37 | # Place the children. This involves some math. |
| 38 | # Compute center positions for children as if they were |
| 39 | # ellipses with a diameter about 1/N times the |
| 40 | # circumference of the big ellipse. |
| 41 | # (There is some rounding involved to make it look |
| 42 | # reasonable for small and large N alike.) |
| 43 | # XXX One day Python will have automatic conversions... |
| 44 | n = len(self.children) |
| 45 | fn = float(n) |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame^] | 46 | if n == 0: return |
Guido van Rossum | 7df0c16 | 1991-01-23 13:41:31 +0000 | [diff] [blame] | 47 | (left, top), (right, bottom) = bounds |
| 48 | width, height = right-left, bottom-top |
| 49 | child_width, child_height = width*3/(n+4), height*3/(n+4) |
| 50 | half_width, half_height = \ |
| 51 | float(width-child_width)/2.0, \ |
| 52 | float(height-child_height)/2.0 |
| 53 | center_h, center_v = center = (left+right)/2, (top+bottom)/2 |
| 54 | fch, fcv = float(center_h), float(center_v) |
| 55 | alpha = 2.0 * pi / fn |
| 56 | for i in range(n): |
| 57 | child = self.children[i] |
| 58 | fi = float(i) |
| 59 | fh, fv = \ |
| 60 | fch + half_width*sin(fi*alpha), \ |
| 61 | fcv - half_height*cos(fi*alpha) |
| 62 | left, top = \ |
| 63 | int(fh) - child_width/2, \ |
| 64 | int(fv) - child_height/2 |
| 65 | right, bottom = \ |
| 66 | left + child_width, \ |
| 67 | top + child_height |
| 68 | child.setbounds((left, top), (right, bottom)) |
| 69 | # |