Mercurial > pyntnclick
comparison pyntnclick/gamescreen.py @ 803:bcc9277a23e6 pyntnclick
Refactor widget positioning API. Remove unused widgets
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sun, 27 Jan 2013 14:52:16 +0200 |
parents | bdaffaa8b6bf |
children | 6f38e20b1417 |
comparison
equal
deleted
inserted
replaced
802:5ec7905b2365 | 803:bcc9277a23e6 |
---|---|
1 # gamescreen.py | 1 # gamescreen.py |
2 # Copyright Boomslang team, 2010 (see COPYING File) | 2 # Copyright Boomslang team, 2010 (see COPYING File) |
3 # Main menu for the game | 3 # Main menu for the game |
4 | 4 |
5 import pygame.draw | 5 import pygame.draw |
6 from pygame import Rect, Surface | 6 from pygame import Surface |
7 from pygame.color import Color | 7 from pygame.color import Color |
8 from pygame.locals import MOUSEBUTTONDOWN, MOUSEMOTION, KEYDOWN, K_ESCAPE | 8 from pygame.locals import MOUSEBUTTONDOWN, MOUSEMOTION, KEYDOWN, K_ESCAPE |
9 | 9 |
10 from pyntnclick.i18n import _ | 10 from pyntnclick.i18n import _ |
11 from pyntnclick.cursor import CursorScreen | 11 from pyntnclick.cursor import CursorScreen |
18 | 18 |
19 class InventorySlot(ImageButtonWidget): | 19 class InventorySlot(ImageButtonWidget): |
20 SELECTED_COLOR = Color("yellow") | 20 SELECTED_COLOR = Color("yellow") |
21 SELECTED_WIDTH = 2 | 21 SELECTED_WIDTH = 2 |
22 | 22 |
23 def __init__(self, rect, gd): | 23 def __init__(self, pos, gd, size): |
24 self.item = None | 24 self.item = None |
25 super(InventorySlot, self).__init__(rect, gd, None) | 25 super(InventorySlot, self).__init__(pos, gd, None, size) |
26 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) | 26 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) |
27 | 27 |
28 def set_item(self, item): | 28 def set_item(self, item): |
29 self.item = item | 29 self.item = item |
30 | 30 |
51 self.parent.select(self.item) | 51 self.parent.select(self.item) |
52 | 52 |
53 | 53 |
54 class UpDownButton(TextButton): | 54 class UpDownButton(TextButton): |
55 # TextButton for now. | 55 # TextButton for now. |
56 def __init__(self, rect, gd): | 56 def __init__(self, pos, gd, size=None): |
57 super(UpDownButton, self).__init__(rect, gd, self.TEXT, padding=3) | 57 super(UpDownButton, self).__init__(pos, gd, self.TEXT, size=size, |
58 padding=3) | |
58 | 59 |
59 | 60 |
60 class UpButton(UpDownButton): | 61 class UpButton(UpDownButton): |
61 TEXT = u'\N{UPWARDS ARROW}UP' | 62 TEXT = u'\N{UPWARDS ARROW}UP' |
62 | 63 |
66 | 67 |
67 | 68 |
68 class InventoryView(Container): | 69 class InventoryView(Container): |
69 MIN_UPDOWN_WIDTH = 16 | 70 MIN_UPDOWN_WIDTH = 16 |
70 | 71 |
71 def __init__(self, rect, gd, screen): | 72 def __init__(self, pos, gd, size, screen): |
72 self.bsize = gd.constants.button_size | 73 self.bsize = gd.constants.button_size |
73 super(InventoryView, self).__init__(rect, gd) | 74 super(InventoryView, self).__init__(pos, gd, size) |
74 self.screen = screen | 75 self.screen = screen |
75 self.game = screen.game | 76 self.game = screen.game |
76 | 77 |
77 slots = (self.rect.width - self.MIN_UPDOWN_WIDTH) / self.bsize | 78 slots = (self.rect.width - self.MIN_UPDOWN_WIDTH) / self.bsize |
78 self.slots = [self.add(self.make_slot(i)) for i in range(slots)] | 79 self.slots = [self.add(self.make_slot(i)) for i in range(slots)] |
79 self.inv_offset = 0 | 80 self.inv_offset = 0 |
80 | 81 |
81 self.updown_width = self.rect.width - slots * self.bsize | 82 self.updown_width = self.rect.width - slots * self.bsize |
82 ud_left = self.rect.right - self.updown_width | 83 ud_left = self.rect.right - self.updown_width |
83 self.up_button = self.add(UpButton(Rect( | 84 self.up_button = self.add(UpButton((ud_left, self.rect.top), gd, |
84 (ud_left, self.rect.top), | 85 (self.updown_width, self.rect.height / 2))) |
85 (self.updown_width, self.rect.height / 2)), gd)) | |
86 self.up_button.add_callback(MOUSEBUTTONDOWN, self.up_callback) | 86 self.up_button.add_callback(MOUSEBUTTONDOWN, self.up_callback) |
87 self.down_button = self.add(DownButton(Rect( | 87 self.down_button = self.add(DownButton( |
88 (ud_left, self.rect.top + self.rect.height / 2), | 88 (ud_left, self.rect.top + self.rect.height / 2), gd, |
89 (self.updown_width, self.rect.height / 2)), gd)) | 89 (self.updown_width, self.rect.height / 2))) |
90 self.down_button.add_callback(MOUSEBUTTONDOWN, self.down_callback) | 90 self.down_button.add_callback(MOUSEBUTTONDOWN, self.down_callback) |
91 | 91 |
92 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) | 92 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) |
93 self.update_slots() | 93 self.update_slots() |
94 | 94 |
95 def make_slot(self, slot): | 95 def make_slot(self, slot): |
96 rect = Rect((self.rect.left + slot * self.bsize, self.rect.top), | 96 pos = (self.rect.left + slot * self.bsize, self.rect.top) |
97 (self.bsize, self.rect.height)) | 97 size = (self.bsize, self.rect.height) |
98 return InventorySlot(rect, self.gd) | 98 return InventorySlot(pos, self.gd, size) |
99 | 99 |
100 def up_callback(self, event, widget): | 100 def up_callback(self, event, widget): |
101 self.inv_offset = max(self.inv_offset - len(self.slots), 0) | 101 self.inv_offset = max(self.inv_offset - len(self.slots), 0) |
102 self.update_slots() | 102 self.update_slots() |
103 | 103 |
136 | 136 |
137 class SceneWidget(Container): | 137 class SceneWidget(Container): |
138 DETAIL_BORDER = 4 | 138 DETAIL_BORDER = 4 |
139 DETAIL_BORDER_COLOR = Color("black") | 139 DETAIL_BORDER_COLOR = Color("black") |
140 | 140 |
141 def __init__(self, rect, gd, scene, screen, is_detail=False): | 141 def __init__(self, pos, gd, size, scene, screen, is_detail=False): |
142 super(SceneWidget, self).__init__(rect, gd) | 142 super(SceneWidget, self).__init__(pos, gd, size) |
143 self.name = scene.NAME | 143 self.name = scene.NAME |
144 self.scene = scene | 144 self.scene = scene |
145 self.screen = screen | 145 self.screen = screen |
146 self.game = screen.game | 146 self.game = screen.game |
147 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) | 147 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) |
148 self.add_callback(MOUSEMOTION, self.mouse_move) | 148 self.add_callback(MOUSEMOTION, self.mouse_move) |
149 self.is_detail = is_detail | 149 self.is_detail = is_detail |
150 if is_detail: | 150 if is_detail: |
151 self.close_button = TextButton((0, 0), self.gd, _("Close")) | 151 self.close_button = TextButton((0, 0), self.gd, _("Close")) |
152 self.close_button.do_prepare() | 152 self.close_button.do_prepare() |
153 # TODO: Don't muck around with close_button's rect | |
153 self.close_button.rect.midbottom = self.rect.midbottom | 154 self.close_button.rect.midbottom = self.rect.midbottom |
154 self.close_button.add_callback('clicked', self.close) | 155 self.close_button.add_callback('clicked', self.close) |
155 self.add(self.close_button) | 156 self.add(self.close_button) |
156 | 157 |
157 def draw(self, surface): | 158 def draw(self, surface): |
192 def close(self, event, widget): | 193 def close(self, event, widget): |
193 self.screen.close_detail(self) | 194 self.screen.close_detail(self) |
194 | 195 |
195 | 196 |
196 class ToolBar(Container): | 197 class ToolBar(Container): |
197 def __init__(self, rect, gd, screen): | 198 def __init__(self, pos, gd, size, screen): |
198 self.screen = screen | 199 self.screen = screen |
199 button_size = gd.constants.button_size | 200 |
200 | 201 super(ToolBar, self).__init__(pos, gd, size) |
201 if not isinstance(rect, Rect): | |
202 rect = Rect(rect, (gd.constants.scene_size[0], button_size)) | |
203 super(ToolBar, self).__init__(rect, gd) | |
204 | 202 |
205 self.bg_color = (31, 31, 31) | 203 self.bg_color = (31, 31, 31) |
206 self.left = self.rect.left | 204 self.left = self.rect.left |
207 | 205 |
208 self.menu_button = self.add_tool( | 206 self.menu_button = self.add_tool( |
209 0, TextButton, gd, _("Menu"), fontname=gd.constants.bold_font, | 207 None, TextButton, _("Menu"), fontname=gd.constants.bold_font, |
210 color="red", padding=1, border=0, bg_color="black") | 208 color="red", padding=1, border=0, bg_color="black") |
211 self.menu_button.add_callback(MOUSEBUTTONDOWN, self.menu_callback) | 209 self.menu_button.add_callback(MOUSEBUTTONDOWN, self.menu_callback) |
212 | 210 |
213 hand_image = gd.resource.get_image('items', 'hand.png') | 211 hand_image = gd.resource.get_image('items', 'hand.png') |
214 self.hand_button = self.add_tool( | 212 self.hand_button = self.add_tool( |
215 None, ImageButtonWidget, gd, hand_image) | 213 None, ImageButtonWidget, hand_image) |
216 self.hand_button.add_callback(MOUSEBUTTONDOWN, self.hand_callback) | 214 self.hand_button.add_callback(MOUSEBUTTONDOWN, self.hand_callback) |
217 | 215 |
218 self.inventory = self.add_tool( | 216 self.inventory = self.add_tool( |
219 self.rect.width - self.left, InventoryView, gd, screen) | 217 self.rect.width - self.left, InventoryView, screen=screen) |
220 | 218 |
221 def add_tool(self, width, cls, *args, **kw): | 219 def add_tool(self, width, cls, *args, **kw): |
222 rect = (self.left, self.rect.top) | 220 pos = (self.left, self.rect.top) |
223 if width is not None: | 221 if width is not None: |
224 rect = Rect(rect, (width, self.rect.height)) | 222 kw['size'] = (width, self.rect.height) |
225 tool = cls(rect, *args, **kw) | 223 tool = cls(pos, self.gd, *args, **kw) |
226 self.add(tool) | 224 self.add(tool) |
227 tool.do_prepare() | 225 tool.do_prepare() |
228 self.left += tool.rect.width | 226 self.left += tool.rect.width |
229 return tool | 227 return tool |
230 | 228 |
276 def reset_game(self, game_state=None): | 274 def reset_game(self, game_state=None): |
277 self._clear_all() | 275 self._clear_all() |
278 self.game = self.create_initial_state(game_state) | 276 self.game = self.create_initial_state(game_state) |
279 | 277 |
280 self.screen_modal = self.container.add( | 278 self.screen_modal = self.container.add( |
281 ModalStackContainer(self.container.rect.copy(), self.gd)) | 279 ModalStackContainer(self.container.pos, self.gd, |
280 self.container.size)) | |
282 self.inner_container = self.screen_modal.add( | 281 self.inner_container = self.screen_modal.add( |
283 Container(self.container.rect.copy(), self.gd)) | 282 Container(self.container.pos, self.gd, self.container.size)) |
284 | 283 |
285 toolbar_height = self.gd.constants.button_size | 284 toolbar_height = self.gd.constants.button_size |
286 rect = Rect(0, 0, self.surface_size[0], | |
287 self.surface_size[1] - toolbar_height) | |
288 | 285 |
289 self.scene_modal = self.inner_container.add( | 286 self.scene_modal = self.inner_container.add( |
290 ModalStackContainer(rect, self.gd)) | 287 ModalStackContainer((0, 0), self.gd, |
288 (self.surface_size[0], self.surface_size[1] - toolbar_height))) | |
291 self.toolbar = self.inner_container.add( | 289 self.toolbar = self.inner_container.add( |
292 ToolBar((0, rect.height), self.gd, self)) | 290 ToolBar((0, self.surface_size[1] - toolbar_height), self.gd, |
291 (self.surface_size[0], toolbar_height), self)) | |
293 self.inventory = self.toolbar.inventory | 292 self.inventory = self.toolbar.inventory |
294 | 293 |
295 self.gd.running = True | 294 self.gd.running = True |
296 | 295 |
297 def game_event_inventory(self, data): | 296 def game_event_inventory(self, data): |
313 | 312 |
314 def show_detail(self, detail_name): | 313 def show_detail(self, detail_name): |
315 self._add_scene(self.game.detail_views[detail_name], True) | 314 self._add_scene(self.game.detail_views[detail_name], True) |
316 | 315 |
317 def _add_scene(self, scene, detail=False): | 316 def _add_scene(self, scene, detail=False): |
318 rect = self.scene_modal.rect.copy() | 317 pos = self.scene_modal.rect.topleft |
318 size = self.scene_modal.rect.size | |
319 if detail: | 319 if detail: |
320 rect = Rect((0, 0), scene.get_detail_size()) | 320 size = scene.get_detail_size() |
321 rect.center = self.scene_modal.rect.center | 321 pos = ((self.scene_modal.rect.width - size[0]) / 2, |
322 | 322 (self.scene_modal.rect.height - size[1]) / 2) |
323 self.scene_modal.add(SceneWidget(rect, self.gd, scene, self, detail)) | 323 |
324 self.scene_modal.add(SceneWidget(pos, self.gd, size, scene, self, | |
325 detail)) | |
324 self.handle_result(scene.enter()) | 326 self.handle_result(scene.enter()) |
325 | 327 |
326 def close_detail(self, detail=None): | 328 def close_detail(self, detail=None): |
327 if detail is None: | 329 if detail is None: |
328 detail = self.scene_modal.top | 330 detail = self.scene_modal.top |
352 def queue_widget(self, widget): | 354 def queue_widget(self, widget): |
353 self._message_queue.append(widget) | 355 self._message_queue.append(widget) |
354 self.show_queued_widget() | 356 self.show_queued_widget() |
355 | 357 |
356 def show_message(self, message): | 358 def show_message(self, message): |
357 rect = Rect((0, 0), (1, 1)) | |
358 max_width = self.gd.constants.screen[0] - 100 | 359 max_width = self.gd.constants.screen[0] - 100 |
359 widget = WrappedTextLabel(rect, self.gd, message, max_width=max_width) | 360 widget = WrappedTextLabel((0, 0), self.gd, message, |
361 max_width=max_width) | |
360 widget.do_prepare() | 362 widget.do_prepare() |
363 # TODO: Use the centering API when it exists | |
361 widget.rect.center = self.container.rect.center | 364 widget.rect.center = self.container.rect.center |
362 self.queue_widget(widget) | 365 self.queue_widget(widget) |
363 | 366 |
364 def handle_result(self, resultset): | 367 def handle_result(self, resultset): |
365 """Handle dealing with result or result sequences""" | 368 """Handle dealing with result or result sequences""" |