Mercurial > mamba
annotate mamba/widgets/base.py @ 77:2aa652b92449
Focus
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sun, 11 Sep 2011 18:30:19 +0200 |
parents | 3cc917814579 |
children | 7a17c5b74148 |
rev | line source |
---|---|
55
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
1 import collections |
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
2 |
23 | 3 import pygame |
77 | 4 from pygame.constants import K_UP, K_DOWN |
58 | 5 from pygame.locals import MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN, KEYDOWN |
23 | 6 |
7 | |
8 class Widget(object): | |
9 | |
10 def __init__(self, rect): | |
38 | 11 if not isinstance(rect, pygame.Rect): |
41
3f44c30a1c39
Correct Text placement
Stefano Rivera <stefano@rivera.za.net>
parents:
38
diff
changeset
|
12 rect = pygame.Rect(rect, (0, 0)) |
3f44c30a1c39
Correct Text placement
Stefano Rivera <stefano@rivera.za.net>
parents:
38
diff
changeset
|
13 self.rect = rect |
58 | 14 self.focussable = False |
77 | 15 self.focussed = False |
55
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
16 self.callbacks = collections.defaultdict(list) |
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
17 |
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
18 def add_callback(self, eventtype, callback, *args): |
671d027f1b71
Callbacks for events in widgets
Stefano Rivera <stefano@rivera.za.net>
parents:
43
diff
changeset
|
19 self.callbacks[eventtype].append((callback, args)) |
23 | 20 |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
21 def event(self, ev): |
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
22 for callback, args in self.callbacks[ev.type]: |
77 | 23 if callback(ev, self, *args): |
24 return True | |
25 return False | |
23 | 26 |
24
30d4f3e62bcf
Refactor widgets *again*, add container to Habitat
Stefano Rivera <stefano@rivera.za.net>
parents:
23
diff
changeset
|
27 def draw(self, surface): |
23 | 28 "Override me" |
29 pass | |
30 | |
31 | |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
32 class Container(Widget): |
23 | 33 |
77 | 34 def __init__(self, rect, root=False): |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
35 super(Container, self).__init__(rect) |
23 | 36 self.children = [] |
77 | 37 self.root = root |
38 self.focussed = root | |
39 self.focussable = True | |
40 self.focussed_child = None | |
23 | 41 |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
42 def event(self, ev): |
77 | 43 """Push an event down through the tree, and fire our own event as a |
44 last resort | |
45 """ | |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
46 if ev.type in (MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN): |
58 | 47 for child in self.children: |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
48 if child.rect.collidepoint(ev.pos): |
77 | 49 if child.event(ev): |
50 return True | |
59
3cc917814579
Container subclasses Widget
Stefano Rivera <stefano@rivera.za.net>
parents:
58
diff
changeset
|
51 if ev.type == KEYDOWN: |
58 | 52 for child in self.children: |
77 | 53 if child.focussed: |
54 if child.event(ev): | |
55 return True | |
56 if super(Container, self).event(ev): | |
57 return True | |
58 if self.root and ev.type == KEYDOWN and ev.key in (K_UP, K_DOWN): | |
59 self.adjust_focus(1 if ev.key == K_DOWN else -1) | |
23 | 60 |
61 def add(self, widget): | |
77 | 62 widget.parent = self |
23 | 63 self.children.append(widget) |
64 | |
77 | 65 def adjust_focus(self, direction): |
66 """Try and adjust focus in direction (integer) | |
67 """ | |
68 if self.focussed_child is not None: | |
69 child = self.children[self.focussed_child] | |
70 if isinstance(child, Container): | |
71 if child.adjust_focus(direction): | |
72 return True | |
73 child.focussed = False | |
74 | |
75 current = self.focussed_child | |
76 if current is None: | |
77 current = -1 if direction > 0 else len(self.children) | |
78 if direction > 0: | |
79 possibles = list(enumerate(self.children))[current + 1:] | |
80 else: | |
81 possibles = list(enumerate(self.children))[:current] | |
82 possibles.reverse() | |
83 for i, child in possibles: | |
84 if child.focussable: | |
85 child.focussed = True | |
86 if isinstance(child, Container): | |
87 if child.adjust_focus(direction): | |
88 self.focussed_child = i | |
89 return True | |
90 child.focussed = False | |
91 continue | |
92 else: | |
93 self.focussed_child = i | |
94 child.focussed = True | |
95 return True | |
96 else: | |
97 return False | |
98 | |
23 | 99 def draw(self, surface): |
100 for child in self.children: | |
24
30d4f3e62bcf
Refactor widgets *again*, add container to Habitat
Stefano Rivera <stefano@rivera.za.net>
parents:
23
diff
changeset
|
101 child.draw(surface) |