Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickpointerdevicehandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include <private/qquickitem_p.h>
7#include <QMouseEvent>
8#include <QDebug>
9
11
12/*!
13 \qmltype PointerDeviceHandler
14 \qmlabstract
15 \since 5.10
16 \preliminary
17 \nativetype QQuickPointerDeviceHandler
18 \inherits PointerHandler
19 \inqmlmodule QtQuick
20 \brief Abstract handler for pointer events with device-specific constraints.
21
22 An intermediate class (not registered as a QML type) for handlers which
23 allow filtering based on device type, pointer type, or keyboard modifiers.
24*/
25QQuickPointerDeviceHandler::QQuickPointerDeviceHandler(QQuickItem *parent)
26 : QQuickPointerHandler(*(new QQuickPointerDeviceHandlerPrivate), parent)
27{
28}
29
30QQuickPointerDeviceHandler::QQuickPointerDeviceHandler(QQuickPointerDeviceHandlerPrivate &dd, QQuickItem *parent)
31 : QQuickPointerHandler(dd, parent)
32{
33}
34
35QInputDevice::DeviceTypes QQuickPointerDeviceHandler::acceptedDevices() const
36{
37 Q_D(const QQuickPointerDeviceHandler);
38 return d->acceptedDevices;
39}
40
41QPointingDevice::PointerTypes QQuickPointerDeviceHandler::acceptedPointerTypes() const
42{
43 Q_D(const QQuickPointerDeviceHandler);
44 return d->acceptedPointerTypes;
45}
46
47/*!
48 \qmlproperty flags QtQuick::PointerDeviceHandler::acceptedButtons
49
50 The mouse buttons which can activate this Pointer Handler.
51
52 By default, this property is set to \l {QtQuick::MouseEvent::button} {Qt.LeftButton}.
53 It can be set to an OR combination of mouse buttons, and will ignore events
54 from other buttons.
55
56 For example, a control could be made to respond to left and right clicks
57 in different ways, with two handlers:
58
59 \qml
60 Item {
61 TapHandler {
62 onTapped: console.log("left clicked")
63 }
64 TapHandler {
65 acceptedButtons: Qt.RightButton
66 onTapped: console.log("right clicked")
67 }
68 }
69 \endqml
70
71 \note Tapping on a touchscreen or tapping the stylus on a graphics tablet
72 emulates clicking the left mouse button. This behavior can be altered via
73 \l {PointerDeviceHandler::acceptedDevices}{acceptedDevices} or
74 \l {PointerDeviceHandler::acceptedPointerTypes}{acceptedPointerTypes}.
75*/
76Qt::MouseButtons QQuickPointerDeviceHandler::acceptedButtons() const
77{
78 Q_D(const QQuickPointerDeviceHandler);
79 return d->acceptedButtons;
80}
81
82void QQuickPointerDeviceHandler::setAcceptedButtons(Qt::MouseButtons buttons)
83{
84 Q_D(QQuickPointerDeviceHandler);
85 if (d->acceptedButtons == buttons)
86 return;
87
88 d->acceptedButtons = buttons;
89 emit acceptedButtonsChanged();
90}
91
92Qt::KeyboardModifiers QQuickPointerDeviceHandler::acceptedModifiers() const
93{
94 Q_D(const QQuickPointerDeviceHandler);
95 return d->acceptedModifiers;
96}
97
98/*!
99 \qmlproperty flags PointerDeviceHandler::acceptedDevices
100
101 The types of pointing devices that can activate this Pointer Handler.
102
103 By default, this property is set to
104 \l{QInputDevice::DeviceType}{PointerDevice.AllDevices}.
105 If you set it to an OR combination of device types, it will ignore events
106 from non-matching devices.
107
108 For example, a control could be made to respond to mouse and stylus clicks
109 in one way, and touchscreen taps in another way, with two handlers:
110
111 \qml
112 Item {
113 TapHandler {
114 acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
115 onTapped: console.log("clicked")
116 }
117 TapHandler {
118 acceptedDevices: PointerDevice.TouchScreen
119 onTapped: console.log("tapped")
120 }
121 }
122 \endqml
123
124 \note Not all platforms are yet able to distinguish mouse and touchpad; and
125 on those that do, you often want to make mouse and touchpad behavior the same.
126*/
127void QQuickPointerDeviceHandler::setAcceptedDevices(QPointingDevice::DeviceTypes acceptedDevices)
128{
129 Q_D(QQuickPointerDeviceHandler);
130 if (d->acceptedDevices == acceptedDevices)
131 return;
132
133 d->acceptedDevices = acceptedDevices;
134 emit acceptedDevicesChanged();
135}
136
137/*!
138 \qmlproperty flags PointerDeviceHandler::acceptedPointerTypes
139
140 The types of pointing instruments (finger, stylus, eraser, etc.)
141 that can activate this Pointer Handler.
142
143 By default, this property is set to
144 \l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}.
145 If you set it to an OR combination of device types, it will ignore events
146 from non-matching \l {PointerDevice}{devices}.
147
148 For example, a control could be made to respond to mouse, touch, and stylus clicks
149 in some way, but delete itself if tapped with an eraser tool on a graphics tablet,
150 with two handlers:
151
152 \qml
153 Rectangle {
154 id: rect
155 TapHandler {
156 acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger | PointerDevice.Pen
157 onTapped: console.log("clicked")
158 }
159 TapHandler {
160 acceptedPointerTypes: PointerDevice.Eraser
161 onTapped: rect.destroy()
162 }
163 }
164 \endqml
165*/
166void QQuickPointerDeviceHandler::setAcceptedPointerTypes(QPointingDevice::PointerTypes acceptedPointerTypes)
167{
168 Q_D(QQuickPointerDeviceHandler);
169 if (d->acceptedPointerTypes == acceptedPointerTypes)
170 return;
171
172 d->acceptedPointerTypes = acceptedPointerTypes;
173 emit acceptedPointerTypesChanged();
174}
175
176/*!
177 \qmlproperty flags PointerDeviceHandler::acceptedModifiers
178
179 If this property is set, it will require the given keyboard modifiers to
180 be pressed in order to react to pointer events, and otherwise ignore them.
181
182 If this property is set to \c Qt.KeyboardModifierMask (the default value),
183 then the PointerHandler ignores the modifier keys.
184
185 For example, an \l [QML] Item could have two handlers of the same type,
186 one of which is enabled only if the required keyboard modifiers are
187 pressed:
188
189 \qml
190 Item {
191 TapHandler {
192 acceptedModifiers: Qt.ControlModifier
193 onTapped: console.log("control-tapped")
194 }
195 TapHandler {
196 acceptedModifiers: Qt.NoModifier
197 onTapped: console.log("tapped")
198 }
199 }
200 \endqml
201
202 If you set \c acceptedModifiers to an OR combination of modifier keys,
203 it means \e all of those modifiers must be pressed to activate the handler:
204
205 \qml
206 Item {
207 TapHandler {
208 acceptedModifiers: Qt.ControlModifier | Qt.AltModifier | Qt.ShiftModifier
209 onTapped: console.log("control-alt-shift-tapped")
210 }
211 }
212 \endqml
213
214 The available modifiers are as follows:
215
216 \value NoModifier No modifier key is allowed.
217 \value ShiftModifier A Shift key on the keyboard must be pressed.
218 \value ControlModifier A Ctrl key on the keyboard must be pressed.
219 \value AltModifier An Alt key on the keyboard must be pressed.
220 \value MetaModifier A Meta key on the keyboard must be pressed.
221 \value KeypadModifier A keypad button must be pressed.
222 \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument).
223 A Mode_switch key on the keyboard must be pressed.
224 \value KeyboardModifierMask The handler does not care which modifiers are pressed.
225
226 If you need even more complex behavior than can be achieved with
227 combinations of multiple handlers with multiple modifier flags, you can
228 check the modifiers in JavaScript code:
229
230 \qml
231 Item {
232 TapHandler {
233 onTapped:
234 switch (point.modifiers) {
235 case Qt.ControlModifier | Qt.AltModifier:
236 console.log("CTRL+ALT");
237 break;
238 case Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier:
239 console.log("CTRL+META+ALT");
240 break;
241 default:
242 console.log("other modifiers", point.modifiers);
243 break;
244 }
245 }
246 }
247 \endqml
248
249 \sa Qt::KeyboardModifier
250*/
251void QQuickPointerDeviceHandler::setAcceptedModifiers(Qt::KeyboardModifiers acceptedModifiers)
252{
253 Q_D(QQuickPointerDeviceHandler);
254 if (d->acceptedModifiers == acceptedModifiers)
255 return;
256
257 d->acceptedModifiers = acceptedModifiers;
258 emit acceptedModifiersChanged();
259}
260
261bool QQuickPointerDeviceHandler::wantsPointerEvent(QPointerEvent *event)
262{
263 Q_D(QQuickPointerDeviceHandler);
264 if (!QQuickPointerHandler::wantsPointerEvent(event))
265 return false;
266 qCDebug(lcPointerHandlerDispatch) << objectName()
267 << "checking device type" << d->acceptedDevices
268 << "pointer type" << d->acceptedPointerTypes
269 << "modifiers" << d->acceptedModifiers;
270 if (!d->acceptedDevices.testFlag(event->device()->type()))
271 return false;
272 if (!d->acceptedPointerTypes.testFlag(event->pointingDevice()->pointerType()))
273 return false;
274 if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers)
275 return false;
276 // Some handlers (HoverHandler, PinchHandler, PointHandler) set
277 // acceptedButtons to Qt::NoButton to indicate that button state is irrelevant.
278 if (event->isSinglePointEvent() && acceptedButtons() != Qt::NoButton && event->type() != QEvent::Wheel &&
279 (static_cast<QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == 0 &&
280 (static_cast<QSinglePointEvent *>(event)->button() & acceptedButtons()) == 0)
281 return false;
282 return true;
283}
284
285QT_END_NAMESPACE
286
287#include "moc_qquickpointerdevicehandler_p.cpp"