diff --git a/src/calibre/gui2/viewer/gestures.py b/src/calibre/gui2/viewer/gestures.py index 1ac75320d7..0f3e9b1f16 100644 --- a/src/calibre/gui2/viewer/gestures.py +++ b/src/calibre/gui2/viewer/gestures.py @@ -29,9 +29,12 @@ SWIPE_HOLD_INTERVAL = 0.5 # seconds HOLD_THRESHOLD = 1.0 # seconds TAP_THRESHOLD = 50 # manhattan pixels SWIPE_DISTANCE = 100 # manhattan pixels +PINCH_CENTER_THRESHOLD = 150 # manhattan pixels +PINCH_SQUEEZE_FACTOR = 2.5 # smaller length must be less that larger length / squeeze factor Tap, TapAndHold, Pinch, Swipe, SwipeAndHold = 'Tap', 'TapAndHold', 'Pinch', 'Swipe', 'SwipeAndHold' Left, Right, Up, Down = 'Left', 'Right', 'Up', 'Down' +In, Out = 'In', 'Out' class TouchPoint(object): @@ -65,10 +68,24 @@ class TouchPoint(object): axis = (Left, Right) if xabs > yabs else (Up, Down) return axis[0 if d < 0 else 1] +def get_pinch(p1, p2): + starts = [p1.start_screen_position, p2.start_screen_position] + ends = [p1.current_screen_position, p2.current_screen_position] + start_center = (starts[0] + starts[1]) / 2.0 + end_center = (ends[0] + ends[1]) / 2.0 + if (start_center - end_center).manhattanLength() > PINCH_CENTER_THRESHOLD: + return None + start_length = (starts[0] - starts[1]).manhattanLength() + end_length = (ends[0] - ends[1]).manhattanLength() + if min(start_length, end_length) > max(start_length, end_length) / PINCH_SQUEEZE_FACTOR: + return None + return In if start_length > end_length else Out + class State(QObject): tapped = pyqtSignal(object) swiped = pyqtSignal(object) + pinched = pyqtSignal(object) tap_hold_started = pyqtSignal(object) tap_hold_updated = pyqtSignal(object) swipe_hold_started = pyqtSignal(object) @@ -156,7 +173,11 @@ class State(QObject): return if Pinch in self.possible_gestures: - pass # TODO: Implement this + points = tuple(self.touch_points.itervalues()) + if len(points) == 2: + pinch_dir = get_pinch(*points) + if pinch_dir is not None: + self.pinched.emit(pinch_dir) if TapAndHold in self.possible_gestures: tp = next(self.touch_points.itervalues()) @@ -182,6 +203,7 @@ class GestureHandler(QObject): self.state.swipe_hold_started.connect(partial(self.handle_swipe_hold, 'start')) self.state.swipe_hold_updated.connect(partial(self.handle_swipe_hold, 'update')) self.state.swipe_hold_finished.connect(partial(self.handle_swipe_hold, 'end')) + self.state.pinched.connect(self.handle_pinch) self.evmap = {QEvent.TouchBegin: 'start', QEvent.TouchUpdate: 'update', QEvent.TouchEnd: 'end'} # Ignore fake mouse events generated by the window system from touch @@ -287,3 +309,7 @@ class GestureHandler(QObject): elif action == 'end': self.last_swipe_hold_update = None + def handle_pinch(self, direction): + attr = 'magnify' if direction is Out else 'shrink' + getattr(self.parent(), '%s_fonts' % attr)() +