Mercurial > sypikslang
annotate gamelib/gui_base.py @ 236:ce1e23ea46e5
added generic background for all windows
author | Rizmari Versfeld <rizziepit@gmail.com> |
---|---|
date | Sun, 13 May 2012 00:17:07 +0200 |
parents | 16ce5ed563c9 |
children | 05afa7ae5df3 |
rev | line source |
---|---|
37 | 1 import pygame |
70 | 2 from pygame.locals import SRCALPHA |
39
d82d3e54a4ef
fixed more pep8 issues
Rizmari Versfeld <rizziepit@gmail.com>
parents:
38
diff
changeset
|
3 from pygame import Surface, Rect |
37 | 4 from pygame.font import Font |
236
ce1e23ea46e5
added generic background for all windows
Rizmari Versfeld <rizziepit@gmail.com>
parents:
212
diff
changeset
|
5 from pygame import image |
37 | 6 |
7 from gamelib import data | |
236
ce1e23ea46e5
added generic background for all windows
Rizmari Versfeld <rizziepit@gmail.com>
parents:
212
diff
changeset
|
8 from gamelib.data import filepath |
37 | 9 |
10 | |
11 # different font sizes | |
12 pygame.font.init() | |
13 font_small = Font(data.filepath('fonts/DejaVuSans.ttf'), 10) | |
14 font_medium = Font(data.filepath('fonts/DejaVuSans.ttf'), 14) | |
15 font_large = Font(data.filepath('fonts/DejaVuSans.ttf'), 18) | |
110
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
16 font_auto = None |
37 | 17 |
18 | |
19 class Drawable(object): | |
38 | 20 |
21 def __init__(self, rect): | |
22 if isinstance(rect, Rect): | |
23 self.rect = rect | |
24 else: | |
25 self.rect = Rect(rect[0], rect[1], rect[2], rect[3]) | |
26 | |
27 def draw(self, surface): | |
28 pass | |
29 | |
30 | |
37 | 31 class Clickable(object): |
38 | 32 |
33 def on_mouse_down(self, pos): | |
34 pass | |
35 | |
36 def on_mouse_up(self, pos): | |
37 pass | |
38 | |
39 def on_mouse_move(self, pos): | |
40 pass | |
41 | |
42 def on_mouse_cancel(self): | |
43 pass | |
44 | |
45 def on_click(self): | |
46 pass | |
47 | |
37 | 48 |
49 class ContainerView(Drawable): | |
38 | 50 |
51 def __init__(self): | |
52 self.children = [] | |
53 | |
54 def add_child(self, child): | |
55 self.children.append(child) | |
56 | |
57 def remove_child(self, child): | |
58 self.children.remove(child) | |
59 | |
60 def get_child_by_pos(self, pos): | |
61 for child in self.children: | |
62 if child.rect.collidepoint(pos): | |
63 if isinstance(child, ContainerView): | |
64 # calculates position relative to child | |
65 x = pos[0] - child.rect[0] | |
66 y = pos[1] - child.rect[1] | |
67 return child.get_child_by_pos((x, y)) | |
68 else: | |
69 return child | |
70 | |
71 def draw_children(self, surface): | |
72 for child in self.children: | |
73 child.draw(surface) | |
74 | |
75 | |
37 | 76 class Window(Clickable, ContainerView): |
38 | 77 |
78 def __init__(self, screen): | |
79 super(Window, self).__init__() | |
80 self.surface = Surface((screen.get_width(), screen.get_height())) | |
81 self.background_colour = None | |
236
ce1e23ea46e5
added generic background for all windows
Rizmari Versfeld <rizziepit@gmail.com>
parents:
212
diff
changeset
|
82 self.background_image = image.load( |
ce1e23ea46e5
added generic background for all windows
Rizmari Versfeld <rizziepit@gmail.com>
parents:
212
diff
changeset
|
83 filepath('images/background.jpg')) |
38 | 84 self.pressed_child = None |
85 | |
86 def on_mouse_down(self, pos): | |
87 child = self.get_child_by_pos(pos) | |
88 if isinstance(child, Clickable): | |
89 # calculates position relative to child | |
90 x = pos[0] - child.rect[0] | |
91 y = pos[1] - child.rect[1] | |
92 child.on_mouse_down((x, y)) | |
93 self.pressed_child = child | |
94 | |
95 def on_mouse_up(self, pos): | |
96 if self.pressed_child: | |
97 child = self.pressed_child | |
98 x = pos[0] - child.rect[0] | |
99 y = pos[1] - child.rect[1] | |
100 child.on_mouse_up((x, y)) | |
101 self.pressed_child = None | |
102 | |
103 def on_mouse_move(self, pos): | |
104 if self.pressed_child: | |
105 if self.pressed_child != self.get_child_by_pos(pos): | |
106 self.pressed_child.on_mouse_cancel() | |
107 self.pressed_child = None | |
108 | |
109 def draw(self, screen): | |
110 if self.background_colour: | |
111 self.surface.fill(self.background_colour) | |
68
7309392d9ca9
fixed widget drawing bugs
Rizmari Versfeld <rizziepit@gmail.com>
parents:
64
diff
changeset
|
112 else: |
7309392d9ca9
fixed widget drawing bugs
Rizmari Versfeld <rizziepit@gmail.com>
parents:
64
diff
changeset
|
113 self.surface.fill((0, 0, 0, 255)) |
38 | 114 if self.background_image: |
115 self.surface.blit(self.background_image, (0, 0)) | |
116 self.draw_children(self.surface) | |
117 screen.blit(self.surface, (0, 0)) | |
118 | |
37 | 119 |
120 class StateDrawable(Drawable): | |
38 | 121 |
122 def __init__(self, rect): | |
123 super(StateDrawable, self).__init__(rect) | |
124 self.state = -1 | |
125 self.states = {} | |
126 self.drawables = [] | |
127 | |
128 def draw(self, surface): | |
129 if self.state != -1 and self.drawables[self.state]: | |
130 self.drawables[self.state].draw(surface) | |
131 | |
132 def add_state(self, state_name, drawable): | |
133 self.states[state_name] = len(self.drawables) | |
134 self.drawables.append(drawable) | |
135 | |
136 def set_state(self, state_name): | |
137 self.state = self.states[state_name] | |
138 | |
139 | |
37 | 140 class Button(Clickable, StateDrawable): |
38 | 141 |
142 def __init__(self, rect, normal_drawable, down_drawable): | |
143 super(Button, self).__init__(rect) | |
144 self.add_state('NORMAL', normal_drawable) | |
145 self.add_state('DOWN', down_drawable) | |
146 self.set_state('NORMAL') | |
147 | |
148 def on_mouse_down(self, pos): | |
149 self.set_state('DOWN') | |
150 | |
151 def on_mouse_up(self, pos): | |
152 self.set_state('NORMAL') | |
153 self.on_click() | |
154 | |
155 def on_mouse_cancel(self): | |
156 self.set_state('NORMAL') | |
157 | |
158 | |
37 | 159 class TextButton(Button): |
160 | |
62
38f41d046c6f
Make button font a parameter. Tweak indication of points to be spent
Neil Muller <drnlmuller@gmail.com>
parents:
55
diff
changeset
|
161 def __init__(self, rect, normal_drawable, down_drawable, text, font, |
212 | 162 shadow, text_rect=None, color=(0, 0, 0), |
163 shadow_color=(128, 128, 128)): | |
38 | 164 super(TextButton, self).__init__(rect, normal_drawable, down_drawable) |
145
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
165 self.text_rect = Rect((0, 0), self.rect.size) |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
166 if text_rect is not None: |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
167 self.text_rect = Rect(*text_rect) |
38 | 168 self.text = text |
110
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
169 if font is font_auto: |
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
170 font = self._auto_font() |
62
38f41d046c6f
Make button font a parameter. Tweak indication of points to be spent
Neil Muller <drnlmuller@gmail.com>
parents:
55
diff
changeset
|
171 self.font = font |
38f41d046c6f
Make button font a parameter. Tweak indication of points to be spent
Neil Muller <drnlmuller@gmail.com>
parents:
55
diff
changeset
|
172 self.shadow = shadow |
212 | 173 self.shadow_color = shadow_color |
174 self.color = color | |
55
86d83dcb7d42
Make text drawing easier to poke at for subclasses
Neil Muller <drnlmuller@gmail.com>
parents:
39
diff
changeset
|
175 self._draw_text() |
86d83dcb7d42
Make text drawing easier to poke at for subclasses
Neil Muller <drnlmuller@gmail.com>
parents:
39
diff
changeset
|
176 |
110
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
177 def _auto_font(self): |
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
178 for font in (font_large, font_medium): |
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
179 h, w = font.size(self.text) |
145
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
180 if w < self.text_rect.width and h < self.text_rect.height: |
110
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
181 return font |
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
182 return font_small |
ff7c953502d5
Auto-downsize fonts on BigButtons that are too large.
Simon Cross <hodgestar@gmail.com>
parents:
74
diff
changeset
|
183 |
55
86d83dcb7d42
Make text drawing easier to poke at for subclasses
Neil Muller <drnlmuller@gmail.com>
parents:
39
diff
changeset
|
184 def _draw_text(self): |
62
38f41d046c6f
Make button font a parameter. Tweak indication of points to be spent
Neil Muller <drnlmuller@gmail.com>
parents:
55
diff
changeset
|
185 self.font.set_bold(True) |
212 | 186 self.text_surface = self.font.render(self.text, True, self.color) |
69 | 187 size = self.font.size(self.text) |
62
38f41d046c6f
Make button font a parameter. Tweak indication of points to be spent
Neil Muller <drnlmuller@gmail.com>
parents:
55
diff
changeset
|
188 if self.shadow: |
212 | 189 s = self.font.render(self.text, True, self.shadow_color) |
74
22b65c943712
prettified main menu - temp background
Rizmari Versfeld <rizziepit@gmail.com>
parents:
71
diff
changeset
|
190 temp = Surface((s.get_width() + 1, s.get_width() + 1), SRCALPHA) |
71 | 191 temp.fill((255, 255, 255, 0)) |
74
22b65c943712
prettified main menu - temp background
Rizmari Versfeld <rizziepit@gmail.com>
parents:
71
diff
changeset
|
192 temp.blit(s, (1, 1)) |
71 | 193 temp.blit(self.text_surface, (0, 0)) |
194 self.text_surface = temp | |
68
7309392d9ca9
fixed widget drawing bugs
Rizmari Versfeld <rizziepit@gmail.com>
parents:
64
diff
changeset
|
195 size = [s + 2 for s in size] |
145
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
196 self.text_offset = Rect((0, 0), size) |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
197 self.text_offset.center = self.text_rect.center |
68
7309392d9ca9
fixed widget drawing bugs
Rizmari Versfeld <rizziepit@gmail.com>
parents:
64
diff
changeset
|
198 self.font.set_bold(False) |
37 | 199 |
38 | 200 def draw(self, surface): |
145
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
201 temp_surface = Surface(self.rect.size, SRCALPHA) |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
202 super(TextButton, self).draw(temp_surface) |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
203 temp_surface.blit(self.text_surface, self.text_offset) |
53277724645b
Science button juggling.
Jeremy Thurgood <firxen@gmail.com>
parents:
143
diff
changeset
|
204 surface.blit(temp_surface, self.rect) |
64 | 205 |
206 | |
143
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
207 class ToggleButton(Button): |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
208 |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
209 def __init__(self, rect, normal_drwble, down_drwble): |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
210 super(ToggleButton, self).__init__(rect, normal_drwble, down_drwble) |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
211 self.toggled = False |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
212 |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
213 def on_click(self): |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
214 self.toggled = not self.toggled |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
215 if self.toggled: |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
216 self.set_state('DOWN') |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
217 else: |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
218 self.set_state('NORMAL') |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
219 |
821ecb98e888
some icons and toggle button
Rizmari Versfeld <rizziepit@gmail.com>
parents:
119
diff
changeset
|
220 |
64 | 221 class TextLabel(Drawable): |
222 | |
223 def __init__(self, rect, text, font, color): | |
224 super(TextLabel, self).__init__(rect) | |
68
7309392d9ca9
fixed widget drawing bugs
Rizmari Versfeld <rizziepit@gmail.com>
parents:
64
diff
changeset
|
225 self.surface = Surface((rect[2], rect[3]), pygame.SRCALPHA) |
64 | 226 self.text = text |
227 self.font = font | |
228 self.color = color | |
229 self._draw_text() | |
230 | |
231 def _draw_text(self): | |
232 self.text_surface = self.font.render(self.text, True, self.color) | |
233 size = self.font.size(self.text) | |
234 # We centre vertically, but start at left edge | |
235 self.text_offset = (0, (self.rect[3] - size[1]) / 2) | |
236 | |
237 def draw(self, surface): | |
238 self.surface.fill((0, 0, 0, 0)) | |
239 super(TextLabel, self).draw(self.surface) | |
240 self.surface.blit(self.text_surface, self.text_offset) | |
241 surface.blit(self.surface, self.rect) | |
113 | 242 |
243 | |
244 class TextBox(TextLabel): | |
245 | |
246 def _draw_text(self): | |
247 self.text_surface = Surface((self.rect[2], self.rect[3]), | |
248 pygame.SRCALPHA) | |
249 current_height = 0 | |
250 current_str = '' | |
251 size = None | |
252 for word in self.text.split(' '): | |
253 size = self.font.size(current_str + word) | |
254 if size[0] < self.rect.width: | |
255 current_str += word + ' ' | |
256 else: | |
257 s = self.font.render(current_str[0:-1], True, self.color) | |
119
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
258 self._resize_text_surface(current_height + size[1]) |
113 | 259 self.text_surface.blit(s, (0, current_height)) |
260 current_height += size[1] | |
261 current_str = word + ' ' | |
262 if current_str[-1] == ' ': | |
263 current_str = current_str[0:-1] | |
264 s = self.font.render(current_str, True, self.color) | |
119
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
265 self._resize_text_surface(current_height + size[1]) |
113 | 266 self.text_surface.blit(s, (0, current_height)) |
267 self.text_offset = (0, 0) | |
268 self.rect.height = current_height + size[1] | |
269 self.surface = Surface((self.rect.width, self.rect.height), | |
270 pygame.SRCALPHA) | |
119
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
271 |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
272 def _resize_text_surface(self, new_height): |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
273 """Resize the text surface if needed""" |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
274 if new_height > self.text_surface.get_rect().height: |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
275 old_text = self.text_surface |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
276 self.text_surface = Surface((self.rect[2], new_height), |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
277 pygame.SRCALPHA) |
9a30162f2a9c
Add more logic around resizing surfaces
Neil Muller <drnlmuller@gmail.com>
parents:
114
diff
changeset
|
278 self.text_surface.blit(old_text, (0, 0)) |