comparison tools/area_editor.py @ 275:2abb61878bb1

Add a 'select object' with pop-up for easier editing
author Neil Muller <drnlmuller@gmail.com>
date Thu, 05 Sep 2013 12:04:14 +0200
parents 521f73061872
children 56e42c00da25
comparison
equal deleted inserted replaced
274:988cf7c8b402 275:2abb61878bb1
53 53
54 def __init__(self, name, x=800, y=600): 54 def __init__(self, name, x=800, y=600):
55 super(EditorLevel, self).__init__(name) 55 super(EditorLevel, self).__init__(name)
56 self.x = x 56 self.x = x
57 self.y = y 57 self.y = y
58 # Lookup initiliasition info from the objects
59 self.lookup = {}
58 60
59 def round_point(self, pos): 61 def round_point(self, pos):
60 return (10 * (pos[0] // 10), 10 * (pos[1] // 10)) 62 return (10 * (pos[0] // 10), 10 * (pos[1] // 10))
63
64 def load(self, space):
65 super(EditorLevel, self).load(space)
66 # Needed to fill in the lookup dict
67 self.reset_objs()
61 68
62 def point_to_pymunk(self, pos): 69 def point_to_pymunk(self, pos):
63 # inverse of point_to_pygame 70 # inverse of point_to_pygame
64 # (this is also the same as point_to_pygame, but a additional 71 # (this is also the same as point_to_pygame, but a additional
65 # function for sanity later in pyweek). 72 # function for sanity later in pyweek).
177 # Reset the object state - needed when changing stuff 184 # Reset the object state - needed when changing stuff
178 self.drawables = [] 185 self.drawables = []
179 self.overlay_drawables = [] 186 self.overlay_drawables = []
180 self._glue = np.PuzzleGlue() 187 self._glue = np.PuzzleGlue()
181 for game_object_dict in self._game_objects: 188 for game_object_dict in self._game_objects:
182 self._create_game_object(pymunk.Space(), **game_object_dict) 189 obj = self._create_game_object(pymunk.Space(), **game_object_dict)
190 self.lookup[obj] = game_object_dict
183 for enemy_dict in self._enemies: 191 for enemy_dict in self._enemies:
184 self._create_enemy(pymunk.Space(), **enemy_dict) 192 obj = self._create_enemy(pymunk.Space(), **enemy_dict)
193 self.lookup[obj] = enemy_dict
185 194
186 def get_class(self, classname, mod=None): 195 def get_class(self, classname, mod=None):
187 # Get the class given the classname 196 # Get the class given the classname
188 modules = { 197 modules = {
189 'game_object': ngo, 198 'game_object': ngo,
210 target.append(old) 219 target.append(old)
211 self.reset_objs() 220 self.reset_objs()
212 alert("Failed to update object %s: %s" % (classname, e)) 221 alert("Failed to update object %s: %s" % (classname, e))
213 return False 222 return False
214 223
224 def find_obj_at_pos(self, mouse_pos):
225 pymunk_pos = self.point_to_pymunk(mouse_pos)
226 # Search visible objects
227 for obj in self.drawables:
228 if obj.get_shape().point_query(pymunk_pos):
229 return obj
230 return None
231
215 232
216 class ObjectTable(TableView): 233 class ObjectTable(TableView):
217 234
218 columns = [TableColumn("Object", 690, 'l', '%r')] 235 columns = [TableColumn("Object", 690, 'l', '%r')]
219 236
243 return None 260 return None
244 261
245 262
246 class EditClassDialog(Dialog): 263 class EditClassDialog(Dialog):
247 264
248 def __init__(self, classname, cls, data): 265 def __init__(self, classname, cls, data, delete=False):
249 super(EditClassDialog, self).__init__() 266 super(EditClassDialog, self).__init__()
250 self.classname = classname 267 self.classname = classname
251 self.rect = pygame.rect.Rect(0, 0, 800, 550) 268 self.rect = pygame.rect.Rect(0, 0, 800, 550)
252 title = Label("Editing %s" % classname) 269 title = Label("Editing %s" % classname)
253 title.rect = pygame.rect.Rect(100, 10, 600, 25) 270 title.rect = pygame.rect.Rect(100, 10, 600, 25)
279 hintlabel = Label(hint) 296 hintlabel = Label(hint)
280 hintlabel.rect = pygame.rect.Rect(640, y, 100, 25) 297 hintlabel.rect = pygame.rect.Rect(640, y, 100, 25)
281 self.add(hintlabel) 298 self.add(hintlabel)
282 y += 30 299 y += 30
283 buttons = [] 300 buttons = []
284 for text in ['OK', 'Cancel']: 301 if delete:
302 labels = ['OK', 'Delete', 'Cancel']
303 else:
304 labels = ['OK', 'Cancel']
305 for text in labels:
285 but = Button(text, action=lambda x=text: self.dismiss(x)) 306 but = Button(text, action=lambda x=text: self.dismiss(x))
286 buttons.append(but) 307 buttons.append(but)
287 row = Row(buttons) 308 row = Row(buttons)
288 row.rect = pygame.rect.Rect(250, 500, 700, 50) 309 row.rect = pygame.rect.Rect(250, 500, 700, 50)
289 self.add(row) 310 self.add(row)
320 self.cur_poly = None 341 self.cur_poly = None
321 self._mouse_drag = False 342 self._mouse_drag = False
322 self._draw_objects = False 343 self._draw_objects = False
323 self._draw_enemies = False 344 self._draw_enemies = False
324 self._draw_lines = False 345 self._draw_lines = False
346 self.sel_mode = False
325 self._start_pos = None 347 self._start_pos = None
326 348
327 def _level_coordinates(self, pos): 349 def _level_coordinates(self, pos):
328 # Move positions to level values 350 # Move positions to level values
329 if not pos: 351 if not pos:
430 -self.mouse_pos[1] + old_pos[1]) 452 -self.mouse_pos[1] + old_pos[1])
431 self._move_view(diff) 453 self._move_view(diff)
432 self.invalidate() 454 self.invalidate()
433 455
434 def mouse_down(self, ev): 456 def mouse_down(self, ev):
435 if ev.button == 1: 457 if self.sel_mode and ev.button == 1:
458 corrected_pos = ev.pos[0] + self.pos[0], ev.pos[1] + self.pos[1]
459 obj = self.level.find_obj_at_pos(corrected_pos)
460 if obj is not None:
461 self._edit_selected(obj)
462 elif ev.button == 1:
436 if self._draw_lines: 463 if self._draw_lines:
437 if self._start_pos is None: 464 if self._start_pos is None:
438 self._start_pos = ev.pos 465 self._start_pos = ev.pos
439 else: 466 else:
440 self.level.add_line(self._start_pos, ev.pos) 467 self.level.add_line(self._start_pos, ev.pos)
476 dialog = EditClassDialog(classname, cls, data) 503 dialog = EditClassDialog(classname, cls, data)
477 if dialog.present() == 'OK': 504 if dialog.present() == 'OK':
478 return dialog.get_data() 505 return dialog.get_data()
479 return None 506 return None
480 507
508 def _edit_selected(self, obj):
509 data = self.level.lookup[obj]
510 cls = obj.__class__
511 classname = obj.__class__.__name__
512 dialog = EditClassDialog(classname, cls, data, True)
513 res = dialog.present()
514 if res == 'OK':
515 edited = dialog.get_data()
516 if edited is not None:
517 for target in [self.level._game_objects, self.level._enemies]:
518 if data in target:
519 self.level.try_new_object(classname, target,
520 edited, data)
521 break
522 elif res == 'Delete':
523 for target in [self.level._game_objects, self.level._enemies]:
524 if data in target:
525 target.remove(data)
526 self.level.reset_objs()
527 break
528
481 def _make_edit_dialog(self, entries): 529 def _make_edit_dialog(self, entries):
482 # Dialog to hold the editor 530 # Dialog to hold the editor
483 edit_box = Dialog() 531 edit_box = Dialog()
484 edit_box.rect = pygame.rect.Rect(0, 0, 700, 500) 532 edit_box.rect = pygame.rect.Rect(0, 0, 700, 500)
485 table = ObjectTable(entries) 533 table = ObjectTable(entries)
740 add_enemy_but.rect.move_ip(MENU_LEFT, y) 788 add_enemy_but.rect.move_ip(MENU_LEFT, y)
741 widgets.append(add_enemy_but) 789 widgets.append(add_enemy_but)
742 y += MENU_BUTTON_HEIGHT + MENU_PAD 790 y += MENU_BUTTON_HEIGHT + MENU_PAD
743 791
744 y += MENU_PAD 792 y += MENU_PAD
793 sel_mode_but = Button('Select Object',
794 action=self.sel_mode)
795 sel_mode_but.rect = BUTTON_RECT.copy()
796 sel_mode_but.rect.move_ip(MENU_LEFT, y)
797 widgets.append(sel_mode_but)
798 y += MENU_BUTTON_HEIGHT + MENU_PAD
799
800 y += MENU_PAD
745 switch_but = Button('Switch to Drawing', action=self.switch_to_draw) 801 switch_but = Button('Switch to Drawing', action=self.switch_to_draw)
746 switch_but.rect = BUTTON_RECT.copy() 802 switch_but.rect = BUTTON_RECT.copy()
747 switch_but.rect.move_ip(MENU_LEFT, y) 803 switch_but.rect.move_ip(MENU_LEFT, y)
748 widgets.append(switch_but) 804 widgets.append(switch_but)
749 y += switch_but.rect.height + MENU_PAD 805 y += switch_but.rect.height + MENU_PAD
796 for widget in self._dMenus[self._menu_mode]: 852 for widget in self._dMenus[self._menu_mode]:
797 self.remove(widget) 853 self.remove(widget)
798 854
799 def _populate_menu(self): 855 def _populate_menu(self):
800 self.level_widget.change_poly(None) 856 self.level_widget.change_poly(None)
857 self.level_widget.sel_mode = False
801 for widget in self._dMenus[self._menu_mode]: 858 for widget in self._dMenus[self._menu_mode]:
802 self.add(widget) 859 self.add(widget)
803 self.invalidate() 860 self.invalidate()
861
862 def sel_mode(self):
863 self.level_widget.sel_mode = not self.level_widget.sel_mode
804 864
805 def mouse_move(self, ev): 865 def mouse_move(self, ev):
806 self.level_widget.mouse_move(ev) 866 self.level_widget.mouse_move(ev)
807 867
808 def draw(self, surface): 868 def draw(self, surface):