Use Qt's builtin swipe gesture recognizer instead of rolling our own

This commit is contained in:
Kovid Goyal 2012-01-05 09:36:15 +05:30
parent 50bbff2417
commit c1376fbb38
2 changed files with 17 additions and 83 deletions

View file

@ -12,14 +12,13 @@
QPainter, QPalette, QBrush, QFontDatabase, QDialog,
QColor, QPoint, QImage, QRegion, QVariant, QIcon,
QFont, pyqtSignature, QAction, QByteArray, QMenu,
pyqtSignal)
pyqtSignal, QSwipeGesture)
from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
from calibre.utils.config import Config, StringConfig
from calibre.utils.localization import get_language
from calibre.gui2.viewer.config_ui import Ui_Dialog
from calibre.gui2.viewer.flip import SlideFlip
from calibre.gui2.viewer.gestures import Gestures
from calibre.gui2.shortcuts import Shortcuts, ShortcutConfig
from calibre.constants import iswindows
from calibre import prints, guess_type
@ -514,7 +513,6 @@ class DocumentView(QWebView): # {{{
def __init__(self, *args):
QWebView.__init__(self, *args)
self.flipper = SlideFlip(self)
self.gestures = Gestures()
self.is_auto_repeat_event = False
self.debug_javascript = False
self.shortcuts = Shortcuts(SHORTCUTS, 'shortcuts/viewer')
@ -582,6 +580,7 @@ def __init__(self, *args):
else:
m.addAction(name, a[key], self.shortcuts.get_sequences(key)[0])
self.goto_location_action.setMenu(self.goto_location_menu)
self.grabGesture(Qt.SwipeGesture)
def goto_next_section(self, *args):
if self.manager is not None:
@ -1047,28 +1046,24 @@ def viewport_resized(self):
self.manager.viewport_resized(self.scroll_fraction)
def event(self, ev):
typ = ev.type()
if typ == ev.TouchBegin:
try:
self.gestures.start_gesture('touch', ev)
except:
import traceback
traceback.print_exc()
elif typ == ev.TouchEnd:
try:
gesture = self.gestures.end_gesture('touch', ev, self.rect())
except:
import traceback
traceback.print_exc()
if gesture is not None:
ev.accept()
if gesture == 'lineleft':
self.next_page()
elif gesture == 'lineright':
self.previous_page()
if ev.type() == ev.Gesture:
swipe = ev.gesture(Qt.SwipeGesture)
if swipe is not None:
self.handle_swipe(swipe)
return True
return QWebView.event(self, ev)
def handle_swipe(self, swipe):
if swipe.state() == Qt.GestureFinished:
if swipe.horizontalDirection() == QSwipeGesture.Left:
self.previous_page()
elif swipe.horizontalDirection() == QSwipeGesture.Right:
self.next_page()
elif swipe.verticalDirection() == QSwipeGesture.Up:
self.goto_previous_section()
elif swipe.horizontalDirection() == QSwipeGesture.Down:
self.goto_next_section()
def mouseReleaseEvent(self, ev):
opos = self.document.ypos
ret = QWebView.mouseReleaseEvent(self, ev)

View file

@ -1,61 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import time
class Gestures(object):
def __init__(self):
self.in_progress = {}
def get_boundary_point(self, event):
t = time.time()
id_ = None
if hasattr(event, 'touchPoints'):
tps = list(event.touchPoints())
tp = None
for t in tps:
if t.isPrimary():
tp = t
break
if tp is None:
tp = tps[0]
gp, p = tp.screenPos(), tp.pos()
id_ = tp.id()
else:
gp, p = event.globalPos(), event.pos()
return (t, gp, p, id_)
def start_gesture(self, typ, event):
self.in_progress[typ] = self.get_boundary_point(event)
def is_in_progress(self, typ):
return typ in self.in_progress
def end_gesture(self, typ, event, widget_rect):
if not self.is_in_progress(typ):
return
start = self.in_progress[typ]
end = self.get_boundary_point(event)
if start[3] != end[3]:
return
timespan = end[0] - start[0]
start_pos, end_pos = start[1], end[1]
xspan = end_pos.x() - start_pos.x()
yspan = end_pos.y() - start_pos.y()
width = widget_rect.width()
if timespan < 1.1 and abs(xspan) >= width/5. and \
abs(yspan) < abs(xspan)/5.:
# Quick horizontal gesture
return 'line'+('left' if xspan < 0 else 'right')
return None