-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathsnapscroll.py
116 lines (89 loc) · 3.57 KB
/
snapscroll.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#############################################################################
##
## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
## Contact: Qt Software Information ([email protected])
##
## This file is part of the Graphics Dojo project on Qt Labs.
##
## This file may be used under the terms of the GNU General Public
## License version 2.0 or 3.0 as published by the Free Software Foundation
## and appearing in the file LICENSE.GPL included in the packaging of
## this file. Please review the following information to ensure GNU
## General Public Licensing requirements will be met:
## http:#www.fsf.org/licensing/licenses/info/GPLv2.html and
## http:#www.gnu.org/copyleft/gpl.html.
##
## If you are unsure which license is appropriate for your use, please
## contact the sales department at [email protected].
##
## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
##
#############################################################################
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
if QT_VERSION < 0x0040500:
sys.stderr.write("You need Qt 4.5 or newer to run this example.\n")
sys.exit(1)
SNAP_THRESHOLD = 10
class SnapView(QWebView):
def __init__(self):
QWebView.__init__(self)
self.snapEnabled = True
self.setWindowTitle(self.tr("Snap-scrolling is ON"))
# rects hit by the line, in main frame's view coordinate
def hitBoundingRects(self, line):
hitRects = []
points = 8
delta = QPoint(line.dx() / points, line.dy() / points)
point = line.p1()
i = 0
while i < points - 1:
point += delta
hit = self.page().mainFrame().hitTestContent(point)
if not hit.boundingRect().isEmpty():
hitRects.append(hit.boundingRect())
i += 1
return hitRects
def keyPressEvent(self, event):
# toggle snapping
if event.key() == Qt.Key_F3:
self.snapEnabled = not self.snapEnabled
if self.snapEnabled:
self.setWindowTitle(self.tr("Snap-scrolling is ON"))
else:
self.setWindowTitle(self.tr("Snap-scrolling is OFF"))
event.accept()
return
# no snapping? do not bother...
if not self.snapEnabled:
QWebView.keyReleaseEvent(self, event)
return
previousOffset = self.page().mainFrame().scrollPosition()
QWebView.keyReleaseEvent(self, event)
if not event.isAccepted():
return
if event.key() == Qt.Key_Down:
ofs = self.page().mainFrame().scrollPosition()
jump = ofs.y() - previousOffset.y()
if jump == 0:
return
jump += SNAP_THRESHOLD
rects = self.hitBoundingRects(QLine(1, 1, self.width() - 1, 1))
i = 0
while i < len(rects):
j = rects[i].top() - previousOffset.y()
if j > SNAP_THRESHOLD and j < jump:
jump = j
i += 1
self.page().mainFrame().setScrollPosition(previousOffset + QPoint(0, jump))
if __name__ == "__main__":
app = QApplication(sys.argv)
view = SnapView()
view.load(QUrl("http://news.bbc.co.uk/text_only.stm"))
view.resize(320, 500)
view.show()
QMessageBox.information(view, "Hint", "Use F3 to toggle snapping on and off")
sys.exit(app.exec_())