Krita Source Code Documentation
Loading...
Searching...
No Matches
KoPointerEvent.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2
3 SPDX-FileCopyrightText: 2006 Thorsten Zachmann <zachmann@kde.org>
4 SPDX-FileCopyrightText: 2006 C. Boemann Rasmussen <cbo@boemann.dk>
5 SPDX-FileCopyrightText: 2006-2007 Thomas Zander <zander@kde.org>
6 SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "KoPointerEvent.h"
12#include <QTabletEvent>
13#include <QMouseEvent>
14#include <QWheelEvent>
15#include <cmath>
16#include <boost/variant2/variant.hpp>
17
18#include <ksharedconfig.h>
19#include <kconfiggroup.h>
20#include <kis_config_notifier.h>
21
23{
24private:
25 Q_OBJECT
26public:
32
33 bool useTouchPressure = true;
34
35private Q_SLOTS:
37
38 KConfigGroup group = KSharedConfig::openConfig()->group("");
39 useTouchPressure = group.readEntry("useTouchPressureSensitivity", true);
40 }
41};
42
44
45#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
46namespace detail {
47
48// Qt's events do not have copy-ctors yet, so we should emulate them
49// See https://bugreports.qt.io/browse/QTBUG-72488
50
51template <class Event> void copyEventHack(const Event *src, QScopedPointer<QEvent> &dst);
52
53template<> void copyEventHack(const QMouseEvent *src, QScopedPointer<QEvent> &dst) {
54 QMouseEvent *tmp = new QMouseEvent(src->type(),
55 src->localPos(), src->windowPos(), src->screenPos(),
56 src->button(), src->buttons(), src->modifiers(),
57 src->source());
58 tmp->setTimestamp(src->timestamp());
59 dst.reset(tmp);
60}
61
62template<> void copyEventHack(const QTabletEvent *src, QScopedPointer<QEvent> &dst) {
63 QTabletEvent *tmp = new QTabletEvent(src->type(),
64 src->posF(), src->globalPosF(),
65 src->deviceType(), src->pointerType(),
66 src->pressure(),
67 src->xTilt(), src->yTilt(),
68 src->tangentialPressure(),
69 src->rotation(),
70 src->z(),
71 src->modifiers(),
72 src->uniqueId(),
73 src->button(), src->buttons());
74 tmp->setTimestamp(src->timestamp());
75 dst.reset(tmp);
76}
77
78template<> void copyEventHack(const QTouchEvent *src, QScopedPointer<QEvent> &dst) {
79 QTouchEvent *tmp = new QTouchEvent(src->type(),
80 src->device(),
81 src->modifiers(),
82 src->touchPointStates(),
83 src->touchPoints());
84 tmp->setTimestamp(src->timestamp());
85 dst.reset(tmp);
86}
87
88}
89#endif
90
91class Q_DECL_HIDDEN KoPointerEvent::Private
92{
93public:
94 template <typename Event>
95 Private(Event *event)
96 : eventPtr(event)
97 {
98 }
99
100 boost::variant2::variant<QMouseEvent*, QTabletEvent*, QTouchEvent*> eventPtr;
102};
103
104bool KoPointerEvent::Private::s_tabletInputReceived;
105
106KoPointerEvent::KoPointerEvent(QMouseEvent *ev, const QPointF &pnt)
107 : point(pnt),
108 d(new Private(ev))
109{
110}
111
112KoPointerEvent::KoPointerEvent(QTabletEvent *ev, const QPointF &pnt)
113 : point(pnt),
114 d(new Private(ev))
115{
116 if (!Private::s_tabletInputReceived) {
117 Private::s_tabletInputReceived = true;
119 }
120}
121
122KoPointerEvent::KoPointerEvent(QTouchEvent* ev, const QPointF &pnt)
123 : point(pnt),
124 d(new Private(ev))
125{
126}
127
129 : point(point)
130 , d(new Private(*(event->d)))
131{
132}
133
135 : point(rhs.point)
136 , d(new Private(*(rhs.d)))
137{
138}
139
141{
142 if (&rhs != this) {
143 *d = *rhs.d;
144 point = rhs.point;
145 }
146
147 return *this;
148}
149
153
154template <typename Event>
155KoPointerEventWrapper::KoPointerEventWrapper(Event *_event, const QPointF &point)
156 : event(_event, point),
157 baseQtEvent(QSharedPointer<QEvent>(static_cast<QEvent*>(_event)))
158{
159}
160
161
162#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
163struct DeepCopyVisitor
164{
165 QPointF point;
166
167 template <typename T>
168 KoPointerEventWrapper operator() (const T *event) {
169 QScopedPointer<QEvent> baseEvent;
170 detail::copyEventHack(event, baseEvent);
171 return {static_cast<T*>(baseEvent.take()), point};
172 }
173};
174#endif
175
177{
178#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
179 return visit(DeepCopyVisitor{point}, d->eventPtr);
180#else
181 struct Visitor {
182
183 QPointF point;
184
185 KoPointerEventWrapper operator() (const QMouseEvent *event) {
186 return KoPointerEventWrapper(event->clone(), point);
187 }
188 KoPointerEventWrapper operator() (const QTabletEvent *event) {
189 return KoPointerEventWrapper(event->clone(), point);
190 }
191 KoPointerEventWrapper operator() (const QTouchEvent *event) {
192 return KoPointerEventWrapper(event->clone(), point);
193 }
194 };
195 return visit(Visitor{point}, d->eventPtr);
196
197
198#endif
199}
200
201Qt::MouseButton KoPointerEvent::button() const
202{
203 struct Visitor {
204 Qt::MouseButton operator() (const QMouseEvent *event) {
205 return event->button();
206 }
207 Qt::MouseButton operator() (const QTabletEvent *event) {
208 return event->button();
209 }
210 Qt::MouseButton operator() (const QTouchEvent *) {
211 return Qt::LeftButton;
212 }
213 };
214
215 return visit(Visitor(), d->eventPtr);
216}
217
218Qt::MouseButtons KoPointerEvent::buttons() const
219{
220 struct Visitor {
221 Qt::MouseButtons operator() (const QMouseEvent *event) {
222 return event->buttons();
223 }
224 Qt::MouseButtons operator() (const QTabletEvent *event) {
225 return event->buttons();
226 }
227 Qt::MouseButtons operator() (const QTouchEvent *) {
228 return Qt::LeftButton;
229 }
230 };
231
232 return visit(Visitor(), d->eventPtr);
233}
234
236{
237#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
238 struct Visitor {
239 QPoint operator() (const QMouseEvent *event) {
240 return event->globalPos();
241 }
242 QPoint operator() (const QTabletEvent *event) {
243 return event->globalPos();
244 }
245 QPoint operator() (const QTouchEvent *) {
246 return QPoint();
247 }
248#else
249 struct Visitor {
250 QPoint operator() (const QMouseEvent *event) {
251 return event->globalPosition().toPoint();
252 }
253 QPoint operator() (const QTabletEvent *event) {
254 return event->globalPosition().toPoint();
255 }
256 QPoint operator() (const QTouchEvent *) {
257 return QPoint();
258 }
259#endif
260
261 };
262
263 return visit(Visitor(), d->eventPtr);
264}
265
267{
268#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
269 struct Visitor {
270 QPoint operator() (const QMouseEvent *event) {
271 return event->pos();
272 }
273 QPoint operator() (const QTabletEvent *event) {
274 return event->pos();
275 }
276 QPoint operator() (const QTouchEvent *event) {
277 return event->touchPoints().at(0).pos().toPoint();
278 }
279 };
280#else
281 struct Visitor {
282 QPoint operator() (const QMouseEvent *event) {
283 return event->position().toPoint();
284 }
285 QPoint operator() (const QTabletEvent *event) {
286 return event->position().toPoint();
287 }
288 QPoint operator() (const QTouchEvent *event) {
289 return event->points().at(0).position().toPoint();
290 }
291 };
292#endif
293 return visit(Visitor(), d->eventPtr);
294}
295
297{
298 return pos().x();
299}
300
302{
303 return pos().y();
304}
305
307{
308 struct Visitor {
309 qreal operator() (const QTabletEvent *event) {
310 return event->pressure();
311 }
312 qreal operator() (const QTouchEvent *event) {
313#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
314 return s_optionContainer->useTouchPressure ? event->touchPoints().at(0).pressure() : 1.0;
315#else
316 return s_optionContainer->useTouchPressure ? event->points().at(0).pressure() : 1.0;
317#endif
318 }
319 qreal operator() (...) {
320 return 1.0;
321 }
322 };
323
324 return visit(Visitor(), d->eventPtr);
325}
326
328{
329 struct Visitor {
330 qreal operator() (const QTabletEvent *event) {
331 return event->rotation();
332 }
333 qreal operator() (const QTouchEvent *event) {
334#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
335 return event->touchPoints().at(0).rotation();
336#else
337 return event->points().at(0).rotation();
338#endif
339 }
340 qreal operator() (...) {
341 return 0.0;
342 }
343 };
344
345 return visit(Visitor(), d->eventPtr);
346}
347
349{
350 struct Visitor {
351 qreal operator() (const QTabletEvent *event) {
352 return std::fmod((event->tangentialPressure() - (-1.0)) / (1.0 - (-1.0)), 2.0);
353 }
354 qreal operator() (...) {
355 return 0.0;
356 }
357 };
358
359 return visit(Visitor(), d->eventPtr);
360}
361
363{
364 struct Visitor {
365 int operator() (const QTabletEvent *event) {
366 return event->xTilt();
367 }
368 int operator() (...) {
369 return 0;
370 }
371 };
372
373 return visit(Visitor(), d->eventPtr);
374}
375
376
378{
379 struct Visitor {
380 int operator() (const QTabletEvent *event) {
381 return event->yTilt();
382 }
383 int operator() (...) {
384 return 0;
385 }
386 };
387
388 return visit(Visitor(), d->eventPtr);
389}
390
392{
393 struct Visitor {
394 int operator() (const QTabletEvent *event) {
395 return event->z();
396 }
397 int operator() (...) {
398 return 0;
399 }
400 };
401
402 return visit(Visitor(), d->eventPtr);
403}
404
406{
407 struct Visitor {
408 ulong operator() (const QInputEvent *event) {
409 return event->timestamp();
410 }
411 };
412
413 return visit(Visitor(), d->eventPtr);
414}
415
417{
418 return d->eventPtr.index() == 1;
419}
420
422{
423 return d->eventPtr.index() == 2;
424}
425
427{
428 return Private::s_tabletInputReceived;
429}
430
431Qt::KeyboardModifiers KoPointerEvent::modifiers() const
432{
433 struct Visitor {
434 Qt::KeyboardModifiers operator() (const QInputEvent *event) {
435 return event->modifiers();
436 }
437 };
438
439 return visit(Visitor(), d->eventPtr);
440}
441
443{
444 struct Visitor {
445 void operator() (QInputEvent *event) {
446 event->accept();
447 }
448 };
449
450 return visit(Visitor(), d->eventPtr);
451}
452
454{
455 struct Visitor {
456 void operator() (QInputEvent *event) {
457 event->ignore();
458 }
459 };
460
461 return visit(Visitor(), d->eventPtr);
462}
463
465{
466 struct Visitor {
467 bool operator() (const QInputEvent *event) {
468 return event->isAccepted();
469 }
470 };
471
472 return visit(Visitor(), d->eventPtr);
473}
474
476{
477 struct Visitor {
478 bool operator() (const QInputEvent *event) {
479 return event->spontaneous();
480 }
481 };
482
483 return visit(Visitor(), d->eventPtr);
484}
485
486#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
487void KoPointerEvent::copyQtPointerEvent(const QMouseEvent *event, QScopedPointer<QEvent> &dst)
488{
489 detail::copyEventHack(event, dst);
490}
491
492void KoPointerEvent::copyQtPointerEvent(const QTabletEvent *event, QScopedPointer<QEvent> &dst)
493{
494 detail::copyEventHack(event, dst);
495}
496
497void KoPointerEvent::copyQtPointerEvent(const QTouchEvent *event, QScopedPointer<QEvent> &dst)
498{
499 detail::copyEventHack(event, dst);
500}
501#endif
502
503#include <KoPointerEvent.moc>
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisConfigNotifier * instance()
const QScopedPointer< Private > d
bool spontaneous() const
return if this event was spontaneous (see QMouseEvent::spontaneous())
qreal pressure() const
Private(Event *event)
QPoint globalPos() const
Return the position screen coordinates.
KoPointerEvent & operator=(const KoPointerEvent &rhs)
qreal rotation() const
return the rotation (or a default value)
KoPointerEvent(QMouseEvent *event, const QPointF &point)
Qt::MouseButton button() const
return button pressed (see QMouseEvent::button());
ulong time() const
Qt::MouseButtons buttons() const
return buttons pressed (see QMouseEvent::buttons());
qreal yTilt() const
qreal tangentialPressure() const
bool isTabletEvent() const
bool isTouchEvent() const
boost::variant2::variant< QMouseEvent *, QTabletEvent *, QTouchEvent * > eventPtr
Qt::KeyboardModifiers modifiers() const
static bool s_tabletInputReceived
bool isAccepted() const
return if the event has been accepted.
QPointF point
The point in document coordinates.
qreal xTilt() const
KoPointerEventWrapper deepCopyEvent() const
static bool tabletInputReceived()
QPoint pos() const
return the position in widget coordinates
KoPointerEventWrapper(Event *_event, const QPointF &point)