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 "qgesture.h"
41#include "private/qgesture_p.h"
42#include "private/qstandardgestures_p.h"
43#if QT_CONFIG(graphicsview)
44#include "qgraphicsview.h"
45#endif
46
47#include <private/qdebug_p.h>
48#ifndef QT_NO_GESTURES
49
50QT_BEGIN_NAMESPACE
51
52 /*!
53 \class QGesture
54 \since 4.6
55 \ingroup gestures
56 \inmodule QtWidgets
57
58 \brief The QGesture class represents a gesture, containing properties that
59 describe the corresponding user input.
60
61 Gesture objects are not constructed directly by developers. They are created by
62 the QGestureRecognizer object that is registered with the application; see
63 QGestureRecognizer::registerRecognizer().
64
65 For an overview of gesture handling in Qt and information on using gestures
66 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
67
68 \section1 Gesture Properties
69
70 The class has a list of properties that can be queried by the user to get
71 some gesture-specific arguments. For example, the pinch gesture has a scale
72 factor that is exposed as a property.
73
74 Developers of custom gesture recognizers can add additional properties in
75 order to provide additional information about a gesture. This can be done
76 by adding new dynamic properties to a QGesture object, or by subclassing
77 the QGesture class (or one of its subclasses).
78
79 \section1 Lifecycle of a Gesture Object
80
81 A QGesture instance is implicitly created when needed and is owned by Qt.
82 Developers should never destroy them or store them for later use as Qt may
83 destroy particular instances of them and create new ones to replace them.
84
85 The registered gesture recognizer monitors the input events for the target
86 object via its \l{QGestureRecognizer::}{recognize()} function, updating the
87 properties of the gesture object as required.
88
89 The gesture object may be delivered to the target object in a QGestureEvent if
90 the corresponding gesture is active or has just been canceled. Each event that
91 is delivered contains a list of gesture objects, since support for more than
92 one gesture may be enabled for the target object. Due to the way events are
93 handled in Qt, gesture events may be filtered by other objects.
94
95 \sa QGestureEvent, QGestureRecognizer
96*/
97
98/*!
99 Constructs a new gesture object with the given \a parent.
100
101 QGesture objects are created by gesture recognizers in the
102 QGestureRecognizer::create() function.
103*/
104QGesture::QGesture(QObject *parent)
105 : QObject(*new QGesturePrivate, parent)
106{
107 d_func()->gestureType = Qt::CustomGesture;
108}
109
110/*!
111 \internal
112*/
113QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
114 : QObject(dd, parent)
115{
116}
117
118/*!
119 Destroys the gesture object.
120*/
121QGesture::~QGesture()
122{
123}
124
125/*!
126 \property QGesture::state
127 \brief the current state of the gesture
128*/
129
130/*!
131 \property QGesture::gestureType
132 \brief the type of the gesture
133*/
134
135/*!
136 \property QGesture::hotSpot
137
138 \brief The point that is used to find the receiver for the gesture event.
139
140 The hot-spot is a point in the global coordinate system, use
141 QWidget::mapFromGlobal() or QGestureEvent::mapToGraphicsScene() to get a
142 local hot-spot.
143
144 The hot-spot should be set by the gesture recognizer to allow gesture event
145 delivery to a QGraphicsObject.
146*/
147
148/*!
149 \property QGesture::hasHotSpot
150 \brief whether the gesture has a hot-spot
151*/
152
153Qt::GestureType QGesture::gestureType() const
154{
155 return d_func()->gestureType;
156}
157
158Qt::GestureState QGesture::state() const
159{
160 return d_func()->state;
161}
162
163QPointF QGesture::hotSpot() const
164{
165 return d_func()->hotSpot;
166}
167
168void QGesture::setHotSpot(const QPointF &value)
169{
170 Q_D(QGesture);
171 d->hotSpot = value;
172 d->isHotSpotSet = true;
173}
174
175bool QGesture::hasHotSpot() const
176{
177 return d_func()->isHotSpotSet;
178}
179
180void QGesture::unsetHotSpot()
181{
182 d_func()->isHotSpotSet = false;
183}
184
185/*!
186 \property QGesture::gestureCancelPolicy
187 \brief the policy for deciding what happens on accepting a gesture
188
189 On accepting one gesture Qt can automatically cancel other gestures
190 that belong to other targets. The policy is normally set to not cancel
191 any other gestures and can be set to cancel all active gestures in the
192 context. For example for all child widgets.
193*/
194
195/*!
196 \enum QGesture::GestureCancelPolicy
197
198 This enum describes how accepting a gesture can cancel other gestures
199 automatically.
200
201 \value CancelNone On accepting this gesture no other gestures will be affected.
202
203 \value CancelAllInContext On accepting this gesture all gestures that are
204 active in the context (respecting the Qt::GestureFlag that were specified
205 when subscribed to the gesture) will be cancelled.
206*/
207
208void QGesture::setGestureCancelPolicy(GestureCancelPolicy policy)
209{
210 Q_D(QGesture);
211 d->gestureCancelPolicy = static_cast<uint>(policy);
212}
213
214QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
215{
216 Q_D(const QGesture);
217 return static_cast<GestureCancelPolicy>(d->gestureCancelPolicy);
218}
219
220/*!
221 \class QPanGesture
222 \since 4.6
223 \brief The QPanGesture class describes a panning gesture made by the user.
224 \ingroup gestures
225 \inmodule QtWidgets
226
227 \image pangesture.png
228
229 For an overview of gesture handling in Qt and information on using gestures
230 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
231
232 \sa QPinchGesture, QSwipeGesture
233*/
234
235/*!
236 \property QPanGesture::lastOffset
237 \brief the last offset recorded for this gesture
238
239 The last offset contains the change in position of the user's input as
240 reported in the \l offset property when a previous gesture event was
241 delivered for this gesture.
242
243 If no previous event was delivered with information about this gesture
244 (i.e., this gesture object contains information about the first movement
245 in the gesture) then this property contains a zero size.
246*/
247
248/*!
249 \property QPanGesture::offset
250 \brief the total offset from the first input position to the current input
251 position
252
253 The offset measures the total change in position of the user's input
254 covered by the gesture on the input device.
255*/
256
257/*!
258 \property QPanGesture::delta
259 \brief the offset from the previous input position to the current input
260
261 This is essentially the same as the difference between offset() and
262 lastOffset().
263*/
264
265/*!
266 \property QPanGesture::acceleration
267 \brief the acceleration in the motion of the touch point for this gesture
268*/
269
270/*!
271 \property QPanGesture::horizontalVelocity
272 \brief the horizontal component of the motion of the touch point for this
273 gesture
274 \since 4.7.1
275 \internal
276
277 \sa verticalVelocity, acceleration
278*/
279
280/*!
281 \property QPanGesture::verticalVelocity
282 \brief the vertical component of the motion of the touch point for this
283 gesture
284 \since 4.7.1
285 \internal
286
287 \sa horizontalVelocity, acceleration
288*/
289
290/*!
291 \internal
292*/
293QPanGesture::QPanGesture(QObject *parent)
294 : QGesture(*new QPanGesturePrivate, parent)
295{
296 d_func()->gestureType = Qt::PanGesture;
297}
298
299/*!
300 Destructor.
301*/
302QPanGesture::~QPanGesture()
303{
304}
305
306QPointF QPanGesture::lastOffset() const
307{
308 return d_func()->lastOffset;
309}
310
311QPointF QPanGesture::offset() const
312{
313 return d_func()->offset;
314}
315
316QPointF QPanGesture::delta() const
317{
318 Q_D(const QPanGesture);
319 return d->offset - d->lastOffset;
320}
321
322qreal QPanGesture::acceleration() const
323{
324 return d_func()->acceleration;
325}
326
327void QPanGesture::setLastOffset(const QPointF &value)
328{
329 d_func()->lastOffset = value;
330}
331
332void QPanGesture::setOffset(const QPointF &value)
333{
334 d_func()->offset = value;
335}
336
337void QPanGesture::setAcceleration(qreal value)
338{
339 d_func()->acceleration = value;
340}
341
342/*!
343 \class QPinchGesture
344 \since 4.6
345 \brief The QPinchGesture class describes a pinch gesture made by the user.
346 \ingroup touch
347 \ingroup gestures
348 \inmodule QtWidgets
349
350 A pinch gesture is a form of touch user input in which the user typically
351 touches two points on the input device with a thumb and finger, before moving
352 them closer together or further apart to change the scale factor, zoom, or level
353 of detail of the user interface.
354
355 For an overview of gesture handling in Qt and information on using gestures
356 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
357
358 \image pinchgesture.png
359
360 Instead of repeatedly applying the same pinching gesture, the user may
361 continue to touch the input device in one place, and apply a second touch
362 to a new point, continuing the gesture. When this occurs, gesture events
363 will continue to be delivered to the target object, containing an instance
364 of QPinchGesture in the Qt::GestureUpdated state.
365
366 \sa QPanGesture, QSwipeGesture
367*/
368
369/*!
370 \enum QPinchGesture::ChangeFlag
371
372 This enum describes the changes that can occur to the properties of
373 the gesture object.
374
375 \value ScaleFactorChanged The scale factor held by scaleFactor changed.
376 \value RotationAngleChanged The rotation angle held by rotationAngle changed.
377 \value CenterPointChanged The center point held by centerPoint changed.
378
379 \sa changeFlags, totalChangeFlags
380*/
381
382/*!
383 \property QPinchGesture::totalChangeFlags
384 \brief the property of the gesture that has change
385
386 This property indicates which of the other properties has changed since the
387 gesture has started. You can use this information to determine which aspect
388 of your user interface needs to be updated.
389
390 \sa changeFlags, scaleFactor, rotationAngle, centerPoint
391*/
392
393/*!
394 \property QPinchGesture::changeFlags
395 \brief the property of the gesture that has changed in the current step
396
397 This property indicates which of the other properties has changed since
398 the previous gesture event included information about this gesture. You
399 can use this information to determine which aspect of your user interface
400 needs to be updated.
401
402 \sa totalChangeFlags, scaleFactor, rotationAngle, centerPoint
403*/
404
405/*!
406 \property QPinchGesture::totalScaleFactor
407 \brief the total scale factor
408
409 The total scale factor measures the total change in scale factor from the
410 original value to the current scale factor.
411
412 \sa scaleFactor, lastScaleFactor
413*/
414/*!
415 \property QPinchGesture::lastScaleFactor
416 \brief the last scale factor recorded for this gesture
417
418 The last scale factor contains the scale factor reported in the
419 \l scaleFactor property when a previous gesture event included
420 information about this gesture.
421
422 If no previous event was delivered with information about this gesture
423 (i.e., this gesture object contains information about the first movement
424 in the gesture) then this property contains zero.
425
426 \sa scaleFactor, totalScaleFactor
427*/
428/*!
429 \property QPinchGesture::scaleFactor
430 \brief the current scale factor
431
432 The scale factor measures the scale factor associated with the distance
433 between two of the user's inputs on a touch device.
434
435 \sa totalScaleFactor, lastScaleFactor
436*/
437
438/*!
439 \property QPinchGesture::totalRotationAngle
440 \brief the total angle covered by the gesture
441
442 This total angle measures the complete angle covered by the gesture. Usually, this
443 is equal to the value held by the \l rotationAngle property, except in the case where
444 the user performs multiple rotations by removing and repositioning one of the touch
445 points, as described above. In this case, the total angle will be the sum of the
446 rotation angles for the multiple stages of the gesture.
447
448 \sa rotationAngle, lastRotationAngle
449*/
450/*!
451 \property QPinchGesture::lastRotationAngle
452 \brief the last reported angle covered by the gesture motion
453
454 The last rotation angle is the angle as reported in the \l rotationAngle property
455 when a previous gesture event was delivered for this gesture.
456
457 \sa rotationAngle, totalRotationAngle
458*/
459/*!
460 \property QPinchGesture::rotationAngle
461 \brief the angle covered by the gesture motion
462
463 \sa totalRotationAngle, lastRotationAngle
464*/
465
466/*!
467 \property QPinchGesture::startCenterPoint
468 \brief the starting position of the center point
469
470 \sa centerPoint, lastCenterPoint
471*/
472/*!
473 \property QPinchGesture::lastCenterPoint
474 \brief the last position of the center point recorded for this gesture
475
476 \sa centerPoint, startCenterPoint
477*/
478/*!
479 \property QPinchGesture::centerPoint
480 \brief the current center point
481
482 The center point is the midpoint between the two input points in the gesture.
483
484 \sa startCenterPoint, lastCenterPoint
485*/
486
487/*!
488 \internal
489*/
490QPinchGesture::QPinchGesture(QObject *parent)
491 : QGesture(*new QPinchGesturePrivate, parent)
492{
493 d_func()->gestureType = Qt::PinchGesture;
494}
495
496/*!
497 Destructor.
498*/
499QPinchGesture::~QPinchGesture()
500{
501}
502
503QPinchGesture::ChangeFlags QPinchGesture::totalChangeFlags() const
504{
505 return d_func()->totalChangeFlags;
506}
507
508void QPinchGesture::setTotalChangeFlags(QPinchGesture::ChangeFlags value)
509{
510 d_func()->totalChangeFlags = value;
511}
512
513QPinchGesture::ChangeFlags QPinchGesture::changeFlags() const
514{
515 return d_func()->changeFlags;
516}
517
518void QPinchGesture::setChangeFlags(QPinchGesture::ChangeFlags value)
519{
520 d_func()->changeFlags = value;
521}
522
523QPointF QPinchGesture::startCenterPoint() const
524{
525 return d_func()->startCenterPoint;
526}
527
528QPointF QPinchGesture::lastCenterPoint() const
529{
530 return d_func()->lastCenterPoint;
531}
532
533QPointF QPinchGesture::centerPoint() const
534{
535 return d_func()->centerPoint;
536}
537
538void QPinchGesture::setStartCenterPoint(const QPointF &value)
539{
540 d_func()->startCenterPoint = value;
541}
542
543void QPinchGesture::setLastCenterPoint(const QPointF &value)
544{
545 d_func()->lastCenterPoint = value;
546}
547
548void QPinchGesture::setCenterPoint(const QPointF &value)
549{
550 d_func()->centerPoint = value;
551}
552
553
554qreal QPinchGesture::totalScaleFactor() const
555{
556 return d_func()->totalScaleFactor;
557}
558
559qreal QPinchGesture::lastScaleFactor() const
560{
561 return d_func()->lastScaleFactor;
562}
563
564qreal QPinchGesture::scaleFactor() const
565{
566 return d_func()->scaleFactor;
567}
568
569void QPinchGesture::setTotalScaleFactor(qreal value)
570{
571 d_func()->totalScaleFactor = value;
572}
573
574void QPinchGesture::setLastScaleFactor(qreal value)
575{
576 d_func()->lastScaleFactor = value;
577}
578
579void QPinchGesture::setScaleFactor(qreal value)
580{
581 d_func()->scaleFactor = value;
582}
583
584
585qreal QPinchGesture::totalRotationAngle() const
586{
587 return d_func()->totalRotationAngle;
588}
589
590qreal QPinchGesture::lastRotationAngle() const
591{
592 return d_func()->lastRotationAngle;
593}
594
595qreal QPinchGesture::rotationAngle() const
596{
597 return d_func()->rotationAngle;
598}
599
600void QPinchGesture::setTotalRotationAngle(qreal value)
601{
602 d_func()->totalRotationAngle = value;
603}
604
605void QPinchGesture::setLastRotationAngle(qreal value)
606{
607 d_func()->lastRotationAngle = value;
608}
609
610void QPinchGesture::setRotationAngle(qreal value)
611{
612 d_func()->rotationAngle = value;
613}
614
615/*!
616 \class QSwipeGesture
617 \since 4.6
618 \brief The QSwipeGesture class describes a swipe gesture made by the user.
619 \ingroup gestures
620 \inmodule QtWidgets
621
622 \image swipegesture.png
623
624 For an overview of gesture handling in Qt and information on using gestures
625 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
626
627 \sa QPanGesture, QPinchGesture
628*/
629
630/*!
631 \enum QSwipeGesture::SwipeDirection
632
633 This enum describes the possible directions for the gesture's motion
634 along the horizontal and vertical axes.
635
636 \value NoDirection The gesture had no motion associated with it on a particular axis.
637 \value Left The gesture involved a horizontal motion to the left.
638 \value Right The gesture involved a horizontal motion to the right.
639 \value Up The gesture involved an upward vertical motion.
640 \value Down The gesture involved a downward vertical motion.
641*/
642
643/*!
644 \property QSwipeGesture::horizontalDirection
645 \brief the horizontal direction of the gesture
646
647 If the gesture has a horizontal component, the horizontal direction
648 is either Left or Right; otherwise, it is NoDirection.
649
650 \sa verticalDirection, swipeAngle
651*/
652
653/*!
654 \property QSwipeGesture::verticalDirection
655 \brief the vertical direction of the gesture
656
657 If the gesture has a vertical component, the vertical direction
658 is either Up or Down; otherwise, it is NoDirection.
659
660 \sa horizontalDirection, swipeAngle
661*/
662
663/*!
664 \property QSwipeGesture::swipeAngle
665 \brief the angle of the motion associated with the gesture
666
667 If the gesture has either a horizontal or vertical component, the
668 swipe angle describes the angle between the direction of motion and the
669 x-axis as defined using the standard widget
670 \l{Coordinate System}{coordinate system}.
671
672 \sa horizontalDirection, verticalDirection
673*/
674
675/*!
676 \property QSwipeGesture::velocity
677 \since 4.7.1
678 \internal
679*/
680
681/*!
682 \internal
683*/
684QSwipeGesture::QSwipeGesture(QObject *parent)
685 : QGesture(*new QSwipeGesturePrivate, parent)
686{
687 d_func()->gestureType = Qt::SwipeGesture;
688}
689
690/*!
691 Destructor.
692*/
693QSwipeGesture::~QSwipeGesture()
694{
695}
696
697QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
698{
699 Q_D(const QSwipeGesture);
700 if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
701 return QSwipeGesture::NoDirection;
702 else if (d->swipeAngle < 90 || d->swipeAngle > 270)
703 return QSwipeGesture::Right;
704 else
705 return QSwipeGesture::Left;
706}
707
708QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
709{
710 Q_D(const QSwipeGesture);
711 if (d->swipeAngle <= 0 || d->swipeAngle == 180)
712 return QSwipeGesture::NoDirection;
713 else if (d->swipeAngle < 180)
714 return QSwipeGesture::Up;
715 else
716 return QSwipeGesture::Down;
717}
718
719qreal QSwipeGesture::swipeAngle() const
720{
721 return d_func()->swipeAngle;
722}
723
724void QSwipeGesture::setSwipeAngle(qreal value)
725{
726 d_func()->swipeAngle = value;
727}
728
729/*!
730 \class QTapGesture
731 \since 4.6
732 \brief The QTapGesture class describes a tap gesture made by the user.
733 \ingroup gestures
734 \inmodule QtWidgets
735
736 For an overview of gesture handling in Qt and information on using gestures
737 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
738
739 \sa QPanGesture, QPinchGesture
740*/
741
742/*!
743 \property QTapGesture::position
744 \brief the position of the tap
745*/
746
747/*!
748 \internal
749*/
750QTapGesture::QTapGesture(QObject *parent)
751 : QGesture(*new QTapGesturePrivate, parent)
752{
753 d_func()->gestureType = Qt::TapGesture;
754}
755
756/*!
757 Destructor.
758*/
759QTapGesture::~QTapGesture()
760{
761}
762
763QPointF QTapGesture::position() const
764{
765 return d_func()->position;
766}
767
768void QTapGesture::setPosition(const QPointF &value)
769{
770 d_func()->position = value;
771}
772/*!
773 \class QTapAndHoldGesture
774 \since 4.6
775 \brief The QTapAndHoldGesture class describes a tap-and-hold (aka LongTap)
776 gesture made by the user.
777 \ingroup gestures
778 \inmodule QtWidgets
779
780 For an overview of gesture handling in Qt and information on using gestures
781 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
782
783 \sa QPanGesture, QPinchGesture
784*/
785
786/*!
787 \property QTapAndHoldGesture::position
788 \brief the position of the tap
789*/
790
791/*!
792 \internal
793*/
794QTapAndHoldGesture::QTapAndHoldGesture(QObject *parent)
795 : QGesture(*new QTapAndHoldGesturePrivate, parent)
796{
797 d_func()->gestureType = Qt::TapAndHoldGesture;
798}
799
800/*!
801 Destructor.
802*/
803QTapAndHoldGesture::~QTapAndHoldGesture()
804{
805}
806
807QPointF QTapAndHoldGesture::position() const
808{
809 return d_func()->position;
810}
811
812void QTapAndHoldGesture::setPosition(const QPointF &value)
813{
814 d_func()->position = value;
815}
816
817/*!
818 Set the timeout, in milliseconds, before the gesture triggers.
819
820 The recognizer will detect a touch down and if \a msecs
821 later the touch is still down, it will trigger the QTapAndHoldGesture.
822 The default value is 700 milliseconds.
823*/
824void QTapAndHoldGesture::setTimeout(int msecs)
825{
826 QTapAndHoldGesturePrivate::Timeout = msecs;
827}
828
829/*!
830 Gets the timeout, in milliseconds, before the gesture triggers.
831
832 The recognizer will detect a touch down and if timeout()
833 later the touch is still down, it will trigger the QTapAndHoldGesture.
834 The default value is 700 milliseconds.
835*/
836int QTapAndHoldGesture::timeout()
837{
838 return QTapAndHoldGesturePrivate::Timeout;
839}
840
841int QTapAndHoldGesturePrivate::Timeout = 700; // in ms
842
843
844/*!
845 \class QGestureEvent
846 \since 4.6
847 \ingroup events
848 \ingroup gestures
849 \inmodule QtWidgets
850
851 \brief The QGestureEvent class provides the description of triggered gestures.
852
853 The QGestureEvent class contains a list of gestures, which can be obtained using the
854 gestures() function.
855
856 The gestures are either active or canceled. A list of those that are currently being
857 executed can be obtained using the activeGestures() function. A list of those which
858 were previously active and have been canceled can be accessed using the
859 canceledGestures() function. A gesture might be canceled if the current window loses
860 focus, for example, or because of a timeout, or for other reasons.
861
862 If the event handler does not accept the event by calling the generic
863 QEvent::accept() function, all individual QGesture object that were not
864 accepted and in the Qt::GestureStarted state will be propagated up the
865 parent widget chain until a widget accepts them individually, by calling
866 QGestureEvent::accept() for each of them, or an event filter consumes the
867 event.
868
869 \section1 Further Reading
870
871 For an overview of gesture handling in Qt and information on using gestures
872 in your applications, see the \l{Gestures in Widgets and Graphics View} document.
873
874 \sa QGesture, QGestureRecognizer,
875 QWidget::grabGesture(), QGraphicsObject::grabGesture()
876*/
877
878/*!
879 Creates new QGestureEvent containing a list of \a gestures.
880*/
881QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
882 : QEvent(QEvent::Gesture), m_gestures(gestures), m_widget(nullptr)
883
884{
885}
886
887/*!
888 Destroys QGestureEvent.
889*/
890QGestureEvent::~QGestureEvent()
891{
892}
893
894/*!
895 Returns all gestures that are delivered in the event.
896*/
897QList<QGesture *> QGestureEvent::gestures() const
898{
899 return m_gestures;
900}
901
902/*!
903 Returns a gesture object by \a type.
904*/
905QGesture *QGestureEvent::gesture(Qt::GestureType type) const
906{
907 for (int i = 0; i < m_gestures.size(); ++i)
908 if (m_gestures.at(i)->gestureType() == type)
909 return m_gestures.at(i);
910 return nullptr;
911}
912
913/*!
914 Returns a list of active (not canceled) gestures.
915*/
916QList<QGesture *> QGestureEvent::activeGestures() const
917{
918 QList<QGesture *> gestures;
919 for (QGesture *gesture : m_gestures) {
920 if (gesture->state() != Qt::GestureCanceled)
921 gestures.append(gesture);
922 }
923 return gestures;
924}
925
926/*!
927 Returns a list of canceled gestures.
928*/
929QList<QGesture *> QGestureEvent::canceledGestures() const
930{
931 QList<QGesture *> gestures;
932 for (QGesture *gesture : m_gestures) {
933 if (gesture->state() == Qt::GestureCanceled)
934 gestures.append(gesture);
935 }
936 return gestures;
937}
938
939/*!
940 Sets the accept flag of the given \a gesture object to the specified \a value.
941
942 Setting the accept flag indicates that the event receiver wants the \a gesture.
943 Unwanted gestures may be propagated to the parent widget.
944
945 By default, gestures in events of type QEvent::Gesture are accepted, and
946 gestures in QEvent::GestureOverride events are ignored.
947
948 For convenience, the accept flag can also be set with
949 \l{QGestureEvent::accept()}{accept(gesture)}, and cleared with
950 \l{QGestureEvent::ignore()}{ignore(gesture)}.
951*/
952void QGestureEvent::setAccepted(QGesture *gesture, bool value)
953{
954 if (gesture)
955 setAccepted(gesture->gestureType(), value);
956}
957
958/*!
959 Sets the accept flag of the given \a gesture object, the equivalent of calling
960 \l{QGestureEvent::setAccepted()}{setAccepted(gesture, true)}.
961
962 Setting the accept flag indicates that the event receiver wants the
963 gesture. Unwanted gestures may be propagated to the parent widget.
964
965 \sa QGestureEvent::ignore()
966*/
967void QGestureEvent::accept(QGesture *gesture)
968{
969 if (gesture)
970 setAccepted(gesture->gestureType(), true);
971}
972
973/*!
974 Clears the accept flag parameter of the given \a gesture object, the equivalent
975 of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
976
977 Clearing the accept flag indicates that the event receiver does not
978 want the gesture. Unwanted gestures may be propagated to the parent widget.
979
980 \sa QGestureEvent::accept()
981*/
982void QGestureEvent::ignore(QGesture *gesture)
983{
984 if (gesture)
985 setAccepted(gesture->gestureType(), false);
986}
987
988/*!
989 Returns \c true if the \a gesture is accepted; otherwise returns \c false.
990*/
991bool QGestureEvent::isAccepted(QGesture *gesture) const
992{
993 return gesture ? isAccepted(gesture->gestureType()) : false;
994}
995
996/*!
997 Sets the accept flag of the given \a gestureType object to the specified
998 \a value.
999
1000 Setting the accept flag indicates that the event receiver wants to receive
1001 gestures of the specified type, \a gestureType. Unwanted gestures may be
1002 propagated to the parent widget.
1003
1004 By default, gestures in events of type QEvent::Gesture are accepted, and
1005 gestures in QEvent::GestureOverride events are ignored.
1006
1007 For convenience, the accept flag can also be set with
1008 \l{QGestureEvent::accept()}{accept(gestureType)}, and cleared with
1009 \l{QGestureEvent::ignore()}{ignore(gestureType)}.
1010*/
1011void QGestureEvent::setAccepted(Qt::GestureType gestureType, bool value)
1012{
1013 setAccepted(false);
1014 m_accepted[gestureType] = value;
1015}
1016
1017/*!
1018 Sets the accept flag of the given \a gestureType, the equivalent of calling
1019 \l{QGestureEvent::setAccepted()}{setAccepted(gestureType, true)}.
1020
1021 Setting the accept flag indicates that the event receiver wants the
1022 gesture. Unwanted gestures may be propagated to the parent widget.
1023
1024 \sa QGestureEvent::ignore()
1025*/
1026void QGestureEvent::accept(Qt::GestureType gestureType)
1027{
1028 setAccepted(gestureType, true);
1029}
1030
1031/*!
1032 Clears the accept flag parameter of the given \a gestureType, the equivalent
1033 of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
1034
1035 Clearing the accept flag indicates that the event receiver does not
1036 want the gesture. Unwanted gestures may be propgated to the parent widget.
1037
1038 \sa QGestureEvent::accept()
1039*/
1040void QGestureEvent::ignore(Qt::GestureType gestureType)
1041{
1042 setAccepted(gestureType, false);
1043}
1044
1045/*!
1046 Returns \c true if the gesture of type \a gestureType is accepted; otherwise
1047 returns \c false.
1048*/
1049bool QGestureEvent::isAccepted(Qt::GestureType gestureType) const
1050{
1051 return m_accepted.value(gestureType, true);
1052}
1053
1054/*!
1055 \internal
1056
1057 Sets the widget for this event to the \a widget specified.
1058*/
1059void QGestureEvent::setWidget(QWidget *widget)
1060{
1061 m_widget = widget;
1062}
1063
1064/*!
1065 Returns the widget on which the event occurred.
1066*/
1067QWidget *QGestureEvent::widget() const
1068{
1069 return m_widget;
1070}
1071
1072#if QT_CONFIG(graphicsview)
1073/*!
1074 Returns the scene-local coordinates if the \a gesturePoint is inside a
1075 graphics view.
1076
1077 This functional might be useful when the gesture event is delivered to a
1078 QGraphicsObject to translate a point in screen coordinates to scene-local
1079 coordinates.
1080
1081 \sa QPointF::isNull()
1082*/
1083QPointF QGestureEvent::mapToGraphicsScene(const QPointF &gesturePoint) const
1084{
1085 QWidget *w = widget();
1086 if (w) // we get the viewport as widget, not the graphics view
1087 w = w->parentWidget();
1088 QGraphicsView *view = qobject_cast<QGraphicsView*>(w);
1089 if (view) {
1090 return view->mapToScene(view->mapFromGlobal(gesturePoint.toPoint()));
1091 }
1092 return QPointF();
1093}
1094#endif // QT_CONFIG(graphicsview)
1095
1096#ifndef QT_NO_DEBUG_STREAM
1097
1098static void formatGestureHeader(QDebug d, const char *className, const QGesture *gesture)
1099{
1100 d << className << "(state=";
1101 QtDebugUtils::formatQEnum(d, gesture->state());
1102 if (gesture->hasHotSpot()) {
1103 d << ",hotSpot=";
1104 QtDebugUtils::formatQPoint(d, gesture->hotSpot());
1105 }
1106}
1107
1108Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QGesture *gesture)
1109{
1110 QDebugStateSaver saver(d);
1111 d.nospace();
1112 switch (gesture->gestureType()) {
1113 case Qt::TapGesture:
1114 formatGestureHeader(d, "QTapGesture", gesture);
1115 d << ",position=";
1116 QtDebugUtils::formatQPoint(d, static_cast<const QTapGesture*>(gesture)->position());
1117 d << ')';
1118 break;
1119 case Qt::TapAndHoldGesture: {
1120 const QTapAndHoldGesture *tap = static_cast<const QTapAndHoldGesture*>(gesture);
1121 formatGestureHeader(d, "QTapAndHoldGesture", tap);
1122 d << ",position=";
1123 QtDebugUtils::formatQPoint(d, tap->position());
1124 d << ",timeout=" << tap->timeout() << ')';
1125 }
1126 break;
1127 case Qt::PanGesture: {
1128 const QPanGesture *pan = static_cast<const QPanGesture*>(gesture);
1129 formatGestureHeader(d, "QPanGesture", pan);
1130 d << ",lastOffset=";
1131 QtDebugUtils::formatQPoint(d, pan->lastOffset());
1132 d << pan->lastOffset();
1133 d << ",offset=";
1134 QtDebugUtils::formatQPoint(d, pan->offset());
1135 d << ",acceleration=" << pan->acceleration() << ",delta=";
1136 QtDebugUtils::formatQPoint(d, pan->delta());
1137 d << ')';
1138 }
1139 break;
1140 case Qt::PinchGesture: {
1141 const QPinchGesture *pinch = static_cast<const QPinchGesture*>(gesture);
1142 formatGestureHeader(d, "QPinchGesture", pinch);
1143 d << ",totalChangeFlags=" << pinch->totalChangeFlags()
1144 << ",changeFlags=" << pinch->changeFlags() << ",startCenterPoint=";
1145 QtDebugUtils::formatQPoint(d, pinch->startCenterPoint());
1146 d << ",lastCenterPoint=";
1147 QtDebugUtils::formatQPoint(d, pinch->lastCenterPoint());
1148 d << ",centerPoint=";
1149 QtDebugUtils::formatQPoint(d, pinch->centerPoint());
1150 d << ",totalScaleFactor=" << pinch->totalScaleFactor()
1151 << ",lastScaleFactor=" << pinch->lastScaleFactor()
1152 << ",scaleFactor=" << pinch->scaleFactor()
1153 << ",totalRotationAngle=" << pinch->totalRotationAngle()
1154 << ",lastRotationAngle=" << pinch->lastRotationAngle()
1155 << ",rotationAngle=" << pinch->rotationAngle() << ')';
1156 }
1157 break;
1158 case Qt::SwipeGesture: {
1159 const QSwipeGesture *swipe = static_cast<const QSwipeGesture*>(gesture);
1160 formatGestureHeader(d, "QSwipeGesture", swipe);
1161 d << ",horizontalDirection=";
1162 QtDebugUtils::formatQEnum(d, swipe->horizontalDirection());
1163 d << ",verticalDirection=";
1164 QtDebugUtils::formatQEnum(d, swipe->verticalDirection());
1165 d << ",swipeAngle=" << swipe->swipeAngle() << ')';
1166 }
1167 break;
1168 default:
1169 formatGestureHeader(d, "Custom gesture", gesture);
1170 d << ",type=" << gesture->gestureType() << ')';
1171 break;
1172 }
1173 return d;
1174}
1175
1176Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QGestureEvent *gestureEvent)
1177{
1178 QDebugStateSaver saver(d);
1179 d.nospace();
1180 d << "QGestureEvent(" << gestureEvent->gestures() << ')';
1181 return d;
1182}
1183
1184#endif // !QT_NO_DEBUG_STREAM
1185QT_END_NAMESPACE
1186
1187#include <moc_qgesture.cpp>
1188
1189#endif // QT_NO_GESTURES
1190