X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=naja%2Fwidgets%2Fbase.py;h=ee6190b91939bdd35176e11257fc570ac2a78adf;hb=0cef06f581d48315a59a19ac06ca1d2be14cbb4c;hp=6b86a870f5adadbb518ed4fc4caae837ccce7650;hpb=5331699e9ab927608ad9fa6841de85a30b1c42b1;p=naja.git diff --git a/naja/widgets/base.py b/naja/widgets/base.py index 6b86a87..ee6190b 100644 --- a/naja/widgets/base.py +++ b/naja/widgets/base.py @@ -1,4 +1,9 @@ +from collections import defaultdict + import pygame +from pygame import locals as pgl + +from naja.events import InvalidateTheWorld, SelectEvent class Widget(object): @@ -6,26 +11,45 @@ class Widget(object): self.pos = pos self.size = size or (0, 0) self._prepared = False + self.callbacks = defaultdict(list) @property def rect(self): return pygame.Rect(self.pos, self.size) def render(self, surface): + '''Draw the widget onto surface''' if not self._prepared: self.prepare() self._prepared = True self.draw(surface) def draw(self, surface): + '''The overrideable bit of widget drawing''' raise NotImplemented() def prepare(self): - raise NotImplemented() + '''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]) + class Container(object): def __init__(self, *widgets): @@ -41,7 +65,16 @@ class Container(object): widget.render(surface) def handle_event(self, ev): - for widget in self.widgets: - if widget.handle_event(ev): - return True + 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