# HG changeset patch # User Neil Muller # Date 1378375454 -7200 # Node ID 2abb61878bb1b24dc11e6c66d622208c720c7ede # Parent 988cf7c8b402a9120f0272f063d5ccdfffa09957 Add a 'select object' with pop-up for easier editing diff -r 988cf7c8b402 -r 2abb61878bb1 tools/area_editor.py --- a/tools/area_editor.py Thu Sep 05 12:03:34 2013 +0200 +++ b/tools/area_editor.py Thu Sep 05 12:04:14 2013 +0200 @@ -55,10 +55,17 @@ super(EditorLevel, self).__init__(name) self.x = x self.y = y + # Lookup initiliasition info from the objects + self.lookup = {} def round_point(self, pos): return (10 * (pos[0] // 10), 10 * (pos[1] // 10)) + def load(self, space): + super(EditorLevel, self).load(space) + # Needed to fill in the lookup dict + self.reset_objs() + def point_to_pymunk(self, pos): # inverse of point_to_pygame # (this is also the same as point_to_pygame, but a additional @@ -179,9 +186,11 @@ self.overlay_drawables = [] self._glue = np.PuzzleGlue() for game_object_dict in self._game_objects: - self._create_game_object(pymunk.Space(), **game_object_dict) + obj = self._create_game_object(pymunk.Space(), **game_object_dict) + self.lookup[obj] = game_object_dict for enemy_dict in self._enemies: - self._create_enemy(pymunk.Space(), **enemy_dict) + obj = self._create_enemy(pymunk.Space(), **enemy_dict) + self.lookup[obj] = enemy_dict def get_class(self, classname, mod=None): # Get the class given the classname @@ -212,6 +221,14 @@ alert("Failed to update object %s: %s" % (classname, e)) return False + def find_obj_at_pos(self, mouse_pos): + pymunk_pos = self.point_to_pymunk(mouse_pos) + # Search visible objects + for obj in self.drawables: + if obj.get_shape().point_query(pymunk_pos): + return obj + return None + class ObjectTable(TableView): @@ -245,7 +262,7 @@ class EditClassDialog(Dialog): - def __init__(self, classname, cls, data): + def __init__(self, classname, cls, data, delete=False): super(EditClassDialog, self).__init__() self.classname = classname self.rect = pygame.rect.Rect(0, 0, 800, 550) @@ -281,7 +298,11 @@ self.add(hintlabel) y += 30 buttons = [] - for text in ['OK', 'Cancel']: + if delete: + labels = ['OK', 'Delete', 'Cancel'] + else: + labels = ['OK', 'Cancel'] + for text in labels: but = Button(text, action=lambda x=text: self.dismiss(x)) buttons.append(but) row = Row(buttons) @@ -322,6 +343,7 @@ self._draw_objects = False self._draw_enemies = False self._draw_lines = False + self.sel_mode = False self._start_pos = None def _level_coordinates(self, pos): @@ -432,7 +454,12 @@ self.invalidate() def mouse_down(self, ev): - if ev.button == 1: + if self.sel_mode and ev.button == 1: + corrected_pos = ev.pos[0] + self.pos[0], ev.pos[1] + self.pos[1] + obj = self.level.find_obj_at_pos(corrected_pos) + if obj is not None: + self._edit_selected(obj) + elif ev.button == 1: if self._draw_lines: if self._start_pos is None: self._start_pos = ev.pos @@ -478,6 +505,27 @@ return dialog.get_data() return None + def _edit_selected(self, obj): + data = self.level.lookup[obj] + cls = obj.__class__ + classname = obj.__class__.__name__ + dialog = EditClassDialog(classname, cls, data, True) + res = dialog.present() + if res == 'OK': + edited = dialog.get_data() + if edited is not None: + for target in [self.level._game_objects, self.level._enemies]: + if data in target: + self.level.try_new_object(classname, target, + edited, data) + break + elif res == 'Delete': + for target in [self.level._game_objects, self.level._enemies]: + if data in target: + target.remove(data) + self.level.reset_objs() + break + def _make_edit_dialog(self, entries): # Dialog to hold the editor edit_box = Dialog() @@ -742,6 +790,14 @@ y += MENU_BUTTON_HEIGHT + MENU_PAD y += MENU_PAD + sel_mode_but = Button('Select Object', + action=self.sel_mode) + sel_mode_but.rect = BUTTON_RECT.copy() + sel_mode_but.rect.move_ip(MENU_LEFT, y) + widgets.append(sel_mode_but) + y += MENU_BUTTON_HEIGHT + MENU_PAD + + y += MENU_PAD switch_but = Button('Switch to Drawing', action=self.switch_to_draw) switch_but.rect = BUTTON_RECT.copy() switch_but.rect.move_ip(MENU_LEFT, y) @@ -798,10 +854,14 @@ def _populate_menu(self): self.level_widget.change_poly(None) + self.level_widget.sel_mode = False for widget in self._dMenus[self._menu_mode]: self.add(widget) self.invalidate() + def sel_mode(self): + self.level_widget.sel_mode = not self.level_widget.sel_mode + def mouse_move(self, ev): self.level_widget.mouse_move(ev)