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/qplatformtheme.h>
48 :
QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
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);
301 qreal v = velocityBuffer.at(
i);
312 Qt::Orientations orient;
318 q->viewportMoved(orient);
319 const QPointF deltaMoved =
item->position() - oldGeom.topLeft();
326 emit q->contentXChanged();
328 emit q->contentYChanged();
349 qreal maxDistance = -1;
350 data.fixingUp =
false;
353 maxDistance =
qAbs(minExtent -
data.move.value());
354 data.flickTarget = minExtent;
356 maxDistance =
qAbs(maxExtent -
data.move.value());
357 data.flickTarget = maxExtent;
369 qCDebug(lcFlickable) <<
"choosing deceleration" << accel <<
"for" << eventType;
380 if (!
data.inOvershoot) {
413 if (!
q->isComponentComplete())
421 if (!
q->isComponentComplete())
445 data.fixingUp =
true;
448 if (
data.transitionToBounds &&
data.transitionToBounds->startTransition(&
data, toPos)) {
449 q->movementStarting();
450 data.fixingUp =
true;
455 data.fixingUp =
true;
464 if (
data.transitionToBounds)
465 data.transitionToBounds->stopTransition();
489 if (
data.move.value() >= minExtent || maxExtent > minExtent) {
491 if (
data.move.value() != minExtent) {
494 }
else if (
data.move.value() <= maxExtent) {
497 }
else if (-std::round(-
data.move.value()) !=
data.move.value()) {
501 if (std::abs(std::round(
val) -
val) < 0.25)
503 else if (
data.smoothVelocity.value() > 0)
505 else if (
data.smoothVelocity.value() < 0)
511 data.inOvershoot =
false;
518 if (
a == 0.0 ||
b == 0.0) {
538 bool atXBeginningChange =
false, atXEndChange =
false;
539 bool atYBeginningChange =
false, atYEndChange =
false;
542 const qreal maxyextent = -
q->maxYExtent();
543 const qreal minyextent = -
q->minYExtent();
550 atYBeginningChange =
true;
562 const qreal maxxextent = -
q->maxXExtent();
563 const qreal minxextent = -
q->minXExtent();
570 atXBeginningChange =
true;
583 qreal originY =
q->originY();
586 emit q->originYChanged();
592 qreal originX =
q->originX();
595 emit q->originXChanged();
599 if (atXEndChange || atYEndChange || atXBeginningChange || atYBeginningChange)
600 emit q->isAtBoundaryChanged();
602 emit q->atXEndChanged();
603 if (atXBeginningChange)
604 emit q->atXBeginningChanged();
606 emit q->atYEndChanged();
607 if (atYBeginningChange)
608 emit q->atYBeginningChanged();
801 return -
d->contentItem->x();
807 d->hData.explicitValue =
true;
808 d->resetTimeline(
d->hData);
809 d->hData.vTime =
d->timeline.time();
813 d->hData.contentPositionChangedExternallyDuringDrag =
d->hData.dragging;
814 d->hData.move.setValue(-
pos);
815 d->hData.contentPositionChangedExternallyDuringDrag =
false;
822 return -
d->contentItem->y();
828 d->vData.explicitValue =
true;
829 d->resetTimeline(
d->vData);
830 d->vData.vTime =
d->timeline.time();
834 d->vData.contentPositionChangedExternallyDuringDrag =
d->vData.dragging;
835 d->vData.move.setValue(-
pos);
836 d->vData.contentPositionChangedExternallyDuringDrag =
false;
856 return d->interactive;
865 d->cancelInteraction();
887 return d->hData.smoothVelocity.value();
893 return d->vData.smoothVelocity.value();
908 return d->hData.atEnd;
914 return d->hData.atBeginning;
920 return d->vData.atEnd;
926 return d->vData.atBeginning;
950 return d->contentItem;
956 if (!
d->visibleArea) {
958 d->visibleArea->updateVisible();
960 return d->visibleArea;
985 return d->flickableDirection;
1012 return d->pixelAligned;
1018 if (align !=
d->pixelAligned) {
1019 d->pixelAligned = align;
1045 if (
v !=
d->syncDrag) {
1047 emit synchronousDragChanged();
1064 if (0 !=
event->timestamp())
1065 return event->timestamp();
1073 return (
window ?
window->effectiveDevicePixelRatio() :
qApp->devicePixelRatio());
1085 if (flickTime > 600) {
1093 if (flickTime > 300)
1141 emit q->flickingHorizontallyChanged();
1145 emit q->flickingVerticallyChanged();
1148 emit q->flickingChanged();
1155 const QVector2D &deltas,
bool overThreshold,
bool momentum,
1156 bool velocitySensitiveOverBounds,
const QVector2D &velocity)
1159 bool rejectY =
false;
1160 bool rejectX =
false;
1162 bool keepY =
q->yflick();
1163 bool keepX =
q->xflick();
1165 bool stealY =
false;
1166 bool stealX =
false;
1173 bool prevHMoved =
hMoved;
1174 bool prevVMoved =
vMoved;
1177 qCDebug(lcFlickable).nospace() << currentTimestamp <<
' ' << eventType <<
" drag @ " << localPos.
x() <<
',' << localPos.
y()
1178 <<
" \u0394 " << deltas.x() <<
',' << deltas.y() <<
" vel " << velocity.
x() <<
',' << velocity.
y()
1179 <<
" thrsld? " << overThreshold <<
" momentum? " << momentum <<
" velSens? " << velocitySensitiveOverBounds
1180 <<
" sincePress " << elapsedSincePress;
1183 qreal dy = deltas.y();
1184 if (overThreshold || elapsedSincePress > 200) {
1213 q->returnToBounds();
1217 if (velocitySensitiveOverBounds) {
1220 newY =
minY + overshoot;
1229 q->returnToBounds();
1233 if (velocitySensitiveOverBounds) {
1236 newY =
maxY - overshoot;
1247 if (!rejectY && overThreshold)
1259 qreal dx = deltas.x();
1260 if (overThreshold || elapsedSincePress > 200) {
1286 q->returnToBounds();
1290 if (velocitySensitiveOverBounds) {
1293 newX = minX + overshoot;
1295 newX = minX + (newX - minX) / 2;
1297 }
else if (newX <
maxX &&
maxX - minX <= 0) {
1302 q->returnToBounds();
1306 if (velocitySensitiveOverBounds) {
1309 newX =
maxX - overshoot;
1322 if (!rejectX && overThreshold)
1335 if ((stealX && keepX) || (stealY && keepY))
1336 q->setKeepMouseGrab(
true);
1353 if ((
hMoved && !prevHMoved) || (
vMoved && !prevVMoved))
1354 q->movementStarting();
1357 if (
q->yflick() && !rejectY)
1359 if (
q->xflick() && !rejectX)
1372 const auto &firstPoint =
event->points().first();
1373 const auto &
pos = firstPoint.position();
1376 bool overThreshold =
false;
1378 if (
event->pointCount() == 1) {
1384 qCDebug(lcFilter) <<
q->objectName() <<
"ignoring multi-touch" <<
event;
1387 drag(currentTimestamp,
event->type(),
pos, deltas, overThreshold,
false,
false, velocity);
1394 q->setKeepMouseGrab(
false);
1410 bool canBoost =
false;
1411 const auto pos =
event->points().first().position();
1412 const auto pressPos =
q->mapFromGlobal(
event->points().first().globalPressPosition());
1414 qCDebug(lcVel) <<
event->deviceType() <<
event->type() <<
"velocity" <<
event->points().first().velocity() <<
"transformed to local" << eventVelocity;
1416 qreal vVelocity = 0;
1431 qreal hVelocity = 0;
1449 bool anyPointGrabbed =
event->points().constEnd() !=
1450 std::find_if(
event->points().constBegin(),
event->points().constEnd(),
1451 [
q,
event](
const QEventPoint &point) { return event->exclusiveGrabber(point) == q; });
1453 bool flickedVertically =
false;
1455 const bool isVerticalFlickAllowed = anyPointGrabbed &&
1458 if (isVerticalFlickAllowed) {
1461 flickedVertically =
flickY(
event->type(), vVelocity);
1464 bool flickedHorizontally =
false;
1466 const bool isHorizontalFlickAllowed = anyPointGrabbed &&
1469 if (isHorizontalFlickAllowed) {
1472 flickedHorizontally =
flickX(
event->type(), hVelocity);
1475 if (!isVerticalFlickAllowed)
1478 if (!isHorizontalFlickAllowed)
1483 q->movementEnding();
1485 if (flickedVertically)
1487 if (flickedHorizontally)
1489 q->movementStarting();
1496 if (
d->interactive && !
d->replayingPressEvent &&
d->wantsPointerEvent(
event)) {
1498 d->handlePressEvent(
event);
1508 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1509 d->handleMoveEvent(
event);
1519 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1520 if (
d->delayedPressEvent) {
1521 d->replayDelayedPress();
1523 auto &firstPoint =
event->point(0);
1524 if (
const auto *grabber =
event->exclusiveGrabber(firstPoint); grabber && grabber->isQuickItemType()) {
1528 QMutableEventPoint::setPosition(firstPoint,
event->scenePosition());
1530 QMutableEventPoint::setPosition(firstPoint,
oldPosition);
1534 d->stealMouse =
false;
1539 d->handleReleaseEvent(
event);
1551 if (
d->interactive &&
d->wantsPointerEvent(
event))
1552 d->cancelInteraction();
1558 bool unhandled =
false;
1559 const auto &firstPoint =
event->points().first();
1560 switch (firstPoint.state()) {
1562 if (
d->interactive && !
d->replayingPressEvent &&
d->wantsPointerEvent(
event)) {
1564 d->handlePressEvent(
event);
1571 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1572 d->handleMoveEvent(
event);
1579 if (
d->interactive &&
d->wantsPointerEvent(
event)) {
1580 if (
d->delayedPressEvent) {
1581 d->replayDelayedPress();
1583 const auto &firstPoint =
event->point(0);
1584 if (
const auto *grabber =
event->exclusiveGrabber(firstPoint); grabber && grabber->isQuickItemType()) {
1586 QScopedPointer<QPointerEvent> localizedEvent(
1592 d->stealMouse =
false;
1597 d->handleReleaseEvent(
event);
1611#if QT_CONFIG(wheelevent)
1612void QQuickFlickable::wheelEvent(QWheelEvent *
event)
1615 if (!
d->interactive || !
d->wantsPointerEvent(
event)) {
1616 QQuickItem::wheelEvent(
event);
1619 qCDebug(lcWheel) <<
event->device() <<
event <<
event->source();
1620 event->setAccepted(
false);
1621 qint64 currentTimestamp =
d->computeCurrentTime(
event);
1622 switch (
event->phase()) {
1624 d->scrollingPhase =
true;
1626 d->vData.velocity = 0;
1627 d->hData.velocity = 0;
1629 d->maybeBeginDrag(currentTimestamp,
event->position());
1630 d->lastPosTime = -1;
1634 if (
d->scrollingPhase)
1639 d->scrollingPhase =
false;
1640 d->draggingEnding();
1643 d->lastPosTime = -1;
1647 d->scrollingPhase =
false;
1648 d->draggingEnding();
1651 d->lastPosTime = -1;
1652 d->stealMouse =
false;
1653 if (!
d->velocityTimeline.isActive() && !
d->timeline.isActive())
1660 d->lastPosTime = currentTimestamp;
1661 qCDebug(lcWheel) <<
"insufficient elapsed time: can't calculate velocity" <<
elapsed;
1667 int xDelta =
event->angleDelta().x();
1668 int yDelta =
event->angleDelta().y();
1671 const qreal wheelScroll = -
qApp->styleHints()->wheelScrollLines() * 24;
1674 if (
yflick() && yDelta != 0) {
1677 qreal scrollPixel = (-yDelta / 120.0 * wheelScroll);
1678 if (scrollPixel > 0) {
1687 const qreal estContentPos = scrollPixel +
d->vData.move.value();
1688 if (scrollPixel > 0) {
1690 scrollPixel =
minYExtent() -
d->vData.move.value();
1693 scrollPixel =
maxYExtent() -
d->vData.move.value();
1696 d->resetTimeline(
d->vData);
1699 d->vData.fixingUp =
true;
1704 if (
xflick() && xDelta != 0) {
1707 qreal scrollPixel = (-xDelta / 120.0 * wheelScroll);
1708 if (scrollPixel > 0) {
1717 const qreal estContentPos = scrollPixel +
d->hData.move.value();
1718 if (scrollPixel > 0) {
1720 scrollPixel =
minXExtent() -
d->hData.move.value();
1723 scrollPixel =
maxXExtent() -
d->hData.move.value();
1726 d->resetTimeline(
d->hData);
1729 d->hData.fixingUp =
true;
1745 elapsed = 120 /
qSqrt(
d->wheelDeceleration * 2 *
d->initialWheelFlickDistance);
1746 if (
yflick() && yDelta != 0) {
1749 if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 &&
d->vData.velocity < 0))
1750 d->vData.velocityBuffer.clear();
1751 d->vData.addVelocitySample(instVelocity,
d->maxVelocity);
1752 d->vData.updateVelocity();
1754 const bool newFlick =
d->flickY(
event->type(),
d->vData.velocity);
1755 if (newFlick && (
d->vData.atBeginning != (yDelta > 0) ||
d->vData.atEnd != (yDelta < 0))) {
1756 d->flickingStarted(
false,
true);
1763 if (
xflick() && xDelta != 0) {
1766 if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 &&
d->hData.velocity < 0))
1767 d->hData.velocityBuffer.clear();
1768 d->hData.addVelocitySample(instVelocity,
d->maxVelocity);
1769 d->hData.updateVelocity();
1771 const bool newFlick =
d->flickX(
event->type(),
d->hData.velocity);
1772 if (newFlick && (
d->hData.atBeginning != (xDelta > 0) ||
d->hData.atEnd != (xDelta < 0))) {
1773 d->flickingStarted(
true,
false);
1783 int xDelta =
event->pixelDelta().x();
1784 int yDelta =
event->pixelDelta().y();
1794 || (
xflick() &&
qAbs(
d->accumulatedWheelPixelDelta.x()) >
qAbs(
d->accumulatedWheelPixelDelta.y() * 2))
1795 || (
yflick() &&
qAbs(
d->accumulatedWheelPixelDelta.y()) >
qAbs(
d->accumulatedWheelPixelDelta.x() * 2))) {
1796 d->drag(currentTimestamp,
event->type(),
event->position(),
d->accumulatedWheelPixelDelta,
1797 true, !
d->scrollingPhase,
true, velocity);
1800 qCDebug(lcWheel) <<
"not dragging: accumulated deltas" <<
d->accumulatedWheelPixelDelta <<
1804 d->lastPosTime = currentTimestamp;
1806 if (!
event->isAccepted())
1807 QQuickItem::wheelEvent(
event);
1865 da->allowChildEventFiltering =
false;
1867 auto &firstPoint =
event->point(0);
1873 if (
event->exclusiveGrabber(firstPoint) ==
q)
1874 event->setExclusiveGrabber(firstPoint,
nullptr);
1876 qCDebug(lcReplay) <<
"replaying" <<
event.data();
1879 QMutableEventPoint::setPosition(firstPoint, firstPoint.scenePosition());
1884 qCDebug(lcReplay) <<
"replay done";
1888 da->allowChildEventFiltering =
true;
1909 const qreal minX =
q->minXExtent();
1918 qreal overshoot = 0.0;
1920 overshoot =
maxX -
x;
1922 overshoot = minX -
x;
1926 emit q->horizontalOvershootChanged();
1953 qreal overshoot = 0.0;
1955 overshoot =
maxY -
y;
1957 overshoot =
minY -
y;
1961 emit q->verticalOvershootChanged();
1968 if (
event->timerId() ==
d->delayedPressTimer.timerId()) {
1969 d->delayedPressTimer.stop();
1970 if (
d->delayedPressEvent) {
1971 d->replayDelayedPress();
1979 return d->vData.startMargin;
1985 return d->hData.startMargin;
2005 if (!
d->hData.explicitValue &&
d->hData.startMargin != 0.)
2007 if (!
d->vData.explicitValue &&
d->vData.startMargin != 0.)
2009 if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) {
2022 d->updateBeginningEnd();
2032 if (
qAbs(velocity) > 0) {
2035 qCDebug(lcVel) <<
"touchpad scroll phase: velocity" << velocity;
2043 qreal velocity = (
data.lastPos -
data.move.value()) * 1000 / dt;
2045 qCDebug(lcVel) <<
"velocity" <<
data.smoothVelocity.value() <<
"->" << velocity
2046 <<
"computed as (" <<
data.lastPos <<
"-" <<
data.move.value() <<
") * 1000 / ("
2048 data.smoothVelocity.setValue(velocity);
2053 if (!
data.inOvershoot && !
data.fixingUp &&
data.flicking
2054 && (
data.move.value() > minExtent ||
data.move.value() < maxExtent)
2055 &&
qAbs(
data.smoothVelocity.value()) > 10) {
2057 qreal overBound =
data.move.value() > minExtent
2058 ?
data.move.value() - minExtent
2059 : maxExtent -
data.move.value();
2060 data.inOvershoot =
true;
2063 if (maxDistance > 0)
2077 bool changed =
false;
2078 if (newGeometry.
width() != oldGeometry.
width()) {
2080 if (
d->hData.viewSize < 0)
2081 d->contentItem->setWidth(
width() -
d->hData.startMargin -
d->hData.endMargin);
2083 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2090 if (
d->vData.viewSize < 0)
2091 d->contentItem->setHeight(
height() -
d->vData.startMargin -
d->vData.endMargin);
2093 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2100 d->updateBeginningEnd();
2117 d->hData.velocity = xVelocity;
2118 d->vData.velocity = yVelocity;
2119 d->hData.vTime =
d->vData.vTime =
d->timeline.time();
2129 d->flickingStarted(flickedX, flickedY);
2135 if (!flickingH && !flickingV)
2141 emit q->flickingHorizontallyChanged();
2145 emit q->flickingVerticallyChanged();
2148 emit q->flickingChanged();
2149 emit q->flickStarted();
2162 d->resetTimeline(
d->hData);
2163 d->resetTimeline(
d->vData);
2169 if (!prop || !prop->data)
2177 o->setParent(prop->object);
2242 return d->boundsBehavior;
2248 if (
b ==
d->boundsBehavior)
2250 d->boundsBehavior =
b;
2304 if (!
d->hData.transitionToBounds)
2306 if (!
d->vData.transitionToBounds)
2309 if (
d->rebound != transition) {
2310 d->rebound = transition;
2342 return d->hData.viewSize;
2348 if (
d->hData.viewSize ==
w)
2350 d->hData.viewSize =
w;
2352 d->contentItem->setWidth(
width() -
d->hData.startMargin -
d->hData.endMargin);
2354 d->contentItem->setWidth(
w);
2355 d->hData.markExtentsDirty();
2357 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2360 }
else if (!
d->pressed &&
d->hData.fixingUp) {
2365 d->updateBeginningEnd();
2371 return d->vData.viewSize;
2377 if (
d->vData.viewSize ==
h)
2379 d->vData.viewSize =
h;
2381 d->contentItem->setHeight(
height() -
d->vData.startMargin -
d->vData.endMargin);
2383 d->contentItem->setHeight(
h);
2384 d->vData.markExtentsDirty();
2386 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2389 }
else if (!
d->pressed &&
d->vData.fixingUp) {
2394 d->updateBeginningEnd();
2411 return d->vData.startMargin;
2417 if (
d->vData.startMargin ==
m)
2419 d->vData.startMargin =
m;
2420 d->vData.markExtentsDirty();
2421 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2426 d->updateBeginningEnd();
2432 return d->vData.endMargin;
2438 if (
d->vData.endMargin ==
m)
2440 d->vData.endMargin =
m;
2441 d->vData.markExtentsDirty();
2442 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2447 d->updateBeginningEnd();
2453 return d->hData.startMargin;
2459 if (
d->hData.startMargin ==
m)
2461 d->hData.startMargin =
m;
2462 d->hData.markExtentsDirty();
2463 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2468 d->updateBeginningEnd();
2474 return d->hData.endMargin;
2480 if (
d->hData.endMargin ==
m)
2482 d->hData.endMargin =
m;
2483 d->hData.markExtentsDirty();
2484 if (!
d->pressed && !
d->hData.moving && !
d->vData.moving) {
2489 d->updateBeginningEnd();
2534 const qreal oldHSize =
d->hData.viewSize;
2535 const qreal oldVSize =
d->vData.viewSize;
2536 const bool needToUpdateWidth =
w != oldHSize;
2537 const bool needToUpdateHeight =
h != oldVSize;
2538 d->hData.viewSize =
w;
2539 d->vData.viewSize =
h;
2541 if (needToUpdateWidth)
2543 if (needToUpdateHeight)
2546 if (center.x() != 0) {
2550 if (center.y() != 0) {
2554 d->updateBeginningEnd();
2575 if (
d->hData.viewSize < 0)
2578 return d->hData.viewSize;
2584 if (
d->vData.viewSize < 0)
2587 return d->vData.viewSize;
2600 const int contentWidthWithMargins =
d->contentItem->width() +
d->hData.startMargin +
d->hData.endMargin;
2604 return std::floor(
qAbs(contentWidthWithMargins -
width()));
2618 const int contentHeightWithMargins =
d->contentItem->height() +
d->vData.startMargin +
d->vData.endMargin;
2622 return std::floor(
qAbs(contentHeightWithMargins -
height()));
2631 if (!
d->replayingPressEvent)
2632 d->cancelInteraction();
2643 q->setKeepMouseGrab(
false);
2647 q->movementEnding();
2654 qCDebug(lcHandlerParent) <<
"reparenting handler" <<
h <<
"to contentItem of" <<
q;
2673 Q_ASSERT_X(receiver !=
this,
"",
"Flickable received a filter event for itself");
2677 d->stealMouse =
false;
2679 if (
event->pointCount() > 1) {
2680 qCDebug(lcFilter) <<
objectName() <<
"ignoring multi-touch" <<
event <<
"for" << receiver;
2681 d->stealMouse =
false;
2686 const auto &firstPoint =
event->points().first();
2688 if (
event->pointCount() == 1 &&
event->exclusiveGrabber(firstPoint) ==
this) {
2695 event->setAccepted(
true);
2700 bool receiverDisabled = receiver && !receiver->
isEnabled();
2701 bool stealThisEvent =
d->stealMouse;
2703 bool receiverRelinquishGrab =
false;
2706 if (
auto *mouseArea = qmlobject_cast<QQuickMouseArea *>(receiver)) {
2707 bool preventStealing = mouseArea->preventStealing();
2708#if QT_CONFIG(quick_draganddrop)
2709 if (mouseArea->drag() && mouseArea->drag()->target())
2710 preventStealing =
true;
2712 if (!preventStealing && receiverKeepsGrab) {
2713 receiverRelinquishGrab = !receiverDisabled
2717 if (receiverRelinquishGrab)
2718 receiverKeepsGrab =
false;
2722 if ((stealThisEvent ||
contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
2724 localizedEvent->setAccepted(
false);
2725 switch (firstPoint.state()) {
2727 d->handleMoveEvent(localizedEvent.data());
2730 d->handlePressEvent(localizedEvent.data());
2731 d->captureDelayedPress(receiver,
event);
2733 d->stealMouse =
false;
2734 stealThisEvent =
false;
2737 d->handleReleaseEvent(localizedEvent.data());
2738 stealThisEvent =
d->stealMouse;
2744 if ((receiver && stealThisEvent && !receiverKeepsGrab && receiver !=
this) || receiverDisabled) {
2745 d->clearDelayedPress();
2746 event->setExclusiveGrabber(firstPoint,
this);
2747 }
else if (
d->delayedPressEvent) {
2748 event->setExclusiveGrabber(firstPoint,
this);
2751 const bool filtered = !receiverRelinquishGrab && (stealThisEvent ||
d->delayedPressEvent || receiverDisabled);
2753 event->setAccepted(
true);
2756 }
else if (
d->lastPosTime != -1) {
2757 d->lastPosTime = -1;
2762 d->lastPosTime = -1;
2763 d->clearDelayedPress();
2764 d->stealMouse =
false;
2779 auto wantsPointerEvent_helper = [
this,
d,
i, pointerEvent]() {
2782 const bool wants =
d->wantsPointerEvent(pointerEvent);
2789 (pointerEvent && !wantsPointerEvent_helper())) {
2790 d->cancelInteraction();
2797 const QObject *grabber = spe->exclusiveGrabber(spe->points().first());
2798 qCDebug(lcFilter) <<
"filtering UngrabMouse" << spe->points().first() <<
"for" <<
i <<
"grabber is" << grabber;
2799 if (grabber !=
this)
2801 }
else if (pointerEvent) {
2817 return d->maxVelocity;
2823 if (
v ==
d->maxVelocity)
2841 return d->deceleration;
2847 if (deceleration ==
d->deceleration)
2849 d->deceleration =
qMax(0.001, deceleration);
2856 return d->hData.flicking ||
d->vData.flicking;
2870 return d->hData.flicking;
2876 return d->vData.flicking;
2890 return d->hData.dragging ||
d->vData.dragging;
2896 return d->hData.dragging;
2902 return d->vData.dragging;
2911 emit q->draggingHorizontallyChanged();
2915 emit q->draggingVerticallyChanged();
2918 emit q->draggingChanged();
2919 emit q->dragStarted();
2929 emit q->draggingHorizontallyChanged();
2933 emit q->draggingVerticallyChanged();
2937 emit q->draggingChanged();
2938 emit q->dragEnded();
2976 return d->pressDelay;
2982 if (
d->pressDelay == delay)
2984 d->pressDelay = delay;
3001 return d->hData.moving ||
d->vData.moving;
3007 return d->hData.moving;
3013 return d->vData.moving;
3019 if ( (
d->hData.transitionToBounds &&
d->hData.transitionToBounds->isActive())
3020 || (
d->vData.transitionToBounds &&
d->vData.transitionToBounds->isActive()) ) {
3027 if (
d->vData.flicking)
3029 d->updateBeginningEnd();
3035 if ( (
d->hData.transitionToBounds &&
d->hData.transitionToBounds->isActive())
3036 || (
d->vData.transitionToBounds &&
d->vData.transitionToBounds->isActive()) ) {
3040 d->updateBeginningEnd();
3046 bool wasMoving =
d->hData.moving ||
d->vData.moving;
3047 if (
d->hMoved && !
d->hData.moving) {
3048 d->hData.moving =
true;
3051 if (
d->vMoved && !
d->vData.moving) {
3052 d->vData.moving =
true;
3056 if (!wasMoving && (
d->hData.moving ||
d->vData.moving)) {
3059#if QT_CONFIG(accessibility)
3060 if (QAccessible::isActive()) {
3061 QAccessibleEvent ev(
this, QAccessible::ScrollingStart);
3062 QAccessible::updateAccessibility(&ev);
3078 const bool wasFlicking =
d->hData.flicking ||
d->vData.flicking;
3079 if (hMovementEnding &&
d->hData.flicking) {
3080 d->hData.flicking =
false;
3083 if (vMovementEnding &&
d->vData.flicking) {
3084 d->vData.flicking =
false;
3087 if (wasFlicking && (!
d->hData.flicking || !
d->vData.flicking)) {
3090 }
else if (
d->hData.flickingWhenDragBegan ||
d->vData.flickingWhenDragBegan) {
3091 d->hData.flickingWhenDragBegan = !hMovementEnding;
3092 d->vData.flickingWhenDragBegan = !vMovementEnding;
3098 if (hMovementEnding &&
d->hData.moving
3099 && (!
d->pressed && !
d->stealMouse)) {
3100 d->hData.moving =
false;
3104 if (vMovementEnding &&
d->vData.moving
3105 && (!
d->pressed && !
d->stealMouse)) {
3106 d->vData.moving =
false;
3113#if QT_CONFIG(accessibility)
3114 if (QAccessible::isActive()) {
3115 QAccessibleEvent ev(
this, QAccessible::ScrollingEnd);
3116 QAccessible::updateAccessibility(&ev);
3121 if (hMovementEnding) {
3122 d->hData.fixingUp =
false;
3123 d->hData.smoothVelocity.setValue(0);
3124 d->hData.previousDragDelta = 0.0;
3126 if (vMovementEnding) {
3127 d->vData.fixingUp =
false;
3128 d->vData.smoothVelocity.setValue(0);
3129 d->vData.previousDragDelta = 0.0;
3136 emit q->horizontalVelocityChanged();
3137 emit q->verticalVelocityChanged();
3158 return d->hData.overshoot;
3179 return d->vData.overshoot;
3231 return d->boundsMovement;
3237 if (
d->boundsMovement == movement)
3240 d->boundsMovement = movement;
3241 emit boundsMovementChanged();
3246#include "moc_qquickflickable_p_p.cpp"
3248#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
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
bool isValid() const noexcept
Returns false if the timer has never been started or invalidated by a call to invalidate().
The QEventPoint class provides information about a point in a QPointerEvent.
bool isSinglePointEvent() const noexcept
Type
This enum type defines the valid event types in Qt.
Type type() const
Returns the event type.
bool isPointerEvent() const noexcept
QGraphicsItem * parentItem() const
Returns a pointer to this item's parent item.
static QPlatformTheme * platformTheme()
static constexpr Policy Preferred
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
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
void maybeBeginDrag(qint64 currentTimestamp, const QPointF &pressPosn, Qt::MouseButtons buttons=Qt::NoButton)
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)
~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
QQmlListProperty< 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
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
QQuickTransition * rebound
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()
void pixelAlignedChanged()
bool isDragging() const
\qmlproperty bool QtQuick::Flickable::dragging \qmlproperty bool QtQuick::Flickable::draggingHorizont...
void setRebound(QQuickTransition *transition)
qreal horizontalOvershoot
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 setSizePolicy(const QLayoutPolicy::Policy &horizontalPolicy, const QLayoutPolicy::Policy &verticalPolicy)
QQuickDeliveryAgentPrivate * deliveryAgentPrivate()
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.
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.
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 GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
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.
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.