[mousetrap/gnome3-wip: 100/240] Pointers now return a list of ScreenPointerEvents which gui.ScreenPointer interprets.



commit 061497cab7fb455d5c85bf379a075a9efc874964
Author: Stoney Jackson <dr stoney gmail com>
Date:   Wed Jun 18 01:18:58 2014 -0400

    Pointers now return a list of ScreenPointerEvents which gui.ScreenPointer interprets.

 src/mousetrap/gui.py                    |   94 +++++++++++++++++++++++++++++--
 src/mousetrap/main.py                   |   27 ++-------
 src/mousetrap/pointers/eyes.py          |   33 ++---------
 src/mousetrap/pointers/interface.py     |    7 ++
 src/mousetrap/pointers/nose_joystick.py |   22 +++++--
 5 files changed, 125 insertions(+), 58 deletions(-)
---
diff --git a/src/mousetrap/gui.py b/src/mousetrap/gui.py
index 04c3e86..c36b594 100644
--- a/src/mousetrap/gui.py
+++ b/src/mousetrap/gui.py
@@ -5,6 +5,12 @@ All things GUI.
 from gi.repository import Gtk
 from gi.repository import Gdk
 
+from Xlib.display import Display
+from Xlib.ext import xtest
+from Xlib import X
+
+import logging
+LOGGER = logging.getLogger(__name__)
 
 class ImageWindow(object):
     def __init__(self, message):
@@ -51,21 +57,99 @@ class Gui(object):
 
 
 class ScreenPointer(object):
+    EVENT_MOVE = 'move'
+    EVENT_CLICK = 'click'
+    EVENT_DOUBLE_CLICK = 'double click'
+    EVENT_TRIPLE_CLICK = 'triple click'
+    EVENT_PRESS = 'press'
+    EVENT_RELEASE = 'release'
+
+    BUTTON_LEFT = 'left button'
+    BUTTON_RIGHT = 'right button'
+    BUTTON_MIDDLE = 'middle button'
+
     def __init__(self):
         gdk_display = Gdk.Display.get_default()
         device_manager = gdk_display.get_device_manager()
         self._pointer = device_manager.get_client_pointer()
         self._screen = gdk_display.get_default_screen()
+        self._moved = False
+        self._event_handlers = {}
+        self._initialize_event_handlers()
 
-    def get_position(self):
-        x_index = 1
-        y_index = 2
-        position = self._pointer.get_position()
+    def _initialize_event_handlers(self):
+        self._event_handlers[self.EVENT_MOVE] = self.set_position
+        self._event_handlers[self.EVENT_CLICK] = self.click
+        self._event_handlers[self.EVENT_DOUBLE_CLICK] = self.double_click
+        self._event_handlers[self.EVENT_TRIPLE_CLICK] = self.triple_click
+        self._event_handlers[self.EVENT_PRESS] = self.press
+        self._event_handlers[self.EVENT_RELEASE] = self.release
 
-        return (position[x_index], position[y_index])
+    def trigger_event(self, event):
+        self._event_handlers[event.name](event.button_or_position)
 
     def set_position(self, position=None):
         '''Move pointer to position (x, y). If position is None,
         no change is made.'''
+        LOGGER.debug('moving to %s', position)
+        self._moved = False
         if position is not None:
             self._pointer.warp(self._screen, position[0], position[1])
+            self._moved = True
+
+    def is_moving(self):
+        '''Returns True if last call to set_position passed a non-None value
+        for position.'''
+        return self._moved
+
+    def get_position(self):
+        x_index = 1
+        y_index = 2
+        position = self._pointer.get_position()
+        return (position[x_index], position[y_index])
+
+    def click(self, button=BUTTON_LEFT):
+        if button != BUTTON_LEFT:
+            raise NotImplementedError('Only left click is implemented.')
+        display = Display()
+        for action in LeftClick().get_actions():
+            LOGGER.debug('%s %s', action.event, action.button)
+            xtest.fake_input(display, action.event, action.button)
+            display.sync()
+
+    def double_click(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+    def triple_click(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+    def triple_click(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+    def press(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+    def release(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+    def is_pressed(self, button=BUTTON_LEFT):
+        raise NotImplementedError()
+
+
+class ScreenPointerEvent(object):
+    def __init__(self, name, button_or_position):
+        self.name = name
+        self.button_or_position = button_or_position
+
+
+class LeftClick(object):
+    def get_actions(self):
+        press = Button(event=X.ButtonPress)
+        release = Button(event=X.ButtonRelease)
+        return [press, release]
+
+
+class Button(object):
+    def __init__(self, event, button=1):
+        self.event = event
+        self.button = button
diff --git a/src/mousetrap/main.py b/src/mousetrap/main.py
index 9147cd7..99d2ac4 100644
--- a/src/mousetrap/main.py
+++ b/src/mousetrap/main.py
@@ -35,35 +35,20 @@ class Main(object):
         self.gui.start()
 
     def on_timeout(self, user_data):
-        from Xlib.display import Display
-        from Xlib.ext import xtest
 
         image = self.camera.read_image()
         self.gui.show_image('Raw', image)
         self.nose.update_image(image)
-        position = self.nose.get_new_position()
-        self.pointer.set_position(position)
+        for event in self.nose.get_pointer_events():
+            self.pointer.trigger_event(event)
 
-        if position is not None:
+        if self.pointer.is_moving():
             return True
 
-        LOGGER.debug('No change.')
-
         self.eyes.update_image(image)
-        keys = self.eyes.get_keys()
-
-        if keys is None:
-            return True
-
-        LOGGER.debug(keys.get_actions())
-
-        display = Display()
-
-        for action in keys.get_actions():
-            LOGGER.debug('%s %s', action.event, action.button)
-
-            xtest.fake_input(display, action.event, action.button)
-            display.sync()
+        events = self.eyes.get_pointer_events()
+        for event in events:
+            self.pointer.trigger_event(event)
 
         return True
 
diff --git a/src/mousetrap/pointers/eyes.py b/src/mousetrap/pointers/eyes.py
index f79099f..dfc67e8 100644
--- a/src/mousetrap/pointers/eyes.py
+++ b/src/mousetrap/pointers/eyes.py
@@ -1,5 +1,6 @@
 import mousetrap.pointers.interface as interface
 from mousetrap.vision import FeatureDetector, FeatureNotFoundException
+from mousetrap.gui import ScreenPointer
 import logging
 
 
@@ -40,18 +41,16 @@ class Pointer(interface.Pointer):
     def get_new_position(self):
         return None
 
-    def get_keys(self):
+    def get_pointer_events(self):
         if self._detect_closed():
-            if not self._is_closed:
-                self._is_closed = True
-
-                return LeftClick()
-
             self._is_closed = True
+            if not self._is_closed:
+                return [ScreenPointerEvent(
+                            ScreenPointer.EVENT_CLICK,
+                            ScreenPointer.BUTTON_LEFT)]
         else:
             self._is_closed = False
-
-        return None
+        return []
 
 
 class LeftEyeLocator(object):
@@ -76,21 +75,3 @@ class LeftEyeLocator(object):
 
         return (0, 0)
 
-
-class LeftClick(object):
-
-    def get_actions(self):
-        from Xlib import X
-
-        press = Button(event=X.ButtonPress)
-
-        release = Button(event=X.ButtonRelease)
-
-        return [press, release]
-
-
-class Button(object):
-
-    def __init__(self, event, button=1):
-        self.event = event
-        self.button = button
diff --git a/src/mousetrap/pointers/interface.py b/src/mousetrap/pointers/interface.py
index 74653d3..7b26c63 100644
--- a/src/mousetrap/pointers/interface.py
+++ b/src/mousetrap/pointers/interface.py
@@ -11,3 +11,10 @@ class Pointer(object):
     def get_new_position(self):
         '''Returns new location (x, y) or None if no change.'''
         raise NotImplementedError('Must implement.')
+
+    def is_tracking(self):
+        '''Returns True if Pointer is tracking subject, and False otherwise.'''
+        raise NotImplementedError('Must implement.')
+
+    def get_pointer_events(self):
+        '''Returns a list of ScreenPointerEvents'''
diff --git a/src/mousetrap/pointers/nose_joystick.py b/src/mousetrap/pointers/nose_joystick.py
index 202fa83..9cee0a7 100644
--- a/src/mousetrap/pointers/nose_joystick.py
+++ b/src/mousetrap/pointers/nose_joystick.py
@@ -1,6 +1,6 @@
 import mousetrap.pointers.interface as interface
 from mousetrap.vision import FeatureDetector, FeatureNotFoundException
-from mousetrap.gui import Gui, ScreenPointer
+from mousetrap.gui import Gui, ScreenPointer, ScreenPointerEvent
 
 from mousetrap.pointers.nose import NoseLocator
 
@@ -19,17 +19,18 @@ class Pointer(interface.Pointer):
 
         self._location = self._pointer.get_position()
 
+        self._tracking = False
+
     def update_image(self, image):
         self._image = image
-
         try:
             point_image = self._nose_locator.locate(image)
+            self._tracking = True
             point_screen = self._convert_image_to_screen_point(*point_image)
-
             self._location = point_screen
         except FeatureNotFoundException:
+            self._tracking = False
             location = self._pointer.get_position()
-
             self._location = self._apply_delta_to_point(location,
                                                         self._last_delta)
 
@@ -70,5 +71,14 @@ class Pointer(interface.Pointer):
 
         return self._apply_delta_to_point(location, delta)
 
-    def get_new_position(self):
-        return self._location
+#    def get_new_position(self):
+#        return self._location
+
+    def is_tracking(self):
+        return self._tracking
+
+    def get_pointer_events(self):
+        if self._location is None:
+            return []
+        else:
+            return [ScreenPointerEvent(ScreenPointer.EVENT_MOVE, self._location)]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]