-
Notifications
You must be signed in to change notification settings - Fork 3
/
HandListener.py
111 lines (82 loc) · 3.68 KB
/
HandListener.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import lib.Leap as Leap
import math
import time
from pymouse import PyMouse
class Timer(object):
def __init__(self, delay):
self.start = time.time()
self.delay = delay
def signal(self):
now = time.time()
if now - self.start > self.delay:
self.start = now
return True
else:
return False
class HandListener(Leap.Listener):
def __init__(self):
super(HandListener, self).__init__()
self.timer = Timer(2)
self.mouse = PyMouse()
def on_init(self, controller):
self.on = True
self.screens = controller.calibrated_screens
controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP)
controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE)
print "Initialized"
def on_connect(self, controller):
print "Connected"
def on_disconnect(self, controller):
print "Disconnected"
def on_exit(self, controller):
print "Exited"
def on_frame(self, controller):
# Get the most recent frame and report some basic information
frame = controller.frame()
#print "Frame id: %d, timestamp: %d, hands: %d, fingers: %d, tools: %d" % (
# frame.id, frame.timestamp, len(frame.hands), len(frame.fingers), len(frame.tools))
if not frame.hands.empty:
hand = frame.hands[0]
if self.on:
self.process_gestures(controller)
if len(hand.fingers) == 1:
finger = hand.fingers[0]
screen_to_choose = None
position = None
chosen_screen = False
for screen in [self.screens[0]]: # Swap new one in when you can handle multiple screens
#for screen in self.screens:
candidate = screen.intersect(finger, True)
x_pos = candidate.x
y_pos = candidate.y
# Throws out datapoints when you point off screen - have to figure out in-bounds geometry for multiscreen
if not (math.isnan(x_pos) or math.isnan(y_pos)):
screen_to_choose = screen
position = candidate
chosen_screen = True
if not chosen_screen: return
x_pixels = position.x * screen_to_choose.width_pixels
y_pixels = screen_to_choose.height_pixels - position.y * screen_to_choose.height_pixels
# currently only sets it in relation to the primary screen
self.mouse.move(x_pixels,y_pixels)
"""
# Handles turning it off and on with 4 finger wave
if len(hand.fingers) >= 4:
result = self.timer.signal()
if result:
self.on = not self.on
#print self.on
"""
def process_gestures(self, controller):
frame = controller.frame()
hand = frame.hands[0]
if len(hand.fingers) < 2: return
x_pos = self.mouse.position()[0]
y_pos = self.mouse.position()[1]
for gesture in frame.gestures():
if gesture.type == Leap.Gesture.TYPE_SCREEN_TAP:
if len(hand.fingers) == 2:
self.mouse.click(x_pos, y_pos, 1)
elif len(hand.fingers) == 3:
self.mouse.click(x_pos, y_pos, 2)
break # hack so that you only count one click with multi-finger gesture