| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- #!/usr/bin/env python
- from __future__ import division
- import pygame
- import sys
- import time
- from threading import Thread
- from math import degrees, cos, sin
- from src.server import GestureServer
- from src.window import FullscreenWindow
- from src.trackers.transform import TransformationTracker
- from src.trackers.tap import TapTracker
- from src.screen import screen_size
- from tests.parse_arguments import create_parser, parse_args
- parser = create_parser()
- parser.add_argument('-f', '--fullscreen', action='store_true', default=False,
- help='run in fullscreen')
- args = parse_args(parser)
- pygame.init()
- # Config
- FINGER_RADIUS = 20
- CENTROID_RADIUS = 15
- W, H = screen_size if args.fullscreen else (640, 480)
- BG_COLOR = 0, 0, 0
- LINE_COLOR = 128, 128, 128
- CIRCLE_COLOR = 255, 255, 255
- RECT_COLOR = 0, 200, 0
- RECT_POS = W / 2, H / 2
- RECT_SIZE = W / 6., H / 6.
- TAP_RADIUS = 65
- TAP_INCREMENT = .3
- BEAM_COLOR = 255, 50, 50
- BEAM_LENGTH = 50
- BEAM_WIDTH = 3
- BEAM_INCREMENT = .8
- MAX_SCALE = 10
- # Create canvas GUI
- flags = pygame.FULLSCREEN if args.fullscreen else 0
- screen = pygame.display.set_mode((W, H), flags)
- def coord(x, y):
- w, h = screen_size
- return int(round(W / w * x)), int(round(H / h * y))
- # Global state
- angle = 0
- scale = 1
- taps = []
- dtaps = []
- def update():
- global taps, dtaps
- # Clear previous frame
- screen.fill(BG_COLOR)
- # Apply scale and rotation to a fixed-size rectangle canvas
- canvas = pygame.Surface(RECT_SIZE)
- canvas.fill(RECT_COLOR)
- transformed = pygame.transform.rotozoom(canvas, degrees(angle), scale)
- rect = transformed.get_rect()
- rect.center = W / 2, H / 2
- screen.blit(transformed, rect)
- # Draw touch points
- if transform.centroid:
- c = coord(*transform.centroid.xy)
- for p in server.points.itervalues():
- xy = coord(p.x, p.y)
- # Draw line to centroid
- if transform.centroid:
- pygame.draw.line(screen, LINE_COLOR, xy, c, 1)
- # Draw outlined circle around touch point
- pygame.draw.circle(screen, CIRCLE_COLOR, xy, FINGER_RADIUS, 1)
- # Fill filled circle with background color within the outline
- pygame.draw.circle(screen, BG_COLOR, xy, FINGER_RADIUS - 1, 0)
- # Draw filled circle around centroid
- if transform.centroid:
- pygame.draw.circle(screen, CIRCLE_COLOR, c, CENTROID_RADIUS)
- # Draw an expanding circle around each tap event
- taps = filter(lambda (xy, r): r <= TAP_RADIUS, taps)
- for tap in taps:
- xy, radius = tap
- pygame.draw.circle(screen, CIRCLE_COLOR, xy, int(radius), 2)
- # Increment radius
- tap[1] += TAP_INCREMENT
- # Shoot a beam from each double tap event to the left
- dtaps = filter(lambda (x, y, s): 0 <= x <= W, dtaps)
- for dtap in dtaps:
- x, y, single = dtap
- if single:
- start_x = x
- end_x = x + BEAM_LENGTH
- dtap[0] += BEAM_INCREMENT
- else:
- start_x = x - BEAM_LENGTH
- end_x = x
- dtap[0] -= BEAM_INCREMENT
- pygame.draw.line(screen, BEAM_COLOR, (start_x, y), (end_x, y), BEAM_WIDTH)
- # Update canvas
- pygame.display.flip()
- # Create server and fullscreen window
- server = GestureServer()
- win = FullscreenWindow(server=server)
- # Bind trackers
- def rotate(gesture):
- global angle
- angle += gesture.get_angle()
- def pinch(gesture):
- global scale
- scale = min(scale * gesture.get_scale(), MAX_SCALE)
- transform = TransformationTracker(win)
- transform.bind('rotate', rotate)
- transform.bind('pinch', pinch)
- tap = TapTracker(win)
- tap.bind('tap', lambda g: taps.append([coord(*g.xy), FINGER_RADIUS]))
- tap.bind('single_tap', lambda g: dtaps.append(list(coord(*g.xy)) + [1]))
- tap.bind('double_tap', lambda g: dtaps.append(list(coord(*g.xy)) + [0]))
- try:
- # Start touch gesture server in separate thread
- thread = Thread(target=server.start)
- thread.daemon = True
- thread.start()
- # Start GUI event loop
- def is_quit_event(e):
- return e.type == pygame.QUIT \
- or (e.type == pygame.KEYDOWN and e.key == ord('q'))
- while not any(filter(is_quit_event, pygame.event.get())):
- update()
- except KeyboardInterrupt:
- pass
- finally:
- server.stop()
|