changeset 454:8cfa757dd7d3

Epic level editor reworking.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 17 Sep 2011 20:37:05 +0200
parents 4f3c55b09fda
children 9d6e5d76a336
files mamba/habitats/editor.py mamba/widgets/base.py mamba/widgets/editlevel.py mamba/widgets/messagebox.py
diffstat 4 files changed, 180 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/mamba/habitats/editor.py	Sat Sep 17 20:30:40 2011 +0200
+++ b/mamba/habitats/editor.py	Sat Sep 17 20:37:05 2011 +0200
@@ -14,9 +14,9 @@
 from mamba.widgets.listbox import ListBox
 from mamba.widgets.toollist import ToolListWidget
 from mamba.widgets.editsprite import EditSpriteBox
+from mamba.widgets.editlevel import EditLevelBox
 from mamba.level import Level, Tileset, TILE_MAP, THING_MAP, InvalidMapError
-from mamba.data import (check_level_exists, get_level_list, get_tileset_list,
-        get_track_list, load_file)
+from mamba.data import check_level_exists, get_level_list, load_file
 from mamba.constants import (SCREEN, EDIT_SCREEN, NAME, ESCAPE_KEYS,
         RESERVED_NAMES)
 
@@ -71,30 +71,42 @@
         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
+        level_name = TextWidget((button_left, button_height),
+                                'Level: %s' % self.level.level_name)
+        self.container.add(level_name)
+        button_height += level_name.rect.height + button_padding
+
+        edit_level = TextButton((button_left, button_height),
+                                'Edit Level Metadata')
+        edit_level.add_callback('clicked', self.edit_level_data)
+        self.container.add(edit_level)
+        button_height += edit_level.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
-        trackname = TextButton((button_left, button_height),
-                'Music: %s' % self.level.background_track, color='white')
-        trackname.add_callback('clicked', self.list_tracks)
-        self.container.add(trackname)
-        button_height += trackname.surface.get_height() + button_padding
+        # 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
+        # trackname = TextButton((button_left, button_height),
+        #         'Music: %s' % self.level.background_track, color='white')
+        # trackname.add_callback('clicked', self.list_tracks)
+        # self.container.add(trackname)
+        # button_height += trackname.surface.get_height() + button_padding
+
         # TODO: Add Image widget for the current tool
         if self.mode != 'Sprites':
             self.current_tool = TextWidget((button_left, button_height),
@@ -275,62 +287,19 @@
             EntryBox((200, 200), message, init_value, callback))
         return True
 
-    def update_name(self, new_name):
+    def update_level_data(self, filename, name, tileset, track):
         self.container.paused = False
-        self.level.name = new_name
+
+        self.level.name = name
+        self.level.background_track = track
+        # err_ts = self.change_tileset(tileset)
+        err_fn = self.check_file(filename)
+
         self.clear_toolbar()
         self.setup_toolbar()
-        return True
 
-    def list_tilesets(self, ev, widget):
-        self.container.paused = True
-        tilesets = get_tileset_list()
-        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)
-        self.display_dialog(ListBox((200, 200), 'Select Level', load_list))
-        return True
-
-    def list_tracks(self, ev, widget):
-        self.container.paused = True
-        tracks = get_track_list()
-        load_list = []
-        for name in tracks:
-            load_button = TextButton((0, 0), name)
-            load_button.add_callback('clicked', self.change_track, name)
-            load_list.append(load_button)
-        self.display_dialog(ListBox((200, 200), 'Select Level', load_list, 6))
-        return True
-
-    def change_tileset(self, ev, widget, new_name):
-        self.level.update_tiles_ascii()
-        old_tileset = self.level.tileset
-        try:
-            self.level.tileset = Tileset(new_name)
-            self.level.restart()
-        except pygame.error, error:
-            self.level.tileset = old_tileset
-            message = MessageBox((300, 300),
-                    'Unable to change tileset:: %s' % error,
-                    self.refresh_display, color='red')
-            widget.parent.add(message)
-            message.grab_focus()
-            return True
-        self.container.paused = False
-        self.clear_toolbar()
-        self.setup_toolbar()
-        return True
-
-    def change_track(self, ev, widget, new_name):
-        self.container.paused = False
-        self.level.background_track = new_name
-        self.clear_toolbar()
-        self.setup_toolbar()
-        return True
+        if err_fn:
+            self.display_dialog(err_fn)
 
     def refresh_display(self):
         self.level.restart()
@@ -338,10 +307,24 @@
         self.setup_toolbar()
         return True
 
+    def change_tileset(self, new_tileset):
+        print "changing tileset"
+        self.level.update_tiles_ascii()
+        old_tileset = self.level.tileset
+        try:
+            self.level.tileset = Tileset(new_tileset)
+            self.level.restart()
+            return None
+        except pygame.error, error:
+            self.level.tileset = old_tileset
+            return MessageBox(
+                (300, 300), 'Unable to change tileset:: %s' % error,
+                color='red')
+
     def check_file(self, new_name):
         message = None
         if new_name == self.level.level_name:
-            return True  # No-op change
+            return None  # No-op change
         if not new_name:
             message = MessageBox((300, 300), 'Please enter a name')
         if new_name in RESERVED_NAMES:
@@ -352,13 +335,9 @@
         elif check_level_exists(new_name, 'user_levels', is_user_dir=True):
             message = MessageBox((300, 300), 'Name already in use')
         if message:
-            self.display_dialog(message)
-            return False
-        self.container.paused = False
+            return message
         self.level.level_name = new_name
-        self.clear_toolbar()
-        self.setup_toolbar()
-        return True
+        return None
 
     def sprite_tool(self, ev, widget, sprite_mode):
         """Handle sprite stuff"""
@@ -390,6 +369,10 @@
                 post_callback=self.commit_line)
         self.display_dialog(sprite_editor)
 
+    def edit_level_data(self, ev, widget):
+        elb = EditLevelBox((200, 100), self.level, self.update_level_data)
+        self.display_dialog(elb)
+
     def commit_line(self, sprite):
         try:
             self.level.validate_sprite(sprite)
--- a/mamba/widgets/base.py	Sat Sep 17 20:30:40 2011 +0200
+++ b/mamba/widgets/base.py	Sat Sep 17 20:37:05 2011 +0200
@@ -163,6 +163,12 @@
         self.children.append(widget)
         self.rect = self.rect.union(widget.rect)
 
+    def add_modal(self, widget):
+        widget.parent = self
+        widget.parent_modal = self.modal
+        self.modal = False
+        self.children.append(widget)
+
     def remove(self, widget):
         widget.parent = None
         if self.focussed_child is not None:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mamba/widgets/editlevel.py	Sat Sep 17 20:37:05 2011 +0200
@@ -0,0 +1,104 @@
+from mamba.data import get_tileset_list, get_track_list
+from mamba.widgets.base import Box
+from mamba.widgets.text import TextWidget, TextButton, EntryTextWidget
+from mamba.widgets.listbox import ListBox
+
+
+class EditLevelBox(Box):
+    """Edit details for a level map"""
+
+    button_padding = 2
+
+    def __init__(self, rect, level, post_callback=None):
+        super(EditLevelBox, self).__init__(rect)
+        self.level = level
+        self.level_filename = self.level.level_name
+        self.level_name = self.level.name
+        self.level_tileset = self.level.tileset.name
+        self.level_track = self.level.background_track
+        self.post_callback = post_callback
+        self.prepare()
+        self.modal = True
+
+    def add_widget(self, cls, *args, **kw):
+        clicked = kw.pop('clicked', None)
+        offset = kw.pop('offset', (0, 0))
+        pos = (self.widget_left + offset[0],
+               self.widget_top + offset[1])
+        widget = cls(pos, *args, **kw)
+        if clicked:
+            widget.add_callback('clicked', *clicked)
+        self.add(widget)
+        self.widget_top += widget.rect.height + self.button_padding
+        return widget
+
+    def prepare(self):
+        self.widget_left = self.rect.left
+        self.widget_top = self.rect.top
+
+        self.add_widget(TextWidget, "Specify Level Details")
+
+        self.filename = self.add_widget(
+            EntryTextWidget, self.level_filename, prompt="File:")
+
+        self.levelname = self.add_widget(
+            EntryTextWidget, self.level_name, prompt='Level Title:')
+
+        # self.tileset = self.add_widget(
+        #     TextButton, 'Tileset: %s' % self.level_tileset,
+        #     color='white', clicked=(self.list_tilesets,))
+
+        self.trackname = self.add_widget(
+            TextButton, 'Music: %s' % self.level_track,
+            color='white', clicked=(self.list_tracks,))
+
+        self.ok_button = self.add_widget(
+            TextButton, 'OK', offset=(10, 0), clicked=(self.close, True))
+
+        self.cancel_button = self.add_widget(
+            TextButton, 'Cancel', offset=(10, 0), clicked=(self.close, False))
+
+        self.rect.width = max(self.rect.width, 400)
+        self.rect.height += 5
+
+    def change_tileset(self, ev, widget, name):
+        self.level_tileset = name
+        self.tileset.text = 'Tileset: %s' % name
+        self.tileset.prepare()
+
+    def change_track(self, ev, widget, name):
+        self.level_track = name
+        self.trackname.text = 'Music: %s' % name
+        self.trackname.prepare()
+
+    def mk_loadlist(self, title, items, callback):
+        load_list = []
+        for name in items:
+            load_button = TextButton((0, 0), name)
+            load_button.add_callback('clicked', callback, name)
+            load_list.append(load_button)
+        lb = ListBox((200, 200), title, load_list, 6)
+        self.add_modal(lb)
+        lb.grab_focus()
+
+    def list_tilesets(self, ev, widget):
+        tilesets = [i for i in get_tileset_list() if i != 'common']
+        self.mk_loadlist('Select Tileset', tilesets, self.change_tileset)
+
+    def list_tracks(self, ev, widget):
+        tracks = get_track_list()
+        self.mk_loadlist('Select Music', tracks, self.change_track)
+
+    def close(self, ev, widget, do_update):
+        self.modal = False
+        self.parent.remove(self)
+        if do_update:
+            self.post_callback(
+                self.filename.value,
+                self.levelname.value,
+                self.level_tileset,
+                self.level_track)
+        return True
+
+    def grab_focus(self):
+        return self.ok_button.grab_focus()
--- a/mamba/widgets/messagebox.py	Sat Sep 17 20:30:40 2011 +0200
+++ b/mamba/widgets/messagebox.py	Sat Sep 17 20:37:05 2011 +0200
@@ -42,6 +42,9 @@
         self.parent.remove(self)
         if self.post_callback:
             self.post_callback()
+        if getattr(self, 'parent_modal', False):
+            self.parent.modal = True
 
     def grab_focus(self):
+        print "mbf", self.text
         return self.ok_button.grab_focus()