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"""