1 from collections import defaultdict
4 from pygame import locals as pgl
6 from naja.events import InvalidateTheWorld, SelectEvent
10 _is_selectable_func = None
12 def __init__(self, pos, size=None):
14 self.size = size or (0, 0)
15 self._prepared = False
16 self.callbacks = defaultdict(list)
20 return pygame.Rect(self.pos, self.size)
22 def render(self, surface):
23 '''Draw the widget onto surface'''
24 if not self._prepared:
29 def draw(self, surface):
30 '''The overrideable bit of widget drawing'''
31 raise NotImplemented()
34 '''Prepare the widget for drawing. This usually caches a surface.'''
36 def handle_event(self, ev):
37 '''Return True if the event has been handled'''
38 if InvalidateTheWorld.matches(ev):
39 # Invalidate has special handling. Widgets should never return
40 # True for for this event
41 self._prepared = False
43 if SelectEvent.matches(ev) or ev.type == pgl.MOUSEBUTTONDOWN:
44 return self.callback('click')
47 def add_callback(self, event, callback):
48 self.callbacks[event].append(callback)
50 def callback(self, event):
51 for callback in self.callbacks[event]:
53 return bool(self.callbacks[event])
55 def set_selectable_callback(self, func):
56 self._is_selectable_func = func
58 def is_selectable(self):
59 """Return False if this widget isn't selectable by SelectorWidget."""
60 if self._is_selectable_func is not None:
61 return self._is_selectable_func()
66 class Container(object):
67 def __init__(self, *widgets):
69 for widget in widgets:
72 def add(self, widget):
73 self.widgets.append(widget)
75 def render(self, surface):
76 for widget in self.widgets:
77 widget.render(surface)
79 def handle_event(self, ev):
80 if hasattr(ev, 'pos'):
81 for widget in self.widgets:
82 if isinstance(widget, Container):
83 if widget.handle_event(ev):
85 elif widget.rect.collidepoint(ev.pos):
86 if widget.handle_event(ev):
89 for widget in self.widgets:
90 if widget.handle_event(ev):