+ '''Prepare the widget for drawing. This usually caches a surface.'''
+
+ def handle_event(self, ev):
+ '''Return True if the event has been handled'''
+ if InvalidateTheWorld.matches(ev):
+ # Invalidate has special handling. Widgets should never return
+ # True for for this event
+ self._prepared = False
+ return False
+ if SelectEvent.matches(ev) or ev.type == pgl.MOUSEBUTTONDOWN:
+ return self.callback('click')
+ return False
+
+ def add_callback(self, event, callback):
+ self.callbacks[event].append(callback)
+
+ def callback(self, event):
+ for callback in self.callbacks[event]:
+ callback(event)
+ return bool(self.callbacks[event])
+
+ def set_selectable_callback(self, func):
+ self._is_selectable_func = func
+
+ def is_selectable(self):
+ """Return False if this widget isn't selectable by SelectorWidget."""
+ if self._is_selectable_func is not None:
+ return self._is_selectable_func()
+ else:
+ return True
+
+
+class Container(object):
+ def __init__(self, *widgets):
+ self.widgets = []
+ for widget in widgets:
+ self.add(widget)
+
+ def add(self, widget):
+ self.widgets.append(widget)
+
+ def render(self, surface):
+ for widget in self.widgets:
+ widget.render(surface)
+
+ def handle_event(self, ev):
+ if hasattr(ev, 'pos'):
+ for widget in self.widgets:
+ if isinstance(widget, Container):
+ if widget.handle_event(ev):
+ return True
+ elif widget.rect.collidepoint(ev.pos):
+ if widget.handle_event(ev):
+ return True
+ else:
+ for widget in self.widgets:
+ if widget.handle_event(ev):
+ return True
+ return False