changeset 338:2cadc8a427f0

a hackful GridContainer for the LevelMenu
author Stefano Rivera <stefano@rivera.za.net>
date Fri, 16 Sep 2011 22:13:17 +0200
parents 170d4a43c00e
children c7d7accca022
files mamba/habitats/levelmenu.py mamba/widgets/base.py
diffstat 2 files changed, 66 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mamba/habitats/levelmenu.py	Fri Sep 16 21:47:56 2011 +0200
+++ b/mamba/habitats/levelmenu.py	Fri Sep 16 22:13:17 2011 +0200
@@ -6,6 +6,7 @@
 from mamba.engine import Habitat, NewHabitatEvent
 from mamba.gamestate import levels, done_levels
 from mamba.level import Level
+from mamba.widgets.base import GridContainer
 from mamba.widgets.levelbutton import LevelButton
 
 
@@ -14,13 +15,18 @@
     def __init__(self):
         super(LevelMenu, self).__init__()
         self.level_buttons = {}
+        WIDTH = 5
+        container = GridContainer(width=WIDTH)
+        self.container.add(container)
         for i, name in enumerate(self.list_levels()):
             level = self.get_level(name)
-            button = LevelButton((20 + 120 * i, 20), level,
-                                 done=name in done_levels)
+            button = LevelButton((20 + 120 * (i % WIDTH),
+                                  20 + 120 * (i // WIDTH)),
+                                 level, done=name in done_levels)
             button.add_callback('clicked', self.level_selected, name)
-            self.container.add(button)
+            container.add(button)
             self.level_buttons[name] = button
+
         self.container.add_callback(KEYDOWN, self.keydown_event)
         self.update_buttons()
 
--- a/mamba/widgets/base.py	Fri Sep 16 21:47:56 2011 +0200
+++ b/mamba/widgets/base.py	Fri Sep 16 22:13:17 2011 +0200
@@ -1,10 +1,11 @@
 import collections
 
 import pygame
-from pygame.constants import K_UP, K_DOWN, K_RETURN
+from pygame.constants import K_UP, K_DOWN, K_LEFT, K_RIGHT, K_RETURN
 from pygame.locals import (KEYDOWN, MOUSEMOTION, MOUSEBUTTONUP,
                            MOUSEBUTTONDOWN, USEREVENT)
 
+from mamba.constants import UP, DOWN, LEFT, RIGHT
 from mamba.engine import UserEvent
 
 
@@ -99,7 +100,9 @@
 
 class Container(Widget):
 
-    def __init__(self, rect):
+    def __init__(self, rect=None):
+        if rect is None:
+            rect = pygame.Rect(0, 0, 0, 0)
         super(Container, self).__init__(rect)
         self.children = []
         self.focussed_child = None
@@ -212,3 +215,55 @@
             self.adjust_focus(1)
         for child in self.children:
             child.draw(surface)
+
+
+class GridContainer(Container):
+    """Hacky container that only supports grids, won't work with Container
+    children, or modal children.
+    """
+
+    def __init__(self, width, rect=None):
+        super(GridContainer, self).__init__(rect)
+        self.width = width
+
+    def event(self, ev):
+        if (ev.type == KEYDOWN and ev.key in (K_UP, K_DOWN, K_LEFT, K_RIGHT)):
+            direction = None
+            if ev.key == K_UP:
+                direction = UP
+            elif ev.key == K_DOWN:
+                direction = DOWN
+            elif ev.key == K_LEFT:
+                direction = LEFT
+            elif ev.key == K_RIGHT:
+                direction = RIGHT
+            return self.adjust_focus(direction)
+
+    def add(self, widget):
+        assert not isinstance(widget, Container)
+        assert not widget.modal
+        super(GridContainer, self).add(widget)
+
+    def adjust_focus(self, direction):
+        if isinstance(direction, int):
+            direction = (direction, 0)
+
+        if len(self.children) == 0:
+            return False
+
+        if self.focussed_child is None:
+            if sum(direction) > 0:
+                self.focussed_child = 0
+            else:
+                self.focussed_child = len(self.children) - 1
+        else:
+            self.children[self.focussed_child].focussed = False
+            if direction[0] != 0:
+                self.focussed_child += direction[0]
+            if direction[1] != 0:
+                self.focussed_child += self.width * direction[1]
+        if not 0 <= self.focussed_child < len(self.children):
+            self.focussed_child = None
+            return False
+        self.children[self.focussed_child].focussed = True
+        return True