X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=naja%2Fwidgets%2Fbase.py;h=815d1d3a3f1cf23fedcc776ff980b5d4b727b051;hb=19e7cc079734bf556fcc8cf2a02945a4dd2f7367;hp=32ff46fa21811e3b99b61d84e6fbac8325cc2433;hpb=f4c61efe7a3154f965781ea65117583750d39d3e;p=naja.git diff --git a/naja/widgets/base.py b/naja/widgets/base.py index 32ff46f..815d1d3 100644 --- a/naja/widgets/base.py +++ b/naja/widgets/base.py @@ -1,24 +1,92 @@ +from collections import defaultdict + import pygame +from pygame import locals as pgl + +from naja.events import InvalidateTheWorld, SelectEvent class Widget(object): + _is_selectable_func = None + def __init__(self, pos, size=None): 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]) + + 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