1#!/usr/bin/env python3 2 3import pyglet 4import glooey 5import autoprop 6import datetime 7from vecrec import Vector, Rect 8 9@autoprop 10class Ring(glooey.Widget): 11 custom_radius = 150 12 13 def __init__(self, radius=None): 14 super().__init__() 15 self._children = [] 16 self._radius = radius or self.custom_radius 17 18 def get_children(self): 19 # Return a copy of the list so the caller can't mess up our internal 20 # state by adding or removing things. 21 return self._children[:] 22 23 def get_radius(self): 24 return self._radius 25 26 def set_radius(self, radius): 27 self._radius = radius 28 self._repack() 29 30 def add(self, widget): 31 self.insert(widget, len(self._children)) 32 33 def insert(self, widget, index): 34 self._attach_child(widget) 35 self._children.insert(index, widget) 36 self._repack_and_regroup_children() 37 38 def replace(self, old_widget, new_widget): 39 i = self._children.index(old_widget) 40 with self.hold_updates(): 41 self.remove(old_widget) 42 self.insert(new_widget, i) 43 44 def remove(self, widget): 45 self._detach_child(widget) 46 self._children.remove(widget) 47 self._repack_and_regroup_children() 48 49 def clear(self): 50 with self.hold_updates(): 51 for child in self._children[:]: 52 self.remove(child) 53 54 def do_claim(self): 55 top = bottom = left = right = 0 56 57 for child, offset in self._yield_offsets(): 58 top = max(top, offset.y + child.claimed_height / 2) 59 bottom = min(bottom, offset.y - child.claimed_height / 2) 60 left = min(left, offset.x - child.claimed_width / 2) 61 right = max(right, offset.x + child.claimed_width / 2) 62 63 return right - left, top - bottom 64 65 def do_resize_children(self): 66 for child, offset in self._yield_offsets(): 67 rect = child.claimed_rect.copy() 68 rect.center = self.rect.center + offset 69 child._resize(rect) 70 71 def _yield_offsets(self): 72 N = len(self._children) 73 for i, child in enumerate(self._children): 74 offset = self.radius * Vector.from_degrees(360 * i / N) 75 yield child, offset 76 77 78 79window = pyglet.window.Window() 80gui = glooey.Gui(window) 81ring = Ring(radius=150) 82 83for i in range(10): 84 green = glooey.Placeholder(50, 50) 85 ring.add(green) 86 87for i in range(0, 10, 2): 88 orange = glooey.Placeholder(50, 50, 'orange') 89 ring.replace(ring.children[i], orange) 90 91gui.add(ring) 92pyglet.app.run() 93 94