Changeset 251:611370331bd1


Ignore:
Timestamp:
Sep 4, 2013, 9:46:06 PM (7 years ago)
Author:
Neil Muller <drnlmuller@…>
Branch:
default
rebase_source:
1ed529f294e4d43e44af9f9093be9778503230d7
Message:

Add framework of edit object dialog

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/area_editor.py

    r239 r251  
    2727from albow.dialogs import alert, Dialog
    2828from albow.layout import Row
     29from albow.fields import TextField
    2930from albow.table_view import TableView, TableColumn
    3031
     
    3233from nagslang.constants import SCREEN
    3334from nagslang.level import Level, POLY_COLORS, LINE_COLOR
    34 from nagslang.enemies import Enemy, get_editable_enemies
    35 from nagslang.game_object import get_editable_game_objects
    36 from nagslang.puzzle import get_editable_puzzlers, PuzzleGlue
     35import nagslang.enemies as ne
     36import nagslang.game_object as ngo
     37import nagslang.puzzle as np
    3738
    3839# layout constants
     
    176177        self.drawables = []
    177178        self.overlay_drawables = []
    178         self._glue = PuzzleGlue()
     179        self._glue = np.PuzzleGlue()
    179180        for game_object_dict in self._game_objects:
    180181            self._create_game_object(pymunk.Space(), **game_object_dict)
    181182        for enemy_dict in self._enemies:
    182183            self._create_enemy(pymunk.Space(), **enemy_dict)
     184
     185    def get_class(self, classname, mod=None):
     186        # Get the class given the classname
     187        modules = {
     188            'game_object': ngo,
     189            'enemies': ne,
     190            'puzzle': np,
     191            }
     192        if '.' in classname:
     193            modname, classname = classname.split('.')
     194            mod = modules[modname]
     195        if mod is None:
     196            mod = ngo
     197        return getattr(mod, classname)
     198
     199    def try_new_object(self, target, new, old=None):
     200        if old in target:
     201            target.remove(old)
     202        try:
     203            target.append(new)
     204            self.reset_objs()
     205            return True
     206        except Exception:
     207            target.remove(new)
     208            if old is not None:
     209                target.append(old)
     210            self.reset_objs()
     211        return False
    183212
    184213
     
    211240            return self.data[self.selected_row]
    212241        return None
     242
     243
     244class EditClassDialog(Dialog):
     245
     246    def __init__(self, classname, cls, data):
     247        super(EditClassDialog, self).__init__()
     248        self.rect = pygame.rect.Rect(0, 0, 800, 550)
     249        title = Label("Editing %s" % classname)
     250        title.rect = pygame.rect.Rect(100, 10, 600, 25)
     251        self.add(title)
     252        requires = cls.requires()
     253        y = 40
     254        self.fields = {}
     255        index = 0
     256        for requirement, hint in requires:
     257            label = Label(requirement)
     258            label.rect = pygame.rect.Rect(40, y, 200, 25)
     259            self.add(label)
     260            field = TextField()
     261            field.rect = pygame.rect.Rect(220, y, 400, 25)
     262            self.add(field)
     263            if data is not None:
     264                if requirement in data:
     265                    field.set_text('%s' % data[requirement])
     266                elif 'args' in data:
     267                    # NB: The ordering assumptions in requires should make
     268                    # this safe, but it's really, really, really fragile
     269                    field.set_text('%s' % data['args'][index])
     270                    index += 1
     271            self.fields[requirement] = field
     272            hintlabel = Label(hint)
     273            hintlabel.rect = pygame.rect.Rect(640, y, 100, 25)
     274            self.add(hintlabel)
     275            y += 30
     276        buttons = []
     277        for text in ['OK', 'Cancel']:
     278            but = Button(text, action=lambda x=text: self.dismiss(x))
     279            buttons.append(but)
     280        row = Row(buttons)
     281        row.rect = pygame.rect.Rect(250, 500, 700, 50)
     282        self.add(row)
     283
     284    def get_data(self):
     285        return ''
    213286
    214287
     
    271344        if self._draw_objects:
    272345            for thing in self.level.drawables:
    273                 if not isinstance(thing, Enemy):
     346                if not isinstance(thing, ne.Enemy):
    274347                    thing.render(level_surface)
    275348        if self._draw_enemies:
    276349            for thing in self.level.drawables:
    277                 if isinstance(thing, Enemy):
     350                if isinstance(thing, ne.Enemy):
    278351                    thing.render(level_surface)
    279352        surface_area = pygame.rect.Rect(self.pos, SCREEN)
     
    376449            alert("Failed to close the polygon")
    377450
     451    def _edit_class(self, classname, cls, data):
     452        # Dialog for class properties
     453        dialog = EditClassDialog(classname, cls, data)
     454        if dialog.present() == 'OK':
     455            return dialog.get_data()
     456        return None
     457
    378458    def _make_edit_dialog(self, entries):
    379459        # Dialog to hold the editor
     
    387467            buttons.append(but)
    388468        row = Row(buttons)
    389         row.rect = pygame.rect.Rect(0, 450, 700, 50)
     469        row.rect = pygame.rect.Rect(250, 450, 700, 50)
    390470        edit_box.add(row)
    391471        edit_box.get_selection = lambda: table.get_selection()
     
    399479            return
    400480        if res == 'OK':
    401             # Edit object stuff goes here
    402             pass
     481            cls = self.level.get_class(choice['classname'])
     482            edited = self._edit_class(choice['classname'], cls, choice)
     483            if edited is not None:
     484                if not self.level.try_new_object(self.level._game_objects,
     485                                                 edited, choice):
     486                    alert('Failed to update GameObject %s'
     487                          % choice['classname'])
    403488        elif res == 'Delete':
    404489            self.level._game_objects.remove(choice)
     
    412497            return
    413498        if res == 'OK':
    414             # Edit object stuff goes here
    415             pass
     499            cls = self.level.get_class(choice['classname'], ne)
     500            edited = self._edit_class(choice['classname'], cls, choice)
     501            if edited is not None:
     502                if not self.level.try_new_object(self.level._enemies,
     503                                                 edited, choice):
     504                    alert('Failed to update Enemy %s'
     505                          % choice['classname'])
    416506        elif res == 'Delete':
    417507            self.level._enemies.remove(choice)
     
    432522            buttons.append(but)
    433523        row = Row(buttons)
    434         row.rect = pygame.rect.Rect(0, 450, 700, 50)
     524        row.rect = pygame.rect.Rect(250, 450, 700, 50)
    435525        choice_box.add(row)
    436526        choice_box.get_selection = lambda: table.get_selection()
     
    438528
    439529    def add_game_object(self):
    440         classes = get_editable_game_objects()
     530        classes = ngo.get_editable_game_objects()
    441531        choose = self._make_choice_dialog(classes)
    442532        res = choose.present()
    443533        choice = choose.get_selection()
    444534        if res == 'OK' and choice is not None:
    445             pass
     535            classname = choice['classname']
     536            cls = choice['class']
     537            new_cls = self._edit_class(classname, cls, None)
     538            if new_cls is not None:
     539                if not self.level.try_new_object(self.level._game_objects,
     540                                                 new_cls, None):
     541                    alert('Failed to add GameObject %s' % classname)
    446542
    447543    def add_enemy(self):
    448         classes = get_editable_enemies()
     544        classes = ne.get_editable_enemies()
    449545        choose = self._make_choice_dialog(classes)
    450546        res = choose.present()
    451547        choice = choose.get_selection()
    452548        if res == 'OK' and choice is not None:
    453             pass
     549            classname = choice['classname']
     550            cls = choice['class']
     551            new_cls = self._edit_class(classname, cls, None)
     552            if new_cls is not None:
     553                if not self.level.try_new_object(self.level._enemies,
     554                                                 new_cls, None):
     555                    alert('Failed to add Enemy %s' % classname)
    454556
    455557    def add_puzzler(self):
    456         classes = get_editable_puzzlers()
     558        classes = np.get_editable_puzzlers()
    457559        choose = self._make_choice_dialog(classes)
    458560        res = choose.present()
    459561        choice = choose.get_selection()
    460562        if res == 'OK' and choice is not None:
    461             pass
     563            classname = choice['classname']
     564            cls = choice['class']
     565            new_cls = self._edit_class(classname, cls, None)
     566            if new_cls is not None:
     567                if not self.level.try_new_object(self.level._game_objects,
     568                                                 new_cls, None):
     569                    alert('Failed to add Puzzler %s' % classname)
    462570
    463571
Note: See TracChangeset for help on using the changeset viewer.