Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Speak.activity
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-07-14 04:46:33 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-07-14 04:46:33 (GMT)
commit16ce908f8277589f9b91caec23e728aaf1644d75 (patch)
tree1c9d27f3603588fccb203037d9af890af5ea5289 /Speak.activity
parent1eeffe9e24f4f8be117f7775eae0f9388b08dc2f (diff)
Implant xeyes
Diffstat (limited to 'Speak.activity')
-rw-r--r--Speak.activity/eye.py56
1 files changed, 38 insertions, 18 deletions
diff --git a/Speak.activity/eye.py b/Speak.activity/eye.py
index b368b41..1fe23f5 100644
--- a/Speak.activity/eye.py
+++ b/Speak.activity/eye.py
@@ -36,13 +36,13 @@ class Eye(gtk.DrawingArea):
self.blink = False
self.x, self.y = 0,0
self.fill_color = fill_color
-
+
# listen for clicks
self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
self.connect("button_press_event", self._mouse_pressed_cb)
self.connect("button_release_event", self._mouse_released_cb)
-
+
# Instead of listening for mouse move events we could poll to see if the mouse has moved
# would let us react to the mouse even when it isn't directly over this widget.
# Unfortunately that would cause a lot of CPU usage. So instead we rely on our parent to
@@ -61,7 +61,7 @@ class Eye(gtk.DrawingArea):
def _mouse_released_cb(self, widget, event):
self.blink = False
self.queue_draw()
-
+
def look_at(self, x, y):
self.x = x
self.y = y
@@ -72,30 +72,50 @@ class Eye(gtk.DrawingArea):
self.y = None
self.queue_draw()
- def pupil_position(self):
- bounds = self.get_allocation()
- abs_x, abs_y = self.translate_coordinates(self.get_toplevel(), 0, 0)
- if self.x is not None and self.y is not None:
- dir_x, dir_y = self.x - abs_x, self.y - abs_y
- else:
+ # Thanks to xeyes :)
+ def computePupil(self):
+ a = self.get_allocation()
+
+ if self.x is None or self.y is None:
# look ahead, but not *directly* in the middle
- if bounds.x+bounds.width/2 < self.parent.get_allocation().width/2:
- dir_x = bounds.width * 0.6
+ if a.x + a.width/2 < self.parent.get_allocation().width/2:
+ cx = a.width * 0.6
else:
- dir_x = bounds.width * 0.4
- dir_y = bounds.height * 0.6
- pupilX = max(min(dir_x, bounds.width), 0)
- pupilY = max(min(dir_y, bounds.height), 0)
- return pupilX, pupilY
+ cx = a.width * 0.4
+ return cx, a.height * 0.6
+
+ EYE_X, EYE_Y = self.translate_coordinates(
+ self.get_toplevel(), a.width/2, a.height/2)
+ EYE_HWIDTH = a.width
+ EYE_HHEIGHT = a.height
+ BALL_DIST = EYE_HWIDTH/4
+
+ dx = self.x - EYE_X
+ dy = self.y - EYE_Y
+
+ if dx or dy:
+ angle = math.atan2(dy, dx)
+ cosa = math.cos(angle)
+ sina = math.sin(angle)
+ h = math.hypot(EYE_HHEIGHT * cosa, EYE_HWIDTH * sina)
+ x = (EYE_HWIDTH * EYE_HHEIGHT) * cosa / h
+ y = (EYE_HWIDTH * EYE_HHEIGHT) * sina / h
+ dist = BALL_DIST * math.hypot(x, y)
+
+ if dist < math.hypot(dx, dy):
+ dx = dist * cosa
+ dy = dist * sina
+
+ return a.width/2 + dx, a.height/2 + dy
def expose(self, widget, event):
self.frame += 1
bounds = self.get_allocation()
-
+
eyeSize = min(bounds.width, bounds.height)
outlineWidth = eyeSize/20.0
pupilSize = eyeSize/10.0
- pupilX, pupilY = self.pupil_position()
+ pupilX, pupilY = self.computePupil()
dX = pupilX - bounds.width/2.
dY = pupilY - bounds.height/2.
distance = math.sqrt(dX*dX + dY*dY)