/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickflickable_p.h"
#include "qquickflickable_p_p.h"
#include "qquickflickablebehavior_p.h"
#include "qquickwindow.h"
#include "qquickwindow_p.h"
#include "qquickevents_p_p.h"

#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquicktransition_p.h>
#include <private/qqmlglobal_p.h>

#include <QtQml/qqmlinfo.h>
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qstylehints.h>
#include <QtCore/qmath.h>
#include "qplatformdefs.h"

#include <math.h>
#include <cmath>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent)

// FlickThreshold determines how far the "mouse" must have moved
// before we perform a flick.
static const int FlickThreshold = 15;

// RetainGrabVelocity is the maxmimum instantaneous velocity that
// will ensure the Flickable retains the grab on consecutive flicks.
static const int RetainGrabVelocity = 100;

// Currently std::round can't be used on Android when using ndk g++, so
// use C version instead. We could just define two versions of Round, one
// for float and one for double, but then only one of them would be used
// and compiler would trigger a warning about unused function.
//
// See https://code.google.com/p/android/issues/detail?id=54418
template<typename T>
static T Round(T t) {
    return round(t);
}
template<>
Q_DECL_UNUSED float Round<float>(float f) {
    return roundf(f);
}

static qreal EaseOvershoot(qreal t) {
    return qAtan(t);
}

QQuickFlickableVisibleArea::QQuickFlickableVisibleArea(QQuickFlickable *parent)
    : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
    , m_yPosition(0.), m_heightRatio(0.)
{
}

qreal QQuickFlickableVisibleArea::widthRatio() const
{
    return m_widthRatio;
}

qreal QQuickFlickableVisibleArea::xPosition() const
{
    return m_xPosition;
}

qreal QQuickFlickableVisibleArea::heightRatio() const
{
    return m_heightRatio;
}

qreal QQuickFlickableVisibleArea::yPosition() const
{
    return m_yPosition;
}

void QQuickFlickableVisibleArea::updateVisible()
{
    QQuickFlickablePrivate *p = QQuickFlickablePrivate::get(flickable);

    bool changeX = false;
    bool changeY = false;
    bool changeWidth = false;
    bool changeHeight = false;

    // Vertical
    const qreal viewheight = flickable->height();
    const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
    qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
    qreal pageSize = viewheight / (maxyextent + viewheight);

    if (pageSize != m_heightRatio) {
        m_heightRatio = pageSize;
        changeHeight = true;
    }
    if (pagePos != m_yPosition) {
        m_yPosition = pagePos;
        changeY = true;
    }

    // Horizontal
    const qreal viewwidth = flickable->width();
    const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
    pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
    pageSize = viewwidth / (maxxextent + viewwidth);

    if (pageSize != m_widthRatio) {
        m_widthRatio = pageSize;
        changeWidth = true;
    }
    if (pagePos != m_xPosition) {
        m_xPosition = pagePos;
        changeX = true;
    }

    if (changeX)
        emit xPositionChanged(m_xPosition);
    if (changeY)
        emit yPositionChanged(m_yPosition);
    if (changeWidth)
        emit widthRatioChanged(m_widthRatio);
    if (changeHeight)
        emit heightRatioChanged(m_heightRatio);
}


class QQuickFlickableReboundTransition : public QQuickTransitionManager
{
public:
    QQuickFlickableReboundTransition(QQuickFlickable *f, const QString &name)
        : flickable(f), axisData(nullptr), propName(name), active(false)
    {
    }

    ~QQuickFlickableReboundTransition()
    {
        flickable = nullptr;
    }

    bool startTransition(QQuickFlickablePrivate::AxisData *data, qreal toPos) {
        QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flickable);
        if (!fp->rebound || !fp->rebound->enabled())
            return false;
        active = true;
        axisData = data;
        axisData->transitionTo = toPos;
        axisData->transitionToSet = true;

        actions.clear();
        actions << QQuickStateAction(fp->contentItem, propName, toPos);
        QQuickTransitionManager::transition(actions, fp->rebound, fp->contentItem);
        return true;
    }

    bool isActive() const {
        return active;
    }

    void stopTransition() {
        if (!flickable || !isRunning())
            return;
        QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flickable);
        if (axisData == &fp->hData)
            axisData->move.setValue(-flickable->contentX());
        else
            axisData->move.setValue(-flickable->contentY());
        active = false;
        cancel();
    }

protected:
    void finished() override {
        if (!flickable)
            return;
        axisData->move.setValue(axisData->transitionTo);
        QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flickable);
        active = false;

        if (!fp->hData.transitionToBounds->isActive()
                && !fp->vData.transitionToBounds->isActive()) {
            flickable->movementEnding();
        }
    }

private:
    QQuickStateOperation::ActionList actions;
    QQuickFlickable *flickable;
    QQuickFlickablePrivate::AxisData *axisData;
    QString propName;
    bool active;
};

QQuickFlickablePrivate::AxisData::~AxisData()
{
    delete transitionToBounds;
}


QQuickFlickablePrivate::QQuickFlickablePrivate()
  : contentItem(new QQuickItem)
    , hData(this, &QQuickFlickablePrivate::setViewportX)
    , vData(this, &QQuickFlickablePrivate::setViewportY)
    , hMoved(false), vMoved(false)
    , stealMouse(false), pressed(false)
    , scrollingPhase(false), interactive(true), calcVelocity(false)
    , pixelAligned(false)
    , syncDrag(false)
    , lastPosTime(-1)
    , lastPressTime(0)
    , deceleration(QML_FLICK_DEFAULTDECELERATION)
    , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
    , delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400)
    , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr)
    , flickableDirection(QQuickFlickable::AutoFlickDirection)
    , boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
    , boundsMovement(QQuickFlickable::FollowBoundsBehavior)
    , rebound(nullptr)
{
}

void QQuickFlickablePrivate::init()
{
    Q_Q(QQuickFlickable);
    QQml_setParent_noEvent(contentItem, q);
    contentItem->setParentItem(q);
    qmlobject_connect(&timeline, QQuickTimeLine, SIGNAL(completed()),
                      q, QQuickFlickable, SLOT(timelineCompleted()));
    qmlobject_connect(&velocityTimeline, QQuickTimeLine, SIGNAL(completed()),
                      q, QQuickFlickable, SLOT(velocityTimelineCompleted()));
    q->setAcceptedMouseButtons(Qt::LeftButton);
    q->setAcceptTouchEvents(false); // rely on mouse events synthesized from touch
    q->setFiltersChildMouseEvents(true);
    QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
    viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
}

/*
    Returns the amount to overshoot by given a velocity.
    Will be roughly in range 0 - size/4
*/
qreal QQuickFlickablePrivate::overShootDistance(qreal size) const
{
    if (maxVelocity <= 0)
        return 0.0;

    return qMin(qreal(QML_FLICK_OVERSHOOT), size/3);
}

void QQuickFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity)
{
    if (v > maxVelocity)
        v = maxVelocity;
    else if (v < -maxVelocity)
        v = -maxVelocity;
    velocityBuffer.append(v);
    if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
        velocityBuffer.remove(0);
}

void QQuickFlickablePrivate::AxisData::updateVelocity()
{
    velocity = 0;
    if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
        int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
        for (int i = 0; i < count; ++i) {
            qreal v = velocityBuffer.at(i);
            velocity += v;
        }
        velocity /= count;
    }
}

void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &)
{
    Q_Q(QQuickFlickable);
    if (item == contentItem) {
        Qt::Orientations orient = nullptr;
        if (change.xChange())
            orient |= Qt::Horizontal;
        if (change.yChange())
            orient |= Qt::Vertical;
        if (orient)
            q->viewportMoved(orient);
        if (orient & Qt::Horizontal)
            emit q->contentXChanged();
        if (orient & Qt::Vertical)
            emit q->contentYChanged();
    }
}

bool QQuickFlickablePrivate::flickX(qreal velocity)
{
    Q_Q(QQuickFlickable);
    return flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity);
}

bool QQuickFlickablePrivate::flickY(qreal velocity)
{
    Q_Q(QQuickFlickable);
    return flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
}

bool QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal,
                                         QQuickTimeLineCallback::Callback fixupCallback, qreal velocity)
{
    Q_Q(QQuickFlickable);
    qreal maxDistance = -1;
    data.fixingUp = false;
    // -ve velocity means list is moving up
    if (velocity > 0) {
        maxDistance = qAbs(minExtent - data.move.value());
        data.flickTarget = minExtent;
    } else {
        maxDistance = qAbs(maxExtent - data.move.value());
        data.flickTarget = maxExtent;
    }
    if (maxDistance > 0 || boundsBehavior & QQuickFlickable::OvershootBounds) {
        qreal v = velocity;
        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
            if (v < 0)
                v = -maxVelocity;
            else
                v = maxVelocity;
        }

        // adjust accel so that we hit a full pixel
        qreal accel = deceleration;
        qreal v2 = v * v;
        qreal dist = v2 / (accel * 2.0);
        if (v > 0)
            dist = -dist;
        qreal target = -Round(-(data.move.value() - dist));
        dist = -target + data.move.value();
        accel = v2 / (2.0f * qAbs(dist));

        resetTimeline(data);
        if (!data.inOvershoot) {
            if (boundsBehavior & QQuickFlickable::OvershootBounds)
                timeline.accel(data.move, v, accel);
            else
                timeline.accel(data.move, v, accel, maxDistance);
        }
        timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this));

        if (&data == &hData)
            return !hData.flicking && q->xflick();
        else if (&data == &vData)
            return !vData.flicking && q->yflick();
        return false;
    } else {
        resetTimeline(data);
        fixup(data, minExtent, maxExtent);
        return false;
    }
}

void QQuickFlickablePrivate::fixupY_callback(void *data)
{
    ((QQuickFlickablePrivate *)data)->fixupY();
}

void QQuickFlickablePrivate::fixupX_callback(void *data)
{
    ((QQuickFlickablePrivate *)data)->fixupX();
}

void QQuickFlickablePrivate::fixupX()
{
    Q_Q(QQuickFlickable);
    if (!q->isComponentComplete())
        return; //Do not fixup from initialization values
    fixup(hData, q->minXExtent(), q->maxXExtent());
}

void QQuickFlickablePrivate::fixupY()
{
    Q_Q(QQuickFlickable);
    if (!q->isComponentComplete())
        return; //Do not fixup from initialization values
    fixup(vData, q->minYExtent(), q->maxYExtent());
}

void QQuickFlickablePrivate::adjustContentPos(AxisData &data, qreal toPos)
{
    Q_Q(QQuickFlickable);
    switch (fixupMode) {
    case Immediate:
        timeline.set(data.move, toPos);
        break;
    case ExtentChanged:
        // The target has changed. Don't start from the beginning; just complete the
        // second half of the animation using the new extent.
        timeline.move(data.move, toPos, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
        data.fixingUp = true;
        break;
    default: {
            if (data.transitionToBounds && data.transitionToBounds->startTransition(&data, toPos)) {
                q->movementStarting();
                data.fixingUp = true;
            } else {
                qreal dist = toPos - data.move;
                timeline.move(data.move, toPos - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
                timeline.move(data.move, toPos, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
                data.fixingUp = true;
            }
        }
    }
}

void QQuickFlickablePrivate::resetTimeline(AxisData &data)
{
    timeline.reset(data.move);
    if (data.transitionToBounds)
        data.transitionToBounds->stopTransition();
}

void QQuickFlickablePrivate::clearTimeline()
{
    timeline.clear();
    if (hData.transitionToBounds)
        hData.transitionToBounds->stopTransition();
    if (vData.transitionToBounds)
        vData.transitionToBounds->stopTransition();
}

void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
    if (data.move.value() >= minExtent || maxExtent > minExtent) {
        resetTimeline(data);
        if (data.move.value() != minExtent) {
            adjustContentPos(data, minExtent);
        }
    } else if (data.move.value() <= maxExtent) {
        resetTimeline(data);
        adjustContentPos(data, maxExtent);
    } else if (-Round(-data.move.value()) != data.move.value()) {
        // We could animate, but since it is less than 0.5 pixel it's probably not worthwhile.
        resetTimeline(data);
        qreal val = data.move.value();
        if (std::abs(-Round(-val) - val) < 0.25) // round small differences
            val = -Round(-val);
        else if (data.smoothVelocity.value() > 0) // continue direction of motion for larger
            val = -std::floor(-val);
        else if (data.smoothVelocity.value() < 0)
            val = -std::ceil(-val);
        else // otherwise round
            val = -Round(-val);
        timeline.set(data.move, val);
    }
    data.inOvershoot = false;
    fixupMode = Normal;
    data.vTime = timeline.time();
}

static bool fuzzyLessThanOrEqualTo(qreal a, qreal b)
{
    if (a == 0.0 || b == 0.0) {
        // qFuzzyCompare is broken
        a += 1.0;
        b += 1.0;
    }
    return a <= b || qFuzzyCompare(a, b);
}

void QQuickFlickablePrivate::updateBeginningEnd()
{
    Q_Q(QQuickFlickable);
    bool atXBeginningChange = false, atXEndChange = false;
    bool atYBeginningChange = false, atYEndChange = false;

    // Vertical
    const qreal maxyextent = -q->maxYExtent();
    const qreal minyextent = -q->minYExtent();
    const qreal ypos = -vData.move.value();
    bool atBeginning = fuzzyLessThanOrEqualTo(ypos, minyextent);
    bool atEnd = fuzzyLessThanOrEqualTo(maxyextent, ypos);

    if (atBeginning != vData.atBeginning) {
        vData.atBeginning = atBeginning;
        atYBeginningChange = true;
    }
    if (atEnd != vData.atEnd) {
        vData.atEnd = atEnd;
        atYEndChange = true;
    }

    // Horizontal
    const qreal maxxextent = -q->maxXExtent();
    const qreal minxextent = -q->minXExtent();
    const qreal xpos = -hData.move.value();
    atBeginning = fuzzyLessThanOrEqualTo(xpos, minxextent);
    atEnd = fuzzyLessThanOrEqualTo(maxxextent, xpos);

    if (atBeginning != hData.atBeginning) {
        hData.atBeginning = atBeginning;
        atXBeginningChange = true;
    }
    if (atEnd != hData.atEnd) {
        hData.atEnd = atEnd;
        atXEndChange = true;
    }

    if (vData.extentsChanged) {
        vData.extentsChanged = false;
        qreal originY = q->originY();
        if (vData.origin != originY) {
            vData.origin = originY;
            emit q->originYChanged();
        }
    }

    if (hData.extentsChanged) {
        hData.extentsChanged = false;
        qreal originX = q->originX();
        if (hData.origin != originX) {
            hData.origin = originX;
            emit q->originXChanged();
        }
    }

    if (atXEndChange || atYEndChange || atXBeginningChange || atYBeginningChange)
        emit q->isAtBoundaryChanged();
    if (atXEndChange)
        emit q->atXEndChanged();
    if (atXBeginningChange)
        emit q->atXBeginningChanged();
    if (atYEndChange)
        emit q->atYEndChanged();
    if (atYBeginningChange)
        emit q->atYBeginningChanged();

    if (visibleArea)
        visibleArea->updateVisible();
}

/*!
    \qmlsignal QtQuick::Flickable::dragStarted()

    This signal is emitted when the view starts to be dragged due to user
    interaction.

    The corresponding handler is \c onDragStarted.
*/

/*!
    \qmlsignal QtQuick::Flickable::dragEnded()

    This signal is emitted when the user stops dragging the view.

    If the velocity of the drag is sufficient at the time the
    touch/mouse button is released then a flick will start.

    The corresponding handler is \c onDragEnded.
*/

/*!
    \qmltype Flickable
    \instantiates QQuickFlickable
    \inqmlmodule QtQuick
    \ingroup qtquick-input
    \ingroup qtquick-containers

    \brief Provides a surface that can be "flicked".
    \inherits Item

    The Flickable item places its children on a surface that can be dragged
    and flicked, causing the view onto the child items to scroll. This
    behavior forms the basis of Items that are designed to show large numbers
    of child items, such as \l ListView and \l GridView.

    In traditional user interfaces, views can be scrolled using standard
    controls, such as scroll bars and arrow buttons. In some situations, it
    is also possible to drag the view directly by pressing and holding a
    mouse button while moving the cursor. In touch-based user interfaces,
    this dragging action is often complemented with a flicking action, where
    scrolling continues after the user has stopped touching the view.

    Flickable does not automatically clip its contents. If it is not used as
    a full-screen item, you should consider setting the \l{Item::}{clip} property
    to true.

    \section1 Example Usage

    \div {class="float-right"}
    \inlineimage flickable.gif
    \enddiv

    The following example shows a small view onto a large image in which the
    user can drag or flick the image in order to view different parts of it.

    \snippet qml/flickable.qml document

    \clearfloat

    Items declared as children of a Flickable are automatically parented to the
    Flickable's \l contentItem.  This should be taken into account when
    operating on the children of the Flickable; it is usually the children of
    \c contentItem that are relevant.  For example, the bound of Items added
    to the Flickable will be available by \c contentItem.childrenRect

    \section1 Examples of contentX and contentY

    The following images demonstrate a flickable being flicked in various
    directions and the resulting \l contentX and \l contentY values.
    The blue square represents the flickable's content, and the black
    border represents the bounds of the flickable.

    \table
        \row
            \li \image flickable-contentXY-resting.png
            \li The \c contentX and \c contentY are both \c 0.
        \row
            \li \image flickable-contentXY-top-left.png
            \li The \c contentX and the \c contentY are both \c 50.
        \row
            \li \image flickable-contentXY-top-right.png
            \li The \c contentX is \c -50 and the \c contentY is \c 50.
        \row
            \li \image flickable-contentXY-bottom-right.png
            \li The \c contentX and the \c contentY are both \c -50.
        \row
            \li \image flickable-contentXY-bottom-left.png
            \li The \c contentX is \c 50 and the \c contentY is \c -50.
    \endtable

    \section1 Limitations

    \note Due to an implementation detail, items placed inside a Flickable
    cannot anchor to the Flickable. Instead, use \l {Item::}{parent}, which
    refers to the Flickable's \l contentItem. The size of the content item is
    determined by \l contentWidth and \l contentHeight.
*/

/*!
    \qmlsignal QtQuick::Flickable::movementStarted()

    This signal is emitted when the view begins moving due to user
    interaction or a generated flick().

    The corresponding handler is \c onMovementStarted.
*/

/*!
    \qmlsignal QtQuick::Flickable::movementEnded()

    This signal is emitted when the view stops moving due to user
    interaction or a generated flick().  If a flick was active, this signal will
    be emitted once the flick stops.  If a flick was not
    active, this signal will be emitted when the
    user stops dragging - i.e. a mouse or touch release.

    The corresponding handler is \c onMovementEnded.
*/

/*!
    \qmlsignal QtQuick::Flickable::flickStarted()

    This signal is emitted when the view is flicked.  A flick
    starts from the point that the mouse or touch is released,
    while still in motion.

    The corresponding handler is \c onFlickStarted.
*/

/*!
    \qmlsignal QtQuick::Flickable::flickEnded()

    This signal is emitted when the view stops moving due to a flick.

    The corresponding handler is \c onFlickEnded.
*/

/*!
    \qmlpropertygroup QtQuick::Flickable::visibleArea
    \qmlproperty real QtQuick::Flickable::visibleArea.xPosition
    \qmlproperty real QtQuick::Flickable::visibleArea.widthRatio
    \qmlproperty real QtQuick::Flickable::visibleArea.yPosition
    \qmlproperty real QtQuick::Flickable::visibleArea.heightRatio

    These properties describe the position and size of the currently viewed area.
    The size is defined as the percentage of the full view currently visible,
    scaled to 0.0 - 1.0.  The page position is usually in the range 0.0 (beginning) to
    1.0 minus size ratio (end), i.e. \c yPosition is in the range 0.0 to 1.0-\c heightRatio.
    However, it is possible for the contents to be dragged outside of the normal
    range, resulting in the page positions also being outside the normal range.

    These properties are typically used to draw a scrollbar. For example:

    \snippet qml/flickableScrollbar.qml 0
    \dots 8
    \snippet qml/flickableScrollbar.qml 1

    \sa {customitems/scrollbar}{UI Components: Scrollbar Example}
*/
QQuickFlickable::QQuickFlickable(QQuickItem *parent)
  : QQuickItem(*(new QQuickFlickablePrivate), parent)
{
    Q_D(QQuickFlickable);
    d->init();
}

QQuickFlickable::QQuickFlickable(QQuickFlickablePrivate &dd, QQuickItem *parent)
  : QQuickItem(dd, parent)
{
    Q_D(QQuickFlickable);
    d->init();
}

QQuickFlickable::~QQuickFlickable()
{
}

/*!
    \qmlproperty real QtQuick::Flickable::contentX
    \qmlproperty real QtQuick::Flickable::contentY

    These properties hold the surface coordinate currently at the top-left
    corner of the Flickable. For example, if you flick an image up 100 pixels,
    \c contentY will increase by 100.

    \note If you flick back to the origin (the top-left corner), after the
    rebound animation, \c contentX will settle to the same value as \c originX,
    and \c contentY to \c originY. These are usually (0,0), however ListView
    and GridView may have an arbitrary origin due to delegate size variation,
    or item insertion/removal outside the visible region. So if you want to
    implement something like a vertical scrollbar, one way is to use
    \c {y: (contentY - originY) * (height / contentHeight)}
    for the position; another way is to use the normalized values in
    \l {QtQuick::Flickable::visibleArea}{visibleArea}.

    \sa {Examples of contentX and contentY}, originX, originY
*/
qreal QQuickFlickable::contentX() const
{
    Q_D(const QQuickFlickable);
    return -d->contentItem->x();
}

void QQuickFlickable::setContentX(qreal pos)
{
    Q_D(QQuickFlickable);
    d->hData.explicitValue = true;
    d->resetTimeline(d->hData);
    d->hData.vTime = d->timeline.time();
    if (isMoving() || isFlicking())
        movementEnding(true, false);
    if (!qFuzzyCompare(-pos, d->hData.move.value()))
        d->hData.move.setValue(-pos);
}

qreal QQuickFlickable::contentY() const
{
    Q_D(const QQuickFlickable);
    return -d->contentItem->y();
}

void QQuickFlickable::setContentY(qreal pos)
{
    Q_D(QQuickFlickable);
    d->vData.explicitValue = true;
    d->resetTimeline(d->vData);
    d->vData.vTime = d->timeline.time();
    if (isMoving() || isFlicking())
        movementEnding(false, true);
    if (!qFuzzyCompare(-pos, d->vData.move.value()))
        d->vData.move.setValue(-pos);
}

/*!
    \qmlproperty bool QtQuick::Flickable::interactive

    This property describes whether the user can interact with the Flickable.
    A user cannot drag or flick a Flickable that is not interactive.

    By default, this property is true.

    This property is useful for temporarily disabling flicking. This allows
    special interaction with Flickable's children; for example, you might want
    to freeze a flickable map while scrolling through a pop-up dialog that
    is a child of the Flickable.
*/
bool QQuickFlickable::isInteractive() const
{
    Q_D(const QQuickFlickable);
    return d->interactive;
}

void QQuickFlickable::setInteractive(bool interactive)
{
    Q_D(QQuickFlickable);
    if (interactive != d->interactive) {
        d->interactive = interactive;
        if (!interactive) {
            d->cancelInteraction();
        }
        emit interactiveChanged();
    }
}

/*!
    \qmlproperty real QtQuick::Flickable::horizontalVelocity
    \qmlproperty real QtQuick::Flickable::verticalVelocity

    The instantaneous velocity of movement along the x and y axes, in pixels/sec.

    The reported velocity is smoothed to avoid erratic output.

    Note that for views with a large content size (more than 10 times the view size),
    the velocity of the flick may exceed the velocity of the touch in the case
    of multiple quick consecutive flicks.  This allows the user to flick faster
    through large content.
*/
qreal QQuickFlickable::horizontalVelocity() const
{
    Q_D(const QQuickFlickable);
    return d->hData.smoothVelocity.value();
}

qreal QQuickFlickable::verticalVelocity() const
{
    Q_D(const QQuickFlickable);
    return d->vData.smoothVelocity.value();
}

/*!
    \qmlproperty bool QtQuick::Flickable::atXBeginning
    \qmlproperty bool QtQuick::Flickable::atXEnd
    \qmlproperty bool QtQuick::Flickable::atYBeginning
    \qmlproperty bool QtQuick::Flickable::atYEnd

    These properties are true if the flickable view is positioned at the beginning,
    or end respectively.
*/
bool QQuickFlickable::isAtXEnd() const
{
    Q_D(const QQuickFlickable);
    return d->hData.atEnd;
}

bool QQuickFlickable::isAtXBeginning() const
{
    Q_D(const QQuickFlickable);
    return d->hData.atBeginning;
}

bool QQuickFlickable::isAtYEnd() const
{
    Q_D(const QQuickFlickable);
    return d->vData.atEnd;
}

bool QQuickFlickable::isAtYBeginning() const
{
    Q_D(const QQuickFlickable);
    return d->vData.atBeginning;
}

/*!
    \qmlproperty Item QtQuick::Flickable::contentItem

    The internal item that contains the Items to be moved in the Flickable.

    Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.

    Items created dynamically need to be explicitly parented to the \e contentItem:
    \code
    Flickable {
        id: myFlickable
        function addItem(file) {
            var component = Qt.createComponent(file)
            component.createObject(myFlickable.contentItem);
        }
    }
    \endcode
*/
QQuickItem *QQuickFlickable::contentItem() const
{
    Q_D(const QQuickFlickable);
    return d->contentItem;
}

QQuickFlickableVisibleArea *QQuickFlickable::visibleArea()
{
    Q_D(QQuickFlickable);
    if (!d->visibleArea) {
        d->visibleArea = new QQuickFlickableVisibleArea(this);
        d->visibleArea->updateVisible(); // calculate initial ratios
    }
    return d->visibleArea;
}

/*!
    \qmlproperty enumeration QtQuick::Flickable::flickableDirection

    This property determines which directions the view can be flicked.

    \list
    \li Flickable.AutoFlickDirection (default) - allows flicking vertically if the
    \e contentHeight is not equal to the \e height of the Flickable.
    Allows flicking horizontally if the \e contentWidth is not equal
    to the \e width of the Flickable.
    \li Flickable.AutoFlickIfNeeded - allows flicking vertically if the
    \e contentHeight is greater than the \e height of the Flickable.
    Allows flicking horizontally if the \e contentWidth is greater than
    to the \e width of the Flickable. (since \c{QtQuick 2.7})
    \li Flickable.HorizontalFlick - allows flicking horizontally.
    \li Flickable.VerticalFlick - allows flicking vertically.
    \li Flickable.HorizontalAndVerticalFlick - allows flicking in both directions.
    \endlist
*/
QQuickFlickable::FlickableDirection QQuickFlickable::flickableDirection() const
{
    Q_D(const QQuickFlickable);
    return d->flickableDirection;
}

void QQuickFlickable::setFlickableDirection(FlickableDirection direction)
{
    Q_D(QQuickFlickable);
    if (direction != d->flickableDirection) {
        d->flickableDirection = direction;
        emit flickableDirectionChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::Flickable::pixelAligned

    This property sets the alignment of \l contentX and \l contentY to
    pixels (\c true) or subpixels (\c false).

    Enable pixelAligned to optimize for still content or moving content with
    high constrast edges, such as one-pixel-wide lines, text or vector graphics.
    Disable pixelAligned when optimizing for animation quality.

    The default is \c false.
*/
bool QQuickFlickable::pixelAligned() const
{
    Q_D(const QQuickFlickable);
    return d->pixelAligned;
}

void QQuickFlickable::setPixelAligned(bool align)
{
    Q_D(QQuickFlickable);
    if (align != d->pixelAligned) {
        d->pixelAligned = align;
        emit pixelAlignedChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::Flickable::synchronousDrag
    \since 5.12

    If this property is set to true, then when the mouse or touchpoint moves
    far enough to begin dragging the content, the content will jump, such that
    the content pixel which was under the cursor or touchpoint when pressed
    remains under that point.

    The default is \c false, which provides a smoother experience (no jump)
    at the cost that some of the drag distance is "lost" at the beginning.
*/
bool QQuickFlickable::synchronousDrag() const
{
    Q_D(const QQuickFlickable);
    return d->syncDrag;
}

void QQuickFlickable::setSynchronousDrag(bool v)
{
    Q_D(QQuickFlickable);
    if (v != d->syncDrag) {
        d->syncDrag = v;
        emit synchronousDragChanged();
    }
}

qint64 QQuickFlickablePrivate::computeCurrentTime(QInputEvent *event) const
{
    if (0 != event->timestamp())
        return event->timestamp();
    if (!timer.isValid())
        return 0LL;
    return timer.elapsed();
}

qreal QQuickFlickablePrivate::devicePixelRatio() const
{
    return (window ? window->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
}

void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
{
    Q_Q(QQuickFlickable);
    timer.start();
    if (interactive && timeline.isActive()
        && ((qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity && !hData.fixingUp && !hData.inOvershoot)
            || (qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity && !vData.fixingUp && !vData.inOvershoot))) {
        stealMouse = true; // If we've been flicked then steal the click.
        int flickTime = timeline.time();
        if (flickTime > 600) {
            // too long between flicks - cancel boost
            hData.continuousFlickVelocity = 0;
            vData.continuousFlickVelocity = 0;
            flickBoost = 1.0;
        } else {
            hData.continuousFlickVelocity = -hData.smoothVelocity.value();
            vData.continuousFlickVelocity = -vData.smoothVelocity.value();
            if (flickTime > 300) // slower flicking - reduce boost
                flickBoost = qMax(1.0, flickBoost - 0.5);
        }
    } else {
        stealMouse = false;
        hData.continuousFlickVelocity = 0;
        vData.continuousFlickVelocity = 0;
        flickBoost = 1.0;
    }
    q->setKeepMouseGrab(stealMouse);

    maybeBeginDrag(computeCurrentTime(event), event->localPos());
}

void QQuickFlickablePrivate::maybeBeginDrag(qint64 currentTimestamp, const QPointF &pressPosn)
{
    Q_Q(QQuickFlickable);
    clearDelayedPress();
    pressed = true;

    if (hData.transitionToBounds)
        hData.transitionToBounds->stopTransition();
    if (vData.transitionToBounds)
        vData.transitionToBounds->stopTransition();
    if (!hData.fixingUp)
        resetTimeline(hData);
    if (!vData.fixingUp)
        resetTimeline(vData);

    hData.reset();
    vData.reset();
    hData.dragMinBound = q->minXExtent() - hData.startMargin;
    vData.dragMinBound = q->minYExtent() - vData.startMargin;
    hData.dragMaxBound = q->maxXExtent() + hData.endMargin;
    vData.dragMaxBound = q->maxYExtent() + vData.endMargin;
    fixupMode = Normal;
    lastPos = QPointF();
    pressPos = pressPosn;
    hData.pressPos = hData.move.value();
    vData.pressPos = vData.move.value();
    bool wasFlicking = hData.flicking || vData.flicking;
    if (hData.flicking) {
        hData.flicking = false;
        emit q->flickingHorizontallyChanged();
    }
    if (vData.flicking) {
        vData.flicking = false;
        emit q->flickingVerticallyChanged();
    }
    if (wasFlicking)
        emit q->flickingChanged();
    lastPosTime = lastPressTime = currentTimestamp;
    vData.velocityTime.start();
    hData.velocityTime.start();
}

void QQuickFlickablePrivate::drag(qint64 currentTimestamp, QEvent::Type eventType, const QPointF &localPos,
                                  const QVector2D &deltas, bool overThreshold, bool momentum,
                                  bool velocitySensitiveOverBounds, const QVector2D &velocity)
{
    Q_Q(QQuickFlickable);
    bool rejectY = false;
    bool rejectX = false;

    bool keepY = q->yflick();
    bool keepX = q->xflick();

    bool stealY = false;
    bool stealX = false;
    if (eventType == QEvent::MouseMove) {
        stealX = stealY = stealMouse;
    } else if (eventType == QEvent::Wheel) {
        stealX = stealY = scrollingPhase;
    }

    bool prevHMoved = hMoved;
    bool prevVMoved = vMoved;

    qint64 elapsedSincePress = currentTimestamp - lastPressTime;

    if (q->yflick()) {
        qreal dy = deltas.y();
        if (overThreshold || elapsedSincePress > 200) {
            if (!vMoved)
                vData.dragStartOffset = dy;
            qreal newY = dy + vData.pressPos - (syncDrag ? 0 : vData.dragStartOffset);
            // Recalculate bounds in case margins have changed, but use the content
            // size estimate taken at the start of the drag in case the drag causes
            // the estimate to be altered
            const qreal minY = vData.dragMinBound + vData.startMargin;
            const qreal maxY = vData.dragMaxBound - vData.endMargin;
            if (!(boundsBehavior & QQuickFlickable::DragOverBounds)) {
                if (fuzzyLessThanOrEqualTo(newY, maxY)) {
                    newY = maxY;
                    rejectY = vData.pressPos == maxY && vData.move.value() == maxY && dy < 0;
                }
                if (fuzzyLessThanOrEqualTo(minY, newY)) {
                    newY = minY;
                    rejectY |= vData.pressPos == minY && vData.move.value() == minY && dy > 0;
                }
            } else {
                qreal vel = velocity.y() / QML_FLICK_OVERSHOOTFRICTION;
                if (vel > 0. && vel > vData.velocity)
                    vData.velocity = qMin(velocity.y() / QML_FLICK_OVERSHOOTFRICTION, float(QML_FLICK_DEFAULTMAXVELOCITY));
                else if (vel < 0. && vel < vData.velocity)
                    vData.velocity = qMax(velocity.y() / QML_FLICK_OVERSHOOTFRICTION, -float(QML_FLICK_DEFAULTMAXVELOCITY));
                if (newY > minY) {
                    // Overshoot beyond the top.  But don't wait for momentum phase to end before returning to bounds.
                    if (momentum && vData.atBeginning) {
                        if (!vData.inRebound) {
                            vData.inRebound = true;
                            q->returnToBounds();
                        }
                        return;
                    }
                    if (velocitySensitiveOverBounds) {
                        qreal overshoot = (newY - minY) * vData.velocity / QML_FLICK_DEFAULTMAXVELOCITY / QML_FLICK_OVERSHOOTFRICTION;
                        overshoot = QML_FLICK_OVERSHOOT * devicePixelRatio() * EaseOvershoot(overshoot / QML_FLICK_OVERSHOOT / devicePixelRatio());
                        newY = minY + overshoot;
                    } else {
                        newY = minY + (newY - minY) / 2;
                    }
                } else if (newY < maxY && maxY - minY <= 0) {
                    // Overshoot beyond the bottom.  But don't wait for momentum phase to end before returning to bounds.
                    if (momentum && vData.atEnd) {
                        if (!vData.inRebound) {
                            vData.inRebound = true;
                            q->returnToBounds();
                        }
                        return;
                    }
                    if (velocitySensitiveOverBounds) {
                        qreal overshoot = (newY - maxY) * vData.velocity / QML_FLICK_DEFAULTMAXVELOCITY / QML_FLICK_OVERSHOOTFRICTION;
                        overshoot = QML_FLICK_OVERSHOOT * devicePixelRatio() * EaseOvershoot(overshoot / QML_FLICK_OVERSHOOT / devicePixelRatio());
                        newY = maxY - overshoot;
                    } else {
                        newY = maxY + (newY - maxY) / 2;
                    }
                }
            }
            if (!rejectY && stealMouse && dy != 0.0 && dy != vData.previousDragDelta) {
                clearTimeline();
                vData.move.setValue(newY);
                vMoved = true;
            }
            if (!rejectY && overThreshold)
                stealY = true;

            if ((newY >= minY && vData.pressPos == minY && vData.move.value() == minY && dy > 0)
                        || (newY <= maxY && vData.pressPos == maxY && vData.move.value() == maxY && dy < 0)) {
                keepY = false;
            }
        }
        vData.previousDragDelta = dy;
    }

    if (q->xflick()) {
        qreal dx = deltas.x();
        if (overThreshold || elapsedSincePress > 200) {
            if (!hMoved)
                hData.dragStartOffset = dx;
            qreal newX = dx + hData.pressPos - (syncDrag ? 0 : hData.dragStartOffset);
            const qreal minX = hData.dragMinBound + hData.startMargin;
            const qreal maxX = hData.dragMaxBound - hData.endMargin;
            if (!(boundsBehavior & QQuickFlickable::DragOverBounds)) {
                if (fuzzyLessThanOrEqualTo(newX, maxX)) {
                    newX = maxX;
                    rejectX = hData.pressPos == maxX && hData.move.value() == maxX && dx < 0;
                }
                if (fuzzyLessThanOrEqualTo(minX, newX)) {
                    newX = minX;
                    rejectX |= hData.pressPos == minX && hData.move.value() == minX && dx > 0;
                }
            } else {
                qreal vel = velocity.x() / QML_FLICK_OVERSHOOTFRICTION;
                if (vel > 0. && vel > hData.velocity)
                    hData.velocity = qMin(velocity.x() / QML_FLICK_OVERSHOOTFRICTION, float(QML_FLICK_DEFAULTMAXVELOCITY));
                else if (vel < 0. && vel < hData.velocity)
                    hData.velocity = qMax(velocity.x() / QML_FLICK_OVERSHOOTFRICTION, -float(QML_FLICK_DEFAULTMAXVELOCITY));
                if (newX > minX) {
                    // Overshoot beyond the left.  But don't wait for momentum phase to end before returning to bounds.
                    if (momentum && hData.atBeginning) {
                        if (!hData.inRebound) {
                            hData.inRebound = true;
                            q->returnToBounds();
                        }
                        return;
                    }
                    if (velocitySensitiveOverBounds) {
                        qreal overshoot = (newX - minX) * hData.velocity / QML_FLICK_DEFAULTMAXVELOCITY / QML_FLICK_OVERSHOOTFRICTION;
                        overshoot = QML_FLICK_OVERSHOOT * devicePixelRatio() * EaseOvershoot(overshoot / QML_FLICK_OVERSHOOT / devicePixelRatio());
                        newX = minX + overshoot;
                    } else {
                        newX = minX + (newX - minX) / 2;
                    }
                } else if (newX < maxX && maxX - minX <= 0) {
                    // Overshoot beyond the right.  But don't wait for momentum phase to end before returning to bounds.
                    if (momentum && hData.atEnd) {
                        if (!hData.inRebound) {
                            hData.inRebound = true;
                            q->returnToBounds();
                        }
                        return;
                    }
                    if (velocitySensitiveOverBounds) {
                        qreal overshoot = (newX - maxX) * hData.velocity / QML_FLICK_DEFAULTMAXVELOCITY / QML_FLICK_OVERSHOOTFRICTION;
                        overshoot = QML_FLICK_OVERSHOOT * devicePixelRatio() * EaseOvershoot(overshoot / QML_FLICK_OVERSHOOT / devicePixelRatio());
                        newX = maxX - overshoot;
                    } else {
                        newX = maxX + (newX - maxX) / 2;
                    }
                }
            }

            if (!rejectX && stealMouse && dx != 0.0 && dx != hData.previousDragDelta) {
                clearTimeline();
                hData.move.setValue(newX);
                hMoved = true;
            }

            if (!rejectX && overThreshold)
                stealX = true;

            if ((newX >= minX && vData.pressPos == minX && vData.move.value() == minX && dx > 0)
                        || (newX <= maxX && vData.pressPos == maxX && vData.move.value() == maxX && dx < 0)) {
                keepX = false;
            }
        }
        hData.previousDragDelta = dx;
    }

    stealMouse = stealX || stealY;
    if (stealMouse) {
        if ((stealX && keepX) || (stealY && keepY))
            q->setKeepMouseGrab(true);
        clearDelayedPress();
    }

    if (rejectY) {
        vData.velocityBuffer.clear();
        vData.velocity = 0;
    }
    if (rejectX) {
        hData.velocityBuffer.clear();
        hData.velocity = 0;
    }

    if (momentum && !hData.flicking && !vData.flicking)
        flickingStarted(hData.velocity != 0, vData.velocity != 0);
    draggingStarting();

    if ((hMoved && !prevHMoved) || (vMoved && !prevVMoved))
        q->movementStarting();

    lastPosTime = currentTimestamp;
    if (q->yflick() && !rejectY)
        vData.addVelocitySample(velocity.y(), maxVelocity);
    if (q->xflick() && !rejectX)
        hData.addVelocitySample(velocity.x(), maxVelocity);
    lastPos = localPos;
}

void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
{
    Q_Q(QQuickFlickable);
    if (!interactive || lastPosTime == -1 || event->buttons() == Qt::NoButton)
        return;

    qint64 currentTimestamp = computeCurrentTime(event);
    QVector2D deltas = QVector2D(event->localPos() - pressPos);
    bool overThreshold = false;
    QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event);
    // TODO guarantee that events always have velocity so that it never needs to be computed here
    if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) {
        qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime);
        if (currentTimestamp == lastTimestamp)
            return; // events are too close together: velocity would be infinite
        qreal elapsed = qreal(currentTimestamp - lastTimestamp) / 1000.;
        velocity = QVector2D(event->localPos() - (lastPos.isNull() ? pressPos : lastPos)) / elapsed;
    }

    if (q->yflick())
        overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, event);
    if (q->xflick())
        overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.x(), Qt::XAxis, event);

    drag(currentTimestamp, event->type(), event->localPos(), deltas, overThreshold, false, false, velocity);
}

void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
{
    Q_Q(QQuickFlickable);
    stealMouse = false;
    q->setKeepMouseGrab(false);
    pressed = false;

    // if we drag then pause before release we should not cause a flick.
    qint64 elapsed = computeCurrentTime(event) - lastPosTime;

    vData.updateVelocity();
    hData.updateVelocity();

    draggingEnding();

    if (lastPosTime == -1)
        return;

    hData.vTime = vData.vTime = timeline.time();

    bool canBoost = false;

    qreal vVelocity = 0;
    if (elapsed < 100 && vData.velocity != 0.) {
        vVelocity = (QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)
                ? QGuiApplicationPrivate::mouseEventVelocity(event).y() : vData.velocity;
    }
    if ((vData.atBeginning && vVelocity > 0.) || (vData.atEnd && vVelocity < 0.)) {
        vVelocity /= 2;
    } else if (vData.continuousFlickVelocity != 0.0
               && vData.viewSize/q->height() > QML_FLICK_MULTIFLICK_RATIO
               && ((vVelocity > 0) == (vData.continuousFlickVelocity > 0))
               && qAbs(vVelocity) > QML_FLICK_MULTIFLICK_THRESHOLD) {
        // accelerate flick for large view flicked quickly
        canBoost = true;
    }

    qreal hVelocity = 0;
    if (elapsed < 100 && hData.velocity != 0.) {
        hVelocity = (QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)
                ? QGuiApplicationPrivate::mouseEventVelocity(event).x() : hData.velocity;
    }
    if ((hData.atBeginning && hVelocity > 0.) || (hData.atEnd && hVelocity < 0.)) {
        hVelocity /= 2;
    } else if (hData.continuousFlickVelocity != 0.0
               && hData.viewSize/q->width() > QML_FLICK_MULTIFLICK_RATIO
               && ((hVelocity > 0) == (hData.continuousFlickVelocity > 0))
               && qAbs(hVelocity) > QML_FLICK_MULTIFLICK_THRESHOLD) {
        // accelerate flick for large view flicked quickly
        canBoost = true;
    }

    flickBoost = canBoost ? qBound(1.0, flickBoost+0.25, QML_FLICK_MULTIFLICK_MAXBOOST) : 1.0;

    bool flickedVertically = false;
    vVelocity *= flickBoost;
    bool isVerticalFlickAllowed = q->yflick() && qAbs(vVelocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold;
    if (isVerticalFlickAllowed) {
        velocityTimeline.reset(vData.smoothVelocity);
        vData.smoothVelocity.setValue(-vVelocity);
        flickedVertically = flickY(vVelocity);
    }

    bool flickedHorizontally = false;
    hVelocity *= flickBoost;
    bool isHorizontalFlickAllowed = q->xflick() && qAbs(hVelocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold;
    if (isHorizontalFlickAllowed) {
        velocityTimeline.reset(hData.smoothVelocity);
        hData.smoothVelocity.setValue(-hVelocity);
        flickedHorizontally = flickX(hVelocity);
    }

    if (!isVerticalFlickAllowed)
        fixupY();

    if (!isHorizontalFlickAllowed)
        fixupX();

    flickingStarted(flickedHorizontally, flickedVertically);
    if (!isViewMoving())
        q->movementEnding();
}

void QQuickFlickable::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickFlickable);
    if (d->interactive) {
        if (!d->pressed)
            d->handleMousePressEvent(event);
        event->accept();
    } else {
        QQuickItem::mousePressEvent(event);
    }
}

void QQuickFlickable::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QQuickFlickable);
    if (d->interactive) {
        d->handleMouseMoveEvent(event);
        event->accept();
    } else {
        QQuickItem::mouseMoveEvent(event);
    }
}

void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QQuickFlickable);
    if (d->interactive) {
        if (d->delayedPressEvent) {
            d->replayDelayedPress();

            // Now send the release
            if (window() && window()->mouseGrabberItem()) {
                QPointF localPos = window()->mouseGrabberItem()->mapFromScene(event->windowPos());
                QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
                QCoreApplication::sendEvent(window(), mouseEvent.data());
            }

            // And the event has been consumed
            d->stealMouse = false;
            d->pressed = false;
            return;
        }

        d->handleMouseReleaseEvent(event);
        event->accept();
    } else {
        QQuickItem::mouseReleaseEvent(event);
    }
}

#if QT_CONFIG(wheelevent)
void QQuickFlickable::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickFlickable);
    if (!d->interactive) {
        QQuickItem::wheelEvent(event);
        return;
    }
    event->setAccepted(false);
    qint64 currentTimestamp = d->computeCurrentTime(event);
    switch (event->phase()) {
    case Qt::ScrollBegin:
        d->scrollingPhase = true;
        d->accumulatedWheelPixelDelta = QVector2D();
        d->vData.velocity = 0;
        d->hData.velocity = 0;
        d->timer.start();
        d->maybeBeginDrag(currentTimestamp, event->position());
        break;
    case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse
    case Qt::ScrollUpdate:
        if (d->scrollingPhase)
            d->pressed = true;
        break;
    case Qt::ScrollMomentum:
        d->pressed = false;
        d->scrollingPhase = false;
        d->draggingEnding();
        event->accept();
        d->lastPosTime = -1;
        break;
    case Qt::ScrollEnd:
        d->pressed = false;
        d->scrollingPhase = false;
        d->draggingEnding();
        event->accept();
        returnToBounds();
        d->lastPosTime = -1;
        d->stealMouse = false;
        if (!d->velocityTimeline.isActive() && !d->timeline.isActive())
            movementEnding(true, true);
        return;
    }

    if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull()) {
        // physical mouse wheel, so use angleDelta
        int xDelta = event->angleDelta().x();
        int yDelta = event->angleDelta().y();
        if (yflick() && yDelta != 0) {
            bool valid = false;
            if (yDelta > 0 && contentY() > -minYExtent()) {
                d->vData.velocity = qMax(yDelta*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4));
                valid = true;
            } else if (yDelta < 0 && contentY() < -maxYExtent()) {
                d->vData.velocity = qMin(yDelta*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
                valid = true;
            }
            if (valid) {
                d->flickY(d->vData.velocity);
                d->flickingStarted(false, true);
                if (d->vData.flicking) {
                    d->vMoved = true;
                    movementStarting();
                }
                event->accept();
            }
        }
        if (xflick() && xDelta != 0) {
            bool valid = false;
            if (xDelta > 0 && contentX() > -minXExtent()) {
                d->hData.velocity = qMax(xDelta*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4));
                valid = true;
            } else if (xDelta < 0 && contentX() < -maxXExtent()) {
                d->hData.velocity = qMin(xDelta*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
                valid = true;
            }
            if (valid) {
                d->flickX(d->hData.velocity);
                d->flickingStarted(true, false);
                if (d->hData.flicking) {
                    d->hMoved = true;
                    movementStarting();
                }
                event->accept();
            }
        }
    } else {
        // use pixelDelta (probably from a trackpad)
        int xDelta = event->pixelDelta().x();
        int yDelta = event->pixelDelta().y();

        qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / 1000.;
        if (elapsed <= 0) {
            d->lastPosTime = currentTimestamp;
            return;
        }
        QVector2D velocity(xDelta / elapsed, yDelta / elapsed);
        d->lastPosTime = currentTimestamp;
        d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta());
        d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta,
                true, !d->scrollingPhase, true, velocity);
        event->accept();
    }

    if (!event->isAccepted())
        QQuickItem::wheelEvent(event);
}
#endif

bool QQuickFlickablePrivate::isInnermostPressDelay(QQuickItem *i) const
{
    Q_Q(const QQuickFlickable);
    QQuickItem *item = i;
    while (item) {
        QQuickFlickable *flick = qobject_cast<QQuickFlickable*>(item);
        if (flick && flick->pressDelay() > 0 && flick->isInteractive()) {
            // Found the innermost flickable with press delay - is it me?
            return (flick == q);
        }
        item = item->parentItem();
    }
    return false;
}

void QQuickFlickablePrivate::captureDelayedPress(QQuickItem *item, QMouseEvent *event)
{
    Q_Q(QQuickFlickable);
    if (!q->window() || pressDelay <= 0)
        return;

    // Only the innermost flickable should handle the delayed press; this allows
    // flickables up the parent chain to all see the events in their filter functions
    if (!isInnermostPressDelay(item))
        return;

    delayedPressEvent = QQuickWindowPrivate::cloneMouseEvent(event);
    delayedPressEvent->setAccepted(false);
    delayedPressTimer.start(pressDelay, q);
}

void QQuickFlickablePrivate::clearDelayedPress()
{
    if (delayedPressEvent) {
        delayedPressTimer.stop();
        delete delayedPressEvent;
        delayedPressEvent = nullptr;
    }
}

void QQuickFlickablePrivate::replayDelayedPress()
{
    Q_Q(QQuickFlickable);
    if (delayedPressEvent) {
        // Losing the grab will clear the delayed press event; take control of it here
        QScopedPointer<QMouseEvent> mouseEvent(delayedPressEvent);
        delayedPressEvent = nullptr;
        delayedPressTimer.stop();

        // If we have the grab, release before delivering the event
        if (QQuickWindow *w = q->window()) {
            QQuickWindowPrivate *wpriv = QQuickWindowPrivate::get(w);
            wpriv->allowChildEventFiltering = false; // don't allow re-filtering during replay
            replayingPressEvent = true;
            if (w->mouseGrabberItem() == q)
                q->ungrabMouse();

            // Use the event handler that will take care of finding the proper item to propagate the event
            QCoreApplication::sendEvent(w, mouseEvent.data());
            replayingPressEvent = false;
            wpriv->allowChildEventFiltering = true;
        }
    }
}

//XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned.
void QQuickFlickablePrivate::setViewportX(qreal x)
{
    Q_Q(QQuickFlickable);
    qreal effectiveX = pixelAligned ? -Round(-x) : x;

    const qreal maxX = q->maxXExtent();
    const qreal minX = q->minXExtent();

    if (boundsMovement == int(QQuickFlickable::StopAtBounds))
        effectiveX = qBound(maxX, effectiveX, minX);

    contentItem->setX(effectiveX);
    if (contentItem->x() != effectiveX)
        return; // reentered

    qreal overshoot = 0.0;
    if (x <= maxX)
        overshoot = maxX - x;
    else if (x >= minX)
        overshoot = minX - x;

    if (overshoot != hData.overshoot) {
        hData.overshoot = overshoot;
        emit q->horizontalOvershootChanged();
    }
}

void QQuickFlickablePrivate::setViewportY(qreal y)
{
    Q_Q(QQuickFlickable);
    qreal effectiveY = pixelAligned ? -Round(-y) : y;

    const qreal maxY = q->maxYExtent();
    const qreal minY = q->minYExtent();

    if (boundsMovement == int(QQuickFlickable::StopAtBounds))
        effectiveY = qBound(maxY, effectiveY, minY);

    contentItem->setY(effectiveY);
    if (contentItem->y() != effectiveY)
        return; // reentered

    qreal overshoot = 0.0;
    if (y <= maxY)
        overshoot = maxY - y;
    else if (y >= minY)
        overshoot = minY - y;

    if (overshoot != vData.overshoot) {
        vData.overshoot = overshoot;
        emit q->verticalOvershootChanged();
    }
}

void QQuickFlickable::timerEvent(QTimerEvent *event)
{
    Q_D(QQuickFlickable);
    if (event->timerId() == d->delayedPressTimer.timerId()) {
        d->delayedPressTimer.stop();
        if (d->delayedPressEvent) {
            d->replayDelayedPress();
        }
    }
}

qreal QQuickFlickable::minYExtent() const
{
    Q_D(const QQuickFlickable);
    return d->vData.startMargin;
}

qreal QQuickFlickable::minXExtent() const
{
    Q_D(const QQuickFlickable);
    return d->hData.startMargin;
}

/* returns -ve */
qreal QQuickFlickable::maxXExtent() const
{
    Q_D(const QQuickFlickable);
    return qMin<qreal>(minXExtent(), width() - vWidth() - d->hData.endMargin);
}
/* returns -ve */
qreal QQuickFlickable::maxYExtent() const
{
    Q_D(const QQuickFlickable);
    return qMin<qreal>(minYExtent(), height() - vHeight() - d->vData.endMargin);
}

void QQuickFlickable::componentComplete()
{
    Q_D(QQuickFlickable);
    QQuickItem::componentComplete();
    if (!d->hData.explicitValue && d->hData.startMargin != 0.)
        setContentX(-minXExtent());
    if (!d->vData.explicitValue && d->vData.startMargin != 0.)
        setContentY(-minYExtent());
}

void QQuickFlickable::viewportMoved(Qt::Orientations orient)
{
    Q_D(QQuickFlickable);
    if (orient & Qt::Vertical)
        d->viewportAxisMoved(d->vData, minYExtent(), maxYExtent(), height(), d->fixupY_callback);
    if (orient & Qt::Horizontal)
        d->viewportAxisMoved(d->hData, minXExtent(), maxXExtent(), width(), d->fixupX_callback);
    d->updateBeginningEnd();
}

void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
                                           QQuickTimeLineCallback::Callback fixupCallback)
{
    if (!scrollingPhase && (pressed || calcVelocity)) {
        int elapsed = data.velocityTime.restart();
        if (elapsed > 0) {
            qreal velocity = (data.lastPos - data.move.value()) * 1000 / elapsed;
            if (qAbs(velocity) > 0) {
                velocityTimeline.reset(data.smoothVelocity);
                if (calcVelocity)
                    velocityTimeline.set(data.smoothVelocity, velocity);
                else
                    velocityTimeline.move(data.smoothVelocity, velocity, reportedVelocitySmoothing);
                velocityTimeline.move(data.smoothVelocity, 0, reportedVelocitySmoothing);
            }
        }
    } else {
        if (timeline.time() > data.vTime) {
            velocityTimeline.reset(data.smoothVelocity);
            qreal velocity = (data.lastPos - data.move.value()) * 1000 / (timeline.time() - data.vTime);
            data.smoothVelocity.setValue(velocity);
        }
    }

    if (!data.inOvershoot && !data.fixingUp && data.flicking
            && (data.move.value() > minExtent || data.move.value() < maxExtent)
            && qAbs(data.smoothVelocity.value()) > 10) {
        // Increase deceleration if we've passed a bound
        qreal overBound = data.move.value() > minExtent
                ? data.move.value() - minExtent
                : maxExtent - data.move.value();
        data.inOvershoot = true;
        qreal maxDistance = overShootDistance(vSize) - overBound;
        resetTimeline(data);
        if (maxDistance > 0)
            timeline.accel(data.move, -data.smoothVelocity.value(), deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
        timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this));
    }

    data.lastPos = data.move.value();
    data.vTime = timeline.time();
}

void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
                             const QRectF &oldGeometry)
{
    Q_D(QQuickFlickable);
    QQuickItem::geometryChanged(newGeometry, oldGeometry);

    bool changed = false;
    if (newGeometry.width() != oldGeometry.width()) {
        changed = true; // we must update visualArea.widthRatio
        if (d->hData.viewSize < 0)
            d->contentItem->setWidth(width());
        // Make sure that we're entirely in view.
        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
            d->fixupMode = QQuickFlickablePrivate::Immediate;
            d->fixupX();
        }
    }
    if (newGeometry.height() != oldGeometry.height()) {
        changed = true; // we must update visualArea.heightRatio
        if (d->vData.viewSize < 0)
            d->contentItem->setHeight(height());
        // Make sure that we're entirely in view.
        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
            d->fixupMode = QQuickFlickablePrivate::Immediate;
            d->fixupY();
        }
    }

    if (changed)
        d->updateBeginningEnd();
}

/*!
    \qmlmethod QtQuick::Flickable::flick(qreal xVelocity, qreal yVelocity)

    Flicks the content with \a xVelocity horizontally and \a yVelocity vertically in pixels/sec.

    Calling this method will update the corresponding moving and flicking properties and signals,
    just like a real flick.
*/

void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
{
    Q_D(QQuickFlickable);
    d->hData.reset();
    d->vData.reset();
    d->hData.velocity = xVelocity;
    d->vData.velocity = yVelocity;
    d->hData.vTime = d->vData.vTime = d->timeline.time();

    const bool flickedX = xflick() && !qFuzzyIsNull(xVelocity) && d->flickX(xVelocity);
    const bool flickedY = yflick() && !qFuzzyIsNull(yVelocity) && d->flickY(yVelocity);

    if (flickedX)
        d->hMoved = true;
    if (flickedY)
        d->vMoved = true;
    movementStarting();
    d->flickingStarted(flickedX, flickedY);
}

void QQuickFlickablePrivate::flickingStarted(bool flickingH, bool flickingV)
{
    Q_Q(QQuickFlickable);
    if (!flickingH && !flickingV)
        return;

    bool wasFlicking = hData.flicking || vData.flicking;
    if (flickingH && !hData.flicking) {
        hData.flicking = true;
        emit q->flickingHorizontallyChanged();
    }
    if (flickingV && !vData.flicking) {
        vData.flicking = true;
        emit q->flickingVerticallyChanged();
    }
    if (!wasFlicking && (hData.flicking || vData.flicking)) {
        emit q->flickingChanged();
        emit q->flickStarted();
    }
}

/*!
    \qmlmethod QtQuick::Flickable::cancelFlick()

    Cancels the current flick animation.
*/

void QQuickFlickable::cancelFlick()
{
    Q_D(QQuickFlickable);
    d->resetTimeline(d->hData);
    d->resetTimeline(d->vData);
    movementEnding();
}

void QQuickFlickablePrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
{
    if (QQuickItem *i = qmlobject_cast<QQuickItem *>(o)) {
        i->setParentItem(static_cast<QQuickFlickablePrivate*>(prop->data)->contentItem);
    } else if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) {
        static_cast<QQuickFlickablePrivate*>(prop->data)->addPointerHandler(pointerHandler);
    } else {
        o->setParent(prop->object); // XXX todo - do we want this?
    }
}

int QQuickFlickablePrivate::data_count(QQmlListProperty<QObject> *)
{
    // XXX todo
    return 0;
}

QObject *QQuickFlickablePrivate::data_at(QQmlListProperty<QObject> *, int)
{
    // XXX todo
    return nullptr;
}

void QQuickFlickablePrivate::data_clear(QQmlListProperty<QObject> *)
{
    // XXX todo
}

QQmlListProperty<QObject> QQuickFlickable::flickableData()
{
    Q_D(QQuickFlickable);
    return QQmlListProperty<QObject>(this, (void *)d, QQuickFlickablePrivate::data_append,
                                             QQuickFlickablePrivate::data_count,
                                             QQuickFlickablePrivate::data_at,
                                             QQuickFlickablePrivate::data_clear);
}

QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
{
    Q_D(QQuickFlickable);
    return QQuickItemPrivate::get(d->contentItem)->children();
}

/*!
    \qmlproperty enumeration QtQuick::Flickable::boundsBehavior
    This property holds whether the surface may be dragged
    beyond the Flickable's boundaries, or overshoot the
    Flickable's boundaries when flicked.

    When the \l boundsMovement is \c Flickable.FollowBoundsBehavior, a value
    other than \c Flickable.StopAtBounds will give a feeling that the edges of
    the view are soft, rather than a hard physical boundary.

    The \c boundsBehavior can be one of:

    \list
    \li Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
    of the flickable, and flicks will not overshoot.
    \li Flickable.DragOverBounds - the contents can be dragged beyond the boundary
    of the Flickable, but flicks will not overshoot.
    \li Flickable.OvershootBounds - the contents can overshoot the boundary when flicked,
    but the content cannot be dragged beyond the boundary of the flickable. (since \c{QtQuick 2.5})
    \li Flickable.DragAndOvershootBounds (default) - the contents can be dragged
    beyond the boundary of the Flickable, and can overshoot the
    boundary when flicked.
    \endlist

    \sa horizontalOvershoot, verticalOvershoot, boundsMovement
*/
QQuickFlickable::BoundsBehavior QQuickFlickable::boundsBehavior() const
{
    Q_D(const QQuickFlickable);
    return d->boundsBehavior;
}

void QQuickFlickable::setBoundsBehavior(BoundsBehavior b)
{
    Q_D(QQuickFlickable);
    if (b == d->boundsBehavior)
        return;
    d->boundsBehavior = b;
    emit boundsBehaviorChanged();
}

/*!
    \qmlproperty Transition QtQuick::Flickable::rebound

    This holds the transition to be applied to the content view when
    it snaps back to the bounds of the flickable. The transition is
    triggered when the view is flicked or dragged past the edge of the
    content area, or when returnToBounds() is called.

    \qml
    import QtQuick 2.0

    Flickable {
        width: 150; height: 150
        contentWidth: 300; contentHeight: 300

        rebound: Transition {
            NumberAnimation {
                properties: "x,y"
                duration: 1000
                easing.type: Easing.OutBounce
            }
        }

        Rectangle {
            width: 300; height: 300
            gradient: Gradient {
                GradientStop { position: 0.0; color: "lightsteelblue" }
                GradientStop { position: 1.0; color: "blue" }
            }
        }
    }
    \endqml

    When the above view is flicked beyond its bounds, it will return to its
    bounds using the transition specified:

    \image flickable-rebound.gif

    If this property is not set, a default animation is applied.
  */
QQuickTransition *QQuickFlickable::rebound() const
{
    Q_D(const QQuickFlickable);
    return d->rebound;
}

void QQuickFlickable::setRebound(QQuickTransition *transition)
{
    Q_D(QQuickFlickable);
    if (transition) {
        if (!d->hData.transitionToBounds)
            d->hData.transitionToBounds = new QQuickFlickableReboundTransition(this, QLatin1String("x"));
        if (!d->vData.transitionToBounds)
            d->vData.transitionToBounds = new QQuickFlickableReboundTransition(this, QLatin1String("y"));
    }
    if (d->rebound != transition) {
        d->rebound = transition;
        emit reboundChanged();
    }
}

/*!
    \qmlproperty real QtQuick::Flickable::contentWidth
    \qmlproperty real QtQuick::Flickable::contentHeight

    The dimensions of the content (the surface controlled by Flickable).
    This should typically be set to the combined size of the items placed in the
    Flickable.

    The following snippet shows how these properties are used to display
    an image that is larger than the Flickable item itself:

    \snippet qml/flickable.qml document

    In some cases, the content dimensions can be automatically set
    based on the \l {Item::childrenRect.width}{childrenRect.width}
    and \l {Item::childrenRect.height}{childrenRect.height} properties
    of the \l contentItem. For example, the previous snippet could be rewritten with:

    \code
    contentWidth: contentItem.childrenRect.width; contentHeight: contentItem.childrenRect.height
    \endcode

    Though this assumes that the origin of the childrenRect is 0,0.
*/
qreal QQuickFlickable::contentWidth() const
{
    Q_D(const QQuickFlickable);
    return d->hData.viewSize;
}

void QQuickFlickable::setContentWidth(qreal w)
{
    Q_D(QQuickFlickable);
    if (d->hData.viewSize == w)
        return;
    d->hData.viewSize = w;
    if (w < 0)
        d->contentItem->setWidth(width());
    else
        d->contentItem->setWidth(w);
    d->hData.markExtentsDirty();
    // Make sure that we're entirely in view.
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupX();
    } else if (!d->pressed && d->hData.fixingUp) {
        d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
        d->fixupX();
    }
    emit contentWidthChanged();
    d->updateBeginningEnd();
}

qreal QQuickFlickable::contentHeight() const
{
    Q_D(const QQuickFlickable);
    return d->vData.viewSize;
}

void QQuickFlickable::setContentHeight(qreal h)
{
    Q_D(QQuickFlickable);
    if (d->vData.viewSize == h)
        return;
    d->vData.viewSize = h;
    if (h < 0)
        d->contentItem->setHeight(height());
    else
        d->contentItem->setHeight(h);
    d->vData.markExtentsDirty();
    // Make sure that we're entirely in view.
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupY();
    } else if (!d->pressed && d->vData.fixingUp) {
        d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
        d->fixupY();
    }
    emit contentHeightChanged();
    d->updateBeginningEnd();
}

/*!
    \qmlproperty real QtQuick::Flickable::topMargin
    \qmlproperty real QtQuick::Flickable::leftMargin
    \qmlproperty real QtQuick::Flickable::bottomMargin
    \qmlproperty real QtQuick::Flickable::rightMargin

    These properties hold the margins around the content.  This space is reserved
    in addition to the contentWidth and contentHeight.
*/


qreal QQuickFlickable::topMargin() const
{
    Q_D(const QQuickFlickable);
    return d->vData.startMargin;
}

void QQuickFlickable::setTopMargin(qreal m)
{
    Q_D(QQuickFlickable);
    if (d->vData.startMargin == m)
        return;
    d->vData.startMargin = m;
    d->vData.markExtentsDirty();
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupY();
    }
    emit topMarginChanged();
    d->updateBeginningEnd();
}

qreal QQuickFlickable::bottomMargin() const
{
    Q_D(const QQuickFlickable);
    return d->vData.endMargin;
}

void QQuickFlickable::setBottomMargin(qreal m)
{
    Q_D(QQuickFlickable);
    if (d->vData.endMargin == m)
        return;
    d->vData.endMargin = m;
    d->vData.markExtentsDirty();
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupY();
    }
    emit bottomMarginChanged();
    d->updateBeginningEnd();
}

qreal QQuickFlickable::leftMargin() const
{
    Q_D(const QQuickFlickable);
    return d->hData.startMargin;
}

void QQuickFlickable::setLeftMargin(qreal m)
{
    Q_D(QQuickFlickable);
    if (d->hData.startMargin == m)
        return;
    d->hData.startMargin = m;
    d->hData.markExtentsDirty();
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupX();
    }
    emit leftMarginChanged();
    d->updateBeginningEnd();
}

qreal QQuickFlickable::rightMargin() const
{
    Q_D(const QQuickFlickable);
    return d->hData.endMargin;
}

void QQuickFlickable::setRightMargin(qreal m)
{
    Q_D(QQuickFlickable);
    if (d->hData.endMargin == m)
        return;
    d->hData.endMargin = m;
    d->hData.markExtentsDirty();
    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
        d->fixupMode = QQuickFlickablePrivate::Immediate;
        d->fixupX();
    }
    emit rightMarginChanged();
    d->updateBeginningEnd();
}

/*!
    \qmlproperty real QtQuick::Flickable::originX
    \qmlproperty real QtQuick::Flickable::originY

    These properties hold the origin of the content. This value always refers
    to the top-left position of the content regardless of layout direction.

    This is usually (0,0), however ListView and GridView may have an arbitrary
    origin due to delegate size variation, or item insertion/removal outside
    the visible region.

    \sa contentX, contentY
*/

qreal QQuickFlickable::originY() const
{
    Q_D(const QQuickFlickable);
    return -minYExtent() + d->vData.startMargin;
}

qreal QQuickFlickable::originX() const
{
    Q_D(const QQuickFlickable);
    return -minXExtent() + d->hData.startMargin;
}


/*!
    \qmlmethod QtQuick::Flickable::resizeContent(real width, real height, QPointF center)

    Resizes the content to \a width x \a height about \a center.

    This does not scale the contents of the Flickable - it only resizes the \l contentWidth
    and \l contentHeight.

    Resizing the content may result in the content being positioned outside
    the bounds of the Flickable.  Calling \l returnToBounds() will
    move the content back within legal bounds.
*/
void QQuickFlickable::resizeContent(qreal w, qreal h, QPointF center)
{
    Q_D(QQuickFlickable);
    const qreal oldHSize = d->hData.viewSize;
    const qreal oldVSize = d->vData.viewSize;
    const bool needToUpdateWidth = w != oldHSize;
    const bool needToUpdateHeight = h != oldVSize;
    d->hData.viewSize = w;
    d->vData.viewSize = h;
    d->contentItem->setSize(QSizeF(w, h));
    if (needToUpdateWidth)
        emit contentWidthChanged();
    if (needToUpdateHeight)
        emit contentHeightChanged();

    if (center.x() != 0) {
        qreal pos = center.x() * w / oldHSize;
        setContentX(contentX() + pos - center.x());
    }
    if (center.y() != 0) {
        qreal pos = center.y() * h / oldVSize;
        setContentY(contentY() + pos - center.y());
    }
    d->updateBeginningEnd();
}

/*!
    \qmlmethod QtQuick::Flickable::returnToBounds()

    Ensures the content is within legal bounds.

    This may be called to ensure that the content is within legal bounds
    after manually positioning the content.
*/
void QQuickFlickable::returnToBounds()
{
    Q_D(QQuickFlickable);
    d->fixupX();
    d->fixupY();
}

qreal QQuickFlickable::vWidth() const
{
    Q_D(const QQuickFlickable);
    if (d->hData.viewSize < 0)
        return width();
    else
        return d->hData.viewSize;
}

qreal QQuickFlickable::vHeight() const
{
    Q_D(const QQuickFlickable);
    if (d->vData.viewSize < 0)
        return height();
    else
        return d->vData.viewSize;
}

bool QQuickFlickable::xflick() const
{
    Q_D(const QQuickFlickable);
    if ((d->flickableDirection & QQuickFlickable::AutoFlickIfNeeded) && (vWidth() > width()))
        return true;
    if (d->flickableDirection == QQuickFlickable::AutoFlickDirection)
        return std::floor(qAbs(vWidth() - width()));
    return d->flickableDirection & QQuickFlickable::HorizontalFlick;
}

bool QQuickFlickable::yflick() const
{
    Q_D(const QQuickFlickable);
    if ((d->flickableDirection & QQuickFlickable::AutoFlickIfNeeded) && (vHeight() > height()))
        return true;
    if (d->flickableDirection == QQuickFlickable::AutoFlickDirection)
        return std::floor(qAbs(vHeight() - height()));
    return d->flickableDirection & QQuickFlickable::VerticalFlick;
}

void QQuickFlickable::mouseUngrabEvent()
{
    Q_D(QQuickFlickable);
    // if our mouse grab has been removed (probably by another Flickable),
    // fix our state
    if (!d->replayingPressEvent)
        d->cancelInteraction();
}

void QQuickFlickablePrivate::cancelInteraction()
{
    Q_Q(QQuickFlickable);
    if (pressed) {
        clearDelayedPress();
        pressed = false;
        draggingEnding();
        stealMouse = false;
        q->setKeepMouseGrab(false);
        fixupX();
        fixupY();
        if (!isViewMoving())
            q->movementEnding();
    }
}

void QQuickFlickablePrivate::addPointerHandler(QQuickPointerHandler *h)
{
    Q_Q(const QQuickFlickable);
    qCDebug(lcHandlerParent) << "reparenting handler" << h << "to contentItem of" << q;
    h->setParent(contentItem);
    QQuickItemPrivate::get(contentItem)->addPointerHandler(h);
}

/*!
    QQuickFlickable::filterMouseEvent checks filtered mouse events and potentially steals them.

    This is how flickable takes over events from other items (\a receiver) that are on top of it.
    It filters their events and may take over (grab) the \a event.
    Return true if the mouse event will be stolen.
    \internal
*/
bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
{
    Q_D(QQuickFlickable);
    QPointF localPos = mapFromScene(event->windowPos());

    Q_ASSERT_X(receiver != this, "", "Flickable received a filter event for itself");
    if (receiver == this && d->stealMouse) {
        // we are already the grabber and we do want the mouse event to ourselves.
        return true;
    }

    bool receiverDisabled = receiver && !receiver->isEnabled();
    bool stealThisEvent = d->stealMouse;
    bool receiverKeepsGrab = receiver && (receiver->keepMouseGrab() || receiver->keepTouchGrab());
    if ((stealThisEvent || contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
        QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
        mouseEvent->setAccepted(false);

        switch (mouseEvent->type()) {
        case QEvent::MouseMove:
            d->handleMouseMoveEvent(mouseEvent.data());
            break;
        case QEvent::MouseButtonPress:
            d->handleMousePressEvent(mouseEvent.data());
            d->captureDelayedPress(receiver, event);
            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
            break;
        case QEvent::MouseButtonRelease:
            d->handleMouseReleaseEvent(mouseEvent.data());
            stealThisEvent = d->stealMouse;
            break;
        default:
            break;
        }
        if ((receiver && stealThisEvent && !receiverKeepsGrab && receiver != this) || receiverDisabled) {
            d->clearDelayedPress();
            grabMouse();
        } else if (d->delayedPressEvent) {
            grabMouse();
        }

        const bool filtered = stealThisEvent || d->delayedPressEvent || receiverDisabled;
        if (filtered) {
            event->setAccepted(true);
        }
        return filtered;
    } else if (d->lastPosTime != -1) {
        d->lastPosTime = -1;
        returnToBounds();
    }
    if (event->type() == QEvent::MouseButtonRelease || (receiverKeepsGrab && !receiverDisabled)) {
        // mouse released, or another item has claimed the grab
        d->lastPosTime = -1;
        d->clearDelayedPress();
        d->stealMouse = false;
        d->pressed = false;
    }
    return false;
}


bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
    Q_D(QQuickFlickable);
    if (!isVisible() || !isEnabled() || !isInteractive()) {
        d->cancelInteraction();
        return QQuickItem::childMouseEventFilter(i, e);
    }

    switch (e->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        return filterMouseEvent(i, static_cast<QMouseEvent *>(e));
    case QEvent::UngrabMouse:
        if (d->window && d->window->mouseGrabberItem() && d->window->mouseGrabberItem() != this) {
            // The grab has been taken away from a child and given to some other item.
            mouseUngrabEvent();
        }
        break;
    default:
        break;
    }

    return QQuickItem::childMouseEventFilter(i, e);
}

/*!
    \qmlproperty real QtQuick::Flickable::maximumFlickVelocity
    This property holds the maximum velocity that the user can flick the view in pixels/second.

    The default value is platform dependent.
*/
qreal QQuickFlickable::maximumFlickVelocity() const
{
    Q_D(const QQuickFlickable);
    return d->maxVelocity;
}

void QQuickFlickable::setMaximumFlickVelocity(qreal v)
{
    Q_D(QQuickFlickable);
    if (v == d->maxVelocity)
        return;
    d->maxVelocity = v;
    emit maximumFlickVelocityChanged();
}

/*!
    \qmlproperty real QtQuick::Flickable::flickDeceleration
    This property holds the rate at which a flick will decelerate.

    The default value is platform dependent.
*/
qreal QQuickFlickable::flickDeceleration() const
{
    Q_D(const QQuickFlickable);
    return d->deceleration;
}

void QQuickFlickable::setFlickDeceleration(qreal deceleration)
{
    Q_D(QQuickFlickable);
    if (deceleration == d->deceleration)
        return;
    d->deceleration = deceleration;
    emit flickDecelerationChanged();
}

bool QQuickFlickable::isFlicking() const
{
    Q_D(const QQuickFlickable);
    return d->hData.flicking ||  d->vData.flicking;
}

/*!
    \qmlproperty bool QtQuick::Flickable::flicking
    \qmlproperty bool QtQuick::Flickable::flickingHorizontally
    \qmlproperty bool QtQuick::Flickable::flickingVertically

    These properties describe whether the view is currently moving horizontally,
    vertically or in either direction, due to the user flicking the view.
*/
bool QQuickFlickable::isFlickingHorizontally() const
{
    Q_D(const QQuickFlickable);
    return d->hData.flicking;
}

bool QQuickFlickable::isFlickingVertically() const
{
    Q_D(const QQuickFlickable);
    return d->vData.flicking;
}

/*!
    \qmlproperty bool QtQuick::Flickable::dragging
    \qmlproperty bool QtQuick::Flickable::draggingHorizontally
    \qmlproperty bool QtQuick::Flickable::draggingVertically

    These properties describe whether the view is currently moving horizontally,
    vertically or in either direction, due to the user dragging the view.
*/
bool QQuickFlickable::isDragging() const
{
    Q_D(const QQuickFlickable);
    return d->hData.dragging ||  d->vData.dragging;
}

bool QQuickFlickable::isDraggingHorizontally() const
{
    Q_D(const QQuickFlickable);
    return d->hData.dragging;
}

bool QQuickFlickable::isDraggingVertically() const
{
    Q_D(const QQuickFlickable);
    return d->vData.dragging;
}

void QQuickFlickablePrivate::draggingStarting()
{
    Q_Q(QQuickFlickable);
    bool wasDragging = hData.dragging || vData.dragging;
    if (hMoved && !hData.dragging) {
        hData.dragging = true;
        emit q->draggingHorizontallyChanged();
    }
    if (vMoved && !vData.dragging) {
        vData.dragging = true;
        emit q->draggingVerticallyChanged();
    }
    if (!wasDragging && (hData.dragging || vData.dragging)) {
        emit q->draggingChanged();
        emit q->dragStarted();
    }
}

void QQuickFlickablePrivate::draggingEnding()
{
    Q_Q(QQuickFlickable);
    const bool wasDragging = hData.dragging || vData.dragging;
    if (hData.dragging) {
        hData.dragging = false;
        emit q->draggingHorizontallyChanged();
    }
    if (vData.dragging) {
        vData.dragging = false;
        emit q->draggingVerticallyChanged();
    }
    if (wasDragging) {
        if (!hData.dragging && !vData.dragging) {
            emit q->draggingChanged();
            emit q->dragEnded();
        }
        hData.inRebound = false;
        vData.inRebound = false;
    }
}

bool QQuickFlickablePrivate::isViewMoving() const
{
    if (timeline.isActive()
            || (hData.transitionToBounds && hData.transitionToBounds->isActive())
            || (vData.transitionToBounds && vData.transitionToBounds->isActive()) ) {
        return true;
    }
    return false;
}

/*!
    \qmlproperty int QtQuick::Flickable::pressDelay

    This property holds the time to delay (ms) delivering a press to
    children of the Flickable.  This can be useful where reacting
    to a press before a flicking action has undesirable effects.

    If the flickable is dragged/flicked before the delay times out
    the press event will not be delivered.  If the button is released
    within the timeout, both the press and release will be delivered.

    Note that for nested Flickables with pressDelay set, the pressDelay of
    outer Flickables is overridden by the innermost Flickable. If the drag
    exceeds the platform drag threshold, the press event will be delivered
    regardless of this property.

    \sa QStyleHints
*/
int QQuickFlickable::pressDelay() const
{
    Q_D(const QQuickFlickable);
    return d->pressDelay;
}

void QQuickFlickable::setPressDelay(int delay)
{
    Q_D(QQuickFlickable);
    if (d->pressDelay == delay)
        return;
    d->pressDelay = delay;
    emit pressDelayChanged();
}

/*!
    \qmlproperty bool QtQuick::Flickable::moving
    \qmlproperty bool QtQuick::Flickable::movingHorizontally
    \qmlproperty bool QtQuick::Flickable::movingVertically

    These properties describe whether the view is currently moving horizontally,
    vertically or in either direction, due to the user either dragging or
    flicking the view.
*/

bool QQuickFlickable::isMoving() const
{
    Q_D(const QQuickFlickable);
    return d->hData.moving || d->vData.moving;
}

bool QQuickFlickable::isMovingHorizontally() const
{
    Q_D(const QQuickFlickable);
    return d->hData.moving;
}

bool QQuickFlickable::isMovingVertically() const
{
    Q_D(const QQuickFlickable);
    return d->vData.moving;
}

void QQuickFlickable::velocityTimelineCompleted()
{
    Q_D(QQuickFlickable);
    if ( (d->hData.transitionToBounds && d->hData.transitionToBounds->isActive())
         || (d->vData.transitionToBounds && d->vData.transitionToBounds->isActive()) ) {
        return;
    }
    // With subclasses such as GridView, velocityTimeline.completed is emitted repeatedly:
    // for example setting currentIndex results in a visual "flick" which the user
    // didn't initiate directly. We don't want to end movement repeatedly, and in
    // that case movementEnding will happen after the sequence of movements ends.
    if (d->vData.flicking)
        movementEnding();
    d->updateBeginningEnd();
}

void QQuickFlickable::timelineCompleted()
{
    Q_D(QQuickFlickable);
    if ( (d->hData.transitionToBounds && d->hData.transitionToBounds->isActive())
         || (d->vData.transitionToBounds && d->vData.transitionToBounds->isActive()) ) {
        return;
    }
    movementEnding();
    d->updateBeginningEnd();
}

void QQuickFlickable::movementStarting()
{
    Q_D(QQuickFlickable);
    bool wasMoving = d->hData.moving || d->vData.moving;
    if (d->hMoved && !d->hData.moving) {
        d->hData.moving = true;
        emit movingHorizontallyChanged();
    }
    if (d->vMoved && !d->vData.moving) {
        d->vData.moving = true;
        emit movingVerticallyChanged();
    }

    if (!wasMoving && (d->hData.moving || d->vData.moving)) {
        emit movingChanged();
        emit movementStarted();
    }
}

void QQuickFlickable::movementEnding()
{
    movementEnding(true, true);
}

void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding)
{
    Q_D(QQuickFlickable);

    // emit flicking signals
    bool wasFlicking = d->hData.flicking || d->vData.flicking;
    if (hMovementEnding && d->hData.flicking) {
        d->hData.flicking = false;
        emit flickingHorizontallyChanged();
    }
    if (vMovementEnding && d->vData.flicking) {
        d->vData.flicking = false;
        emit flickingVerticallyChanged();
    }
    if (wasFlicking && (!d->hData.flicking || !d->vData.flicking)) {
        emit flickingChanged();
        emit flickEnded();
    }

    // emit moving signals
    bool wasMoving = isMoving();
    if (hMovementEnding && d->hData.moving
            && (!d->pressed && !d->stealMouse)) {
        d->hData.moving = false;
        d->hMoved = false;
        emit movingHorizontallyChanged();
    }
    if (vMovementEnding && d->vData.moving
            && (!d->pressed && !d->stealMouse)) {
        d->vData.moving = false;
        d->vMoved = false;
        emit movingVerticallyChanged();
    }
    if (wasMoving && !isMoving()) {
        emit movingChanged();
        emit movementEnded();
    }

    if (hMovementEnding) {
        d->hData.fixingUp = false;
        d->hData.smoothVelocity.setValue(0);
        d->hData.previousDragDelta = 0.0;
    }
    if (vMovementEnding) {
        d->vData.fixingUp = false;
        d->vData.smoothVelocity.setValue(0);
        d->vData.previousDragDelta = 0.0;
    }
}

void QQuickFlickablePrivate::updateVelocity()
{
    Q_Q(QQuickFlickable);
    emit q->horizontalVelocityChanged();
    emit q->verticalVelocityChanged();
}

/*!
    \qmlproperty real QtQuick::Flickable::horizontalOvershoot
    \since 5.9

    This property holds the horizontal overshoot, that is, the horizontal distance by
    which the contents has been dragged or flicked past the bounds of the flickable.
    The value is negative when the content is dragged or flicked beyond the beginning,
    and positive when beyond the end; \c 0.0 otherwise.

    Whether the values are reported for dragging and/or flicking is determined by
    \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
    is \c Flickable.StopAtBounds.

    \sa verticalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::horizontalOvershoot() const
{
    Q_D(const QQuickFlickable);
    return d->hData.overshoot;
}

/*!
    \qmlproperty real QtQuick::Flickable::verticalOvershoot
    \since 5.9

    This property holds the vertical overshoot, that is, the vertical distance by
    which the contents has been dragged or flicked past the bounds of the flickable.
    The value is negative when the content is dragged or flicked beyond the beginning,
    and positive when beyond the end; \c 0.0 otherwise.

    Whether the values are reported for dragging and/or flicking is determined by
    \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
    is \c Flickable.StopAtBounds.

    \sa horizontalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::verticalOvershoot() const
{
    Q_D(const QQuickFlickable);
    return d->vData.overshoot;
}

/*!
    \qmlproperty enumeration QtQuick::Flickable::boundsMovement
    \since 5.10

    This property holds whether the flickable will give a feeling that the edges of the
    view are soft, rather than a hard physical boundary.

    The \c boundsMovement can be one of:

    \list
    \li Flickable.StopAtBounds - this allows implementing custom edge effects where the
    contents do not follow drags or flicks beyond the bounds of the flickable. The values
    of \l horizontalOvershoot and \l verticalOvershoot can be utilized to implement custom
    edge effects.
    \li Flickable.FollowBoundsBehavior (default) - whether the contents follow drags or
    flicks beyond the bounds of the flickable is determined by \l boundsBehavior.
    \endlist

    The following example keeps the contents within bounds and instead applies a flip
    effect when flicked over horizontal bounds:
    \code
    Flickable {
        id: flickable
        boundsMovement: Flickable.StopAtBounds
        boundsBehavior: Flickable.DragAndOvershootBounds
        transform: Rotation {
            axis { x: 0; y: 1; z: 0 }
            origin.x: flickable.width / 2
            origin.y: flickable.height / 2
            angle: Math.min(30, Math.max(-30, flickable.horizontalOvershoot))
        }
    }
    \endcode

    The following example keeps the contents within bounds and instead applies an opacity
    effect when dragged over vertical bounds:
    \code
    Flickable {
        boundsMovement: Flickable.StopAtBounds
        boundsBehavior: Flickable.DragOverBounds
        opacity: Math.max(0.5, 1.0 - Math.abs(verticalOvershoot) / height)
    }
    \endcode

    \sa boundsBehavior, verticalOvershoot, horizontalOvershoot
*/
QQuickFlickable::BoundsMovement QQuickFlickable::boundsMovement() const
{
    Q_D(const QQuickFlickable);
    return d->boundsMovement;
}

void QQuickFlickable::setBoundsMovement(BoundsMovement movement)
{
    Q_D(QQuickFlickable);
    if (d->boundsMovement == movement)
        return;

    d->boundsMovement = movement;
    emit boundsMovementChanged();
}

QT_END_NAMESPACE

#include "moc_qquickflickable_p.cpp"
