52QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
56 QPanGesture *q =
static_cast<QPanGesture *>(state);
57 QPanGesturePrivate *d = q->d_func();
59 QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
60 switch (event->type()) {
61 case QEvent::TouchBegin: {
62 result = QGestureRecognizer::MayBeGesture;
63 d->lastOffset = d->offset = QPointF();
64 d->pointCount = m_pointCount;
67 case QEvent::TouchEnd: {
68 if (q->state() != Qt::NoGesture) {
69 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
70 if (ev->points().size() == d->pointCount) {
71 d->lastOffset = d->offset;
72 d->offset = panOffset(ev->points(), d->pointCount);
74 result = QGestureRecognizer::FinishGesture;
76 result = QGestureRecognizer::CancelGesture;
80 case QEvent::TouchUpdate: {
81 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
82 if (ev->points().size() >= d->pointCount) {
83 d->lastOffset = d->offset;
84 d->offset = panOffset(ev->points(), d->pointCount);
85 if (d->offset.x() > 10 || d->offset.y() > 10 ||
86 d->offset.x() < -10 || d->offset.y() < -10) {
87 q->setHotSpot(ev->points().first().globalPressPosition());
88 result = QGestureRecognizer::TriggerGesture;
90 result = QGestureRecognizer::MayBeGesture;
133 QPinchGesture *q =
static_cast<QPinchGesture *>(state);
136 QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
138 switch (event->type()) {
139 case QEvent::TouchBegin: {
140 result = QGestureRecognizer::MayBeGesture;
143 case QEvent::TouchEnd: {
144 if (q->state() != Qt::NoGesture) {
145 result = QGestureRecognizer::FinishGesture;
147 result = QGestureRecognizer::CancelGesture;
151 case QEvent::TouchUpdate: {
152 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
153 d->changeFlags = { };
154 if (ev->points().size() == 2) {
155 const QEventPoint &p1 = ev->points().at(0);
156 const QEventPoint &p2 = ev->points().at(1);
158 d->hotSpot = p1.globalPosition();
159 d->isHotSpotSet =
true;
161 QPointF centerPoint = (p1.globalPosition() + p2.globalPosition()) / 2.0;
163 d->startPosition[0] = p1.globalPosition();
164 d->startPosition[1] = p2.globalPosition();
165 d->lastCenterPoint = centerPoint;
167 d->lastCenterPoint = d->centerPoint;
169 d->centerPoint = centerPoint;
171 d->changeFlags |= QPinchGesture::CenterPointChanged;
174 d->scaleFactor = 1.0;
175 d->lastScaleFactor = 1.0;
177 d->lastScaleFactor = d->scaleFactor;
178 QLineF line(p1.globalPosition(), p2.globalPosition());
179 QLineF lastLine(p1.globalLastPosition(), p2.globalLastPosition());
180 qreal newScaleFactor = line.length() / lastLine.length();
181 if (newScaleFactor > kSingleStepScaleMax || newScaleFactor < kSingleStepScaleMin)
182 return QGestureRecognizer::Ignore;
183 d->scaleFactor = newScaleFactor;
185 d->totalScaleFactor = d->totalScaleFactor * d->scaleFactor;
186 d->changeFlags |= QPinchGesture::ScaleFactorChanged;
188 qreal angle = QLineF(p1.globalPosition(), p2.globalPosition()).angle();
191 qreal startAngle = QLineF(p1.globalPressPosition(), p2.globalPressPosition()).angle();
192 if (startAngle > 180)
194 const qreal rotationAngle = startAngle - angle;
196 d->lastRotationAngle = 0.0;
198 d->lastRotationAngle = d->rotationAngle;
199 d->rotationAngle = rotationAngle;
200 d->totalRotationAngle += d->rotationAngle - d->lastRotationAngle;
201 d->changeFlags |= QPinchGesture::RotationAngleChanged;
203 d->totalChangeFlags |= d->changeFlags;
205 result = QGestureRecognizer::TriggerGesture;
208 if (q->state() == Qt::NoGesture)
209 result = QGestureRecognizer::Ignore;
211 result = QGestureRecognizer::FinishGesture;
258 QSwipeGesture *q =
static_cast<QSwipeGesture *>(state);
261 QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
263 switch (event->type()) {
264 case QEvent::TouchBegin: {
265 d->velocityValue = 1;
267 d->state = QSwipeGesturePrivate::Started;
268 result = QGestureRecognizer::MayBeGesture;
271 case QEvent::TouchEnd: {
272 if (q->state() != Qt::NoGesture) {
273 result = QGestureRecognizer::FinishGesture;
275 result = QGestureRecognizer::CancelGesture;
279 case QEvent::TouchUpdate: {
280 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
281 if (d->state == QSwipeGesturePrivate::NoGesture)
282 result = QGestureRecognizer::CancelGesture;
283 else if (ev->points().size() == 3) {
284 d->state = QSwipeGesturePrivate::ThreePointsReached;
285 const QEventPoint &p1 = ev->points().at(0);
286 const QEventPoint &p2 = ev->points().at(1);
287 const QEventPoint &p3 = ev->points().at(2);
289 if (d->lastPositions[0].isNull()) {
290 d->lastPositions[0] = p1.globalPressPosition().toPoint();
291 d->lastPositions[1] = p2.globalPressPosition().toPoint();
292 d->lastPositions[2] = p3.globalPressPosition().toPoint();
294 d->hotSpot = p1.globalPosition();
295 d->isHotSpotSet =
true;
297 int xDistance = (p1.globalPosition().x() - d->lastPositions[0].x() +
298 p2.globalPosition().x() - d->lastPositions[1].x() +
299 p3.globalPosition().x() - d->lastPositions[2].x()) / 3;
300 int yDistance = (p1.globalPosition().y() - d->lastPositions[0].y() +
301 p2.globalPosition().y() - d->lastPositions[1].y() +
302 p3.globalPosition().y() - d->lastPositions[2].y()) / 3;
304 const int distance = xDistance >= yDistance ? xDistance : yDistance;
305 int elapsedTime = d->time.restart();
308 d->velocityValue = 0.9 * d->velocityValue + (qreal) distance / elapsedTime;
309 d->swipeAngle = QLineF(p1.globalPressPosition(), p1.globalPosition()).angle();
311 static const int MoveThreshold = 50;
312 static const int directionChangeThreshold = MoveThreshold / 8;
313 if (qAbs(xDistance) > MoveThreshold || qAbs(yDistance) > MoveThreshold) {
315 d->lastPositions[0] = p1.globalPosition().toPoint();
316 d->lastPositions[1] = p2.globalPosition().toPoint();
317 d->lastPositions[2] = p3.globalPosition().toPoint();
318 result = QGestureRecognizer::TriggerGesture;
320 if (d->verticalDirection == QSwipeGesture::NoDirection || qAbs(yDistance) > directionChangeThreshold) {
321 const QSwipeGesture::SwipeDirection vertical = yDistance > 0
322 ? QSwipeGesture::Down : QSwipeGesture::Up;
323 if (d->verticalDirection != QSwipeGesture::NoDirection && d->verticalDirection != vertical)
324 result = QGestureRecognizer::CancelGesture;
325 d->verticalDirection = vertical;
327 if (d->horizontalDirection == QSwipeGesture::NoDirection || qAbs(xDistance) > directionChangeThreshold) {
328 const QSwipeGesture::SwipeDirection horizontal = xDistance > 0
329 ? QSwipeGesture::Right : QSwipeGesture::Left;
330 if (d->horizontalDirection != QSwipeGesture::NoDirection && d->horizontalDirection != horizontal)
331 result = QGestureRecognizer::CancelGesture;
332 d->horizontalDirection = horizontal;
335 if (q->state() != Qt::NoGesture)
336 result = QGestureRecognizer::TriggerGesture;
338 result = QGestureRecognizer::MayBeGesture;
340 }
else if (ev->points().size() > 3) {
341 result = QGestureRecognizer::CancelGesture;
344 case QSwipeGesturePrivate::NoGesture:
345 result = QGestureRecognizer::MayBeGesture;
347 case QSwipeGesturePrivate::Started:
348 result = QGestureRecognizer::Ignore;
350 case QSwipeGesturePrivate::ThreePointsReached:
351 result = (ev->touchPointStates() & QEventPoint::State::Pressed)
352 ? QGestureRecognizer::CancelGesture : QGestureRecognizer::Ignore;
400 QTapGesture *q =
static_cast<QTapGesture *>(state);
403 QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
405 switch (event->type()) {
406 case QEvent::TouchBegin: {
407 const auto ev =
static_cast<
const QTouchEvent *>(event);
408 d->position = ev->points().at(0).position();
409 q->setHotSpot(ev->points().at(0).globalPosition());
410 result = QGestureRecognizer::TriggerGesture;
413 case QEvent::TouchUpdate:
414 case QEvent::TouchEnd: {
415 const auto ev =
static_cast<
const QTouchEvent *>(event);
416 if (q->state() != Qt::NoGesture && ev->points().size() == 1) {
417 const QEventPoint &p = ev->points().at(0);
418 QPoint delta = p.position().toPoint() - p.pressPosition().toPoint();
419 enum { TapRadius = 40 };
420 if (delta.manhattanLength() <= TapRadius) {
421 if (event->type() == QEvent::TouchEnd)
422 result = QGestureRecognizer::FinishGesture;
424 result = QGestureRecognizer::TriggerGesture;
429 case QEvent::MouseButtonPress:
430 case QEvent::MouseMove:
431 case QEvent::MouseButtonRelease:
432 result = QGestureRecognizer::Ignore;
435 result = QGestureRecognizer::Ignore;
471 QTapAndHoldGesture *q =
static_cast<QTapAndHoldGesture *>(state);
474 if (object == state && event->type() == QEvent::Timer) {
475 d->tapAndHoldTimer.stop();
476 return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
479 enum { TapRadius = 40 };
481 switch (event->type()) {
482#if QT_CONFIG(graphicsview)
483 case QEvent::GraphicsSceneMousePress: {
484 const QGraphicsSceneMouseEvent *gsme =
static_cast<
const QGraphicsSceneMouseEvent *>(event);
485 d->position = gsme->screenPos();
486 q->setHotSpot(d->position);
487 d->tapAndHoldTimer.start(QTapAndHoldGesturePrivate::Timeout * 1ms, q);
488 return QGestureRecognizer::MayBeGesture;
491 case QEvent::MouseButtonPress: {
492 const QMouseEvent *me =
static_cast<
const QMouseEvent *>(event);
493 d->position = me->globalPosition().toPoint();
494 q->setHotSpot(d->position);
495 d->tapAndHoldTimer.start(QTapAndHoldGesturePrivate::Timeout * 1ms, q);
496 return QGestureRecognizer::MayBeGesture;
498 case QEvent::TouchBegin: {
499 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
500 d->position = ev->points().at(0).globalPressPosition();
501 q->setHotSpot(d->position);
502 d->tapAndHoldTimer.start(QTapAndHoldGesturePrivate::Timeout * 1ms, q);
503 return QGestureRecognizer::MayBeGesture;
505#if QT_CONFIG(graphicsview)
506 case QEvent::GraphicsSceneMouseRelease:
508 case QEvent::MouseButtonRelease:
509 case QEvent::TouchEnd:
510 return QGestureRecognizer::CancelGesture;
511 case QEvent::TouchUpdate: {
512 const QTouchEvent *ev =
static_cast<
const QTouchEvent *>(event);
513 if (d->tapAndHoldTimer.isActive() && ev->points().size() == 1) {
514 const QEventPoint &p = ev->points().at(0);
515 QPoint delta = p.position().toPoint() - p.pressPosition().toPoint();
516 if (delta.manhattanLength() <= TapRadius)
517 return QGestureRecognizer::MayBeGesture;
519 return QGestureRecognizer::CancelGesture;
521 case QEvent::MouseMove: {
522 const QMouseEvent *me =
static_cast<
const QMouseEvent *>(event);
523 QPoint delta = me->globalPosition().toPoint() - d->position.toPoint();
524 if (d->tapAndHoldTimer.isActive() && delta.manhattanLength() <= TapRadius)
525 return QGestureRecognizer::MayBeGesture;
526 return QGestureRecognizer::CancelGesture;
528#if QT_CONFIG(graphicsview)
529 case QEvent::GraphicsSceneMouseMove: {
530 const QGraphicsSceneMouseEvent *gsme =
static_cast<
const QGraphicsSceneMouseEvent *>(event);
531 QPoint delta = gsme->screenPos() - d->position.toPoint();
532 if (d->tapAndHoldTimer.isActive() && delta.manhattanLength() <= TapRadius)
533 return QGestureRecognizer::MayBeGesture;
534 return QGestureRecognizer::CancelGesture;
538 return QGestureRecognizer::Ignore;