322QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
328 Q_CONSTINIT
static QElapsedTimer monotonicTimer;
329 if (!monotonicTimer.isValid())
330 monotonicTimer.start();
332 QFlickGesture *q =
static_cast<QFlickGesture *>(state);
333 QFlickGesturePrivate *d = q->d_func();
335 QScroller *scroller = d->receiverScroller;
339 QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
340#if QT_CONFIG(graphicsview)
341 QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
345 if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
350 const QMouseEvent *me =
nullptr;
351#if QT_CONFIG(graphicsview)
352 const QGraphicsSceneMouseEvent *gsme =
nullptr;
354 const QTouchEvent *te =
nullptr;
359 Qt::KeyboardModifiers keyboardModifiers = Qt::NoModifier;
360 Qt::MouseButtons mouseButtons = Qt::NoButton;
361 switch (event->type()) {
362 case QEvent::MouseButtonPress:
363 case QEvent::MouseButtonRelease:
364 case QEvent::MouseMove:
367 if (button != Qt::NoButton) {
368 me =
static_cast<
const QMouseEvent *>(event);
369 keyboardModifiers = me->modifiers();
370 mouseButtons = me->buttons();
371 globalPos = me->globalPosition().toPoint();
374#if QT_CONFIG(graphicsview)
375 case QEvent::GraphicsSceneMousePress:
376 case QEvent::GraphicsSceneMouseRelease:
377 case QEvent::GraphicsSceneMouseMove:
378 if (!receiverGraphicsObject)
380 if (button != Qt::NoButton) {
381 gsme =
static_cast<
const QGraphicsSceneMouseEvent *>(event);
382 keyboardModifiers = gsme->modifiers();
383 mouseButtons = gsme->buttons();
384 globalPos = gsme->screenPos();
388 case QEvent::TouchBegin:
389 case QEvent::TouchEnd:
390 case QEvent::TouchUpdate:
391 if (button == Qt::NoButton) {
392 te =
static_cast<
const QTouchEvent *>(event);
393 keyboardModifiers = te->modifiers();
394 if (!te->points().isEmpty())
395 globalPos = te->points().at(0).globalPosition().toPoint();
401 if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive))
402 return Ignore | ConsumeEventHint;
406 case QEvent::MouseButtonDblClick:
407 if (scroller->state() != QScroller::Inactive)
408 return Ignore | ConsumeEventHint;
416#if QT_CONFIG(graphicsview)
424 QScroller::Input inputType = (QScroller::Input) 0;
426 switch (event->type()) {
427 case QEvent::MouseButtonPress:
428 if (me && me->button() == button && me->buttons() == button) {
429 point = me->globalPosition().toPoint();
430 inputType = QScroller::InputPress;
433 return CancelGesture;
436 case QEvent::MouseButtonRelease:
437 if (me && me->button() == button) {
438 point = me->globalPosition().toPoint();
439 inputType = QScroller::InputRelease;
442 case QEvent::MouseMove:
443 if (me && me->buttons() == button) {
444 point = me->globalPosition().toPoint();
445 inputType = QScroller::InputMove;
449#if QT_CONFIG(graphicsview)
450 case QEvent::GraphicsSceneMousePress:
451 if (gsme && gsme->button() == button && gsme->buttons() == button) {
452 point = gsme->scenePos();
453 inputType = QScroller::InputPress;
456 return CancelGesture;
459 case QEvent::GraphicsSceneMouseRelease:
460 if (gsme && gsme->button() == button) {
461 point = gsme->scenePos();
462 inputType = QScroller::InputRelease;
465 case QEvent::GraphicsSceneMouseMove:
466 if (gsme && gsme->buttons() == button) {
467 point = gsme->scenePos();
468 inputType = QScroller::InputMove;
473 case QEvent::TouchBegin:
474 inputType = QScroller::InputPress;
476 case QEvent::TouchEnd:
478 inputType = QScroller::InputRelease;
480 case QEvent::TouchUpdate:
482 inputType = QScroller::InputMove;
484 if (te->pointingDevice()->type() == QInputDevice::DeviceType::TouchPad) {
485 if (te->points().size() != 2)
488 point = te->points().at(0).scenePressPosition() +
489 ((te->points().at(0).scenePosition() - te->points().at(0).scenePressPosition()) +
490 (te->points().at(1).scenePosition() - te->points().at(1).scenePressPosition())) / 2;
492 if (te->points().size() != 1)
495 point = te->points().at(0).scenePosition();
504 if (inputType == QScroller::InputPress) {
505 const auto activeScrollers = QScroller::activeScrollers();
506 for (QScroller *as : activeScrollers) {
507 if (as != scroller) {
508 QRegion scrollerRegion;
510 if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
511 scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
512#if QT_CONFIG(graphicsview)
513 }
else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
514 if (
const auto *scene = go->scene()) {
515 const auto goBoundingRectMappedToScene = go->mapToScene(go->boundingRect());
516 const auto views = scene->views();
517 for (QGraphicsView *gv : views) {
518 scrollerRegion |= gv->mapFromScene(goBoundingRectMappedToScene)
519 .translated(gv->mapToGlobal(QPoint(0, 0)));
525 if (scrollerRegion.contains(globalPos))
531 bool scrollerWasDragging = (scroller->state() == QScroller::Dragging);
532 bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling);
535 if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
536 point = w->mapFromGlobal(point.toPoint());
537#if QT_CONFIG(graphicsview)
538 else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
539 point = go->mapFromScene(point);
543 scroller->handleInput(inputType, point, monotonicTimer.elapsed());
548 bool scrollerIsActive = (scroller->state() == QScroller::Dragging ||
549 scroller->state() == QScroller::Scrolling);
554#if QT_CONFIG(graphicsview)
557 ) && scrollerIsActive)
558 result |= ConsumeEventHint;
566#if QT_CONFIG(graphicsview)
570 if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
571 PressDelayHandler::instance()->scrollerBecameActive(keyboardModifiers, mouseButtons);
572 else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
573 PressDelayHandler::instance()->scrollerWasIntercepted();
579 switch (event->type()) {
580 case QEvent::MouseButtonPress:
581#if QT_CONFIG(graphicsview)
582 case QEvent::GraphicsSceneMousePress:
584 if (scroller->state() == QScroller::Pressed) {
585 int pressDelay =
int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
586 if (pressDelay > 0) {
587 result |= ConsumeEventHint;
589 PressDelayHandler::instance()->pressed(event, pressDelay);
594 case QEvent::TouchBegin:
595 q->setHotSpot(globalPos);
596 result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
599 case QEvent::MouseMove:
600#if QT_CONFIG(graphicsview)
601 case QEvent::GraphicsSceneMouseMove:
603 if (PressDelayHandler::instance()->isDelaying())
604 result |= ConsumeEventHint;
606 case QEvent::TouchUpdate:
607 result |= scrollerIsActive ? TriggerGesture : Ignore;
610#if QT_CONFIG(graphicsview)
611 case QEvent::GraphicsSceneMouseRelease:
613 case QEvent::MouseButtonRelease:
614 if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
615 result |= ConsumeEventHint;
617 case QEvent::TouchEnd:
618 result |= scrollerIsActive ? FinishGesture : CancelGesture;