1
0

scroll.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #!/usr/bin/env python
  2. """An zoomed image viewer that demonstrates Surface.scroll
  3. This example shows a scrollable image that has a zoom factor of eight.
  4. It uses the Surface.scroll function to shift the image on the display
  5. surface. A clip rectangle protects a margin area. If called as a function,
  6. the example accepts an optional image file path. If run as a program
  7. it takes an optional file path command line argument. If no file
  8. is provided a default image file is used.
  9. When running click on a black triangle to move one pixel in the direction
  10. the triangle points. Or use the arrow keys. Close the window or press ESC
  11. to quit.
  12. """
  13. import sys
  14. import os
  15. import pygame
  16. from pygame.transform import scale
  17. from pygame.locals import *
  18. main_dir = os.path.dirname(os.path.abspath(__file__))
  19. DIR_UP = 1
  20. DIR_DOWN = 2
  21. DIR_LEFT = 3
  22. DIR_RIGHT = 4
  23. zoom_factor = 8
  24. def draw_arrow(surf, color, posn, direction):
  25. x, y = posn
  26. if direction == DIR_UP:
  27. pointlist = ((x - 29, y + 30), (x + 30, y + 30),
  28. (x + 1, y - 29), (x, y - 29))
  29. elif direction == DIR_DOWN:
  30. pointlist = ((x - 29, y - 29), (x + 30, y - 29),
  31. (x + 1, y + 30), (x, y + 30))
  32. elif direction == DIR_LEFT:
  33. pointlist = ((x + 30, y - 29), (x + 30, y + 30),
  34. (x - 29, y + 1), (x - 29, y))
  35. else:
  36. pointlist = ((x - 29, y - 29), (x - 29, y + 30),
  37. (x + 30, y + 1), (x + 30, y))
  38. pygame.draw.polygon(surf, color, pointlist)
  39. def add_arrow_button(screen, regions, posn, direction):
  40. draw_arrow(screen, Color('black'), posn, direction)
  41. draw_arrow(regions, (direction, 0, 0), posn, direction)
  42. def scroll_view(screen, image, direction, view_rect):
  43. dx = dy = 0
  44. src_rect = None
  45. zoom_view_rect = screen.get_clip()
  46. image_w, image_h = image.get_size()
  47. if direction == DIR_UP:
  48. if view_rect.top > 0:
  49. screen.scroll(dy=zoom_factor)
  50. view_rect.move_ip(0, -1)
  51. src_rect = view_rect.copy()
  52. src_rect.h = 1
  53. dst_rect = zoom_view_rect.copy()
  54. dst_rect.h = zoom_factor
  55. elif direction == DIR_DOWN:
  56. if view_rect.bottom < image_h:
  57. screen.scroll(dy=-zoom_factor)
  58. view_rect.move_ip(0, 1)
  59. src_rect = view_rect.copy()
  60. src_rect.h = 1
  61. src_rect.bottom = view_rect.bottom
  62. dst_rect = zoom_view_rect.copy()
  63. dst_rect.h = zoom_factor
  64. dst_rect.bottom = zoom_view_rect.bottom
  65. elif direction == DIR_LEFT:
  66. if view_rect.left > 0:
  67. screen.scroll(dx=zoom_factor)
  68. view_rect.move_ip(-1, 0)
  69. src_rect = view_rect.copy()
  70. src_rect.w = 1
  71. dst_rect = zoom_view_rect.copy()
  72. dst_rect.w = zoom_factor
  73. elif direction == DIR_RIGHT:
  74. if view_rect.right < image_w:
  75. screen.scroll(dx=-zoom_factor)
  76. view_rect.move_ip(1, 0)
  77. src_rect = view_rect.copy()
  78. src_rect.w = 1
  79. src_rect.right = view_rect.right
  80. dst_rect = zoom_view_rect.copy()
  81. dst_rect.w = zoom_factor
  82. dst_rect.right = zoom_view_rect.right
  83. if src_rect is not None:
  84. scale(image.subsurface(src_rect),
  85. dst_rect.size,
  86. screen.subsurface(dst_rect))
  87. pygame.display.update(zoom_view_rect)
  88. def main(image_file=None):
  89. if image_file is None:
  90. image_file = os.path.join(main_dir, 'data', 'arraydemo.bmp')
  91. margin = 80
  92. view_size = (30, 20)
  93. zoom_view_size = (view_size[0] * zoom_factor,
  94. view_size[1] * zoom_factor)
  95. win_size = (zoom_view_size[0] + 2 * margin,
  96. zoom_view_size[1] + 2 * margin)
  97. background_color = Color('beige')
  98. pygame.init()
  99. # set up key repeating so we can hold down the key to scroll.
  100. old_k_delay, old_k_interval = pygame.key.get_repeat ()
  101. pygame.key.set_repeat (500, 30)
  102. try:
  103. screen = pygame.display.set_mode(win_size)
  104. screen.fill(background_color)
  105. pygame.display.flip()
  106. image = pygame.image.load(image_file).convert()
  107. image_w, image_h = image.get_size()
  108. if image_w < view_size[0] or image_h < view_size[1]:
  109. print ("The source image is too small for this example.")
  110. print ("A %i by %i or larger image is required." % zoom_view_size)
  111. return
  112. regions = pygame.Surface(win_size, 0, 24)
  113. add_arrow_button(screen, regions,
  114. (40, win_size[1] // 2), DIR_LEFT)
  115. add_arrow_button(screen, regions,
  116. (win_size[0] - 40, win_size[1] // 2), DIR_RIGHT)
  117. add_arrow_button(screen, regions,
  118. (win_size[0] // 2, 40), DIR_UP)
  119. add_arrow_button(screen, regions,
  120. (win_size[0] // 2, win_size[1] - 40), DIR_DOWN)
  121. pygame.display.flip()
  122. screen.set_clip((margin, margin, zoom_view_size[0], zoom_view_size[1]))
  123. view_rect = Rect(0, 0, view_size[0], view_size[1])
  124. scale(image.subsurface(view_rect), zoom_view_size,
  125. screen.subsurface(screen.get_clip()))
  126. pygame.display.flip()
  127. # the direction we will scroll in.
  128. direction = None
  129. clock = pygame.time.Clock()
  130. clock.tick()
  131. going = True
  132. while going:
  133. # wait for events before doing anything.
  134. #events = [pygame.event.wait()] + pygame.event.get()
  135. events = pygame.event.get()
  136. for e in events:
  137. if e.type == KEYDOWN:
  138. if e.key == K_ESCAPE:
  139. going = False
  140. elif e.key == K_DOWN:
  141. scroll_view(screen, image, DIR_DOWN, view_rect)
  142. elif e.key == K_UP:
  143. scroll_view(screen, image, DIR_UP, view_rect)
  144. elif e.key == K_LEFT:
  145. scroll_view(screen, image, DIR_LEFT, view_rect)
  146. elif e.key == K_RIGHT:
  147. scroll_view(screen, image, DIR_RIGHT, view_rect)
  148. elif e.type == QUIT:
  149. going = False
  150. elif e.type == MOUSEBUTTONDOWN:
  151. direction = regions.get_at(e.pos)[0]
  152. elif e.type == MOUSEBUTTONUP:
  153. direction = None
  154. if direction:
  155. scroll_view(screen, image, direction, view_rect)
  156. clock.tick(30)
  157. finally:
  158. pygame.key.set_repeat (old_k_delay, old_k_interval)
  159. pygame.quit()
  160. if __name__ == '__main__':
  161. if len(sys.argv) > 1:
  162. image_file = sys.argv[1]
  163. else:
  164. image_file = None
  165. main(image_file)