Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/widgets/widgets/qscrollbar.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||
5 | ** | - | ||||||||||||||||||
6 | ** This file is part of the QtWidgets module of the Qt Toolkit. | - | ||||||||||||||||||
7 | ** | - | ||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||||||||
16 | ** | - | ||||||||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||
24 | ** | - | ||||||||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||
35 | ** | - | ||||||||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
37 | ** | - | ||||||||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | #include "qapplication.h" | - | ||||||||||||||||||
41 | #include "qcursor.h" | - | ||||||||||||||||||
42 | #include "qevent.h" | - | ||||||||||||||||||
43 | #include "qpainter.h" | - | ||||||||||||||||||
44 | #include "qscrollbar.h" | - | ||||||||||||||||||
45 | #include "qstyle.h" | - | ||||||||||||||||||
46 | #include "qstyleoption.h" | - | ||||||||||||||||||
47 | #include "qmenu.h" | - | ||||||||||||||||||
48 | #include <QtCore/qelapsedtimer.h> | - | ||||||||||||||||||
49 | - | |||||||||||||||||||
50 | #ifndef QT_NO_SCROLLBAR | - | ||||||||||||||||||
51 | - | |||||||||||||||||||
52 | #ifndef QT_NO_ACCESSIBILITY | - | ||||||||||||||||||
53 | #include "qaccessible.h" | - | ||||||||||||||||||
54 | #endif | - | ||||||||||||||||||
55 | #include <limits.h> | - | ||||||||||||||||||
56 | #include "qscrollbar_p.h" | - | ||||||||||||||||||
57 | - | |||||||||||||||||||
58 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
59 | - | |||||||||||||||||||
60 | /*! | - | ||||||||||||||||||
61 | \class QScrollBar | - | ||||||||||||||||||
62 | \brief The QScrollBar widget provides a vertical or horizontal scroll bar. | - | ||||||||||||||||||
63 | - | |||||||||||||||||||
64 | \ingroup basicwidgets | - | ||||||||||||||||||
65 | \inmodule QtWidgets | - | ||||||||||||||||||
66 | - | |||||||||||||||||||
67 | A scroll bar is a control that enables the user to access parts of a | - | ||||||||||||||||||
68 | document that is larger than the widget used to display it. It provides | - | ||||||||||||||||||
69 | a visual indication of the user's current position within the document | - | ||||||||||||||||||
70 | and the amount of the document that is visible. Scroll bars are usually | - | ||||||||||||||||||
71 | equipped with other controls that enable more accurate navigation. | - | ||||||||||||||||||
72 | Qt displays scroll bars in a way that is appropriate for each platform. | - | ||||||||||||||||||
73 | - | |||||||||||||||||||
74 | If you need to provide a scrolling view onto another widget, it may be | - | ||||||||||||||||||
75 | more convenient to use the QScrollArea class because this provides a | - | ||||||||||||||||||
76 | viewport widget and scroll bars. QScrollBar is useful if you need to | - | ||||||||||||||||||
77 | implement similar functionality for specialized widgets using QAbstractScrollArea; | - | ||||||||||||||||||
78 | for example, if you decide to subclass QAbstractItemView. | - | ||||||||||||||||||
79 | For most other situations where a slider control is used to obtain a value | - | ||||||||||||||||||
80 | within a given range, the QSlider class may be more appropriate for your | - | ||||||||||||||||||
81 | needs. | - | ||||||||||||||||||
82 | - | |||||||||||||||||||
83 | \table | - | ||||||||||||||||||
84 | \row \li \image qscrollbar-picture.png | - | ||||||||||||||||||
85 | \li Scroll bars typically include four separate controls: a slider, | - | ||||||||||||||||||
86 | scroll arrows, and a page control. | - | ||||||||||||||||||
87 | - | |||||||||||||||||||
88 | \list | - | ||||||||||||||||||
89 | \li a. The slider provides a way to quickly go to any part of the | - | ||||||||||||||||||
90 | document, but does not support accurate navigation within large | - | ||||||||||||||||||
91 | documents. | - | ||||||||||||||||||
92 | \li b. The scroll arrows are push buttons which can be used to accurately | - | ||||||||||||||||||
93 | navigate to a particular place in a document. For a vertical scroll bar | - | ||||||||||||||||||
94 | connected to a text editor, these typically move the current position one | - | ||||||||||||||||||
95 | "line" up or down, and adjust the position of the slider by a small | - | ||||||||||||||||||
96 | amount. In editors and list boxes a "line" might mean one line of text; | - | ||||||||||||||||||
97 | in an image viewer it might mean 20 pixels. | - | ||||||||||||||||||
98 | \li c. The page control is the area over which the slider is dragged (the | - | ||||||||||||||||||
99 | scroll bar's background). Clicking here moves the scroll bar towards | - | ||||||||||||||||||
100 | the click by one "page". This value is usually the same as the length of | - | ||||||||||||||||||
101 | the slider. | - | ||||||||||||||||||
102 | \endlist | - | ||||||||||||||||||
103 | \endtable | - | ||||||||||||||||||
104 | - | |||||||||||||||||||
105 | Each scroll bar has a value that indicates how far the slider is from | - | ||||||||||||||||||
106 | the start of the scroll bar; this is obtained with value() and set | - | ||||||||||||||||||
107 | with setValue(). This value always lies within the range of values | - | ||||||||||||||||||
108 | defined for the scroll bar, from \l{QAbstractSlider::minimum()}{minimum()} | - | ||||||||||||||||||
109 | to \l{QAbstractSlider::minimum()}{maximum()} inclusive. The range of | - | ||||||||||||||||||
110 | acceptable values can be set with setMinimum() and setMaximum(). | - | ||||||||||||||||||
111 | At the minimum value, the top edge of the slider (for a vertical scroll | - | ||||||||||||||||||
112 | bar) or left edge (for a horizontal scroll bar) will be at the top (or | - | ||||||||||||||||||
113 | left) end of the scroll bar. At the maximum value, the bottom (or right) | - | ||||||||||||||||||
114 | edge of the slider will be at the bottom (or right) end of the scroll bar. | - | ||||||||||||||||||
115 | - | |||||||||||||||||||
116 | The length of the slider is usually related to the value of the page step, | - | ||||||||||||||||||
117 | and typically represents the proportion of the document area shown in a | - | ||||||||||||||||||
118 | scrolling view. The page step is the amount that the value changes by | - | ||||||||||||||||||
119 | when the user presses the \uicontrol{Page Up} and \uicontrol{Page Down} keys, and is | - | ||||||||||||||||||
120 | set with setPageStep(). Smaller changes to the value defined by the | - | ||||||||||||||||||
121 | line step are made using the cursor keys, and this quantity is set with | - | ||||||||||||||||||
122 | \l{QAbstractSlider::}{setSingleStep()}. | - | ||||||||||||||||||
123 | - | |||||||||||||||||||
124 | Note that the range of values used is independent of the actual size | - | ||||||||||||||||||
125 | of the scroll bar widget. You do not need to take this into account when | - | ||||||||||||||||||
126 | you choose values for the range and the page step. | - | ||||||||||||||||||
127 | - | |||||||||||||||||||
128 | The range of values specified for the scroll bar are often determined | - | ||||||||||||||||||
129 | differently to those for a QSlider because the length of the slider | - | ||||||||||||||||||
130 | needs to be taken into account. If we have a document with 100 lines, | - | ||||||||||||||||||
131 | and we can only show 20 lines in a widget, we may wish to construct a | - | ||||||||||||||||||
132 | scroll bar with a page step of 20, a minimum value of 0, and a maximum | - | ||||||||||||||||||
133 | value of 80. This would give us a scroll bar with five "pages". | - | ||||||||||||||||||
134 | - | |||||||||||||||||||
135 | \table | - | ||||||||||||||||||
136 | \row \li \inlineimage qscrollbar-values.png | - | ||||||||||||||||||
137 | \li The relationship between a document length, the range of values used | - | ||||||||||||||||||
138 | in a scroll bar, and the page step is simple in many common situations. | - | ||||||||||||||||||
139 | The scroll bar's range of values is determined by subtracting a | - | ||||||||||||||||||
140 | chosen page step from some value representing the length of the document. | - | ||||||||||||||||||
141 | In such cases, the following equation is useful: | - | ||||||||||||||||||
142 | \e{document length} = maximum() - minimum() + pageStep(). | - | ||||||||||||||||||
143 | \endtable | - | ||||||||||||||||||
144 | - | |||||||||||||||||||
145 | QScrollBar only provides integer ranges. Note that although | - | ||||||||||||||||||
146 | QScrollBar handles very large numbers, scroll bars on current | - | ||||||||||||||||||
147 | screens cannot usefully represent ranges above about 100,000 pixels. | - | ||||||||||||||||||
148 | Beyond that, it becomes difficult for the user to control the | - | ||||||||||||||||||
149 | slider using either the keyboard or the mouse, and the scroll | - | ||||||||||||||||||
150 | arrows will have limited use. | - | ||||||||||||||||||
151 | - | |||||||||||||||||||
152 | ScrollBar inherits a comprehensive set of signals from QAbstractSlider: | - | ||||||||||||||||||
153 | \list | - | ||||||||||||||||||
154 | \li \l{QAbstractSlider::valueChanged()}{valueChanged()} is emitted when the | - | ||||||||||||||||||
155 | scroll bar's value has changed. The tracking() determines whether this | - | ||||||||||||||||||
156 | signal is emitted during user interaction. | - | ||||||||||||||||||
157 | \li \l{QAbstractSlider::rangeChanged()}{rangeChanged()} is emitted when the | - | ||||||||||||||||||
158 | scroll bar's range of values has changed. | - | ||||||||||||||||||
159 | \li \l{QAbstractSlider::sliderPressed()}{sliderPressed()} is emitted when | - | ||||||||||||||||||
160 | the user starts to drag the slider. | - | ||||||||||||||||||
161 | \li \l{QAbstractSlider::sliderMoved()}{sliderMoved()} is emitted when the user | - | ||||||||||||||||||
162 | drags the slider. | - | ||||||||||||||||||
163 | \li \l{QAbstractSlider::sliderReleased()}{sliderReleased()} is emitted when | - | ||||||||||||||||||
164 | the user releases the slider. | - | ||||||||||||||||||
165 | \li \l{QAbstractSlider::actionTriggered()}{actionTriggered()} is emitted | - | ||||||||||||||||||
166 | when the scroll bar is changed by user interaction or via the | - | ||||||||||||||||||
167 | \l{QAbstractSlider::triggerAction()}{triggerAction()} function. | - | ||||||||||||||||||
168 | \endlist | - | ||||||||||||||||||
169 | - | |||||||||||||||||||
170 | A scroll bar can be controlled by the keyboard, but it has a | - | ||||||||||||||||||
171 | default focusPolicy() of Qt::NoFocus. Use setFocusPolicy() to | - | ||||||||||||||||||
172 | enable keyboard interaction with the scroll bar: | - | ||||||||||||||||||
173 | \list | - | ||||||||||||||||||
174 | \li Left/Right move a horizontal scroll bar by one single step. | - | ||||||||||||||||||
175 | \li Up/Down move a vertical scroll bar by one single step. | - | ||||||||||||||||||
176 | \li PageUp moves up one page. | - | ||||||||||||||||||
177 | \li PageDown moves down one page. | - | ||||||||||||||||||
178 | \li Home moves to the start (mininum). | - | ||||||||||||||||||
179 | \li End moves to the end (maximum). | - | ||||||||||||||||||
180 | \endlist | - | ||||||||||||||||||
181 | - | |||||||||||||||||||
182 | The slider itself can be controlled by using the | - | ||||||||||||||||||
183 | \l{QAbstractSlider::triggerAction()}{triggerAction()} function to simulate | - | ||||||||||||||||||
184 | user interaction with the scroll bar controls. This is useful if you have | - | ||||||||||||||||||
185 | many different widgets that use a common range of values. | - | ||||||||||||||||||
186 | - | |||||||||||||||||||
187 | Most GUI styles use the pageStep() value to calculate the size of the | - | ||||||||||||||||||
188 | slider. | - | ||||||||||||||||||
189 | - | |||||||||||||||||||
190 | \table 100% | - | ||||||||||||||||||
191 | \row \li \inlineimage macintosh-horizontalscrollbar.png Screenshot of a Macintosh style scroll bar | - | ||||||||||||||||||
192 | \li A scroll bar shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}. | - | ||||||||||||||||||
193 | \row \li \inlineimage windowsvista-horizontalscrollbar.png Screenshot of a Windows Vista style scroll bar | - | ||||||||||||||||||
194 | \li A scroll bar shown in the \l{Windows Vista Style Widget Gallery}{Windows Vista widget style}. | - | ||||||||||||||||||
195 | \row \li \inlineimage fusion-horizontalscrollbar.png Screenshot of a Fusion style scroll bar | - | ||||||||||||||||||
196 | \li A scroll bar shown in the \l{Fusion Style Widget Gallery}{Fusion widget style}. | - | ||||||||||||||||||
197 | \endtable | - | ||||||||||||||||||
198 | - | |||||||||||||||||||
199 | \sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example} | - | ||||||||||||||||||
200 | */ | - | ||||||||||||||||||
201 | - | |||||||||||||||||||
202 | bool QScrollBarPrivate::updateHoverControl(const QPoint &pos) | - | ||||||||||||||||||
203 | { | - | ||||||||||||||||||
204 | Q_Q(QScrollBar); | - | ||||||||||||||||||
205 | QRect lastHoverRect = hoverRect; | - | ||||||||||||||||||
206 | QStyle::SubControl lastHoverControl = hoverControl; | - | ||||||||||||||||||
207 | bool doesHover = q->testAttribute(Qt::WA_Hover); | - | ||||||||||||||||||
208 | if (lastHoverControl != newHoverControl(pos) && doesHover) {
| 0 | ||||||||||||||||||
209 | q->update(lastHoverRect); | - | ||||||||||||||||||
210 | q->update(hoverRect); | - | ||||||||||||||||||
211 | return true; never executed: return true; | 0 | ||||||||||||||||||
212 | } | - | ||||||||||||||||||
213 | return !doesHover; never executed: return !doesHover; | 0 | ||||||||||||||||||
214 | } | - | ||||||||||||||||||
215 | - | |||||||||||||||||||
216 | QStyle::SubControl QScrollBarPrivate::newHoverControl(const QPoint &pos) | - | ||||||||||||||||||
217 | { | - | ||||||||||||||||||
218 | Q_Q(QScrollBar); | - | ||||||||||||||||||
219 | QStyleOptionSlider opt; | - | ||||||||||||||||||
220 | q->initStyleOption(&opt); | - | ||||||||||||||||||
221 | opt.subControls = QStyle::SC_All; | - | ||||||||||||||||||
222 | hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, pos, q); | - | ||||||||||||||||||
223 | if (hoverControl == QStyle::SC_None)
| 0 | ||||||||||||||||||
224 | hoverRect = QRect(); never executed: hoverRect = QRect(); | 0 | ||||||||||||||||||
225 | else | - | ||||||||||||||||||
226 | hoverRect = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, hoverControl, q); never executed: hoverRect = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, hoverControl, q); | 0 | ||||||||||||||||||
227 | return hoverControl; never executed: return hoverControl; | 0 | ||||||||||||||||||
228 | } | - | ||||||||||||||||||
229 | - | |||||||||||||||||||
230 | void QScrollBarPrivate::setTransient(bool value) | - | ||||||||||||||||||
231 | { | - | ||||||||||||||||||
232 | Q_Q(QScrollBar); | - | ||||||||||||||||||
233 | if (transient != value) {
| 0 | ||||||||||||||||||
234 | transient = value; | - | ||||||||||||||||||
235 | if (q->isVisible()) {
| 0 | ||||||||||||||||||
236 | if (q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, q))
| 0 | ||||||||||||||||||
237 | q->update(); never executed: q->update(); | 0 | ||||||||||||||||||
238 | } else if (!transient) { never executed: end of block
| 0 | ||||||||||||||||||
239 | q->show(); | - | ||||||||||||||||||
240 | } never executed: end of block | 0 | ||||||||||||||||||
241 | } never executed: end of block | 0 | ||||||||||||||||||
242 | } never executed: end of block | 0 | ||||||||||||||||||
243 | - | |||||||||||||||||||
244 | void QScrollBarPrivate::flash() | - | ||||||||||||||||||
245 | { | - | ||||||||||||||||||
246 | Q_Q(QScrollBar); | - | ||||||||||||||||||
247 | if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, q)) {
| 0 | ||||||||||||||||||
248 | flashed = true; | - | ||||||||||||||||||
249 | if (!q->isVisible())
| 0 | ||||||||||||||||||
250 | q->show(); never executed: q->show(); | 0 | ||||||||||||||||||
251 | else | - | ||||||||||||||||||
252 | q->update(); never executed: q->update(); | 0 | ||||||||||||||||||
253 | } | - | ||||||||||||||||||
254 | if (!flashTimer)
| 0 | ||||||||||||||||||
255 | flashTimer = q->startTimer(0); never executed: flashTimer = q->startTimer(0); | 0 | ||||||||||||||||||
256 | } never executed: end of block | 0 | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | void QScrollBarPrivate::activateControl(uint control, int threshold) | - | ||||||||||||||||||
259 | { | - | ||||||||||||||||||
260 | QAbstractSlider::SliderAction action = QAbstractSlider::SliderNoAction; | - | ||||||||||||||||||
261 | switch (control) { | - | ||||||||||||||||||
262 | case QStyle::SC_ScrollBarAddPage: never executed: case QStyle::SC_ScrollBarAddPage: | 0 | ||||||||||||||||||
263 | action = QAbstractSlider::SliderPageStepAdd; | - | ||||||||||||||||||
264 | break; never executed: break; | 0 | ||||||||||||||||||
265 | case QStyle::SC_ScrollBarSubPage: never executed: case QStyle::SC_ScrollBarSubPage: | 0 | ||||||||||||||||||
266 | action = QAbstractSlider::SliderPageStepSub; | - | ||||||||||||||||||
267 | break; never executed: break; | 0 | ||||||||||||||||||
268 | case QStyle::SC_ScrollBarAddLine: never executed: case QStyle::SC_ScrollBarAddLine: | 0 | ||||||||||||||||||
269 | action = QAbstractSlider::SliderSingleStepAdd; | - | ||||||||||||||||||
270 | break; never executed: break; | 0 | ||||||||||||||||||
271 | case QStyle::SC_ScrollBarSubLine: never executed: case QStyle::SC_ScrollBarSubLine: | 0 | ||||||||||||||||||
272 | action = QAbstractSlider::SliderSingleStepSub; | - | ||||||||||||||||||
273 | break; never executed: break; | 0 | ||||||||||||||||||
274 | case QStyle::SC_ScrollBarFirst: never executed: case QStyle::SC_ScrollBarFirst: | 0 | ||||||||||||||||||
275 | action = QAbstractSlider::SliderToMinimum; | - | ||||||||||||||||||
276 | break; never executed: break; | 0 | ||||||||||||||||||
277 | case QStyle::SC_ScrollBarLast: never executed: case QStyle::SC_ScrollBarLast: | 0 | ||||||||||||||||||
278 | action = QAbstractSlider::SliderToMaximum; | - | ||||||||||||||||||
279 | break; never executed: break; | 0 | ||||||||||||||||||
280 | default: never executed: default: | 0 | ||||||||||||||||||
281 | break; never executed: break; | 0 | ||||||||||||||||||
282 | } | - | ||||||||||||||||||
283 | - | |||||||||||||||||||
284 | if (action) {
| 0 | ||||||||||||||||||
285 | q_func()->setRepeatAction(action, threshold); | - | ||||||||||||||||||
286 | q_func()->triggerAction(action); | - | ||||||||||||||||||
287 | } never executed: end of block | 0 | ||||||||||||||||||
288 | } never executed: end of block | 0 | ||||||||||||||||||
289 | - | |||||||||||||||||||
290 | void QScrollBarPrivate::stopRepeatAction() | - | ||||||||||||||||||
291 | { | - | ||||||||||||||||||
292 | Q_Q(QScrollBar); | - | ||||||||||||||||||
293 | QStyle::SubControl tmp = pressedControl; | - | ||||||||||||||||||
294 | q->setRepeatAction(QAbstractSlider::SliderNoAction); | - | ||||||||||||||||||
295 | pressedControl = QStyle::SC_None; | - | ||||||||||||||||||
296 | - | |||||||||||||||||||
297 | if (tmp == QStyle::SC_ScrollBarSlider)
| 0 | ||||||||||||||||||
298 | q->setSliderDown(false); never executed: q->setSliderDown(false); | 0 | ||||||||||||||||||
299 | - | |||||||||||||||||||
300 | QStyleOptionSlider opt; | - | ||||||||||||||||||
301 | q->initStyleOption(&opt); | - | ||||||||||||||||||
302 | q->repaint(q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, tmp, q)); | - | ||||||||||||||||||
303 | } never executed: end of block | 0 | ||||||||||||||||||
304 | - | |||||||||||||||||||
305 | /*! | - | ||||||||||||||||||
306 | Initialize \a option with the values from this QScrollBar. This method | - | ||||||||||||||||||
307 | is useful for subclasses when they need a QStyleOptionSlider, but don't want | - | ||||||||||||||||||
308 | to fill in all the information themselves. | - | ||||||||||||||||||
309 | - | |||||||||||||||||||
310 | \sa QStyleOption::initFrom() | - | ||||||||||||||||||
311 | */ | - | ||||||||||||||||||
312 | void QScrollBar::initStyleOption(QStyleOptionSlider *option) const | - | ||||||||||||||||||
313 | { | - | ||||||||||||||||||
314 | if (!option)
| 0 | ||||||||||||||||||
315 | return; never executed: return; | 0 | ||||||||||||||||||
316 | - | |||||||||||||||||||
317 | Q_D(const QScrollBar); | - | ||||||||||||||||||
318 | option->initFrom(this); | - | ||||||||||||||||||
319 | option->subControls = QStyle::SC_None; | - | ||||||||||||||||||
320 | option->activeSubControls = QStyle::SC_None; | - | ||||||||||||||||||
321 | option->orientation = d->orientation; | - | ||||||||||||||||||
322 | option->minimum = d->minimum; | - | ||||||||||||||||||
323 | option->maximum = d->maximum; | - | ||||||||||||||||||
324 | option->sliderPosition = d->position; | - | ||||||||||||||||||
325 | option->sliderValue = d->value; | - | ||||||||||||||||||
326 | option->singleStep = d->singleStep; | - | ||||||||||||||||||
327 | option->pageStep = d->pageStep; | - | ||||||||||||||||||
328 | option->upsideDown = d->invertedAppearance; | - | ||||||||||||||||||
329 | if (d->orientation == Qt::Horizontal)
| 0 | ||||||||||||||||||
330 | option->state |= QStyle::State_Horizontal; never executed: option->state |= QStyle::State_Horizontal; | 0 | ||||||||||||||||||
331 | if ((d->flashed || !d->transient) && style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this))
| 0 | ||||||||||||||||||
332 | option->state |= QStyle::State_On; never executed: option->state |= QStyle::State_On; | 0 | ||||||||||||||||||
333 | } never executed: end of block | 0 | ||||||||||||||||||
334 | - | |||||||||||||||||||
335 | - | |||||||||||||||||||
336 | #define HORIZONTAL (d_func()->orientation == Qt::Horizontal) | - | ||||||||||||||||||
337 | #define VERTICAL !HORIZONTAL | - | ||||||||||||||||||
338 | - | |||||||||||||||||||
339 | /*! | - | ||||||||||||||||||
340 | Constructs a vertical scroll bar. | - | ||||||||||||||||||
341 | - | |||||||||||||||||||
342 | The \a parent argument is sent to the QWidget constructor. | - | ||||||||||||||||||
343 | - | |||||||||||||||||||
344 | The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the | - | ||||||||||||||||||
345 | \l {QAbstractSlider::maximum} {maximum} to 99, with a | - | ||||||||||||||||||
346 | \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a | - | ||||||||||||||||||
347 | \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an | - | ||||||||||||||||||
348 | initial \l {QAbstractSlider::value} {value} of 0. | - | ||||||||||||||||||
349 | */ | - | ||||||||||||||||||
350 | QScrollBar::QScrollBar(QWidget *parent) | - | ||||||||||||||||||
351 | : QAbstractSlider(*new QScrollBarPrivate, parent) | - | ||||||||||||||||||
352 | { | - | ||||||||||||||||||
353 | d_func()->orientation = Qt::Vertical; | - | ||||||||||||||||||
354 | d_func()->init(); | - | ||||||||||||||||||
355 | } never executed: end of block | 0 | ||||||||||||||||||
356 | - | |||||||||||||||||||
357 | /*! | - | ||||||||||||||||||
358 | Constructs a scroll bar with the given \a orientation. | - | ||||||||||||||||||
359 | - | |||||||||||||||||||
360 | The \a parent argument is passed to the QWidget constructor. | - | ||||||||||||||||||
361 | - | |||||||||||||||||||
362 | The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the | - | ||||||||||||||||||
363 | \l {QAbstractSlider::maximum} {maximum} to 99, with a | - | ||||||||||||||||||
364 | \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a | - | ||||||||||||||||||
365 | \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an | - | ||||||||||||||||||
366 | initial \l {QAbstractSlider::value} {value} of 0. | - | ||||||||||||||||||
367 | */ | - | ||||||||||||||||||
368 | QScrollBar::QScrollBar(Qt::Orientation orientation, QWidget *parent) | - | ||||||||||||||||||
369 | : QAbstractSlider(*new QScrollBarPrivate, parent) | - | ||||||||||||||||||
370 | { | - | ||||||||||||||||||
371 | d_func()->orientation = orientation; | - | ||||||||||||||||||
372 | d_func()->init(); | - | ||||||||||||||||||
373 | } never executed: end of block | 0 | ||||||||||||||||||
374 | - | |||||||||||||||||||
375 | - | |||||||||||||||||||
376 | - | |||||||||||||||||||
377 | /*! | - | ||||||||||||||||||
378 | Destroys the scroll bar. | - | ||||||||||||||||||
379 | */ | - | ||||||||||||||||||
380 | QScrollBar::~QScrollBar() | - | ||||||||||||||||||
381 | { | - | ||||||||||||||||||
382 | } | - | ||||||||||||||||||
383 | - | |||||||||||||||||||
384 | void QScrollBarPrivate::init() | - | ||||||||||||||||||
385 | { | - | ||||||||||||||||||
386 | Q_Q(QScrollBar); | - | ||||||||||||||||||
387 | invertedControls = true; | - | ||||||||||||||||||
388 | pressedControl = hoverControl = QStyle::SC_None; | - | ||||||||||||||||||
389 | pointerOutsidePressedControl = false; | - | ||||||||||||||||||
390 | transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, q); | - | ||||||||||||||||||
391 | flashed = false; | - | ||||||||||||||||||
392 | flashTimer = 0; | - | ||||||||||||||||||
393 | q->setFocusPolicy(Qt::NoFocus); | - | ||||||||||||||||||
394 | QSizePolicy sp(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Slider); | - | ||||||||||||||||||
395 | if (orientation == Qt::Vertical)
| 0 | ||||||||||||||||||
396 | sp.transpose(); never executed: sp.transpose(); | 0 | ||||||||||||||||||
397 | q->setSizePolicy(sp); | - | ||||||||||||||||||
398 | q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); | - | ||||||||||||||||||
399 | q->setAttribute(Qt::WA_OpaquePaintEvent); | - | ||||||||||||||||||
400 | - | |||||||||||||||||||
401 | #if !defined(QT_NO_CONTEXTMENU) && defined(Q_OS_WINCE) | - | ||||||||||||||||||
402 | if (!q->style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, q)) { | - | ||||||||||||||||||
403 | q->setContextMenuPolicy(Qt::PreventContextMenu); | - | ||||||||||||||||||
404 | } | - | ||||||||||||||||||
405 | #endif | - | ||||||||||||||||||
406 | } never executed: end of block | 0 | ||||||||||||||||||
407 | - | |||||||||||||||||||
408 | #ifndef QT_NO_CONTEXTMENU | - | ||||||||||||||||||
409 | /*! \reimp */ | - | ||||||||||||||||||
410 | void QScrollBar::contextMenuEvent(QContextMenuEvent *event) | - | ||||||||||||||||||
411 | { | - | ||||||||||||||||||
412 | if (!style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, this)) {
| 0 | ||||||||||||||||||
413 | QAbstractSlider::contextMenuEvent(event); | - | ||||||||||||||||||
414 | return ; never executed: return ; | 0 | ||||||||||||||||||
415 | } | - | ||||||||||||||||||
416 | - | |||||||||||||||||||
417 | #ifndef QT_NO_MENU | - | ||||||||||||||||||
418 | bool horiz = HORIZONTAL; | - | ||||||||||||||||||
419 | QPointer<QMenu> menu = new QMenu(this); | - | ||||||||||||||||||
420 | QAction *actScrollHere = menu->addAction(tr("Scroll here")); | - | ||||||||||||||||||
421 | menu->addSeparator(); | - | ||||||||||||||||||
422 | QAction *actScrollTop = menu->addAction(horiz ? tr("Left edge") : tr("Top")); | - | ||||||||||||||||||
423 | QAction *actScrollBottom = menu->addAction(horiz ? tr("Right edge") : tr("Bottom")); | - | ||||||||||||||||||
424 | menu->addSeparator(); | - | ||||||||||||||||||
425 | QAction *actPageUp = menu->addAction(horiz ? tr("Page left") : tr("Page up")); | - | ||||||||||||||||||
426 | QAction *actPageDn = menu->addAction(horiz ? tr("Page right") : tr("Page down")); | - | ||||||||||||||||||
427 | menu->addSeparator(); | - | ||||||||||||||||||
428 | QAction *actScrollUp = menu->addAction(horiz ? tr("Scroll left") : tr("Scroll up")); | - | ||||||||||||||||||
429 | QAction *actScrollDn = menu->addAction(horiz ? tr("Scroll right") : tr("Scroll down")); | - | ||||||||||||||||||
430 | QAction *actionSelected = menu->exec(event->globalPos()); | - | ||||||||||||||||||
431 | delete menu; | - | ||||||||||||||||||
432 | if (actionSelected == 0)
| 0 | ||||||||||||||||||
433 | /* do nothing */ ; never executed: ; | 0 | ||||||||||||||||||
434 | else if (actionSelected == actScrollHere)
| 0 | ||||||||||||||||||
435 | setValue(d_func()->pixelPosToRangeValue(horiz ? event->pos().x() : event->pos().y())); never executed: setValue(d_func()->pixelPosToRangeValue(horiz ? event->pos().x() : event->pos().y())); | 0 | ||||||||||||||||||
436 | else if (actionSelected == actScrollTop)
| 0 | ||||||||||||||||||
437 | triggerAction(QAbstractSlider::SliderToMinimum); never executed: triggerAction(QAbstractSlider::SliderToMinimum); | 0 | ||||||||||||||||||
438 | else if (actionSelected == actScrollBottom)
| 0 | ||||||||||||||||||
439 | triggerAction(QAbstractSlider::SliderToMaximum); never executed: triggerAction(QAbstractSlider::SliderToMaximum); | 0 | ||||||||||||||||||
440 | else if (actionSelected == actPageUp)
| 0 | ||||||||||||||||||
441 | triggerAction(QAbstractSlider::SliderPageStepSub); never executed: triggerAction(QAbstractSlider::SliderPageStepSub); | 0 | ||||||||||||||||||
442 | else if (actionSelected == actPageDn)
| 0 | ||||||||||||||||||
443 | triggerAction(QAbstractSlider::SliderPageStepAdd); never executed: triggerAction(QAbstractSlider::SliderPageStepAdd); | 0 | ||||||||||||||||||
444 | else if (actionSelected == actScrollUp)
| 0 | ||||||||||||||||||
445 | triggerAction(QAbstractSlider::SliderSingleStepSub); never executed: triggerAction(QAbstractSlider::SliderSingleStepSub); | 0 | ||||||||||||||||||
446 | else if (actionSelected == actScrollDn)
| 0 | ||||||||||||||||||
447 | triggerAction(QAbstractSlider::SliderSingleStepAdd); never executed: triggerAction(QAbstractSlider::SliderSingleStepAdd); | 0 | ||||||||||||||||||
448 | #endif // QT_NO_MENU | - | ||||||||||||||||||
449 | } never executed: end of block | 0 | ||||||||||||||||||
450 | #endif // QT_NO_CONTEXTMENU | - | ||||||||||||||||||
451 | - | |||||||||||||||||||
452 | - | |||||||||||||||||||
453 | /*! \reimp */ | - | ||||||||||||||||||
454 | QSize QScrollBar::sizeHint() const | - | ||||||||||||||||||
455 | { | - | ||||||||||||||||||
456 | ensurePolished(); | - | ||||||||||||||||||
457 | QStyleOptionSlider opt; | - | ||||||||||||||||||
458 | initStyleOption(&opt); | - | ||||||||||||||||||
459 | - | |||||||||||||||||||
460 | int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt, this); | - | ||||||||||||||||||
461 | int scrollBarSliderMin = style()->pixelMetric(QStyle::PM_ScrollBarSliderMin, &opt, this); | - | ||||||||||||||||||
462 | QSize size; | - | ||||||||||||||||||
463 | if (opt.orientation == Qt::Horizontal)
| 0 | ||||||||||||||||||
464 | size = QSize(scrollBarExtent * 2 + scrollBarSliderMin, scrollBarExtent); never executed: size = QSize(scrollBarExtent * 2 + scrollBarSliderMin, scrollBarExtent); | 0 | ||||||||||||||||||
465 | else | - | ||||||||||||||||||
466 | size = QSize(scrollBarExtent, scrollBarExtent * 2 + scrollBarSliderMin); never executed: size = QSize(scrollBarExtent, scrollBarExtent * 2 + scrollBarSliderMin); | 0 | ||||||||||||||||||
467 | - | |||||||||||||||||||
468 | return style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, size, this) never executed: return style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, size, this) .expandedTo(QApplication::globalStrut()); | 0 | ||||||||||||||||||
469 | .expandedTo(QApplication::globalStrut()); never executed: return style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, size, this) .expandedTo(QApplication::globalStrut()); | 0 | ||||||||||||||||||
470 | } | - | ||||||||||||||||||
471 | - | |||||||||||||||||||
472 | /*!\reimp */ | - | ||||||||||||||||||
473 | void QScrollBar::sliderChange(SliderChange change) | - | ||||||||||||||||||
474 | { | - | ||||||||||||||||||
475 | QAbstractSlider::sliderChange(change); | - | ||||||||||||||||||
476 | } never executed: end of block | 0 | ||||||||||||||||||
477 | - | |||||||||||||||||||
478 | /*! | - | ||||||||||||||||||
479 | \reimp | - | ||||||||||||||||||
480 | */ | - | ||||||||||||||||||
481 | bool QScrollBar::event(QEvent *event) | - | ||||||||||||||||||
482 | { | - | ||||||||||||||||||
483 | Q_D(QScrollBar); | - | ||||||||||||||||||
484 | switch(event->type()) { | - | ||||||||||||||||||
485 | case QEvent::HoverEnter: never executed: case QEvent::HoverEnter: | 0 | ||||||||||||||||||
486 | case QEvent::HoverLeave: never executed: case QEvent::HoverLeave: | 0 | ||||||||||||||||||
487 | case QEvent::HoverMove: never executed: case QEvent::HoverMove: | 0 | ||||||||||||||||||
488 | if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
| 0 | ||||||||||||||||||
489 | d_func()->updateHoverControl(he->pos()); never executed: d_func()->updateHoverControl(he->pos()); | 0 | ||||||||||||||||||
490 | break; never executed: break; | 0 | ||||||||||||||||||
491 | case QEvent::StyleChange: never executed: case QEvent::StyleChange: | 0 | ||||||||||||||||||
492 | d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)); | - | ||||||||||||||||||
493 | break; never executed: break; | 0 | ||||||||||||||||||
494 | case QEvent::Timer: never executed: case QEvent::Timer: | 0 | ||||||||||||||||||
495 | if (static_cast<QTimerEvent *>(event)->timerId() == d->flashTimer) {
| 0 | ||||||||||||||||||
496 | if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)) {
| 0 | ||||||||||||||||||
497 | d->flashed = false; | - | ||||||||||||||||||
498 | update(); | - | ||||||||||||||||||
499 | } never executed: end of block | 0 | ||||||||||||||||||
500 | killTimer(d->flashTimer); | - | ||||||||||||||||||
501 | d->flashTimer = 0; | - | ||||||||||||||||||
502 | } never executed: end of block | 0 | ||||||||||||||||||
503 | break; never executed: break; | 0 | ||||||||||||||||||
504 | default: never executed: default: | 0 | ||||||||||||||||||
505 | break; never executed: break; | 0 | ||||||||||||||||||
506 | } | - | ||||||||||||||||||
507 | return QAbstractSlider::event(event); never executed: return QAbstractSlider::event(event); | 0 | ||||||||||||||||||
508 | } | - | ||||||||||||||||||
509 | - | |||||||||||||||||||
510 | /*! | - | ||||||||||||||||||
511 | \reimp | - | ||||||||||||||||||
512 | */ | - | ||||||||||||||||||
513 | #ifndef QT_NO_WHEELEVENT | - | ||||||||||||||||||
514 | void QScrollBar::wheelEvent(QWheelEvent *event) | - | ||||||||||||||||||
515 | { | - | ||||||||||||||||||
516 | event->ignore(); | - | ||||||||||||||||||
517 | int delta = event->delta(); | - | ||||||||||||||||||
518 | // scrollbar is a special case - in vertical mode it reaches minimum | - | ||||||||||||||||||
519 | // value in the upper position, however QSlider's minimum value is on | - | ||||||||||||||||||
520 | // the bottom. So we need to invert a value, but since the scrollbar is | - | ||||||||||||||||||
521 | // inverted by default, we need to inverse the delta value for the | - | ||||||||||||||||||
522 | // horizontal orientation. | - | ||||||||||||||||||
523 | if (event->orientation() == Qt::Horizontal)
| 0 | ||||||||||||||||||
524 | delta = -delta; never executed: delta = -delta; | 0 | ||||||||||||||||||
525 | Q_D(QScrollBar); | - | ||||||||||||||||||
526 | if (d->scrollByDelta(event->orientation(), event->modifiers(), delta))
| 0 | ||||||||||||||||||
527 | event->accept(); never executed: event->accept(); | 0 | ||||||||||||||||||
528 | - | |||||||||||||||||||
529 | if (event->phase() == Qt::ScrollBegin)
| 0 | ||||||||||||||||||
530 | d->setTransient(false); never executed: d->setTransient(false); | 0 | ||||||||||||||||||
531 | else if (event->phase() == Qt::ScrollEnd)
| 0 | ||||||||||||||||||
532 | d->setTransient(true); never executed: d->setTransient(true); | 0 | ||||||||||||||||||
533 | } never executed: end of block | 0 | ||||||||||||||||||
534 | #endif | - | ||||||||||||||||||
535 | - | |||||||||||||||||||
536 | /*! | - | ||||||||||||||||||
537 | \reimp | - | ||||||||||||||||||
538 | */ | - | ||||||||||||||||||
539 | void QScrollBar::paintEvent(QPaintEvent *) | - | ||||||||||||||||||
540 | { | - | ||||||||||||||||||
541 | Q_D(QScrollBar); | - | ||||||||||||||||||
542 | QPainter p(this); | - | ||||||||||||||||||
543 | QStyleOptionSlider opt; | - | ||||||||||||||||||
544 | initStyleOption(&opt); | - | ||||||||||||||||||
545 | opt.subControls = QStyle::SC_All; | - | ||||||||||||||||||
546 | if (d->pressedControl) {
| 0 | ||||||||||||||||||
547 | opt.activeSubControls = (QStyle::SubControl)d->pressedControl; | - | ||||||||||||||||||
548 | if (!d->pointerOutsidePressedControl)
| 0 | ||||||||||||||||||
549 | opt.state |= QStyle::State_Sunken; never executed: opt.state |= QStyle::State_Sunken; | 0 | ||||||||||||||||||
550 | } else { never executed: end of block | 0 | ||||||||||||||||||
551 | opt.activeSubControls = (QStyle::SubControl)d->hoverControl; | - | ||||||||||||||||||
552 | } never executed: end of block | 0 | ||||||||||||||||||
553 | style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this); | - | ||||||||||||||||||
554 | } never executed: end of block | 0 | ||||||||||||||||||
555 | - | |||||||||||||||||||
556 | /*! | - | ||||||||||||||||||
557 | \reimp | - | ||||||||||||||||||
558 | */ | - | ||||||||||||||||||
559 | void QScrollBar::mousePressEvent(QMouseEvent *e) | - | ||||||||||||||||||
560 | { | - | ||||||||||||||||||
561 | Q_D(QScrollBar); | - | ||||||||||||||||||
562 | - | |||||||||||||||||||
563 | if (d->repeatActionTimer.isActive())
| 0 | ||||||||||||||||||
564 | d->stopRepeatAction(); never executed: d->stopRepeatAction(); | 0 | ||||||||||||||||||
565 | - | |||||||||||||||||||
566 | bool midButtonAbsPos = style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition, | - | ||||||||||||||||||
567 | 0, this); | - | ||||||||||||||||||
568 | QStyleOptionSlider opt; | - | ||||||||||||||||||
569 | initStyleOption(&opt); | - | ||||||||||||||||||
570 | - | |||||||||||||||||||
571 | if (d->maximum == d->minimum // no range
| 0 | ||||||||||||||||||
572 | || (e->buttons() & (~e->button())) // another button was clicked before
| 0 | ||||||||||||||||||
573 | || !(e->button() == Qt::LeftButton || (midButtonAbsPos && e->button() == Qt::MidButton)))
| 0 | ||||||||||||||||||
574 | return; never executed: return; | 0 | ||||||||||||||||||
575 | - | |||||||||||||||||||
576 | d->pressedControl = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this); | - | ||||||||||||||||||
577 | d->pointerOutsidePressedControl = false; | - | ||||||||||||||||||
578 | - | |||||||||||||||||||
579 | QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, | - | ||||||||||||||||||
580 | QStyle::SC_ScrollBarSlider, this); | - | ||||||||||||||||||
581 | QPoint click = e->pos(); | - | ||||||||||||||||||
582 | QPoint pressValue = click - sr.center() + sr.topLeft(); | - | ||||||||||||||||||
583 | d->pressValue = d->orientation == Qt::Horizontal ? d->pixelPosToRangeValue(pressValue.x()) :
| 0 | ||||||||||||||||||
584 | d->pixelPosToRangeValue(pressValue.y()); | - | ||||||||||||||||||
585 | if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
| 0 | ||||||||||||||||||
586 | d->clickOffset = HORIZONTAL ? (click.x()-sr.x()) : (click.y()-sr.y());
| 0 | ||||||||||||||||||
587 | d->snapBackPosition = d->position; | - | ||||||||||||||||||
588 | } never executed: end of block | 0 | ||||||||||||||||||
589 | - | |||||||||||||||||||
590 | if ((d->pressedControl == QStyle::SC_ScrollBarAddPage
| 0 | ||||||||||||||||||
591 | || d->pressedControl == QStyle::SC_ScrollBarSubPage)
| 0 | ||||||||||||||||||
592 | && ((midButtonAbsPos && e->button() == Qt::MidButton)
| 0 | ||||||||||||||||||
593 | || (style()->styleHint(QStyle::SH_ScrollBar_LeftClickAbsolutePosition, &opt, this)
| 0 | ||||||||||||||||||
594 | && e->button() == Qt::LeftButton))) {
| 0 | ||||||||||||||||||
595 | int sliderLength = HORIZONTAL ? sr.width() : sr.height();
| 0 | ||||||||||||||||||
596 | setSliderPosition(d->pixelPosToRangeValue((HORIZONTAL ? e->pos().x() | - | ||||||||||||||||||
597 | : e->pos().y()) - sliderLength / 2)); | - | ||||||||||||||||||
598 | d->pressedControl = QStyle::SC_ScrollBarSlider; | - | ||||||||||||||||||
599 | d->clickOffset = sliderLength / 2; | - | ||||||||||||||||||
600 | } never executed: end of block | 0 | ||||||||||||||||||
601 | const int initialDelay = 500; // default threshold | - | ||||||||||||||||||
602 | QElapsedTimer time; | - | ||||||||||||||||||
603 | time.start(); | - | ||||||||||||||||||
604 | d->activateControl(d->pressedControl, initialDelay); | - | ||||||||||||||||||
605 | repaint(style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this)); | - | ||||||||||||||||||
606 | if (time.elapsed() >= initialDelay && d->repeatActionTimer.isActive()) {
| 0 | ||||||||||||||||||
607 | // It took more than 500ms (the initial timer delay) to process | - | ||||||||||||||||||
608 | // the control activation and repaint(), we therefore need | - | ||||||||||||||||||
609 | // to restart the timer in case we have a pending mouse release event; | - | ||||||||||||||||||
610 | // otherwise we'll get a timer event right before the release event, | - | ||||||||||||||||||
611 | // causing the repeat action to be invoked twice on a single mouse click. | - | ||||||||||||||||||
612 | // 50ms is the default repeat time (see activateControl/setRepeatAction). | - | ||||||||||||||||||
613 | d->repeatActionTimer.start(50, this); | - | ||||||||||||||||||
614 | } never executed: end of block | 0 | ||||||||||||||||||
615 | if (d->pressedControl == QStyle::SC_ScrollBarSlider)
| 0 | ||||||||||||||||||
616 | setSliderDown(true); never executed: setSliderDown(true); | 0 | ||||||||||||||||||
617 | } never executed: end of block | 0 | ||||||||||||||||||
618 | - | |||||||||||||||||||
619 | - | |||||||||||||||||||
620 | /*! | - | ||||||||||||||||||
621 | \reimp | - | ||||||||||||||||||
622 | */ | - | ||||||||||||||||||
623 | void QScrollBar::mouseReleaseEvent(QMouseEvent *e) | - | ||||||||||||||||||
624 | { | - | ||||||||||||||||||
625 | Q_D(QScrollBar); | - | ||||||||||||||||||
626 | if (!d->pressedControl)
| 0 | ||||||||||||||||||
627 | return; never executed: return; | 0 | ||||||||||||||||||
628 | - | |||||||||||||||||||
629 | if (e->buttons() & (~e->button())) // some other button is still pressed
| 0 | ||||||||||||||||||
630 | return; never executed: return; | 0 | ||||||||||||||||||
631 | - | |||||||||||||||||||
632 | d->stopRepeatAction(); | - | ||||||||||||||||||
633 | } never executed: end of block | 0 | ||||||||||||||||||
634 | - | |||||||||||||||||||
635 | - | |||||||||||||||||||
636 | /*! | - | ||||||||||||||||||
637 | \reimp | - | ||||||||||||||||||
638 | */ | - | ||||||||||||||||||
639 | void QScrollBar::mouseMoveEvent(QMouseEvent *e) | - | ||||||||||||||||||
640 | { | - | ||||||||||||||||||
641 | Q_D(QScrollBar); | - | ||||||||||||||||||
642 | if (!d->pressedControl)
| 0 | ||||||||||||||||||
643 | return; never executed: return; | 0 | ||||||||||||||||||
644 | - | |||||||||||||||||||
645 | QStyleOptionSlider opt; | - | ||||||||||||||||||
646 | initStyleOption(&opt); | - | ||||||||||||||||||
647 | if (!(e->buttons() & Qt::LeftButton
| 0 | ||||||||||||||||||
648 | || ((e->buttons() & Qt::MidButton)
| 0 | ||||||||||||||||||
649 | && style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition, &opt, this))))
| 0 | ||||||||||||||||||
650 | return; never executed: return; | 0 | ||||||||||||||||||
651 | - | |||||||||||||||||||
652 | if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
| 0 | ||||||||||||||||||
653 | QPoint click = e->pos(); | - | ||||||||||||||||||
654 | int newPosition = d->pixelPosToRangeValue((HORIZONTAL ? click.x() : click.y()) -d->clickOffset); | - | ||||||||||||||||||
655 | int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); | - | ||||||||||||||||||
656 | if (m >= 0) {
| 0 | ||||||||||||||||||
657 | QRect r = rect(); | - | ||||||||||||||||||
658 | r.adjust(-m, -m, m, m); | - | ||||||||||||||||||
659 | if (! r.contains(e->pos()))
| 0 | ||||||||||||||||||
660 | newPosition = d->snapBackPosition; never executed: newPosition = d->snapBackPosition; | 0 | ||||||||||||||||||
661 | } never executed: end of block | 0 | ||||||||||||||||||
662 | setSliderPosition(newPosition); | - | ||||||||||||||||||
663 | } else if (!style()->styleHint(QStyle::SH_ScrollBar_ScrollWhenPointerLeavesControl, &opt, this)) { never executed: end of block
| 0 | ||||||||||||||||||
664 | - | |||||||||||||||||||
665 | if (style()->styleHint(QStyle::SH_ScrollBar_RollBetweenButtons, &opt, this)
| 0 | ||||||||||||||||||
666 | && d->pressedControl & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
| 0 | ||||||||||||||||||
667 | QStyle::SubControl newSc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this); | - | ||||||||||||||||||
668 | if (newSc == d->pressedControl && !d->pointerOutsidePressedControl)
| 0 | ||||||||||||||||||
669 | return; // nothing to do never executed: return; | 0 | ||||||||||||||||||
670 | if (newSc & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
| 0 | ||||||||||||||||||
671 | d->pointerOutsidePressedControl = false; | - | ||||||||||||||||||
672 | QRect scRect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, newSc, this); | - | ||||||||||||||||||
673 | scRect |= style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this); | - | ||||||||||||||||||
674 | d->pressedControl = newSc; | - | ||||||||||||||||||
675 | d->activateControl(d->pressedControl, 0); | - | ||||||||||||||||||
676 | update(scRect); | - | ||||||||||||||||||
677 | return; never executed: return; | 0 | ||||||||||||||||||
678 | } | - | ||||||||||||||||||
679 | } never executed: end of block | 0 | ||||||||||||||||||
680 | - | |||||||||||||||||||
681 | // stop scrolling when the mouse pointer leaves a control | - | ||||||||||||||||||
682 | // similar to push buttons | - | ||||||||||||||||||
683 | QRect pr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this); | - | ||||||||||||||||||
684 | if (pr.contains(e->pos()) == d->pointerOutsidePressedControl) {
| 0 | ||||||||||||||||||
685 | if ((d->pointerOutsidePressedControl = !d->pointerOutsidePressedControl)) {
| 0 | ||||||||||||||||||
686 | d->pointerOutsidePressedControl = true; | - | ||||||||||||||||||
687 | setRepeatAction(SliderNoAction); | - | ||||||||||||||||||
688 | repaint(pr); | - | ||||||||||||||||||
689 | } else { never executed: end of block | 0 | ||||||||||||||||||
690 | d->activateControl(d->pressedControl); | - | ||||||||||||||||||
691 | } never executed: end of block | 0 | ||||||||||||||||||
692 | } | - | ||||||||||||||||||
693 | } never executed: end of block | 0 | ||||||||||||||||||
694 | } never executed: end of block | 0 | ||||||||||||||||||
695 | - | |||||||||||||||||||
696 | - | |||||||||||||||||||
697 | int QScrollBarPrivate::pixelPosToRangeValue(int pos) const | - | ||||||||||||||||||
698 | { | - | ||||||||||||||||||
699 | Q_Q(const QScrollBar); | - | ||||||||||||||||||
700 | QStyleOptionSlider opt; | - | ||||||||||||||||||
701 | q->initStyleOption(&opt); | - | ||||||||||||||||||
702 | QRect gr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, | - | ||||||||||||||||||
703 | QStyle::SC_ScrollBarGroove, q); | - | ||||||||||||||||||
704 | QRect sr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, | - | ||||||||||||||||||
705 | QStyle::SC_ScrollBarSlider, q); | - | ||||||||||||||||||
706 | int sliderMin, sliderMax, sliderLength; | - | ||||||||||||||||||
707 | - | |||||||||||||||||||
708 | if (orientation == Qt::Horizontal) {
| 0 | ||||||||||||||||||
709 | sliderLength = sr.width(); | - | ||||||||||||||||||
710 | sliderMin = gr.x(); | - | ||||||||||||||||||
711 | sliderMax = gr.right() - sliderLength + 1; | - | ||||||||||||||||||
712 | if (q->layoutDirection() == Qt::RightToLeft)
| 0 | ||||||||||||||||||
713 | opt.upsideDown = !opt.upsideDown; never executed: opt.upsideDown = !opt.upsideDown; | 0 | ||||||||||||||||||
714 | } else { never executed: end of block | 0 | ||||||||||||||||||
715 | sliderLength = sr.height(); | - | ||||||||||||||||||
716 | sliderMin = gr.y(); | - | ||||||||||||||||||
717 | sliderMax = gr.bottom() - sliderLength + 1; | - | ||||||||||||||||||
718 | } never executed: end of block | 0 | ||||||||||||||||||
719 | - | |||||||||||||||||||
720 | return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin, never executed: return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin, sliderMax - sliderMin, opt.upsideDown); | 0 | ||||||||||||||||||
721 | sliderMax - sliderMin, opt.upsideDown); never executed: return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin, sliderMax - sliderMin, opt.upsideDown); | 0 | ||||||||||||||||||
722 | } | - | ||||||||||||||||||
723 | - | |||||||||||||||||||
724 | /*! \reimp | - | ||||||||||||||||||
725 | */ | - | ||||||||||||||||||
726 | void QScrollBar::hideEvent(QHideEvent *) | - | ||||||||||||||||||
727 | { | - | ||||||||||||||||||
728 | Q_D(QScrollBar); | - | ||||||||||||||||||
729 | if (d->pressedControl) {
| 0 | ||||||||||||||||||
730 | d->pressedControl = QStyle::SC_None; | - | ||||||||||||||||||
731 | setRepeatAction(SliderNoAction); | - | ||||||||||||||||||
732 | } never executed: end of block | 0 | ||||||||||||||||||
733 | } never executed: end of block | 0 | ||||||||||||||||||
734 | - | |||||||||||||||||||
735 | /*! \internal | - | ||||||||||||||||||
736 | Returns the style option for scroll bar. | - | ||||||||||||||||||
737 | */ | - | ||||||||||||||||||
738 | Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollbar) | - | ||||||||||||||||||
739 | { | - | ||||||||||||||||||
740 | QStyleOptionSlider opt; | - | ||||||||||||||||||
741 | scrollbar->initStyleOption(&opt); | - | ||||||||||||||||||
742 | return opt; never executed: return opt; | 0 | ||||||||||||||||||
743 | } | - | ||||||||||||||||||
744 | - | |||||||||||||||||||
745 | QT_END_NAMESPACE | - | ||||||||||||||||||
746 | - | |||||||||||||||||||
747 | #include "moc_qscrollbar.cpp" | - | ||||||||||||||||||
748 | - | |||||||||||||||||||
749 | #endif // QT_NO_SCROLLBAR | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |