Mercurial > mamba
view mamba/habitats/levelmenu.py @ 524:dc5fdd7b3ce5
Defocus while we still have the focused things to defocus. Otherwise we crash in a way that makes confluence sad.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Sun, 18 Sep 2011 00:57:21 +0200 |
parents | 9393dc6f5707 |
children | c798ba211b6e |
line wrap: on
line source
"""Level menu.""" import pygame from pygame.locals import KEYDOWN, K_PAGEUP, K_PAGEDOWN from mamba.constants import ESCAPE_KEYS from mamba.engine import Habitat, NewHabitatEvent, HabitatSetupEvent from mamba.gamestate import done_levels from mamba.data import get_official_levels, load_image from mamba.level import Level from mamba.widgets.overlay import OverlayButton from mamba.widgets.base import GridContainer from mamba.widgets.levelbutton import LevelButton OFFICIAL_LEVELS = [] LEVEL_CACHE = {} class LevelMenu(Habitat): WIDTH = 5 HEIGHT = 3 def __init__(self): super(LevelMenu, self).__init__() self.level_buttons = {} self.page = 0 self.bg_image = load_image('menus/level-menu.png') self.grid_container = GridContainer(width=self.WIDTH) self.container.add(self.grid_container) self.prev_button = self.add_box((9, 497), (52, 45), 'left', self.change_page, -1) self.next_button = self.add_box((738, 497), (54, 44), 'right', self.change_page, 1) self.add_box((12, 11), (142, 41), 'back', self.return_to_mainmenu) self.container.add_callback(KEYDOWN, self.keydown_event) def add_box(self, pos, size, overlay_name, clicked, *args): image = load_image('menus/submenu-%s.png' % overlay_name) box = OverlayButton(pygame.Rect(pos, size), image) box.add_callback('clicked', clicked, *args) self.container.add(box) return box def draw_background(self): self.surface.blit(self.bg_image, self.surface.get_rect()) def on_enter(self): super(LevelMenu, self).on_enter() self._setup_levels() def dispatch(self, ev): if HabitatSetupEvent.matches(ev): self._setup_levels(ev) return super(LevelMenu, self).dispatch(ev) def _setup_levels(self, ev=None): if ev is not None: self.setup_levels() else: HabitatSetupEvent.post() def setup_level(self, i, name): level = self.get_level(name) button = LevelButton((94 + (100 + 27) * (i % self.WIDTH), 92 + (120 + 27) * (i // self.WIDTH)), level) button.add_callback('clicked', self.level_selected, name) button.done = level.unique_name() in done_levels self.grid_container.add(button) self.level_buttons[name] = button def setup_levels(self): if not getattr(self, '_setup_gen', None): self._setup_gen = self._setup_levels_gen() try: self._setup_gen.next() HabitatSetupEvent.post() except StopIteration: self._setup_gen = None # We're done here. return def _setup_levels_gen(self): del self.grid_container.children[:] levels = list(self.list_levels()) if self.page * self.WIDTH * self.HEIGHT > len(levels): self.page = len(levels) // self.WIDTH // self.HEIGHT elif self.page < 0: self.page = 0 first = self.page * self.WIDTH * self.HEIGHT last = first + (self.WIDTH * self.HEIGHT) for i, name in enumerate(levels[first:last]): yield self.setup_level(i, name) if self.page == 0: self.prev_button.disable() else: self.prev_button.enable() if len(levels) <= last: self.next_button.disable() else: self.next_button.enable() self.container.defocus() # We now have widgets, let's give them focus self.container.adjust_focus(1) def change_page(self, ev, widget, direction): self.container.defocus() self.page += direction self.setup_levels() return True def list_levels(self): raise NotImplementedError() def get_level(self, name): raise NotImplementedError() def level_selected(self, ev, widget, name): from mamba.habitats.level import LevelHabitat next_level = self.mk_next_level(name) NewHabitatEvent.post( LevelHabitat(widget.level, self.go_menu, next_level)) return True def mk_next_level(self, name): return self.go_menu @classmethod def go_menu(cls): NewHabitatEvent.post(cls()) def keydown_event(self, ev, widget): if ev.key in ESCAPE_KEYS: return self.return_to_mainmenu(ev, widget) if ev.key == K_PAGEUP: return self.change_page(ev, widget, -1) if ev.key == K_PAGEDOWN: return self.change_page(ev, widget, 1) def return_to_mainmenu(self, ev, widget): from mamba.habitats.mainmenu import MainMenu NewHabitatEvent.post(MainMenu()) return True class OfficialLevelMenu(LevelMenu): level_namespace = 'official' def mk_next_level(self, name): levels = self.list_levels() if name not in levels: return self.go_menu idx = levels.index(name) + 1 if idx >= len(levels): return self.go_menu next_name = levels[idx] def next_level(): from mamba.habitats.level import LevelHabitat next_level = self.mk_next_level(next_name) NewHabitatEvent.post(LevelHabitat(self.get_level(next_name), self.go_menu, next_level)) return next_level def list_levels(self): if not OFFICIAL_LEVELS: OFFICIAL_LEVELS.extend(get_official_levels()) return OFFICIAL_LEVELS[:] def get_level(self, name): if name not in LEVEL_CACHE: LEVEL_CACHE[name] = Level(name, self.level_namespace) return LEVEL_CACHE[name]