Mercurial > mamba
view mamba/habitats/editor.py @ 276:9c57025781e7
Warn on enter filename results
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Thu, 15 Sep 2011 17:57:28 +0200 |
parents | 51bec5e6191e |
children | 82aa91664e27 |
line wrap: on
line source
"""Habitat for editing levels.""" import pygame.display from pygame.locals import SWSURFACE, KEYDOWN, K_1, K_2 from mamba.engine import Habitat, NewHabitatEvent from mamba.widgets.level import EditLevelWidget from mamba.widgets.text import TextWidget, TextButton from mamba.widgets.imagebutton import ImageButtonWidget from mamba.widgets.messagebox import MessageBox from mamba.widgets.entrybox import EntryBox from mamba.widgets.listbox import ListBox from mamba.widgets.toollist import ToolListWidget from mamba.level import Level, Tileset, TILE_MAP, THING_MAP from mamba.data import check_level_exists, list_levels, list_tilesets from mamba.constants import (SCREEN, EDIT_SCREEN, NAME, ESCAPE_KEYS, RESERVED_NAMES) MAX_TOOLS = 6 class EditorHabitat(Habitat): def __init__(self, level_name): super(EditorHabitat, self).__init__(EDIT_SCREEN) self.level = Level(level_name) self.edit_widget = EditLevelWidget(self.level) self.container.add(self.edit_widget) self.container.add_callback(KEYDOWN, self.keydown_event) self.mode = 'Tile' def on_enter(self): # We need to juggle the display to the correct size # This is a horrible hack pygame.display.quit() pygame.display.init() pygame.display.set_mode(EDIT_SCREEN, SWSURFACE) pygame.display.set_caption('%s Level editor' % NAME) super(EditorHabitat, self).on_enter() self.setup_toolbar() def on_exit(self): # We need to juggle the display to the correct size # This is a horrible hack super(EditorHabitat, self).on_exit() pygame.display.quit() pygame.display.init() pygame.display.set_mode(SCREEN, SWSURFACE) pygame.display.set_caption(NAME) def keydown_event(self, ev, widget): if ev.key in ESCAPE_KEYS: from mamba.habitats.mainmenu import MainMenu NewHabitatEvent.post(MainMenu()) elif ev.key == K_1: # Activate floor button self.floor_button.forced_click() def setup_toolbar(self): """Draw the editor toolbar""" button_height = 5 button_left = 820 button_padding = 2 filename = TextButton( (button_left, button_height), 'File: %s' % self.level.level_name, color='white') filename.add_callback('clicked', self.do_edit, 'Specify filename', self.level.level_name, self.check_file) self.container.add(filename) button_height += filename.rect.height + button_padding levelname = TextButton((button_left, button_height), 'Level: %s' % self.level.name, color='white') levelname.add_callback('clicked', self.do_edit, 'Edit Level Title', self.level.name, self.update_name) self.container.add(levelname) button_height += levelname.rect.height + button_padding tilesetname = TextButton((button_left, button_height), 'Tileset: %s' % self.level.tileset.name, color='white') tilesetname.add_callback('clicked', self.list_tilesets) self.container.add(tilesetname) button_height += tilesetname.surface.get_height() + button_padding # TODO: Add Image widget for the current tool self.current_tool = TextWidget((button_left, button_height), 'Tool: Floor', color='white') self.container.add(self.current_tool) button_height += self.current_tool.surface.get_height() button_height += button_padding self.floor_button = ImageButtonWidget( (button_left, button_height), self.level.tileset.floor, 'Floor', color='white') self.container.add(self.floor_button) self.floor_button.add_callback('clicked', self.change_tool, '.', 'Floor') self.edit_widget.set_tool('.') button_height += (self.floor_button.surface.get_height() + button_padding) if self.mode == 'Tile': tile_map = TILE_MAP change_mode_text = 'Switch to Things' elif self.mode == 'Thing': tile_map = THING_MAP change_mode_text = 'Switch to Tiles' tool_list = [] for tile_char in sorted(tile_map): try: tile = self.level.tileset[tile_char] except pygame.error: # Ignore stuff we can't load for now continue if tile is None: continue if tile.name: text = tile.name else: text = 'Tile' tile_button = ImageButtonWidget((0, 0), tile.image, text, color='white') tile_button.add_callback('clicked', self.change_tool, tile_char, text) tool_list.append(tile_button) self.tool_widget = ToolListWidget((button_left, button_height), tool_list, MAX_TOOLS, start_key=K_2) self.container.add(self.tool_widget) button_height += self.tool_widget.rect.height + 2 mode_button = TextButton((button_left, button_height), change_mode_text) mode_button.add_callback('clicked', self.change_toolbar) self.container.add(mode_button) button_height += mode_button.surface.get_height() + button_padding button_height += 2 new = TextButton((button_left, button_height), "New") new.add_callback('clicked', self.new) self.container.add(new) load = TextButton((button_left + 60, button_height), "Load") load.add_callback('clicked', self.load) self.container.add(load) save = TextButton((button_left + 120, button_height), "Save") save.add_callback('clicked', self.save) self.container.add(save) def change_tool(self, ev, widget, new_tool, text): self.edit_widget.set_tool(new_tool) self.current_tool.text = 'Tool: %s' % text self.current_tool.prepare() def save(self, ev, widget): if self.level.level_name in RESERVED_NAMES: print "Can't save over reserved name" return if not self.level: print "Need a level name" return self.level.save_level() def new(self, ev, widget): self.load_level(ev, widget, 'blank') def load(self, ev, widget): levels = list_levels() load_list = [] for level_name in levels: if level_name in RESERVED_NAMES: continue load_button = TextButton((0, 0), level_name) load_button.add_callback('clicked', self.load_level, level_name) load_list.append(load_button) load_dialog = ListBox((200, 200), 'Select Level', load_list) self.container.add(load_dialog) load_dialog.grab_focus() def load_level(self, ev, widget, level_name): self.container.remove(self.edit_widget) self.level = Level(level_name) if level_name in RESERVED_NAMES: self.level.level_name = '' # Special case for new level self.edit_widget = EditLevelWidget(self.level) self.container.add(self.edit_widget) self.clear_toolbar() self.setup_toolbar() def change_toolbar(self, ev, widget): if self.mode == 'Tile': self.mode = 'Thing' elif self.mode == 'Thing': self.mode = 'Tile' self.clear_toolbar() self.setup_toolbar() def clear_toolbar(self): """Remove every non-edit widget from the container""" for widget in self.container.children[:]: if widget is not self.edit_widget: self.container.remove(widget) def do_edit(self, ev, widget, message, init_value, callback): editbox = EntryBox((200, 200), message, init_value, callback) self.container.add(editbox) editbox.grab_focus() def update_name(self, new_name): self.level.name = new_name self.clear_toolbar() self.setup_toolbar() return True def list_tilesets(self, ev, widget): tilesets = list_tilesets() load_list = [] for name in tilesets: if name == 'common': continue load_button = TextButton((0, 0), name) load_button.add_callback('clicked', self.change_tileset, name) load_list.append(load_button) load_dialog = ListBox((200, 200), 'Select Level', load_list) self.container.add(load_dialog) load_dialog.grab_focus() def change_tileset(self, ev, widget, new_name): self.level.tileset = Tileset(new_name) self.level.update_tiles_ascii() self.level.restart() self.clear_toolbar() self.setup_toolbar() return True def check_file(self, new_name): messagebox = None if new_name == self.level.level_name: return True # No-op change if not new_name: messagebox = MessageBox((300, 300), 'Please enter a name') if check_level_exists(new_name): messagebox = MessageBox((300, 300), 'Name already in use') if messagebox: self.container.add(messagebox) messagebox.grab_focus() return False self.level.level_name = new_name self.clear_toolbar() self.setup_toolbar() return True