from logger import Logger class GestureTracker(Logger): """ Abstract class for gesture tracker definitions. Contains methods for changing the state of touch points. """ # Supported gesture types gesture_types = [] # Configurable properties (see configure() method) configurable = [] def __init__(self, window=None): # Hashmap of gesture types self.handlers = {} if window: window.add_tracker(self) def bind(self, gesture_type, handler, *args, **kwargs): """ Bind a handler to a gesture type. Multiple handlers can be bound to a single gesture type. Optionally, (keyword) arguments that will be passed to the handler along with a Gesture object can be specified. """ if gesture_type not in self.gesture_types: raise ValueError('Unsupported gesture type "%s".' % gesture_type) h = handler, args, kwargs if gesture_type not in self.handlers: self.handlers[gesture_type] = [h] else: self.handlers[gesture_type].append(h) def trigger(self, gesture): if gesture._type not in self.handlers: self.debug('Triggered "%s", but no handlers are bound.' % gesture._type) return self.info('Triggered %s.' % gesture) for handler, args, kwargs in self.handlers[gesture._type]: handler(gesture, *args, **kwargs) def is_type_bound(self, gesture_type): return gesture_type in self.handlers def on_point_down(self, point): pass def on_point_move(self, point): pass def on_point_up(self, point): pass def configure(self, **kwargs): for name, value in kwargs.iteritems(): if name not in self.configurable: raise ValueError('%s.%s is not a configurable property.' % (self.__class__.__name__, name)) setattr(self, name, value) def __getattr__(self, name): """ Allow calls like: tracker.gesture(...) instead of: tracker.bind('gesture', ...) """ if name not in self.gesture_types: raise AttributeError("'%s' has no attribute '%s'" % (self.__class__.__name__, name)) return lambda handler: self.bind(name, handler) class Gesture(object): """ Abstract class that represents a triggered gesture. """ pass