Mercurial > mamba
changeset 77:2aa652b92449
Focus
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sun, 11 Sep 2011 18:30:19 +0200 |
parents | a2694a024c83 |
children | b1019923cb12 |
files | mamba/engine.py mamba/widgets/base.py |
diffstat | 2 files changed, 58 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mamba/engine.py Sun Sep 11 18:26:55 2011 +0200 +++ b/mamba/engine.py Sun Sep 11 18:30:19 2011 +0200 @@ -42,7 +42,7 @@ def __init__(self): self.surface = None - self.container = Container(pygame.Rect((0, 0), SCREEN)) + self.container = Container(pygame.Rect((0, 0), SCREEN), root=True) def on_enter(self): """Called when this becomes the current habitat."""
--- a/mamba/widgets/base.py Sun Sep 11 18:26:55 2011 +0200 +++ b/mamba/widgets/base.py Sun Sep 11 18:30:19 2011 +0200 @@ -1,6 +1,7 @@ import collections import pygame +from pygame.constants import K_UP, K_DOWN from pygame.locals import MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN, KEYDOWN @@ -11,6 +12,7 @@ rect = pygame.Rect(rect, (0, 0)) self.rect = rect self.focussable = False + self.focussed = False self.callbacks = collections.defaultdict(list) def add_callback(self, eventtype, callback, *args): @@ -18,7 +20,9 @@ def event(self, ev): for callback, args in self.callbacks[ev.type]: - callback(ev, self, *args) + if callback(ev, self, *args): + return True + return False def draw(self, surface): "Override me" @@ -27,23 +31,71 @@ class Container(Widget): - def __init__(self, rect): + def __init__(self, rect, root=False): super(Container, self).__init__(rect) self.children = [] + self.root = root + self.focussed = root + self.focussable = True + self.focussed_child = None def event(self, ev): + """Push an event down through the tree, and fire our own event as a + last resort + """ if ev.type in (MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN): for child in self.children: if child.rect.collidepoint(ev.pos): - child.event(ev) + if child.event(ev): + return True if ev.type == KEYDOWN: for child in self.children: - child.event(ev) - super(Container, self).event(ev) + if child.focussed: + if child.event(ev): + return True + if super(Container, self).event(ev): + return True + if self.root and ev.type == KEYDOWN and ev.key in (K_UP, K_DOWN): + self.adjust_focus(1 if ev.key == K_DOWN else -1) def add(self, widget): + widget.parent = self self.children.append(widget) + def adjust_focus(self, direction): + """Try and adjust focus in direction (integer) + """ + if self.focussed_child is not None: + child = self.children[self.focussed_child] + if isinstance(child, Container): + if child.adjust_focus(direction): + return True + child.focussed = False + + current = self.focussed_child + if current is None: + current = -1 if direction > 0 else len(self.children) + if direction > 0: + possibles = list(enumerate(self.children))[current + 1:] + else: + possibles = list(enumerate(self.children))[:current] + possibles.reverse() + for i, child in possibles: + if child.focussable: + child.focussed = True + if isinstance(child, Container): + if child.adjust_focus(direction): + self.focussed_child = i + return True + child.focussed = False + continue + else: + self.focussed_child = i + child.focussed = True + return True + else: + return False + def draw(self, surface): for child in self.children: child.draw(surface)