comparison tools/rect_drawer.py @ 506:d54667b2c44d

Partial zoom support
author Neil Muller <neil@dip.sun.ac.za>
date Fri, 03 Sep 2010 11:24:12 +0200
parents 4c8aa01b606c
children caec319a4ae3
comparison
equal deleted inserted replaced
505:4c8aa01b606c 506:d54667b2c44d
13 from albow.controls import Button, Image 13 from albow.controls import Button, Image
14 from albow.palette_view import PaletteView 14 from albow.palette_view import PaletteView
15 from albow.file_dialogs import request_old_filename 15 from albow.file_dialogs import request_old_filename
16 from albow.resource import get_font 16 from albow.resource import get_font
17 from pygame.locals import SWSURFACE, K_LEFT, K_RIGHT, K_UP, K_DOWN, \ 17 from pygame.locals import SWSURFACE, K_LEFT, K_RIGHT, K_UP, K_DOWN, \
18 K_t, K_d, K_i, K_r, K_o, K_b, \ 18 K_t, K_d, K_i, K_r, K_o, K_b, K_z, \
19 BLEND_RGBA_MIN, SRCALPHA 19 BLEND_RGBA_MIN, SRCALPHA
20 import pygame 20 import pygame
21 from pygame.colordict import THECOLORS 21 from pygame.colordict import THECOLORS
22 22
23 from gamelib import constants 23 from gamelib import constants
24 constants.DEBUG = True 24 constants.DEBUG = True
25 MENU_WIDTH = 200
26 MENU_BUTTON_HEIGHT = 30
27 ZOOM = 4
25 28
26 from gamelib import state 29 from gamelib import state
27 state.DEBUG_RECTS = True 30 state.DEBUG_RECTS = True
28 from gamelib.widgets import BoomLabel 31 from gamelib.widgets import BoomLabel
29 32
66 rect_thick = 3 69 rect_thick = 3
67 draw_thick = 1 70 draw_thick = 1
68 71
69 def __init__(self, state): 72 def __init__(self, state):
70 self.state = state 73 self.state = state
71 super(AppImage, self).__init__(pygame.rect.Rect(0, 0, 800, 600)) 74 super(AppImage, self).__init__(pygame.rect.Rect(0, 0, constants.SCREEN[0], constants.SCREEN[1]))
72 self.mode = 'draw' 75 self.mode = 'draw'
73 self.rects = [] 76 self.rects = []
74 self.images = [] 77 self.images = []
75 self.start_pos = None 78 self.start_pos = None
76 self.end_pos = None 79 self.end_pos = None
93 self.draw_thing_rects = True 96 self.draw_thing_rects = True
94 self.draw_images = True 97 self.draw_images = True
95 self.trans_images = False 98 self.trans_images = False
96 self.draw_toolbar = True 99 self.draw_toolbar = True
97 self.old_mouse_pos = None 100 self.old_mouse_pos = None
101 self.zoom_display = False
98 self.find_existing_intersects() 102 self.find_existing_intersects()
99 103
100 def find_existing_intersects(self): 104 def find_existing_intersects(self):
101 """Parse the things in the scene for overlaps""" 105 """Parse the things in the scene for overlaps"""
102 if self.state.current_detail: 106 if self.state.current_detail:
196 self.draw_rects = not self.draw_rects 200 self.draw_rects = not self.draw_rects
197 201
198 def toggle_toolbar(self): 202 def toggle_toolbar(self):
199 self.draw_toolbar = not self.draw_toolbar 203 self.draw_toolbar = not self.draw_toolbar
200 204
205 def toggle_zoom(self):
206 self.zoom_display = not self.zoom_display
207
201 def draw_mode(self): 208 def draw_mode(self):
202 self.mode = 'draw' 209 self.mode = 'draw'
203 210
204 def del_mode(self): 211 def del_mode(self):
205 self.mode = 'del' 212 self.mode = 'del'
220 else: 227 else:
221 surf.blit(imsurf, r, None) 228 surf.blit(imsurf, r, None)
222 surface.blit(surf, cropped_rect) 229 surface.blit(surf, cropped_rect)
223 230
224 def draw(self, surface): 231 def draw(self, surface):
232 if self.zoom_display:
233 base_surface = surface.copy()
234 self.do_unzoomed_draw(base_surface)
235 zoomed = pygame.transform.scale(base_surface, (ZOOM * constants.SCREEN[0], ZOOM * constants.SCREEN[1]))
236 surface.blit(zoomed, (0, 0))
237 else:
238 self.do_unzoomed_draw(surface)
239
240 def do_unzoomed_draw(self, surface):
225 if self.state.current_detail: 241 if self.state.current_detail:
226 if self.draw_things: 242 if self.draw_things:
227 self.state.draw_detail(surface, None) 243 self.state.draw_detail(surface, None)
228 else: 244 else:
229 self.state.current_detail.draw_background(surface) 245 self.state.current_detail.draw_background(surface)
251 if self.current_image and self.mode == 'image': 267 if self.current_image and self.mode == 'image':
252 if self.current_image.rect.colliderect(surface.get_rect()): 268 if self.current_image.rect.colliderect(surface.get_rect()):
253 cropped_rect = self.current_image.rect.clip(surface.get_rect()) 269 cropped_rect = self.current_image.rect.clip(surface.get_rect())
254 self.draw_sub_image(self.current_image, surface, cropped_rect) 270 self.draw_sub_image(self.current_image, surface, cropped_rect)
255 if self.draw_toolbar: 271 if self.draw_toolbar:
256 toolbar_rect = pygame.rect.Rect(0, 550, 800, 50) 272 toolbar_rect = pygame.rect.Rect(0, constants.SCREEN[1] - constants.BUTTON_SIZE, constants.SCREEN[0], constants.BUTTON_SIZE)
257 tb_surf = surface.subsurface(0, 550, 800, 50).convert_alpha() 273 tb_surf = surface.subsurface(0, constants.SCREEN[1] - constants.BUTTON_SIZE, constants.SCREEN[0], constants.BUTTON_SIZE).convert_alpha()
258 tb_surf.fill(pygame.color.Color(127, 0, 0, 191)) 274 tb_surf.fill(pygame.color.Color(127, 0, 0, 191))
259 surface.blit(tb_surf, (0, 550)) 275 surface.blit(tb_surf, (0, constants.SCREEN[1] - constants.BUTTON_SIZE))
260 # frame_rect(surface, (127, 0, 0), toolbar_rect, 2) 276 # frame_rect(surface, (127, 0, 0), toolbar_rect, 2)
261 277
262 def _make_dict(self): 278 def _make_dict(self):
263 d = {} 279 d = {}
264 for col, rect in self.rects: 280 for col, rect in self.rects:
290 try: 306 try:
291 image_data = pygame.image.load(imagename) 307 image_data = pygame.image.load(imagename)
292 self.current_image = Image(image_data) 308 self.current_image = Image(image_data)
293 self.place_image_menu.enabled = True 309 self.place_image_menu.enabled = True
294 # ensure we're off screen to start 310 # ensure we're off screen to start
295 self.current_image.rect = image_data.get_rect().move(1000, 600) 311 self.current_image.rect = image_data.get_rect().move(constants.SCREEN[0] + MENU_WIDTH, constants.SCREEN[1])
296 except pygame.error, e: 312 except pygame.error, e:
297 print 'Unable to load image %s' % e 313 print 'Unable to load image %s' % e
298 314
299 def image_mode(self): 315 def image_mode(self):
300 self.mode = 'image' 316 self.mode = 'image'
301 self.start_pos = None 317 self.start_pos = None
302 self.end_pos = None 318 self.end_pos = None
303 # So we do the right thing for off screen images 319 # So we do the right thing for off screen images
304 self.old_mouse_pos = None 320 self.old_mouse_pos = None
305 321
322 def _conv_pos(self, mouse_pos):
323 if self.zoom_display:
324 pos = (mouse_pos[0] / ZOOM, mouse_pos[1] / ZOOM)
325 else:
326 pos = mouse_pos
327 return pos
328
306 def do_mouse_move(self, e): 329 def do_mouse_move(self, e):
330 pos = self._conv_pos(e.pos)
307 if self.mode == 'image' and self.current_image: 331 if self.mode == 'image' and self.current_image:
308 if self.old_mouse_pos: 332 if self.old_mouse_pos:
309 delta = (e.pos[0] - self.old_mouse_pos[0], e.pos[1] - self.old_mouse_pos[1]) 333 delta = (pos[0] - self.old_mouse_pos[0], pos[1] - self.old_mouse_pos[1])
310 self.current_image.rect.center = (self.current_image.rect.center[0] + delta[0], self.current_image.rect.center[1] + delta[1]) 334 self.current_image.rect.center = (self.current_image.rect.center[0] + delta[0], self.current_image.rect.center[1] + delta[1])
311 else: 335 else:
312 self.current_image.rect.center = e.pos 336 self.current_image.rect.center = pos
313 self.invalidate() 337 self.invalidate()
314 self.old_mouse_pos = e.pos 338 self.old_mouse_pos = pos
315 339
316 def key_down(self, e): 340 def key_down(self, e):
317 if self.mode == 'image' and self.current_image: 341 if self.mode == 'image' and self.current_image:
318 # Move the image by 1 pixel 342 # Move the image by 1 pixel
319 cur_pos = self.current_image.rect.center 343 cur_pos = self.current_image.rect.center
335 self.toggle_images() 359 self.toggle_images()
336 elif e.key == K_d: 360 elif e.key == K_d:
337 self.toggle_rects() 361 self.toggle_rects()
338 elif e.key == K_b: 362 elif e.key == K_b:
339 self.toggle_toolbar() 363 self.toggle_toolbar()
364 elif e.key == K_z:
365 self.toggle_zoom()
340 366
341 def mouse_down(self, e): 367 def mouse_down(self, e):
368 pos = self._conv_pos(e.pos)
342 if self.mode == 'del': 369 if self.mode == 'del':
343 pos = e.pos
344 cand = None 370 cand = None
345 # Images are drawn above rectangles, so search those first 371 # Images are drawn above rectangles, so search those first
346 for image in self.images: 372 for image in self.images:
347 if image.rect.collidepoint(pos): 373 if image.rect.collidepoint(pos):
348 cand = image 374 cand = image
357 break 383 break
358 if cand: 384 if cand:
359 self.rects.remove(cand) 385 self.rects.remove(cand)
360 self.invalidate() 386 self.invalidate()
361 elif self.mode == 'draw': 387 elif self.mode == 'draw':
362 self.start_pos = e.pos 388 self.start_pos = pos
363 self.end_pos = e.pos 389 self.end_pos = pos
364 elif self.mode == 'image': 390 elif self.mode == 'image':
365 if self.current_image: 391 if self.current_image:
366 self.images.append(self.current_image) 392 self.images.append(self.current_image)
367 self.current_image = None 393 self.current_image = None
368 self.old_mouse_pos = None 394 self.old_mouse_pos = None
375 break 401 break
376 if cand: 402 if cand:
377 self.images.remove(cand) 403 self.images.remove(cand)
378 self.current_image = cand 404 self.current_image = cand
379 # We want to move relative to the current mouse pos, so 405 # We want to move relative to the current mouse pos, so
380 self.old_mouse_pos = e.pos 406 self.old_mouse_pos = pos
381 self.invalidate() 407 self.invalidate()
382 408
383 def mouse_up(self, e): 409 def mouse_up(self, e):
384 if self.mode == 'draw': 410 if self.mode == 'draw':
385 rect = pygame.rect.Rect(self.start_pos[0], self.start_pos[1], 411 rect = pygame.rect.Rect(self.start_pos[0], self.start_pos[1],
389 self.rects.append((self.rect_color, rect)) 415 self.rects.append((self.rect_color, rect))
390 self.start_pos = self.end_pos = None 416 self.start_pos = self.end_pos = None
391 417
392 def mouse_drag(self, e): 418 def mouse_drag(self, e):
393 if self.mode == 'draw': 419 if self.mode == 'draw':
394 self.end_pos = e.pos 420 self.end_pos = self._conv_pos(e.pos)
395 self.invalidate() 421 self.invalidate()
396 422
397 def make_button(text, action, ypos): 423 def make_button(text, action, ypos):
398 button = Button(text, action=action, font=get_font(15, 'VeraBd.ttf')) 424 button = Button(text, action=action, font=get_font(15, 'VeraBd.ttf'))
399 button.align = 'l' 425 button.align = 'l'
400 button.rect = pygame.rect.Rect(0, 0, 200, 30) 426 button.rect = pygame.rect.Rect(0, 0, MENU_WIDTH, MENU_BUTTON_HEIGHT)
401 button.rect.move_ip(805, ypos) 427 button.rect.move_ip(805, ypos)
402 return button 428 return button
403 429
404 class RectApp(RootWidget): 430 class RectApp(RootWidget):
405 """Handle the app stuff for the rect drawer""" 431 """Handle the app stuff for the rect drawer"""
445 toggle_rects = make_button("Show Drawn Rects (d)", self.image.toggle_rects, y) 471 toggle_rects = make_button("Show Drawn Rects (d)", self.image.toggle_rects, y)
446 self.add(toggle_rects) 472 self.add(toggle_rects)
447 y += toggle_rects.get_rect().h 473 y += toggle_rects.get_rect().h
448 toggle_toolbar = make_button("Show Toolbar (b)", self.image.toggle_toolbar, y) 474 toggle_toolbar = make_button("Show Toolbar (b)", self.image.toggle_toolbar, y)
449 self.add(toggle_toolbar) 475 self.add(toggle_toolbar)
476 y += toggle_toolbar.get_rect().h
477 toggle_zoom = make_button("Zoom (z)", self.image.toggle_zoom, y)
478 self.add(toggle_zoom)
479 y += toggle_zoom.get_rect().h
450 quit_but = make_button("Quit", self.quit, 570) 480 quit_but = make_button("Quit", self.quit, 570)
451 self.add(quit_but) 481 self.add(quit_but)
452 482
453 def key_down(self, event): 483 def key_down(self, event):
454 # Dispatch to image widget 484 # Dispatch to image widget
468 sys.exit(0) 498 sys.exit(0)
469 pygame.display.init() 499 pygame.display.init()
470 pygame.font.init() 500 pygame.font.init()
471 # enable key repeating 501 # enable key repeating
472 pygame.key.set_repeat(200, 100) 502 pygame.key.set_repeat(200, 100)
473 display = pygame.display.set_mode((1000, 600)) 503 display = pygame.display.set_mode((constants.SCREEN[0] + MENU_WIDTH, constants.SCREEN[1]))
474 state = state.initial_state() 504 state = state.initial_state()
475 if len(sys.argv) < 3: 505 if len(sys.argv) < 3:
476 try: 506 try:
477 state.set_current_scene(sys.argv[1]) 507 state.set_current_scene(sys.argv[1])
478 state.do_check = None 508 state.do_check = None