347Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scrollGestureType)
350 QScroller *s = scroller(target);
352 return Qt::GestureType(0);
354 QScrollerPrivate *sp = s->d_ptr;
356 ungrabGesture(target);
358 Qt::MouseButton button;
359 switch (scrollGestureType) {
360 case LeftMouseButtonGesture : button = Qt::LeftButton;
break;
361 case RightMouseButtonGesture : button = Qt::RightButton;
break;
362 case MiddleMouseButtonGesture: button = Qt::MiddleButton;
break;
364 case TouchGesture : button = Qt::NoButton;
break;
367 sp->recognizer =
new QFlickGestureRecognizer(button);
368 sp->recognizerType = QGestureRecognizer::registerRecognizer(sp->recognizer);
370 if (target->isWidgetType()) {
371 QWidget *widget =
static_cast<QWidget *>(target);
372 widget->grabGesture(sp->recognizerType);
373 if (scrollGestureType == TouchGesture)
374 widget->setAttribute(Qt::WA_AcceptTouchEvents);
375#if QT_CONFIG(graphicsview)
376 }
else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) {
377 if (scrollGestureType == TouchGesture)
378 go->setAcceptTouchEvents(
true);
379 go->grabGesture(sp->recognizerType);
382 return sp->recognizerType;
624void QScroller::scrollTo(
const QPointF &pos,
int scrollTime)
628 if (d->state == Pressed || d->state == Dragging )
632 if (d->state == Inactive && !d->prepareScrolling(QPointF()))
635 QPointF newpos = clampToRect(pos, d->contentPosRange);
636 qreal snapX = d->nextSnapPos(newpos.x(), 0, Qt::Horizontal);
637 qreal snapY = d->nextSnapPos(newpos.y(), 0, Qt::Vertical);
643 qCDebug(lcScroller) <<
"QScroller::scrollTo(req:" << pos <<
" [pix] / snap:"
644 << newpos <<
", " << scrollTime <<
" [ms])";
646 if (newpos == d->contentPosition + d->overshootPosition)
649 QPointF vel = velocity();
653 qreal time = qreal(scrollTime) / 1000;
655 d->createScrollToSegments(vel.x(), time, newpos.x(), Qt::Horizontal, QScrollerPrivate::ScrollTypeScrollTo);
656 d->createScrollToSegments(vel.y(), time, newpos.y(), Qt::Vertical, QScrollerPrivate::ScrollTypeScrollTo);
659 d->setContentPositionHelperScrolling();
660 d->setState(scrollTime ? Scrolling : Inactive);
688void QScroller::ensureVisible(
const QRectF &rect, qreal xmargin, qreal ymargin,
int scrollTime)
692 if (d->state == Pressed || d->state == Dragging )
695 if (d->state == Inactive && !d->prepareScrolling(QPointF()))
699 QPointF startPos(d->scrollingSegmentsEndPos(Qt::Horizontal),
700 d->scrollingSegmentsEndPos(Qt::Vertical));
702 QRectF marginRect(rect.x() - xmargin, rect.y() - ymargin,
703 rect.width() + 2 * xmargin, rect.height() + 2 * ymargin);
705 QSizeF visible = d->viewportSize;
706 QRectF visibleRect(startPos, visible);
708 qCDebug(lcScroller) <<
"QScroller::ensureVisible(" << rect <<
" [pix], " << xmargin
709 <<
" [pix], " << ymargin <<
" [pix], " << scrollTime <<
"[ms])";
710 qCDebug(lcScroller) <<
" --> content position:" << d->contentPosition;
712 if (visibleRect.contains(marginRect))
715 QPointF newPos = startPos;
717 if (visibleRect.width() < rect.width()) {
719 if (rect.left() > visibleRect.left())
720 newPos.setX(rect.left());
721 else if (rect.right() < visibleRect.right())
722 newPos.setX(rect.right() - visible.width());
724 }
else if (visibleRect.width() < marginRect.width()) {
725 newPos.setX(rect.center().x() - visibleRect.width() / 2);
726 }
else if (marginRect.left() > visibleRect.left()) {
727 newPos.setX(marginRect.left());
728 }
else if (marginRect.right() < visibleRect.right()) {
729 newPos.setX(marginRect.right() - visible.width());
732 if (visibleRect.height() < rect.height()) {
734 if (rect.top() > visibleRect.top())
735 newPos.setX(rect.top());
736 else if (rect.bottom() < visibleRect.bottom())
737 newPos.setX(rect.bottom() - visible.height());
739 }
else if (visibleRect.height() < marginRect.height()) {
740 newPos.setY(rect.center().y() - visibleRect.height() / 2);
741 }
else if (marginRect.top() > visibleRect.top()) {
742 newPos.setY(marginRect.top());
743 }
else if (marginRect.bottom() < visibleRect.bottom()) {
744 newPos.setY(marginRect.bottom() - visible.height());
748 newPos = clampToRect(newPos, d->contentPosRange);
749 if (newPos == startPos)
752 scrollTo(newPos, scrollTime);
934bool QScroller::handleInput(Input input,
const QPointF &position, qint64 timestamp)
938 qCDebug(lcScroller) <<
"QScroller::handleInput(" << input <<
", " << d->stateName(d->state)
939 <<
", " << position <<
", " << timestamp <<
')';
943 typedef bool (QScrollerPrivate::*inputhandler_t)(
const QPointF &position, qint64 timestamp);
944 inputhandler_t handler;
947 statechange statechanges[] = {
948 { QScroller::Inactive, InputPress, &QScrollerPrivate::pressWhileInactive },
949 { QScroller::Pressed, InputMove, &QScrollerPrivate::moveWhilePressed },
950 { QScroller::Pressed, InputRelease, &QScrollerPrivate::releaseWhilePressed },
951 { QScroller::Dragging, InputMove, &QScrollerPrivate::moveWhileDragging },
952 { QScroller::Dragging, InputRelease, &QScrollerPrivate::releaseWhileDragging },
953 { QScroller::Scrolling, InputPress, &QScrollerPrivate::pressWhileScrolling }
956 for (
int i = 0; i <
int(
sizeof(statechanges) /
sizeof(*statechanges)); ++i) {
957 statechange *sc = statechanges + i;
959 if (d->state == sc->state && input == sc->input)
960 return (d->*sc->handler)(position - d->overshootPosition, timestamp);
998void QScrollerPrivate::updateVelocity(
const QPointF &deltaPixelRaw, qint64 deltaTime)
1004 QPointF ppm = q->pixelPerMeter();
1005 const QScrollerPropertiesPrivate *sp = properties.d.data();
1006 QPointF deltaPixel = deltaPixelRaw;
1008 qCDebug(lcScroller) <<
"QScroller::updateVelocity(" << deltaPixelRaw
1009 <<
" [delta pix], " << deltaTime <<
" [delta ms])";
1012 if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / ((ppm.x() + ppm.y()) / 2) * 1000) > qreal(2.5))
1013 deltaPixel = deltaPixelRaw * qreal(2.5) * ppm / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength();
1015 QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / ppm;
1019 qreal smoothing = sp->dragVelocitySmoothingFactor * qMin(qreal(deltaTime), qreal(50)) / qreal(50);
1023 if ((releaseVelocity != QPointF(0, 0)) && (deltaTime < 100)) {
1024 qCDebug(lcScroller) <<
"SMOOTHED from " << newv <<
" to "
1025 << newv * smoothing + releaseVelocity * (qreal(1) - smoothing);
1028 if (!newv.x() || (qSign(releaseVelocity.x()) == qSign(newv.x())))
1029 newv.setX(newv.x() * smoothing + releaseVelocity.x() * (qreal(1) - smoothing));
1030 if (!newv.y() || (qSign(releaseVelocity.y()) == qSign(newv.y())))
1031 newv.setY(newv.y() * smoothing + releaseVelocity.y() * (qreal(1) - smoothing));
1033 qCDebug(lcScroller) <<
"NO SMOOTHING to " << newv;
1035 releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity));
1036 releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity));
1038 qCDebug(lcScroller) <<
" --> new velocity:" << releaseVelocity;
1041void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress,
1042 qreal startPos, qreal deltaPos, qreal stopPos,
1043 QEasingCurve::Type curve, Qt::Orientation orientation)
1045 if (startPos == stopPos || deltaPos == 0)
1049 if (orientation == Qt::Horizontal && !xSegments.isEmpty()) {
1050 const auto &lastX = xSegments.constLast();
1051 s.startTime = lastX.startTime + lastX.deltaTime * lastX.stopProgress;
1052 }
else if (orientation == Qt::Vertical && !ySegments.isEmpty()) {
1053 const auto &lastY = ySegments.constLast();
1054 s.startTime = lastY.startTime + lastY.deltaTime * lastY.stopProgress;
1056 s.startTime = monotonicTimer.elapsed();
1059 s.startPos = startPos;
1060 s.deltaPos = deltaPos;
1061 s.stopPos = stopPos;
1062 s.deltaTime = deltaTime * 1000;
1063 s.stopProgress = stopProgress;
1064 s.curve.setType(curve);
1067 if (orientation == Qt::Horizontal)
1068 xSegments.enqueue(s);
1070 ySegments.enqueue(s);
1072 qCDebug(lcScroller) <<
"+++ Added a new ScrollSegment: " << s;
1158void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal endPos,
1159 Qt::Orientation orientation, ScrollType type)
1163 if (orientation == Qt::Horizontal)
1168 qCDebug(lcScroller) <<
"+++ createScrollToSegments: t:" << deltaTime <<
"ep:"
1169 << endPos <<
"o:" <<
int(orientation);
1171 const QScrollerPropertiesPrivate *sp = properties.d.data();
1173 qreal startPos = (orientation == Qt::Horizontal) ? contentPosition.x() + overshootPosition.x()
1174 : contentPosition.y() + overshootPosition.y();
1175 qreal deltaPos = (endPos - startPos) / 2;
1177 pushSegment(type, deltaTime * qreal(0.3), qreal(1.0), startPos, deltaPos, startPos + deltaPos,
1178 QEasingCurve::InQuad, orientation);
1179 pushSegment(type, deltaTime * qreal(0.7), qreal(1.0), startPos + deltaPos, deltaPos, endPos,
1180 sp->scrollingCurve.type(), orientation);
1185void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos,
1186 qreal deltaTime, qreal deltaPos,
1187 Qt::Orientation orientation)
1189 const QScrollerPropertiesPrivate *sp = properties.d.data();
1191 QScrollerProperties::OvershootPolicy policy;
1196 if (orientation == Qt::Horizontal) {
1198 policy = sp->hOvershootPolicy;
1199 minPos = contentPosRange.left();
1200 maxPos = contentPosRange.right();
1201 viewSize = viewportSize.width();
1204 policy = sp->vOvershootPolicy;
1205 minPos = contentPosRange.top();
1206 maxPos = contentPosRange.bottom();
1207 viewSize = viewportSize.height();
1210 bool alwaysOvershoot = (policy == QScrollerProperties::OvershootAlwaysOn);
1211 bool noOvershoot = (policy == QScrollerProperties::OvershootAlwaysOff) || !sp->overshootScrollDistanceFactor;
1212 bool canOvershoot = !noOvershoot && (alwaysOvershoot || maxPos);
1214 qCDebug(lcScroller) <<
"+++ createScrollingSegments: s:" << startPos <<
"maxPos:" << maxPos
1215 <<
"o:" <<
int(orientation);
1217 qCDebug(lcScroller) <<
"v = " << v <<
", decelerationFactor = " << sp->decelerationFactor
1218 <<
", curveType = " << sp->scrollingCurve.type();
1220 qreal endPos = startPos + deltaPos;
1222 qCDebug(lcScroller) <<
" Real Delta:" << deltaPos;
1225 if ((startPos < minPos && endPos < minPos) ||
1226 (startPos > maxPos && endPos > maxPos)) {
1227 qreal stopPos = endPos < minPos ? minPos : maxPos;
1228 qreal oDeltaTime = sp->overshootScrollTime;
1230 pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), startPos,
1231 stopPos - startPos, stopPos, sp->scrollingCurve.type(), orientation);
1236 qreal nextSnap = nextSnapPos(endPos, 0, orientation);
1237 qreal lowerSnapPos = nextSnapPos(startPos, -1, orientation);
1238 qreal higherSnapPos = nextSnapPos(startPos, 1, orientation);
1240 qCDebug(lcScroller) <<
" Real Delta:" << lowerSnapPos <<
'-' << nextSnap <<
'-' <<higherSnapPos;
1243 if (nextSnap > higherSnapPos || qIsNaN(higherSnapPos))
1244 higherSnapPos = nextSnap;
1245 if (nextSnap < lowerSnapPos || qIsNaN(lowerSnapPos))
1246 lowerSnapPos = nextSnap;
1248 if (qAbs(v) < sp->minimumVelocity) {
1250 qCDebug(lcScroller) <<
"### below minimum Vel" << orientation;
1253 if (qIsNaN(nextSnap) || nextSnap == startPos)
1258 qreal snapDistance = higherSnapPos - lowerSnapPos;
1260 qreal pressDistance = (orientation == Qt::Horizontal) ?
1261 lastPosition.x() - pressPosition.x() :
1262 lastPosition.y() - pressPosition.y();
1265 if (sp->snapPositionRatio == 0.0 || qAbs(pressDistance / sp->snapPositionRatio) > snapDistance)
1267 else if (pressDistance < 0.0)
1268 endPos = lowerSnapPos;
1270 endPos = higherSnapPos;
1272 deltaPos = endPos - startPos;
1273 qreal midPos = startPos + deltaPos * qreal(0.3);
1274 pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.3), qreal(1.0), startPos,
1275 midPos - startPos, midPos, QEasingCurve::InQuad, orientation);
1276 pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.7), qreal(1.0), midPos,
1277 endPos - midPos, endPos, sp->scrollingCurve.type(), orientation);
1282 if (v > 0 && !qIsNaN(higherSnapPos)) {
1284 if (endPos - startPos)
1285 deltaTime *= qAbs((higherSnapPos - startPos) / (endPos - startPos));
1286 if (deltaTime > sp->snapTime)
1287 deltaTime = sp->snapTime;
1288 endPos = higherSnapPos;
1290 }
else if (v < 0 && !qIsNaN(lowerSnapPos)) {
1292 if (endPos - startPos)
1293 deltaTime *= qAbs((lowerSnapPos - startPos) / (endPos - startPos));
1294 if (deltaTime > sp->snapTime)
1295 deltaTime = sp->snapTime;
1296 endPos = lowerSnapPos;
1299 }
else if (endPos < minPos || endPos > maxPos) {
1300 qreal stopPos = endPos < minPos ? minPos : maxPos;
1302 qCDebug(lcScroller) <<
"Overshoot: delta:" << (stopPos - startPos);
1304 if (!canOvershoot) {
1305 pushSegment(ScrollTypeFlick, deltaTime, qreal(1), startPos, deltaPos, stopPos,
1306 sp->scrollingCurve.type(), orientation);
1308 qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos));
1309 qreal oDeltaTime = sp->overshootScrollTime;
1310 qreal oStopProgress = qMin(stopProgress + oDeltaTime * qreal(0.3) / deltaTime, qreal(1));
1311 qreal oDistance = startPos + deltaPos * sp->scrollingCurve.valueForProgress(oStopProgress) - stopPos;
1312 qreal oMaxDistance = qSign(oDistance) * (viewSize * sp->overshootScrollDistanceFactor);
1314 qCDebug(lcScroller) <<
"1 oDistance:" << oDistance <<
"Max:" << oMaxDistance
1315 <<
"stopP/oStopP" << stopProgress << oStopProgress;
1317 if (qAbs(oDistance) > qAbs(oMaxDistance)) {
1318 oStopProgress = progressForValue(sp->scrollingCurve,
1319 qAbs((stopPos + oMaxDistance - startPos) / deltaPos));
1320 oDistance = oMaxDistance;
1321 qCDebug(lcScroller) <<
"2 oDistance:" << oDistance <<
"Max:" << oMaxDistance
1322 <<
"stopP/oStopP" << stopProgress << oStopProgress;
1325 pushSegment(ScrollTypeFlick, deltaTime, oStopProgress, startPos, deltaPos,
1326 stopPos + oDistance, sp->scrollingCurve.type(), orientation);
1327 pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0),
1328 stopPos + oDistance, -oDistance, stopPos, sp->scrollingCurve.type(),
1334 pushSegment(ScrollTypeFlick, deltaTime, qreal(1.0), startPos, deltaPos, endPos,
1335 sp->scrollingCurve.type(), orientation);
1375bool QScrollerPrivate::prepareScrolling(
const QPointF &position)
1377 QScrollPrepareEvent spe(position);
1379 sendEvent(target, &spe);
1381 qCDebug(lcScroller) <<
"QScrollPrepareEvent returned from" << target <<
"with" << spe.isAccepted()
1382 <<
"mcp:" << spe.contentPosRange() <<
"cp:" << spe.contentPos();
1383 if (spe.isAccepted()) {
1384 QPointF oldContentPos = contentPosition + overshootPosition;
1385 QPointF contentDelta = spe.contentPos() - oldContentPos;
1387 viewportSize = spe.viewportSize();
1388 contentPosRange = spe.contentPosRange();
1389 if (contentPosRange.width() < 0)
1390 contentPosRange.setWidth(0);
1391 if (contentPosRange.height() < 0)
1392 contentPosRange.setHeight(0);
1393 contentPosition = clampToRect(spe.contentPos(), contentPosRange);
1394 overshootPosition = spe.contentPos() - contentPosition;
1397 if (contentDelta != QPointF(0, 0)) {
1399 for (
int i = 0; i < xSegments.size(); i++)
1400 xSegments[i].startPos -= contentDelta.x();
1402 for (
int i = 0; i < ySegments.size(); i++)
1403 ySegments[i].startPos -= contentDelta.y();
1406 if (QWidget *w = qobject_cast<QWidget *>(target))
1407 setDpiFromWidget(w);
1408#if QT_CONFIG(graphicsview)
1409 if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(target)) {
1411 if (
const auto *scene = go->scene()) {
1412 const auto views = scene->views();
1413 if (!views.isEmpty())
1414 setDpiFromWidget(views.first());
1419 if (state == QScroller::Scrolling) {
1420 recalcScrollingSegments();
1502bool QScrollerPrivate::moveWhilePressed(
const QPointF &position, qint64 timestamp)
1505 const QScrollerPropertiesPrivate *sp = properties.d.data();
1506 QPointF ppm = q->pixelPerMeter();
1508 QPointF deltaPixel = position - pressPosition;
1510 bool moveAborted =
false;
1511 bool moveStarted = (((deltaPixel / ppm).manhattanLength()) > sp->dragStartDistance);
1515 QRectF max = contentPosRange;
1516 bool canScrollX = (max.width() > 0);
1517 bool canScrollY = (max.height() > 0);
1519 if (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)
1521 if (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)
1524 if (qAbs(deltaPixel.x() / ppm.x()) < qAbs(deltaPixel.y() / ppm.y())) {
1534 setState(QScroller::Inactive);
1535 moveStarted =
false;
1537 }
else if (moveStarted) {
1538 setState(QScroller::Dragging);
1541 deltaPixel = deltaPixel - deltaPixel * (sp->dragStartDistance / deltaPixel.manhattanLength());
1543 if (deltaPixel != QPointF(0, 0)) {
1545 handleDrag(pressPosition + deltaPixel, timestamp);
1568bool QScrollerPrivate::releaseWhileDragging(
const QPointF &position, qint64 timestamp)
1571 const QScrollerPropertiesPrivate *sp = properties.d.data();
1574 handleDrag(position, timestamp);
1578 QPointF deltaPixel = position - pressPosition;
1579 if (((deltaPixel / q->pixelPerMeter()).manhattanLength()) > sp->dragStartDistance) {
1582 if ((oldVelocity != QPointF(0, 0)) && sp->acceleratingFlickMaximumTime &&
1583 ((timestamp - pressTimestamp) < qint64(sp->acceleratingFlickMaximumTime * 1000))) {
1586 int signX = 0, signY = 0;
1587 if (releaseVelocity.x())
1588 signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1;
1589 if (releaseVelocity.y())
1590 signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1;
1593 releaseVelocity.setX(qBound(-sp->maximumVelocity,
1594 oldVelocity.x() * sp->acceleratingFlickSpeedupFactor,
1595 sp->maximumVelocity));
1597 releaseVelocity.setY(qBound(-sp->maximumVelocity,
1598 oldVelocity.y() * sp->acceleratingFlickSpeedupFactor,
1599 sp->maximumVelocity));
1603 QPointF ppm = q->pixelPerMeter();
1604 createScrollingSegments(releaseVelocity, contentPosition + overshootPosition, ppm);
1606 qCDebug(lcScroller) <<
"QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity
1607 <<
"-- minimum velocity:" << sp->minimumVelocity <<
"overshoot" << overshootPosition;
1609 if (xSegments.isEmpty() && ySegments.isEmpty())
1610 setState(QScroller::Inactive);
1612 setState(QScroller::Scrolling);
1728void QScrollerPrivate::setContentPositionHelperDragging(
const QPointF &deltaPos)
1730 const QScrollerPropertiesPrivate *sp = properties.d.data();
1732 if (sp->overshootDragResistanceFactor)
1733 overshootPosition /= sp->overshootDragResistanceFactor;
1735 QPointF oldPos = contentPosition + overshootPosition;
1736 QPointF newPos = oldPos + deltaPos;
1738 qCDebug(lcScroller) <<
"QScroller::setContentPositionHelperDragging(" << deltaPos <<
" [pix])";
1739 qCDebug(lcScroller) <<
" --> overshoot:" << overshootPosition <<
"- old pos:" << oldPos <<
"- new pos:" << newPos;
1741 QPointF newClampedPos = clampToRect(newPos, contentPosRange);
1744 bool alwaysOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
1745 bool alwaysOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
1746 bool noOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) ||
1747 ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) ||
1748 !sp->overshootDragDistanceFactor;
1749 bool noOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) ||
1750 ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) ||
1751 !sp->overshootDragDistanceFactor;
1752 bool canOvershootX = !noOvershootX && (alwaysOvershootX || contentPosRange.width());
1753 bool canOvershootY = !noOvershootY && (alwaysOvershootY || contentPosRange.height());
1755 qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0;
1756 qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0;
1758 qreal maxOvershootX = viewportSize.width() * sp->overshootDragDistanceFactor;
1759 qreal maxOvershootY = viewportSize.height() * sp->overshootDragDistanceFactor;
1761 qCDebug(lcScroller) <<
" --> noOs:" << noOvershootX <<
"drf:" << sp->overshootDragResistanceFactor
1762 <<
"mdf:" << sp->overshootScrollDistanceFactor <<
"ossP:"<<sp->hOvershootPolicy;
1763 qCDebug(lcScroller) <<
" --> canOS:" << canOvershootX <<
"newOS:" << newOvershootX <<
"maxOS:" << maxOvershootX;
1765 if (sp->overshootDragResistanceFactor) {
1766 newOvershootX *= sp->overshootDragResistanceFactor;
1767 newOvershootY *= sp->overshootDragResistanceFactor;
1772 newOvershootX = qBound(-maxOvershootX, newOvershootX, maxOvershootX);
1773 newOvershootY = qBound(-maxOvershootY, newOvershootY, maxOvershootY);
1775 overshootPosition.setX(newOvershootX);
1776 overshootPosition.setY(newOvershootY);
1777 contentPosition = newClampedPos;
1779 QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated);
1780 sendEvent(target, &se);
1781 firstScroll =
false;
1783 qCDebug(lcScroller) <<
" --> new position:" << newClampedPos <<
"- new overshoot:"
1784 << overshootPosition <<
"- overshoot x/y?:" << overshootPosition;
1848qreal QScrollerPrivate::nextSnapPos(qreal p,
int dir, Qt::Orientation orientation)
const
1850 qreal bestSnapPos =
Q_QNAN;
1856 if (orientation == Qt::Horizontal) {
1857 minPos = contentPosRange.left();
1858 maxPos = contentPosRange.right();
1860 minPos = contentPosRange.top();
1861 maxPos = contentPosRange.bottom();
1864 if (orientation == Qt::Horizontal) {
1866 for (qreal snapPos : snapPositionsX) {
1867 qreal snapPosDist = snapPos - p;
1868 if ((dir > 0 && snapPosDist < 0) ||
1869 (dir < 0 && snapPosDist > 0))
1871 if (snapPos < minPos || snapPos > maxPos )
1874 if (qIsNaN(bestSnapPos) ||
1875 qAbs(snapPosDist) < bestSnapPosDist ) {
1876 bestSnapPos = snapPos;
1877 bestSnapPosDist = qAbs(snapPosDist);
1882 if (snapIntervalX > 0.0) {
1883 qreal first = minPos + snapFirstX;
1886 snapPos = qCeil((p - first) / snapIntervalX) * snapIntervalX + first;
1888 snapPos = qFloor((p - first) / snapIntervalX) * snapIntervalX + first;
1889 else if (p <= first)
1893 qreal last = qFloor((maxPos - first) / snapIntervalX) * snapIntervalX + first;
1897 snapPos = qRound((p - first) / snapIntervalX) * snapIntervalX + first;
1900 if (snapPos >= first && snapPos <= maxPos ) {
1901 qreal snapPosDist = snapPos - p;
1903 if (qIsNaN(bestSnapPos) ||
1904 qAbs(snapPosDist) < bestSnapPosDist ) {
1905 bestSnapPos = snapPos;
1906 bestSnapPosDist = qAbs(snapPosDist);
1913 for (qreal snapPos : snapPositionsY) {
1914 qreal snapPosDist = snapPos - p;
1915 if ((dir > 0 && snapPosDist < 0) ||
1916 (dir < 0 && snapPosDist > 0))
1918 if (snapPos < minPos || snapPos > maxPos )
1921 if (qIsNaN(bestSnapPos) ||
1922 qAbs(snapPosDist) < bestSnapPosDist) {
1923 bestSnapPos = snapPos;
1924 bestSnapPosDist = qAbs(snapPosDist);
1929 if (snapIntervalY > 0.0) {
1930 qreal first = minPos + snapFirstY;
1933 snapPos = qCeil((p - first) / snapIntervalY) * snapIntervalY + first;
1935 snapPos = qFloor((p - first) / snapIntervalY) * snapIntervalY + first;
1936 else if (p <= first)
1940 qreal last = qFloor((maxPos - first) / snapIntervalY) * snapIntervalY + first;
1944 snapPos = qRound((p - first) / snapIntervalY) * snapIntervalY + first;
1947 if (snapPos >= first && snapPos <= maxPos ) {
1948 qreal snapPosDist = snapPos - p;
1950 if (qIsNaN(bestSnapPos) ||
1951 qAbs(snapPosDist) < bestSnapPosDist) {
1952 bestSnapPos = snapPos;
1953 bestSnapPosDist = qAbs(snapPosDist);