10#if QT_CONFIG(quick_draganddrop)
14#include <QtQuick/private/qquickpointerhandler_p.h>
15#include <QtQuick/private/qquicktransition_p.h>
16#include <private/qqmlglobal_p.h>
18#include <QtQml/qqmlinfo.h>
19#include <QtGui/qevent.h>
20#include <QtGui/qguiapplication.h>
21#include <QtGui/private/qguiapplication_p.h>
22#include <QtGui/private/qeventpoint_p.h>
23#include <QtGui/qstylehints.h>
24#include <QtCore/qmath.h>
25#include <qpa/qplatformintegration.h>
49 , m_yPosition(0.), m_heightRatio(0.)
79 bool changeWidth =
false;
80 bool changeHeight =
false;
85 const qreal maxYBounds = maxyextent + viewheight;
89 qreal y =
p->pixelAligned ? std::round(
p->vData.move.value()) :
p->vData.move.value();
90 pagePos = (-
y + flickable->
minYExtent()) / maxYBounds;
91 pageSize = viewheight / maxYBounds;
94 if (pageSize != m_heightRatio) {
95 m_heightRatio = pageSize;
98 if (pagePos != m_yPosition) {
99 m_yPosition = pagePos;
106 const qreal maxXBounds = maxxextent + viewwidth;
108 qreal x =
p->pixelAligned ? std::round(
p->hData.move.value()) :
p->hData.move.value();
109 pagePos = (-
x + flickable->
minXExtent()) / maxXBounds;
110 pageSize = viewwidth / maxXBounds;
116 if (pageSize != m_widthRatio) {
117 m_widthRatio = pageSize;
120 if (pagePos != m_xPosition) {
121 m_xPosition = pagePos;
151 if (!
fp->rebound || !
fp->rebound->enabled())
172 if (axisData == &
fp->hData)
188 if (!
fp->hData.transitionToBounds->isActive()
189 && !
fp->vData.transitionToBounds->isActive()) {
222 return flickable->
contains(posInFlickable);
249 if (wheelDecelerationEnv > 0)
263 q->setAcceptTouchEvents(
true);
264 q->setFiltersChildMouseEvents(
true);
300 qreal v = velocityBuffer.at(
i);
311 Qt::Orientations orient;
317 q->viewportMoved(orient);
325 emit q->contentXChanged();
327 emit q->contentYChanged();
348 qreal maxDistance = -1;
349 data.fixingUp =
false;
352 maxDistance =
qAbs(minExtent -
data.move.value());
353 data.flickTarget = minExtent;
355 maxDistance =
qAbs(maxExtent -
data.move.value());
356 data.flickTarget = maxExtent;
368 qCDebug(lcFlickable) <<
"choosing deceleration" << accel <<
"for" << eventType;
379 if (!
data.inOvershoot) {
412 if (!
q->isComponentComplete())
420 if (!
q->isComponentComplete())
444 data.fixingUp =
true;
447 if (
data.transitionToBounds &&
data.transitionToBounds->startTransition(&
data, toPos)) {
448 q->movementStarting();
449 data.fixingUp =
true;
454 data.fixingUp =
true;
463 if (
data.transitionToBounds)
464 data.transitionToBounds->stopTransition();
488 if (
data.move.value() >= minExtent || maxExtent > minExtent) {
490 if (
data.move.value() != minExtent) {
493 }
else if (
data.move.value() <= maxExtent) {
496 }
else if (-std::round(-
data.move.value()) !=
data.move.value()) {
502 else if (
data.smoothVelocity.value() > 0)
504 else if (
data.smoothVelocity.value() < 0)
510 data.inOvershoot =
false;
517 if (
a == 0.0 ||
b == 0.0) {
537 bool atXBeginningChange =
false, atXEndChange =
false;
538 bool atYBeginningChange =
false, atYEndChange =
false;
541 const qreal maxyextent = -
q->maxYExtent();
542 const qreal minyextent = -
q->minYExtent();
549 atYBeginningChange =
true;
561 const qreal maxxextent = -
q->maxXExtent();
562 const qreal minxextent = -
q->minXExtent();
569 atXBeginningChange =
true;
582 qreal originY =
q->originY();
585 emit q->originYChanged();
591 qreal originX =
q->originX();
594 emit q->originXChanged();
598 if (atXEndChange || atYEndChange || atXBeginningChange || atYBeginningChange)
599 emit q->isAtBoundaryChanged();
601 emit q->atXEndChanged();
602 if (atXBeginningChange)
603 emit q->atXBeginningChanged();
605 emit q->atYEndChanged();
606 if (atYBeginningChange)
607 emit q->atYBeginningChanged();
800 return -
d->contentItem->x();
806 d->hData.explicitValue =
true;
807 d->resetTimeline(
d->hData);
808 d->hData.vTime =
d->timeline.time();
812 d->hData.contentPositionChangedExternallyDuringDrag =
d->hData.dragging;
813 d->hData.move.setValue(-
pos);
814 d->hData.contentPositionChangedExternallyDuringDrag =
false;
821 return -
d->contentItem->y();
827 d->vData.explicitValue =
true;
828 d->resetTimeline(
d->vData);
829 d->vData.vTime =
d->timeline.time();
833 d->vData.contentPositionChangedExternallyDuringDrag =
d->vData.dragging;
834 d->vData.move.setValue(-
pos);
835 d->vData.contentPositionChangedExternallyDuringDrag =
false;
855 return d->interactive;
864 d->cancelInteraction();
886 return d->hData.smoothVelocity.value();
892 return d->vData.smoothVelocity.value();
907 return d->hData.atEnd;
913 return d->hData.atBeginning;
919 return d->vData.atEnd;
925 return d->vData.atBeginning;
949 return d->contentItem;
955 if (!
d->visibleArea) {
957 d->visibleArea->updateVisible();
959 return d->visibleArea;
984 return d->flickableDirection;
1011 return d->pixelAligned;
1017 if (align !=
d->pixelAligned) {
1018 d->pixelAligned = align;
1044 if (
v !=
d->syncDrag) {
1046 emit synchronousDragChanged();
1063 if (0 !=
event->timestamp())
1064 return event->timestamp();
1072 return (
window ?
window->effectiveDevicePixelRatio() :
qApp->devicePixelRatio());
1084 if (flickTime > 600) {
1092 if (flickTime > 300)
1137 emit q->flickingHorizontallyChanged();
1141 emit q->flickingVerticallyChanged();
1144 emit q->flickingChanged();
1151 const QVector2D &deltas,
bool overThreshold,
bool momentum,
1152 bool velocitySensitiveOverBounds,
const QVector2D &velocity)
1155 bool rejectY =
false;
1156 bool rejectX =
false;
1158 bool keepY =
q->yflick();
1159 bool keepX =
q->xflick();
1161 bool stealY =
false;
1162 bool stealX =
false;
1169 bool prevHMoved =
hMoved;
1170 bool prevVMoved =
vMoved;
1173 qCDebug(lcFlickable).nospace() << currentTimestamp <<
' ' << eventType <<
" drag @ " << localPos.
x() <<
',' << localPos.
y()
1174 <<
" \u0394 " << deltas.
x() <<
',' << deltas.
y() <<
" vel " << velocity.
x() <<
',' << velocity.
y()
1175 <<
" thrsld? " << overThreshold <<
" momentum? " << momentum <<
" velSens? " << velocitySensitiveOverBounds
1176 <<
" sincePress " << elapsedSincePress;
1180 if (overThreshold || elapsedSincePress > 200) {
1209 q->returnToBounds();
1213 if (velocitySensitiveOverBounds) {
1216 newY =
minY + overshoot;
1225 q->returnToBounds();
1229 if (velocitySensitiveOverBounds) {
1232 newY =
maxY - overshoot;
1243 if (!rejectY && overThreshold)
1256 if (overThreshold || elapsedSincePress > 200) {
1282 q->returnToBounds();
1286 if (velocitySensitiveOverBounds) {
1289 newX = minX + overshoot;
1291 newX = minX + (newX - minX) / 2;
1293 }
else if (newX <
maxX &&
maxX - minX <= 0) {
1298 q->returnToBounds();
1302 if (velocitySensitiveOverBounds) {
1305 newX =
maxX - overshoot;
1318 if (!rejectX && overThreshold)
1331 if ((stealX && keepX) || (stealY && keepY))
1332 q->setKeepMouseGrab(
true);
1349 if ((
hMoved && !prevHMoved) || (
vMoved && !prevVMoved))
1350 q->movementStarting();
1353 if (
q->yflick() && !rejectY)
1355 if (
q->xflick() && !rejectX)
1368 const auto &firstPoint =
event->points().first();
1369 const auto &
pos = firstPoint.position();
1372 bool overThreshold =
false;
1374 if (
event->pointCount() == 1) {
1380 qCDebug(lcFilter) <<
q->objectName() <<
"ignoring multi-touch" <<
event;
1383 drag(currentTimestamp,
event->type(),
pos, deltas, overThreshold,
false,
false, velocity);
1390 q->setKeepMouseGrab(
false);
1406 bool canBoost =
false;
1407 const auto pos =
event->points().first().position();
1408 const auto pressPos =
q->mapFromGlobal(
event->points().first().globalPressPosition());
1410 qCDebug(lcVel) <<
event->deviceType() <<
event->type() <<
"velocity" <<
event->points().first().velocity() <<
"transformed to local" << eventVelocity;
1412 qreal vVelocity = 0;
1427 qreal hVelocity = 0;
1445 bool flickedVertically =
false;
1448 if (isVerticalFlickAllowed) {
1451 flickedVertically =
flickY(
event->type(), vVelocity);
1454 bool flickedHorizontally =
false;
1457 if (isHorizontalFlickAllowed) {
1460 flickedHorizontally =
flickX(
event->type(), hVelocity);
1463 if (!isVerticalFlickAllowed)
1466 if (!isHorizontalFlickAllowed)
1471 q->movementEnding();
1473 if (flickedVertically)
1475 if (flickedHorizontally)
1477 q->movementStarting();
1484 if (
d->interactive && !
d->replayingPressEvent &&
d->wantsPointerEvent(
event)) {
1486 d->handlePressEvent(
event);
1496 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1497 d->handleMoveEvent(
event);
1507 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1508 if (
d->delayedPressEvent) {
1509 d->replayDelayedPress();
1514 const auto oldPosition =
event->point(0).position();
1515 QMutableEventPoint::setPosition(
event->point(0), grabber->mapFromScene(
event->scenePosition()));
1521 d->stealMouse =
false;
1526 d->handleReleaseEvent(
event);
1536 bool unhandled =
false;
1537 const auto &firstPoint =
event->points().first();
1538 switch (firstPoint.state()) {
1540 if (
d->interactive && !
d->replayingPressEvent &&
d->wantsPointerEvent(
event)) {
1542 d->handlePressEvent(
event);
1549 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1550 d->handleMoveEvent(
event);
1557 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1558 if (
d->delayedPressEvent) {
1559 d->replayDelayedPress();
1562 auto &firstPoint =
event->point(0);
1564 const auto localPos = grabber->mapFromScene(firstPoint.scenePosition());
1570 d->stealMouse =
false;
1575 d->handleReleaseEvent(
event);
1589#if QT_CONFIG(wheelevent)
1590void QQuickFlickable::wheelEvent(QWheelEvent *
event)
1593 if (!
d->interactive || !
d->wantsPointerEvent(
event)) {
1594 QQuickItem::wheelEvent(
event);
1597 qCDebug(lcWheel) <<
event->device() <<
event <<
event->source();
1598 event->setAccepted(
false);
1599 qint64 currentTimestamp =
d->computeCurrentTime(
event);
1600 switch (
event->phase()) {
1602 d->scrollingPhase =
true;
1604 d->vData.velocity = 0;
1605 d->hData.velocity = 0;
1607 d->maybeBeginDrag(currentTimestamp,
event->position());
1608 d->lastPosTime = -1;
1612 if (
d->scrollingPhase)
1617 d->scrollingPhase =
false;
1618 d->draggingEnding();
1621 d->lastPosTime = -1;
1625 d->scrollingPhase =
false;
1626 d->draggingEnding();
1629 d->lastPosTime = -1;
1630 d->stealMouse =
false;
1631 if (!
d->velocityTimeline.isActive() && !
d->timeline.isActive())
1638 d->lastPosTime = currentTimestamp;
1639 qCDebug(lcWheel) <<
"insufficient elapsed time: can't calculate velocity" <<
elapsed;
1645 int xDelta =
event->angleDelta().x();
1646 int yDelta =
event->angleDelta().y();
1649 const qreal wheelScroll = -
qApp->styleHints()->wheelScrollLines() * 24;
1652 if (
yflick() && yDelta != 0) {
1655 qreal scrollPixel = (-yDelta / 120.0 * wheelScroll);
1657 const qreal estContentPos = scrollPixel +
d->vData.move.value();
1658 if (scrollPixel > 0) {
1662 scrollPixel =
minYExtent() -
d->vData.move.value();
1667 scrollPixel =
maxYExtent() -
d->vData.move.value();
1671 d->resetTimeline(
d->vData);
1674 d->vData.fixingUp =
true;
1679 if (
xflick() && xDelta != 0) {
1682 qreal scrollPixel = (-xDelta / 120.0 * wheelScroll);
1684 const qreal estContentPos = scrollPixel +
d->hData.move.value();
1685 if (scrollPixel > 0) {
1689 scrollPixel =
minXExtent() -
d->hData.move.value();
1694 scrollPixel =
maxXExtent() -
d->hData.move.value();
1698 d->resetTimeline(
d->hData);
1701 d->hData.fixingUp =
true;
1717 elapsed = 120 /
qSqrt(
d->wheelDeceleration * 2 *
d->initialWheelFlickDistance);
1718 if (
yflick() && yDelta != 0) {
1721 if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 &&
d->vData.velocity < 0))
1722 d->vData.velocityBuffer.clear();
1723 d->vData.addVelocitySample(instVelocity,
d->maxVelocity);
1724 d->vData.updateVelocity();
1726 const bool newFlick =
d->flickY(
event->type(),
d->vData.velocity);
1727 if (newFlick && (
d->vData.atBeginning != (yDelta > 0) ||
d->vData.atEnd != (yDelta < 0))) {
1728 d->flickingStarted(
false,
true);
1735 if (
xflick() && xDelta != 0) {
1738 if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 &&
d->hData.velocity < 0))
1739 d->hData.velocityBuffer.clear();
1740 d->hData.addVelocitySample(instVelocity,
d->maxVelocity);
1741 d->hData.updateVelocity();
1743 const bool newFlick =
d->flickX(
event->type(),
d->hData.velocity);
1744 if (newFlick && (
d->hData.atBeginning != (xDelta > 0) ||
d->hData.atEnd != (xDelta < 0))) {
1745 d->flickingStarted(
true,
false);
1755 int xDelta =
event->pixelDelta().x();
1756 int yDelta =
event->pixelDelta().y();
1766 || (
xflick() &&
qAbs(
d->accumulatedWheelPixelDelta.x()) >
qAbs(
d->accumulatedWheelPixelDelta.y() * 2))
1767 || (
yflick() &&
qAbs(
d->accumulatedWheelPixelDelta.y()) >
qAbs(
d->accumulatedWheelPixelDelta.x() * 2))) {
1768 d->drag(currentTimestamp,
event->type(),
event->position(),
d->accumulatedWheelPixelDelta,
1769 true, !
d->scrollingPhase,
true, velocity);
1772 qCDebug(lcWheel) <<
"not dragging: accumulated deltas" <<
d->accumulatedWheelPixelDelta <<
1776 d->lastPosTime = currentTimestamp;
1778 if (!
event->isAccepted())
1779 QQuickItem::wheelEvent(
event);
1837 da->allowChildEventFiltering =
false;
1839 auto &firstPoint =
event->point(0);
1845 if (
event->exclusiveGrabber(firstPoint) ==
q)
1846 event->setExclusiveGrabber(firstPoint,
nullptr);
1848 qCDebug(lcReplay) <<
"replaying" <<
event.data();
1851 QMutableEventPoint::setPosition(firstPoint, firstPoint.scenePosition());
1856 qCDebug(lcReplay) <<
"replay done";
1860 da->allowChildEventFiltering =
true;
1881 const qreal minX =
q->minXExtent();
1890 qreal overshoot = 0.0;
1892 overshoot =
maxX -
x;
1894 overshoot = minX -
x;
1898 emit q->horizontalOvershootChanged();
1925 qreal overshoot = 0.0;
1927 overshoot =
maxY -
y;
1929 overshoot =
minY -
y;
1933 emit q->verticalOvershootChanged();
1940 if (
event->timerId() ==
d->delayedPressTimer.timerId()) {
1941 d->delayedPressTimer.stop();
1942 if (
d->delayedPressEvent) {
1943 d->replayDelayedPress();
1951 return d->vData.startMargin;
1957 return d->hData.startMargin;
1977 if (!
d->hData.explicitValue &&
d->hData.startMargin != 0.)
1979 if (!
d->vData.explicitValue &&
d->vData.startMargin != 0.)
1981 if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) {
1994 d->updateBeginningEnd();
2004 if (
qAbs(velocity) > 0) {
2007 qCDebug(lcVel) <<
"touchpad scroll phase: velocity" << velocity;
2015 qreal velocity = (
data.lastPos -
data.move.value()) * 1000 / dt;
2017 qCDebug(lcVel) <<
"velocity" <<
data.smoothVelocity.value() <<
"->" << velocity
2018 <<
"computed as (" <<
data.lastPos <<
"-" <<
data.move.value() <<
") * 1000 / ("
2020 data.smoothVelocity.setValue(velocity);
2025 if (!
data.inOvershoot && !
data.fixingUp &&
data.flicking
2026 && (
data.move.value() > minExtent ||
data.move.value() < maxExtent)
2027 &&
qAbs(
data.smoothVelocity.value()) > 10) {
2029 qreal overBound =
data.move.value() > minExtent
2030 ?
data.move.value() - minExtent
2031 : maxExtent -
data.move.value();
2032 data.inOvershoot =
true;
2035 if (maxDistance > 0)
2049 bool changed =
false;
2050 if (newGeometry.
width() != oldGeometry.
width()) {
2052 if (
d->hData.viewSize < 0)
2053 d->contentItem->setWidth(
width() -
d->hData.startMargin -
d->hData.endMargin);
2055 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2062 if (
d->vData.viewSize < 0)
2063 d->contentItem->setHeight(
height() -
d->vData.startMargin -
d->vData.endMargin);
2065 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2072 d->updateBeginningEnd();
2089 d->hData.velocity = xVelocity;
2090 d->vData.velocity = yVelocity;
2091 d->hData.vTime =
d->vData.vTime =
d->timeline.time();
2101 d->flickingStarted(flickedX, flickedY);
2107 if (!flickingH && !flickingV)
2113 emit q->flickingHorizontallyChanged();
2117 emit q->flickingVerticallyChanged();
2120 emit q->flickingChanged();
2121 emit q->flickStarted();
2134 d->resetTimeline(
d->hData);
2135 d->resetTimeline(
d->vData);
2141 if (!prop || !prop->
data)
2214 return d->boundsBehavior;
2220 if (
b ==
d->boundsBehavior)
2222 d->boundsBehavior =
b;
2276 if (!
d->hData.transitionToBounds)
2278 if (!
d->vData.transitionToBounds)
2281 if (
d->rebound != transition) {
2282 d->rebound = transition;
2314 return d->hData.viewSize;
2320 if (
d->hData.viewSize ==
w)
2322 d->hData.viewSize =
w;
2324 d->contentItem->setWidth(
width() -
d->hData.startMargin -
d->hData.endMargin);
2326 d->contentItem->setWidth(
w);
2327 d->hData.markExtentsDirty();
2329 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2332 }
else if (!
d->pressed &&
d->hData.fixingUp) {
2337 d->updateBeginningEnd();
2343 return d->vData.viewSize;
2349 if (
d->vData.viewSize ==
h)
2351 d->vData.viewSize =
h;
2353 d->contentItem->setHeight(
height() -
d->vData.startMargin -
d->vData.endMargin);
2355 d->contentItem->setHeight(
h);
2356 d->vData.markExtentsDirty();
2358 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2361 }
else if (!
d->pressed &&
d->vData.fixingUp) {
2366 d->updateBeginningEnd();
2383 return d->vData.startMargin;
2389 if (
d->vData.startMargin ==
m)
2391 d->vData.startMargin =
m;
2392 d->vData.markExtentsDirty();
2393 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2398 d->updateBeginningEnd();
2404 return d->vData.endMargin;
2410 if (
d->vData.endMargin ==
m)
2412 d->vData.endMargin =
m;
2413 d->vData.markExtentsDirty();
2414 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2419 d->updateBeginningEnd();
2425 return d->hData.startMargin;
2431 if (
d->hData.startMargin ==
m)
2433 d->hData.startMargin =
m;
2434 d->hData.markExtentsDirty();
2435 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2440 d->updateBeginningEnd();
2446 return d->hData.endMargin;
2452 if (
d->hData.endMargin ==
m)
2454 d->hData.endMargin =
m;
2455 d->hData.markExtentsDirty();
2456 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2461 d->updateBeginningEnd();
2506 const qreal oldHSize =
d->hData.viewSize;
2507 const qreal oldVSize =
d->vData.viewSize;
2508 const bool needToUpdateWidth =
w != oldHSize;
2509 const bool needToUpdateHeight =
h != oldVSize;
2510 d->hData.viewSize =
w;
2511 d->vData.viewSize =
h;
2513 if (needToUpdateWidth)
2515 if (needToUpdateHeight)
2518 if (center.x() != 0) {
2522 if (center.y() != 0) {
2526 d->updateBeginningEnd();
2547 if (
d->hData.viewSize < 0)
2550 return d->hData.viewSize;
2556 if (
d->vData.viewSize < 0)
2559 return d->vData.viewSize;
2572 const int contentWidthWithMargins =
d->contentItem->width() +
d->hData.startMargin +
d->hData.endMargin;
2576 return std::floor(
qAbs(contentWidthWithMargins -
width()));
2590 const int contentHeightWithMargins =
d->contentItem->height() +
d->vData.startMargin +
d->vData.endMargin;
2594 return std::floor(
qAbs(contentHeightWithMargins -
height()));
2603 if (!
d->replayingPressEvent)
2604 d->cancelInteraction();
2615 q->setKeepMouseGrab(
false);
2619 q->movementEnding();
2626 qCDebug(lcHandlerParent) <<
"reparenting handler" <<
h <<
"to contentItem of" <<
q;
2645 Q_ASSERT_X(receiver !=
this,
"",
"Flickable received a filter event for itself");
2649 d->stealMouse =
false;
2651 if (
event->pointCount() > 1) {
2652 qCDebug(lcFilter) <<
objectName() <<
"ignoring multi-touch" <<
event <<
"for" << receiver;
2653 d->stealMouse =
false;
2658 const auto &firstPoint =
event->points().first();
2660 if (
event->pointCount() == 1 &&
event->exclusiveGrabber(firstPoint) ==
this) {
2667 event->setAccepted(
true);
2672 bool receiverDisabled = receiver && !receiver->
isEnabled();
2673 bool stealThisEvent =
d->stealMouse;
2675 bool receiverRelinquishGrab =
false;
2678 if (
auto *mouseArea = qmlobject_cast<QQuickMouseArea *>(receiver)) {
2679 bool preventStealing = mouseArea->preventStealing();
2680#if QT_CONFIG(quick_draganddrop)
2681 if (mouseArea->drag() && mouseArea->drag()->target())
2682 preventStealing =
true;
2684 if (!preventStealing && receiverKeepsGrab) {
2685 receiverRelinquishGrab = !receiverDisabled
2689 if (receiverRelinquishGrab)
2690 receiverKeepsGrab =
false;
2694 if ((stealThisEvent ||
contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
2696 localizedEvent->setAccepted(
false);
2697 switch (firstPoint.state()) {
2699 d->handleMoveEvent(localizedEvent.
data());
2702 d->handlePressEvent(localizedEvent.
data());
2703 d->captureDelayedPress(receiver,
event);
2705 d->stealMouse =
false;
2706 stealThisEvent =
false;
2709 d->handleReleaseEvent(localizedEvent.
data());
2710 stealThisEvent =
d->stealMouse;
2716 if ((receiver && stealThisEvent && !receiverKeepsGrab && receiver !=
this) || receiverDisabled) {
2717 d->clearDelayedPress();
2718 event->setExclusiveGrabber(firstPoint,
this);
2719 }
else if (
d->delayedPressEvent) {
2720 event->setExclusiveGrabber(firstPoint,
this);
2723 const bool filtered = !receiverRelinquishGrab && (stealThisEvent ||
d->delayedPressEvent || receiverDisabled);
2725 event->setAccepted(
true);
2728 }
else if (
d->lastPosTime != -1) {
2729 d->lastPosTime = -1;
2734 d->lastPosTime = -1;
2735 d->clearDelayedPress();
2736 d->stealMouse =
false;
2751 auto wantsPointerEvent_helper = [
this,
d,
i, pointerEvent]() {
2754 const bool wants =
d->wantsPointerEvent(pointerEvent);
2761 (pointerEvent && !wantsPointerEvent_helper())) {
2762 d->cancelInteraction();
2769 const QObject *grabber = spe->exclusiveGrabber(spe->points().first());
2770 qCDebug(lcFilter) <<
"filtering UngrabMouse" << spe->points().first() <<
"for" <<
i <<
"grabber is" << grabber;
2771 if (grabber !=
this)
2773 }
else if (pointerEvent) {
2789 return d->maxVelocity;
2795 if (
v ==
d->maxVelocity)
2813 return d->deceleration;
2819 if (deceleration ==
d->deceleration)
2821 d->deceleration =
qMax(0.001, deceleration);
2828 return d->hData.flicking ||
d->vData.flicking;
2842 return d->hData.flicking;
2848 return d->vData.flicking;
2862 return d->hData.dragging ||
d->vData.dragging;
2868 return d->hData.dragging;
2874 return d->vData.dragging;
2883 emit q->draggingHorizontallyChanged();
2887 emit q->draggingVerticallyChanged();
2890 emit q->draggingChanged();
2891 emit q->dragStarted();
2901 emit q->draggingHorizontallyChanged();
2905 emit q->draggingVerticallyChanged();
2909 emit q->draggingChanged();
2910 emit q->dragEnded();
2948 return d->pressDelay;
2954 if (
d->pressDelay == delay)
2956 d->pressDelay = delay;
2973 return d->hData.moving ||
d->vData.moving;
2979 return d->hData.moving;
2985 return d->vData.moving;
2991 if ( (
d->hData.transitionToBounds &&
d->hData.transitionToBounds->isActive())
2992 || (
d->vData.transitionToBounds &&
d->vData.transitionToBounds->isActive()) ) {
2999 if (
d->vData.flicking)
3001 d->updateBeginningEnd();
3007 if ( (
d->hData.transitionToBounds &&
d->hData.transitionToBounds->isActive())
3008 || (
d->vData.transitionToBounds &&
d->vData.transitionToBounds->isActive()) ) {
3012 d->updateBeginningEnd();
3018 bool wasMoving =
d->hData.moving ||
d->vData.moving;
3019 if (
d->hMoved && !
d->hData.moving) {
3020 d->hData.moving =
true;
3023 if (
d->vMoved && !
d->vData.moving) {
3024 d->vData.moving =
true;
3028 if (!wasMoving && (
d->hData.moving ||
d->vData.moving)) {
3031#if QT_CONFIG(accessibility)
3032 if (QAccessible::isActive()) {
3033 QAccessibleEvent ev(
this, QAccessible::ScrollingStart);
3034 QAccessible::updateAccessibility(&ev);
3050 const bool wasFlicking =
d->hData.flicking ||
d->vData.flicking;
3051 if (hMovementEnding &&
d->hData.flicking) {
3052 d->hData.flicking =
false;
3055 if (vMovementEnding &&
d->vData.flicking) {
3056 d->vData.flicking =
false;
3059 if (wasFlicking && (!
d->hData.flicking || !
d->vData.flicking)) {
3062 }
else if (
d->hData.flickingWhenDragBegan ||
d->vData.flickingWhenDragBegan) {
3063 d->hData.flickingWhenDragBegan = !hMovementEnding;
3064 d->vData.flickingWhenDragBegan = !vMovementEnding;
3070 if (hMovementEnding &&
d->hData.moving
3071 && (!
d->pressed && !
d->stealMouse)) {
3072 d->hData.moving =
false;
3076 if (vMovementEnding &&
d->vData.moving
3077 && (!
d->pressed && !
d->stealMouse)) {
3078 d->vData.moving =
false;
3085#if QT_CONFIG(accessibility)
3086 if (QAccessible::isActive()) {
3087 QAccessibleEvent ev(
this, QAccessible::ScrollingEnd);
3088 QAccessible::updateAccessibility(&ev);
3093 if (hMovementEnding) {
3094 d->hData.fixingUp =
false;
3095 d->hData.smoothVelocity.setValue(0);
3096 d->hData.previousDragDelta = 0.0;
3098 if (vMovementEnding) {
3099 d->vData.fixingUp =
false;
3100 d->vData.smoothVelocity.setValue(0);
3101 d->vData.previousDragDelta = 0.0;
3108 emit q->horizontalVelocityChanged();
3109 emit q->verticalVelocityChanged();
3130 return d->hData.overshoot;
3151 return d->vData.overshoot;
3203 return d->boundsMovement;
3209 if (
d->boundsMovement == movement)
3212 d->boundsMovement = movement;
3213 emit boundsMovementChanged();
3218#include "moc_qquickflickable_p_p.cpp"
3220#include "moc_qquickflickable_p.cpp"
void start(int msec, QObject *obj)
\obsolete Use chrono overload instead.
void stop()
Stops the timer.
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
qint64 elapsed() const noexcept
Returns the number of milliseconds since this QElapsedTimer was last started.
void start() noexcept
Starts this timer.
bool isValid() const noexcept
Returns false if the timer has never been started or invalidated by a call to invalidate().
Type
This enum type defines the valid event types in Qt.
QGraphicsItem * parentItem() const
Returns a pointer to this item's parent item.
static QPlatformIntegration * platformIntegration()
QString objectName
the name of this object
void remove(int idx, int count=1)
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
A base class for pointer events.
virtual void setAccepted(bool accepted) override
\reimp
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
static bool isTabletEvent(const QPointerEvent *ev)
static bool isTouchEvent(const QPointerEvent *ev)
static bool isMouseEvent(const QPointerEvent *ev)
static QPointerEvent * clonePointerEvent(QPointerEvent *event, std::optional< QPointF > transformedLocalPos=std::nullopt)
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold=-1)
static void localizePointerEvent(QPointerEvent *ev, const QQuickItem *dest)
bool contains(const QPointF &point) const override
void resetTimeline(AxisData &data)
static void fixupX_callback(void *)
virtual bool flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, QQuickTimeLineCallback::Callback fixupCallback, QEvent::Type eventType, qreal velocity)
static qsizetype data_count(QQmlListProperty< QObject > *)
void flickingStarted(bool flickingH, bool flickingV)
void captureDelayedPress(QQuickItem *item, QPointerEvent *event)
qreal initialWheelFlickDistance
qint64 computeCurrentTime(QInputEvent *event) const
qreal overShootDistance(qreal velocity) const
void setViewportY(qreal y)
bool flickY(QEvent::Type eventType, qreal velocity)
void handleMoveEvent(QPointerEvent *)
bool isInnermostPressDelay(QQuickItem *item) const
QQuickFlickable::BoundsMovement boundsMovement
void adjustContentPos(AxisData &data, qreal toPos)
void drag(qint64 currentTimestamp, QEvent::Type eventType, const QPointF &localPos, const QVector2D &deltas, bool overThreshold, bool momentum, bool velocitySensitiveOverBounds, const QVector2D &velocity)
QQuickTransition * rebound
void addPointerHandler(QQuickPointerHandler *h) override
void setViewportX(qreal x)
virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent)
static QQuickFlickablePrivate * get(QQuickFlickable *o)
QQuickFlickable::FlickableDirection flickableDirection
bool isViewMoving() const
QQuickTimeLine velocityTimeline
static void fixupY_callback(void *)
static void data_clear(QQmlListProperty< QObject > *)
qreal devicePixelRatio() const
void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override
static void data_append(QQmlListProperty< QObject > *, QObject *)
void replayDelayedPress()
QPointerEvent * delayedPressEvent
QQuickFlickableVisibleArea * visibleArea
void handleReleaseEvent(QPointerEvent *)
void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, QQuickTimeLineCallback::Callback fixupCallback)
void handlePressEvent(QPointerEvent *)
QQuickFlickable::BoundsBehavior boundsBehavior
static QObject * data_at(QQmlListProperty< QObject > *, qsizetype)
QBasicTimer delayedPressTimer
void updateBeginningEnd()
QVector2D firstPointLocalVelocity(QPointerEvent *event)
bool flickX(QEvent::Type eventType, qreal velocity)
void maybeBeginDrag(qint64 currentTimestamp, const QPointF &pressPosn)
~QQuickFlickableReboundTransition()
bool startTransition(QQuickFlickablePrivate::AxisData *data, qreal toPos)
QQuickFlickableReboundTransition(QQuickFlickable *f, const QString &name)
void yPositionChanged(qreal yPosition)
void heightRatioChanged(qreal heightRatio)
void widthRatioChanged(qreal widthRatio)
void xPositionChanged(qreal xPosition)
QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr)
void flickDecelerationChanged()
void setMaximumFlickVelocity(qreal)
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
friend class QQuickFlickableReboundTransition
void touchEvent(QTouchEvent *event) override
This event handler can be reimplemented in a subclass to receive touch events for an item.
void mouseUngrabEvent() override
This event handler can be reimplemented in a subclass to be notified when a mouse ungrab event has oc...
void setBottomMargin(qreal m)
Q_INVOKABLE void flick(qreal xVelocity, qreal yVelocity)
\qmlmethod QtQuick::Flickable::flick(qreal xVelocity, qreal yVelocity)
void setPixelAligned(bool align)
void maximumFlickVelocityChanged()
bool isAtXEnd() const
\qmlproperty bool QtQuick::Flickable::atXBeginning \qmlproperty bool QtQuick::Flickable::atXEnd \qmlp...
virtual qreal minYExtent() const
QQuickFlickable(QQuickItem *parent=nullptr)
\qmlsignal QtQuick::Flickable::dragStarted()
void boundsBehaviorChanged()
Q_INVOKABLE void returnToBounds()
\qmlmethod QtQuick::Flickable::returnToBounds()
void setPressDelay(int delay)
bool isMovingHorizontally() const
FINALQQmlListProperty< QObject > flickableData
bool isInteractive() const
\qmlproperty bool QtQuick::Flickable::interactive
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
~QQuickFlickable() override
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setContentWidth(qreal)
void setLeftMargin(qreal m)
bool isFlickingVertically() const
BoundsBehavior boundsBehavior
FINALQQuickTransition * rebound
FINALqreal verticalOvershoot
virtual void setContentX(qreal pos)
void mousePressEvent(QMouseEvent *event) override
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center)
\qmlmethod QtQuick::Flickable::resizeContent(real width, real height, QPointF center)
FlickableDirection flickableDirection
void setRightMargin(qreal m)
void setTopMargin(qreal m)
bool filterPointerEvent(QQuickItem *receiver, QPointerEvent *event)
void interactiveChanged()
virtual void viewportMoved(Qt::Orientations orient)
bool isDraggingHorizontally() const
void flickableDirectionChanged()
FINALqreal horizontalOvershoot
void pixelAlignedChanged()
bool isDragging() const
\qmlproperty bool QtQuick::Flickable::dragging \qmlproperty bool QtQuick::Flickable::draggingHorizont...
void setRebound(QQuickTransition *transition)
void bottomMarginChanged()
void movingHorizontallyChanged()
Q_INVOKABLE void cancelFlick()
\qmlmethod QtQuick::Flickable::cancelFlick()
qreal maximumFlickVelocity
bool childMouseEventFilter(QQuickItem *, QEvent *) override
void flickingVerticallyChanged()
bool isAtYBeginning() const
bool isFlickingHorizontally() const
\qmlproperty bool QtQuick::Flickable::flicking \qmlproperty bool QtQuick::Flickable::flickingHorizont...
void setFlickDeceleration(qreal)
void setInteractive(bool)
bool isMoving() const
\qmlproperty bool QtQuick::Flickable::moving \qmlproperty bool QtQuick::Flickable::movingHorizontally...
bool isAtXBeginning() const
void mouseReleaseEvent(QMouseEvent *event) override
This event handler can be reimplemented in a subclass to receive mouse release events for an item.
void contentWidthChanged()
friend class QQuickFlickableVisibleArea
virtual void setContentY(qreal pos)
void movingVerticallyChanged()
void rightMarginChanged()
void mouseMoveEvent(QMouseEvent *event) override
This event handler can be reimplemented in a subclass to receive mouse move events for an item.
QQuickFlickableVisibleArea * visibleArea
void setFlickableDirection(FlickableDirection)
virtual qreal maxXExtent() const
void flickingHorizontallyChanged()
virtual qreal maxYExtent() const
BoundsMovement boundsMovement
void contentHeightChanged()
void setSynchronousDrag(bool v)
bool isDraggingVertically() const
virtual qreal minXExtent() const
QQmlListProperty< QQuickItem > flickableChildren
void setContentHeight(qreal)
void velocityTimelineCompleted()
void setBoundsMovement(BoundsMovement movement)
bool isMovingVertically() const
void setBoundsBehavior(BoundsBehavior)
QTransform windowToItemTransform() const
Returns a transform that maps points from window space into item space.
quint32 replayingPressEvent
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
QQuickDeliveryAgentPrivate * deliveryAgentPrivate()
virtual void addPointerHandler(QQuickPointerHandler *h)
QQmlListProperty< QQuickItem > children()
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
virtual void mouseReleaseEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse release events for an item.
Q_INVOKABLE QPointF mapFromItem(const QQuickItem *item, const QPointF &point) const
Maps the given point in item's coordinate system to the equivalent point within this item's coordinat...
Qt::MouseButtons acceptedMouseButtons() const
Returns the mouse buttons accepted by this item.
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
void setParentItem(QQuickItem *parent)
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
QPointF mapFromScene(const QPointF &point) const
Maps the given point in the scene's coordinate system to the equivalent point within this item's coor...
qreal y
Defines the item's y position relative to its parent.
virtual Q_INVOKABLE bool contains(const QPointF &point) const
\qmlmethod bool QtQuick::Item::contains(point point)
bool keepTouchGrab() const
Returns whether the touch points grabbed by this item should exclusively remain with this item.
QQuickWindow * window() const
Returns the window in which this item is rendered.
virtual void mousePressEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
qreal width
This property holds the width of this item.
bool keepMouseGrab() const
Returns whether mouse input should exclusively remain with this item.
virtual void touchEvent(QTouchEvent *event)
This event handler can be reimplemented in a subclass to receive touch events for an item.
qreal height
This property holds the height of this item.
virtual bool childMouseEventFilter(QQuickItem *, QEvent *)
Reimplement this method to filter the pointer events that are received by this item's children.
virtual void mouseMoveEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse move events for an item.
void setValue(qreal v) override
Set the current value.
virtual qreal value() const
Return the current value.
The QQuickTimeLine class provides a timeline for controlling animations.
void reset(QQuickTimeLineValue &)
Cancel (but don't complete) all scheduled actions for timeLineValue.
int accel(QQuickTimeLineValue &, qreal velocity, qreal accel)
Decelerate timeLineValue from the starting velocity to zero at the given acceleration rate.
void callback(const QQuickTimeLineCallback &)
Execute the event.
bool isActive() const
Returns true if the timeline is active.
void clear()
Resets the timeline.
void set(QQuickTimeLineValue &, qreal)
Set the value of timeLineValue.
void move(QQuickTimeLineValue &, qreal destination, int time=500)
Linearly change the timeLineValue from its current value to the given destination value over time mil...
void transition(const QList< QQuickStateAction > &, QQuickTransition *transition, QObject *defaultTarget=nullptr)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
A base class for pointer events containing a single point, such as mouse events.
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
\macro QT_RESTRICTED_CAST_FROM_ASCII
The QTouchEvent class contains parameters that describe a touch event.
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
The QVector2D class represents a vector or vertex in 2D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
Combined button and popup list for selecting options.
@ MouseEventNotSynthesized
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
qfloat16 qSqrt(qfloat16 f)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat maxX
GLfloat GLfloat GLfloat GLfloat h
GLuint GLenum GLenum transform
GLdouble GLdouble GLdouble GLdouble q
#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method)
Connect Signal of Sender to Method of Receiver.
void QQml_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
QQuickItem * qmlobject_cast< QQuickItem * >(QObject *object)
static bool fuzzyLessThanOrEqualTo(qreal a, qreal b)
static qreal EaseOvershoot(qreal t)
static QT_BEGIN_NAMESPACE const int RetainGrabVelocity
const qreal _q_MaximumWheelDeceleration
#define QML_FLICK_SAMPLEBUFFER
const qreal _q_MinimumFlickVelocity
#define QML_FLICK_OVERSHOOT
#define QML_FLICK_MULTIFLICK_MAXBOOST
#define QML_FLICK_MULTIFLICK_THRESHOLD
#define QML_FLICK_OVERSHOOTFRICTION
#define QML_FLICK_DISCARDSAMPLES
#define QML_FLICK_MULTIFLICK_RATIO
#define Q_ASSERT_X(cond, x, msg)
QLatin1StringView QLatin1String
static double elapsed(qint64 after, qint64 before)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
bool testFlag(MaskType mask, FlagType flag)
std::uniform_real_distribution dist(1, 2.5)
[2]
void addVelocitySample(qreal v, qreal maxVelocity)
uint flickingWhenDragBegan
QQuickFlickableReboundTransition * transitionToBounds
uint contentPositionChangedExternallyDuringDrag
QPODVector< qreal, 10 > velocityBuffer
qreal continuousFlickVelocity
QQuickFlickablePrivate::Velocity smoothVelocity
QQuickTimeLineValueProxy< QQuickFlickablePrivate > move
QElapsedTimer velocityTime
void setValue(qreal v) override
Set the current value.
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent