void AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
{
    ScheduledScrollUpdate scrollUpdate(nodeID, scrollPosition, programmaticScroll, scrollingLayerPositionAction);
    
    if (m_updateNodeScrollPositionTimer.isActive()) {
        if (m_scheduledScrollUpdate.matchesUpdateType(scrollUpdate)) {
            m_scheduledScrollUpdate.scrollPosition = scrollPosition;
            return;
        }
    
        // If the parameters don't match what was previously scheduled, dispatch immediately.
        m_updateNodeScrollPositionTimer.stop();
        updateScrollPositionAfterAsyncScroll(m_scheduledScrollUpdate.nodeID, m_scheduledScrollUpdate.scrollPosition, m_scheduledScrollUpdate.isProgrammaticScroll, m_scheduledScrollUpdate.updateLayerPositionAction);
        updateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, programmaticScroll, scrollingLayerPositionAction);
        return;
    }

    m_scheduledScrollUpdate = scrollUpdate;
    m_updateNodeScrollPositionTimer.startOneShot(0);
}
示例#2
0
void QAbstractKineticScrollerPrivate::handleMove(QMouseEvent *me, QPoint &delta)
{
    Q_Q(QAbstractKineticScroller);

    if (mode == QAbstractKineticScroller::AccelerationMode) {
        // we need delta to be the delta to ipos, not pos in this case
        delta = me->globalPos() - ipos;
    }

    if (axisLockThreshold) {
        int dx = qAbs(delta.x());
        int dy = qAbs(delta.y());
        if (dx || dy) {
            bool vertical = (dy > dx);
            qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx);
            qKSDebug() << "axis lock: " << alpha << " / " << axisLockThreshold << " - isvertical: " << vertical << " - dx: " << dx << " - dy: " << dy;
            if (alpha <= axisLockThreshold) {
                if (vertical)
                    delta.setX(0);
                else
                    delta.setY(0);
            }
        }
    }

    switch (mode) {
    case QAbstractKineticScroller::PushMode:
        // Scroll by the amount of pixels the cursor has moved
        // since the last motion event.
        scrollUpdate(delta);
        pos = me->globalPos();
        break;

    case QAbstractKineticScroller::AccelerationMode: {
        // Set acceleration relative to the initial click
        QSize size = q->viewportSize();
        qreal signX = 0, signY = 0;
        if (delta.x() < 0)
            signX = -1;
        else if (delta.x() > 0)
            signX = 1;
        if (delta.y() < 0)
            signY = -1;
        else if (delta.y() > 0)
            signY = 1;

        velocity.setX(signX * ((qreal(qAbs(delta.x())) / qreal(size.width()) * (maxVelocity - minVelocity)) + minVelocity));
        velocity.setY(signY * ((qreal(qAbs(delta.y())) / qreal(size.height()) * (maxVelocity - minVelocity)) + minVelocity));
        break;
    }
    case QAbstractKineticScroller::AutoMode:
        QPointF newVelocity = calculateVelocity(delta, lastTime.elapsed());
        QPoint maxPos = q->maximumScrollPosition();

        bool alwaysOvershoot = (overshootPolicy == QAbstractKineticScroller::OvershootAlwaysOn);

        if (!maxPos.x() && !alwaysOvershoot) {
            delta.setX(0);
            newVelocity.setX(0);
        }
        if (!maxPos.y() && !alwaysOvershoot) {
            delta.setY(0);
            newVelocity.setY(0);
        }
        velocity = newVelocity;

        scrollUpdate(delta);

        if (maxPos.x() || alwaysOvershoot)
            pos.setX(me->globalPos().x());
        if (maxPos.y() || alwaysOvershoot)
            pos.setY(me->globalPos().y());
        break;
    }
}