Mercurial > pyntnclick
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 |