From cc0ad5d918ee62eaea2cc04e9b7d7678f469f4aa Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 11 Feb 2014 10:59:30 +0530 Subject: [PATCH] Implement swipe and hold --- src/calibre/gui2/viewer/gestures.py | 34 ++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/viewer/gestures.py b/src/calibre/gui2/viewer/gestures.py index 5cfa3fdffa..1ac75320d7 100644 --- a/src/calibre/gui2/viewer/gestures.py +++ b/src/calibre/gui2/viewer/gestures.py @@ -25,8 +25,10 @@ if iswindows and sys.getwindowsversion()[:2] >= (6, 2): # At least windows 7 except Exception: pass +SWIPE_HOLD_INTERVAL = 0.5 # seconds HOLD_THRESHOLD = 1.0 # seconds -SWIPE_DISTANCE = 50 # manhattan pixels +TAP_THRESHOLD = 50 # manhattan pixels +SWIPE_DISTANCE = 100 # manhattan pixels Tap, TapAndHold, Pinch, Swipe, SwipeAndHold = 'Tap', 'TapAndHold', 'Pinch', 'Swipe', 'SwipeAndHold' Left, Right, Up, Down = 'Left', 'Right', 'Up', 'Down' @@ -121,10 +123,10 @@ class State(QObject): if TapAndHold in self.possible_gestures: self.tap_hold_updated.emit(tp) if SwipeAndHold in self.possible_gestures: - self.swipe_hold_updated.emit(tp) + self.swipe_hold_updated.emit(self.hold_data[1]) else: self.possible_gestures &= {TapAndHold, SwipeAndHold} - if tp.total_movement > SWIPE_DISTANCE: + if tp.total_movement > TAP_THRESHOLD: st = tp.swipe_type if st is None: self.possible_gestures.clear() @@ -132,7 +134,7 @@ class State(QObject): self.hold_started = True self.possible_gestures = {SwipeAndHold} self.hold_data = (now, st) - self.swipe_hold_started.emit(tp) + self.swipe_hold_started.emit(st) else: self.possible_gestures = {TapAndHold} self.hold_started = True @@ -142,7 +144,7 @@ class State(QObject): def finalize(self): if Tap in self.possible_gestures: tp = next(self.touch_points.itervalues()) - if tp.total_movement <= SWIPE_DISTANCE: + if tp.total_movement <= TAP_THRESHOLD: self.tapped.emit(tp) return @@ -171,11 +173,15 @@ class GestureHandler(QObject): def __init__(self, view): QObject.__init__(self, view) self.state = State() + self.last_swipe_hold_update = None self.state.swiped.connect(self.handle_swipe) self.state.tapped.connect(self.handle_tap) self.state.tap_hold_started.connect(partial(self.handle_tap_hold, 'start')) self.state.tap_hold_updated.connect(partial(self.handle_tap_hold, 'update')) self.state.tap_hold_finished.connect(partial(self.handle_tap_hold, 'end')) + 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.evmap = {QEvent.TouchBegin: 'start', QEvent.TouchUpdate: 'update', QEvent.TouchEnd: 'end'} # Ignore fake mouse events generated by the window system from touch @@ -263,3 +269,21 @@ class GestureHandler(QObject): # We have to use post event otherwise the popup remains an alien widget and does not receive events QApplication.postEvent(self.parent(), ev) + def handle_swipe_hold(self, action, direction): + view = self.parent() + if action == 'start': + self.last_swipe_hold_update = time.time() + try: + self.handle_swipe(direction) + finally: + view.is_auto_repeat_event = False + elif action == 'update' and self.last_swipe_hold_update is not None and time.time() - self.last_swipe_hold_update > SWIPE_HOLD_INTERVAL: + view.is_auto_repeat_event = True + self.last_swipe_hold_update = time.time() + try: + self.handle_swipe(direction) + finally: + view.is_auto_repeat_event = False + elif action == 'end': + self.last_swipe_hold_update = None +