eric6/WebBrowser/AutoScroll/AutoScroller.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7229
53054eb5b15a
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2016 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the automatic scroller.
8 """
9
10 #
11 # This module is based on the Qupzilla auto scroller.
12 # Copyright (C) 2014 David Rosca <nowrep@gmail.com>
13 #
14
15 from __future__ import unicode_literals
16
17 from PyQt5.QtCore import Qt, QObject, QRect, QEvent, QPoint
18 from PyQt5.QtWidgets import QApplication, QLabel
19
20 from .FrameScroller import FrameScroller
21
22 import Preferences
23 import UI.PixmapCache
24
25
26 class AutoScroller(QObject):
27 """
28 Class implementing the automatic scroller.
29 """
30 def __init__(self, parent=None):
31 """
32 Constructor
33
34 @param parent reference to the parent object
35 @type QObject
36 """
37 super(AutoScroller, self).__init__(parent)
38
39 self.__view = None
40
41 self.__indicator = QLabel()
42 self.__indicator.resize(32, 32)
43 self.__indicator.setContentsMargins(0, 0, 0, 0)
44 self.__indicator.installEventFilter(self)
45
46 self.__scroller = FrameScroller(self)
47 self.__scroller.setScrollDivider(
48 Preferences.getWebBrowser("AutoScrollDivider"))
49
50 self.__enabled = Preferences.getWebBrowser("AutoScrollEnabled")
51
52 def isEnabled(self):
53 """
54 Public method to get the enabled state.
55
56 @return enabled state
57 @rtype bool
58 """
59 return self.__enabled
60
61 def mouseMove(self, evt):
62 """
63 Public method to handle mouse move events.
64
65 @param evt reference to the mouse move event
66 @type QMouseEvent
67 @return flag indicating, that the event was handled
68 @rtype bool
69 """
70 if self.__enabled and self.__indicator.isVisible():
71 rect = self.__indicatorGlobalRect()
72 xlen = 0
73 ylen = 0
74 egp = evt.globalPos()
75
76 if rect.left() > egp.x():
77 xlen = egp.x() - rect.left()
78 elif rect.right() < egp.x():
79 xlen = egp.x() - rect.right()
80
81 if rect.top() > egp.y():
82 ylen = egp.y() - rect.top()
83 elif rect.bottom() < egp.y():
84 ylen = egp.y() - rect.bottom()
85
86 self.__scroller.startScrolling(xlen, ylen)
87
88 return False
89
90 def mousePress(self, view, evt):
91 """
92 Public method to handle mouse button presses.
93
94 @param view reference to the web view the button was pressed on
95 @type WebBrowserView
96 @param evt reference to the mouse button press event
97 @type QMouseEvent
98 @return flag indicating, that the event was handled
99 @rtype bool
100 """
101 if self.__enabled:
102 middleButton = evt.buttons() == Qt.MiddleButton
103
104 if view:
105 # test for start
106 if self.__view != view and middleButton:
107 return self.__showIndicator(view, evt.pos())
108 elif not self.__indicator.isVisible() and middleButton:
109 return self.__showIndicator(view, evt.pos())
110
111 # test for stop
112 if self.__indicator.isVisible():
113 self.__stopScrolling()
114 return True
115
116 return False
117
118 def mouseRelease(self, evt):
119 """
120 Public method to handle mouse button releases.
121
122 @param evt reference to the mouse button release event
123 @type QMouseEvent
124 @return flag indicating, that the event was handled
125 @rtype bool
126 """
127 if self.__enabled and self.__indicator.isVisible():
128 if not self.__indicatorGlobalRect().contains(
129 evt.globalPos()):
130 self.__stopScrolling()
131 return True
132
133 return False
134
135 def wheel(self):
136 """
137 Public method to handle a mouse wheel event.
138
139 @return flag indicating, that the event was handled
140 @rtype bool
141 """
142 if self.__enabled and self.__indicator.isVisible():
143 self.__stopScrolling()
144 return True
145
146 return False
147
148 def preferencesChanged(self):
149 """
150 Public method to handle a change of the settings.
151 """
152 enabled = Preferences.getWebBrowser("AutoScrollEnabled")
153 if enabled != self.__enabled:
154 if self.__indicator.isVisible():
155 self.__stopScrolling()
156 self.__enabled = enabled
157
158 self.__scroller.setScrollDivider(
159 Preferences.getWebBrowser("AutoScrollDivider"))
160
161 def eventFilter(self, obj, evt):
162 """
163 Public method to handle event for an object.
164
165 @param obj refernce to the object sending the event
166 @type QObject
167 @param evt reference to the event to be handled
168 @type QEvent
169 @return flag indicating, that the event was handled
170 @rtype bool
171 """
172 if obj == self.__indicator:
173 if evt.type() == QEvent.Enter:
174 self.__scroller.stopScrolling()
175 elif evt.type() in [QEvent.Wheel, QEvent.Hide,
176 QEvent.MouseButtonPress]:
177 self.__stopScrolling()
178
179 return False
180
181 def __showIndicator(self, view, pos):
182 """
183 Private method to show the auto scroll indicator.
184
185 @param view reference to the view to show the indicator on
186 @type WebBrowserView
187 @param pos position to show the indicator at
188 @type QPoint
189 @return flag indicating, that the indicator is shown
190 @rtype bool
191 """
192 hit = view.page().hitTestContent(pos)
193
194 if hit.isContentEditable() or not hit.linkUrl().isEmpty():
195 return False
196
197 jsSource = """
198 var out = {
199 vertical:
200 window.innerWidth > document.documentElement.clientWidth,
201 horizontal:
202 window.innerHeight > document.documentElement.clientHeight
203 };
204 out;"""
205
206 res = view.page().execJavaScript(jsSource)
207 if res is None:
208 return False
209
210 vertical = res["vertical"]
211 horizontal = res["horizontal"]
212 if not vertical and not horizontal:
213 return False
214
215 if vertical and horizontal:
216 self.__indicator.setPixmap(
217 UI.PixmapCache.getPixmap("scrollAll.png"))
218 elif vertical:
219 self.__indicator.setPixmap(
220 UI.PixmapCache.getPixmap("scrollVertical.png"))
221 else:
222 self.__indicator.setPixmap(
223 UI.PixmapCache.getPixmap("scrollHorizontal.png"))
224
225 self.__view = view
226 p = QPoint(
227 pos.x() - self.__indicator.pixmap().width() // 2,
228 pos.y() - self.__indicator.pixmap().height() // 2
229 )
230
231 self.__indicator.setParent(self.__view)
232 self.__indicator.move(p)
233 self.__indicator.show()
234
235 self.__scroller.setPage(view.page())
236
237 self.__view.inputWidget().grabMouse()
238 QApplication.setOverrideCursor(Qt.ArrowCursor)
239
240 return True
241
242 def __stopScrolling(self):
243 """
244 Private method to stop scrolling.
245 """
246 self.__view.inputWidget().releaseMouse()
247 QApplication.restoreOverrideCursor()
248
249 self.__indicator.hide()
250 self.__indicator.setParent(None)
251 self.__scroller.stopScrolling()
252
253 def __indicatorGlobalRect(self):
254 """
255 Private method to calculate the global indicator parameters.
256
257 @return global indicator parameters
258 @rtype QRect
259 """
260 pos = self.__indicator.parentWidget().mapToGlobal(
261 self.__indicator.geometry().topLeft())
262 return QRect(pos.x(), pos.y(),
263 self.__indicator.width(), self.__indicator.height())

eric ide

mercurial