changeset 106:d1152f2a0e13

Mouse affects focus
author Stefano Rivera <stefano@rivera.za.net>
date Sun, 11 Sep 2011 20:05:35 +0200
parents 87acd3ddc972
children c292e6003266
files mamba/engine.py mamba/habitats/mainmenu.py mamba/widgets/base.py
diffstat 3 files changed, 46 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/mamba/engine.py	Sun Sep 11 19:59:14 2011 +0200
+++ b/mamba/engine.py	Sun Sep 11 20:05:35 2011 +0200
@@ -43,8 +43,7 @@
     def __init__(self, size=SCREEN):
         self.surface_size = size
         self.surface = None
-        self.container = Container(pygame.Rect((0, 0), self.surface_size),
-                                   root=True)
+        self.container = Container(pygame.Rect((0, 0), self.surface_size))
 
     def on_enter(self):
         """Called when this becomes the current habitat."""
--- a/mamba/habitats/mainmenu.py	Sun Sep 11 19:59:14 2011 +0200
+++ b/mamba/habitats/mainmenu.py	Sun Sep 11 20:05:35 2011 +0200
@@ -6,6 +6,7 @@
 
 from mamba.constants import ESCAPE_KEYS
 from mamba.engine import Habitat, NewHabitatEvent
+from mamba.widgets.base import Container
 from mamba.widgets.text import TextButton
 
 
@@ -20,6 +21,13 @@
         self.container.add(quit)
         self.container.add_callback(KEYDOWN, self.keydown_event)
 
+        c = Container((400, 100))
+        c.add(TextButton((400, 100), "3", color='white'))
+        self.container.add(c)
+        c = Container((400, 200))
+        c.add(TextButton((400, 200), "4", color='white'))
+        self.container.add(c)
+
     def start_event(self, ev, widget):
         if ev.key == K_RETURN:
             from mamba.habitats.level import LevelHabitat
--- a/mamba/widgets/base.py	Sun Sep 11 19:59:14 2011 +0200
+++ b/mamba/widgets/base.py	Sun Sep 11 20:05:35 2011 +0200
@@ -13,12 +13,26 @@
         self.rect = rect
         self.focussable = False
         self.focussed = False
+        self.parent = None
         self.callbacks = collections.defaultdict(list)
 
     def add_callback(self, eventtype, callback, *args):
         self.callbacks[eventtype].append((callback, args))
 
     def event(self, ev):
+        if ev.type == MOUSEBUTTONDOWN and self.focussable:
+            root = self
+            while root.parent is not None:
+                root = root.parent
+            root.defocus()
+            widget = self
+            while widget.parent is not None:
+                parent = widget.parent
+                if isinstance(parent, Container):
+                    parent.focussed_child = parent.children.index(widget)
+                widget = parent
+            self.focussed = True
+
         for callback, args in self.callbacks[ev.type]:
             if callback(ev, self, *args):
                 return True
@@ -31,11 +45,9 @@
 
 class Container(Widget):
 
-    def __init__(self, rect, root=False):
+    def __init__(self, rect):
         super(Container, self).__init__(rect)
         self.children = []
-        self.root = root
-        self.focussable = True
         self.focussed_child = None
 
     def event(self, ev):
@@ -54,12 +66,21 @@
                         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):
+        if (self.parent is None and ev.type == KEYDOWN
+                and ev.key in (K_UP, K_DOWN)):
             return self.adjust_focus(1 if ev.key == K_DOWN else -1)
 
     def add(self, widget):
         widget.parent = self
         self.children.append(widget)
+        self.rect = self.rect.union(widget.rect)
+
+    def defocus(self):
+        if self.focussed_child is not None:
+            child = self.children[self.focussed_child]
+            if isinstance(child, Container):
+                child.defocus()
+            child.focussed = False
 
     def adjust_focus(self, direction):
         """Try and adjust focus in direction (integer)
@@ -69,7 +90,8 @@
             if isinstance(child, Container):
                 if child.adjust_focus(direction):
                     return True
-            child.focussed = False
+            else:
+                child.focussed = False
 
         current = self.focussed_child
         if current is None:
@@ -82,31 +104,29 @@
         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
+                return True
+            if isinstance(child, Container):
+                if child.adjust_focus(direction):
                     self.focussed_child = i
-                    child.focussed = True
                     return True
         else:
-            if self.root:
-                if self.focussed_child:
+            if self.parent is None:
+                if self.focussed_child is not None:
                     # At the end, mark the last one as focussed, again
                     child = self.children[self.focussed_child]
                     if isinstance(child, Container):
                         if child.adjust_focus(-direction):
                             return True
-                    child.focussed = True
+                    else:
+                        child.focussed = True
+                        return True
             else:
                 self.focussed_child = None
             return False
 
     def draw(self, surface):
-        if self.root and not self.focussed:
+        if self.parent is None and not self.focussed:
             self.focussed = True
             self.adjust_focus(1)
         for child in self.children: