/****************************************************************************
**
** Copyright (C) 2016 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 "qquickmousearea_p.h"
#include "qquickmousearea_p_p.h"
#include "qquickwindow.h"
#if QT_CONFIG(quick_draganddrop)
#include "qquickdrag_p.h"
#endif

#include <private/qqmldata_p.h>
#include <private/qsgadaptationlayer_p.h>

#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qevent.h>
#include <QtGui/qstylehints.h>

#include <float.h>

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)

Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE)

QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
  moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
  propagateComposedEvents(false), overThreshold(false),
  pressAndHoldInterval(-1)
#if QT_CONFIG(quick_draganddrop)
  , drag(nullptr)
#endif
#if QT_CONFIG(cursor)
  , cursor(nullptr)
#endif
{
}

QQuickMouseAreaPrivate::~QQuickMouseAreaPrivate()
{
#if QT_CONFIG(quick_draganddrop)
    delete drag;
#endif
#if QT_CONFIG(cursor)
    delete cursor;
#endif
}

void QQuickMouseAreaPrivate::init()
{
    Q_Q(QQuickMouseArea);
    q->setAcceptedMouseButtons(Qt::LeftButton);
    q->setAcceptTouchEvents(false); // rely on mouse events synthesized from touch
    q->setFiltersChildMouseEvents(true);
    if (qmlVisualTouchDebugging()) {
        q->setFlag(QQuickItem::ItemHasContents);
    }
}

void QQuickMouseAreaPrivate::saveEvent(QMouseEvent *event)
{
    lastPos = event->localPos();
    lastScenePos = event->windowPos();
    lastButton = event->button();
    lastButtons = event->buttons();
    lastModifiers = event->modifiers();
    lastFlags = event->flags();
}

bool QQuickMouseAreaPrivate::isPressAndHoldConnected()
{
    Q_Q(QQuickMouseArea);
    IS_SIGNAL_CONNECTED(q, QQuickMouseArea, pressAndHold, (QQuickMouseEvent *));
}

bool QQuickMouseAreaPrivate::isDoubleClickConnected()
{
    Q_Q(QQuickMouseArea);
    IS_SIGNAL_CONNECTED(q, QQuickMouseArea, doubleClicked, (QQuickMouseEvent *));
}

bool QQuickMouseAreaPrivate::isClickConnected()
{
    Q_Q(QQuickMouseArea);
    IS_SIGNAL_CONNECTED(q, QQuickMouseArea, clicked, (QQuickMouseEvent *));
}

bool QQuickMouseAreaPrivate::isWheelConnected()
{
    Q_Q(QQuickMouseArea);
    IS_SIGNAL_CONNECTED(q, QQuickMouseArea, wheel, (QQuickWheelEvent *));
}

void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t)
{
    Q_Q(QQuickMouseArea);
    if (!window || !propagateComposedEvents)
        return;
    QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y()));
    propagateHelper(event, window->contentItem(), scenePos, t);
}

bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *item,const QPointF &sp, PropagateType sig)
{
    //Based off of QQuickWindow::deliverInitialMousePressEvent
    //But specific to MouseArea, so doesn't belong in window
    Q_Q(const QQuickMouseArea);
    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);

    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
        QPointF p = item->mapFromScene(sp);
        if (!item->contains(p))
            return false;
    }

    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
    for (int ii = children.count() - 1; ii >= 0; --ii) {
        QQuickItem *child = children.at(ii);
        if (!child->isVisible() || !child->isEnabled())
            continue;
        if (propagateHelper(ev, child, sp, sig))
            return true;
    }

    QQuickMouseArea* ma = qobject_cast<QQuickMouseArea*>(item);
    if (ma && ma != q && ma->isEnabled() && itemPrivate->acceptedMouseButtons() & ev->button()) {
        switch (sig) {
        case Click:
            if (!ma->d_func()->isClickConnected())
                return false;
            break;
        case DoubleClick:
            if (!ma->d_func()->isDoubleClickConnected())
                return false;
            break;
        case PressAndHold:
            if (!ma->d_func()->isPressAndHoldConnected())
                return false;
            break;
        }
        QPointF p = item->mapFromScene(sp);
        if (item->contains(p)) {
            ev->setX(p.x());
            ev->setY(p.y());
            ev->setAccepted(true);//It is connected, they have to explicitly ignore to let it slide
            switch (sig) {
            case Click: emit ma->clicked(ev); break;
            case DoubleClick: emit ma->doubleClicked(ev); break;
            case PressAndHold: emit ma->pressAndHold(ev); break;
            }
            if (ev->isAccepted())
                return true;
        }
    }
    return false;

}

/*!
    \qmltype MouseArea
    \instantiates QQuickMouseArea
    \inqmlmodule QtQuick
    \ingroup qtquick-input
    \brief Enables simple mouse handling.
    \inherits Item

    A MouseArea is an invisible item that is typically used in conjunction with
    a visible item in order to provide mouse handling for that item.
    By effectively acting as a proxy, the logic for mouse handling can be
    contained within a MouseArea item.

    The \l enabled property is used to enable and disable mouse handling for
    the proxied item. When disabled, the mouse area becomes transparent to
    mouse events.

    MouseArea is an invisible Item, but it has a visible property.
    When set to false, the mouse area becomes transparent to mouse events.

    The \l pressed read-only property indicates whether or not the user is
    holding down a mouse button over the mouse area. This property is often
    used in bindings between properties in a user interface. The containsMouse
    read-only property indicates the presence of the mouse cursor over the
    mouse area but, by default, only when a mouse button is held down; see
    the containsMouse documentation for details.

    Information about the mouse position and button clicks are provided via
    signals for which event handler properties are defined. The most commonly
    used involved handling mouse presses and clicks: onClicked, onDoubleClicked,
    onPressed, onReleased and onPressAndHold. It's also possible to handle mouse
    wheel events via the onWheel signal.

    If a MouseArea overlaps with the area of other MouseArea items, you can choose
    to propagate \c clicked, \c doubleClicked and \c pressAndHold events to these
    other items by setting propagateComposedEvents to true and rejecting events
    that should be propagated. See the propagateComposedEvents documentation for
    details.

    By default, MouseArea items only report mouse clicks and not changes to the
    position of the mouse cursor. Setting the hoverEnabled property ensures that
    handlers defined for onPositionChanged, onEntered and onExited are used and
    that the containsMouse property is updated even when no mouse buttons are
    pressed.

    \section1 Example Usage

    \div {class="float-right"}
    \inlineimage qml-mousearea-snippet.png
    \enddiv

    The following example uses a MouseArea in a \l Rectangle that changes
    the \l Rectangle color to red when clicked:

    \snippet qml/mousearea/mousearea.qml import
    \codeline
    \snippet qml/mousearea/mousearea.qml intro

    \clearfloat
    Many MouseArea signals pass a \l{MouseEvent}{mouse} parameter that contains
    additional information about the mouse event, such as the position, button,
    and any key modifiers.

    Here is an extension of the previous example that produces a different
    color when the area is right clicked:

    \snippet qml/mousearea/mousearea.qml intro-extended

    \sa MouseEvent, {mousearea}{MouseArea example},
    {Important Concepts In Qt Quick - User Input}
*/

/*!
    \qmlsignal QtQuick::MouseArea::entered()

    This signal is emitted when the mouse enters the mouse area.

    By default this signal is only emitted if a button is currently
    pressed. Set \l hoverEnabled to true to emit this signal
    even when no mouse button is pressed.

    \sa hoverEnabled
*/

/*!
    \qmlsignal QtQuick::MouseArea::exited()

    This signal is emitted when the mouse exits the mouse area.

    By default this signal is only emitted if a button is currently
    pressed. Set \l hoverEnabled to true to emit this signal
    even when no mouse button is pressed.

    The example below shows a fairly typical relationship between
    two MouseAreas, with \c mouseArea2 on top of \c mouseArea1. Moving the
    mouse into \c mouseArea2 from \c mouseArea1 will cause \c mouseArea1
    to emit the \c exited signal.
    \qml
    Rectangle {
        width: 400; height: 400
        MouseArea {
            id: mouseArea1
            anchors.fill: parent
            hoverEnabled: true
        }
        MouseArea {
            id: mouseArea2
            width: 100; height: 100
            anchors.centerIn: parent
            hoverEnabled: true
        }
    }
    \endqml

    If instead you give the two MouseAreas a parent-child relationship,
    moving the mouse into \c mouseArea2 from \c mouseArea1 will \b not
    cause \c mouseArea1 to emit \c exited. Instead, they will
    both be considered to be simultaneously hovered.

    \sa hoverEnabled
*/

/*!
    \qmlsignal QtQuick::MouseArea::positionChanged(MouseEvent mouse)

    This signal is emitted when the mouse position changes.

    The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y
    position, and any buttons currently pressed.

    By default this signal is only emitted if a button is currently
    pressed. Set \l hoverEnabled to true to emit this signal
    even when no mouse button is pressed.

    When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter has no effect.
*/

/*!
    \qmlsignal QtQuick::MouseArea::clicked(MouseEvent mouse)

    This signal is emitted when there is a click. A click is defined as a press followed by a release,
    both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
    releasing is also considered a click).

    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
    position of the release of the click, and whether the click was held.

    When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter has no effect, unless the \l propagateComposedEvents property is \c true.
*/

/*!
    \qmlsignal QtQuick::MouseArea::pressed(MouseEvent mouse)

    This signal is emitted when there is a press.
    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
    position and which button was pressed.

    When handling this signal, use the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter to control whether this MouseArea handles the press and all future mouse events until
    release. The default is to accept the event and not allow other MouseAreas beneath this one to
    handle the event.  If \e accepted is set to false, no further events will be sent to this MouseArea
    until the button is next pressed.
*/

/*!
    \qmlsignal QtQuick::MouseArea::released(MouseEvent mouse)

    This signal is emitted when there is a release.
    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
    position of the release of the click, and whether the click was held.

    When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter has no effect.

    \sa canceled
*/

/*!
    \qmlsignal QtQuick::MouseArea::pressAndHold(MouseEvent mouse)

    This signal is emitted when there is a long press (currently 800ms).
    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
    position of the press, and which button is pressed.

    When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter has no effect, unless the \l propagateComposedEvents property is \c true.
*/

/*!
    \qmlsignal QtQuick::MouseArea::doubleClicked(MouseEvent mouse)

    This signal is emitted when there is a double-click (a press followed by a release followed by a press).
    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
    position of the release of the click, and whether the click was held.

    When handling this signal, if the \l {MouseEvent::}{accepted} property of the \a mouse
    parameter is set to false, the pressed/released/clicked signals will be emitted for the second
    click; otherwise they are suppressed.  The \c accepted property defaults to true.
*/

/*!
    \qmlsignal QtQuick::MouseArea::canceled()

    This signal is emitted when mouse events have been canceled, because another item stole the mouse event handling.

    This signal is for advanced use: it is useful when there is more than one MouseArea
    that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
    case, if you execute some logic in the \c onPressed signal handler and then start dragging, the
    \l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
    the logic when the MouseArea has lost the mouse handling to the \l Flickable,
    \c canceled should be handled in addition to \l released.
*/

/*!
    \qmlsignal QtQuick::MouseArea::wheel(WheelEvent wheel)

    This signal is emitted in response to both mouse wheel and trackpad scroll gestures.

    The \a wheel parameter provides information about the event, including the x and y
    position, any buttons currently pressed, and information about the wheel movement, including
    angleDelta and pixelDelta.
*/

QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
  : QQuickItem(*(new QQuickMouseAreaPrivate), parent)
{
    Q_D(QQuickMouseArea);
    d->init();
#if QT_CONFIG(cursor)
    // Explcitly call setCursor on QQuickItem since
    // it internally keeps a boolean hasCursor that doesn't
    // get set to true unless you call setCursor
    setCursor(Qt::ArrowCursor);
#endif
}

QQuickMouseArea::~QQuickMouseArea()
{
}

/*!
    \qmlproperty real QtQuick::MouseArea::mouseX
    \qmlproperty real QtQuick::MouseArea::mouseY
    These properties hold the coordinates of the mouse cursor.

    If the hoverEnabled property is false then these properties will only be valid
    while a button is pressed, and will remain valid as long as the button is held
    down even if the mouse is moved outside the area.

    By default, this property is false.

    If hoverEnabled is true then these properties will be valid when:
    \list
        \li no button is pressed, but the mouse is within the MouseArea (containsMouse is true).
        \li a button is pressed and held, even if it has since moved out of the area.
    \endlist

    The coordinates are relative to the MouseArea.
*/
qreal QQuickMouseArea::mouseX() const
{
    Q_D(const QQuickMouseArea);
    return d->lastPos.x();
}

qreal QQuickMouseArea::mouseY() const
{
    Q_D(const QQuickMouseArea);
    return d->lastPos.y();
}

/*!
    \qmlproperty bool QtQuick::MouseArea::enabled
    This property holds whether the item accepts mouse events.

    \note Due to historical reasons, this property is not equivalent to
    Item.enabled. It only affects mouse events, and its effect does not
    propagate to child items.

    By default, this property is true.
*/
bool QQuickMouseArea::isEnabled() const
{
    Q_D(const QQuickMouseArea);
    return d->enabled;
}

void QQuickMouseArea::setEnabled(bool a)
{
    Q_D(QQuickMouseArea);
    if (a != d->enabled) {
        d->enabled = a;
        emit enabledChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::MouseArea::scrollGestureEnabled
    \since 5.5

    This property controls whether this MouseArea responds to scroll gestures
    from non-mouse devices, such as the 2-finger flick gesture on a trackpad.
    If set to false, the \l wheel signal be emitted only when the wheel event
    comes from an actual mouse with a wheel, while scroll gesture events will
    pass through to any other Item that will handle them. For example, the user
    might perform a flick gesture while the cursor is over an item containing a
    MouseArea, intending to interact with a Flickable which is underneath.
    Setting this property to false will allow the PinchArea to handle the mouse
    wheel or the pinch gesture, while the Flickable handles the flick gesture.

    By default, this property is true.
*/
bool QQuickMouseArea::isScrollGestureEnabled() const
{
    Q_D(const QQuickMouseArea);
    return d->scrollGestureEnabled;
}

void QQuickMouseArea::setScrollGestureEnabled(bool e)
{
    Q_D(QQuickMouseArea);
    if (e != d->scrollGestureEnabled) {
        d->scrollGestureEnabled = e;
        emit scrollGestureEnabledChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::MouseArea::preventStealing
    This property holds whether the mouse events may be stolen from this
    MouseArea.

    If a MouseArea is placed within an item that filters child mouse
    events, such as Flickable, the mouse
    events may be stolen from the MouseArea if a gesture is recognized
    by the parent item, e.g. a flick gesture.  If preventStealing is
    set to true, no item will steal the mouse events.

    Note that setting preventStealing to true once an item has started
    stealing events will have no effect until the next press event.

    By default this property is false.
*/
bool QQuickMouseArea::preventStealing() const
{
    Q_D(const QQuickMouseArea);
    return d->preventStealing;
}

void QQuickMouseArea::setPreventStealing(bool prevent)
{
    Q_D(QQuickMouseArea);
    if (prevent != d->preventStealing) {
        d->preventStealing = prevent;
        setKeepMouseGrab(d->preventStealing && d->enabled);
        emit preventStealingChanged();
    }
}


/*!
    \qmlproperty bool QtQuick::MouseArea::propagateComposedEvents
    This property holds whether composed mouse events will automatically propagate to
    other MouseAreas that overlap with this MouseArea but are lower in the visual stacking order.
    By default, this property is false.

    MouseArea contains several composed events: \c clicked, \c doubleClicked and \c pressAndHold.
    These are composed of basic mouse events, like \c pressed, and can be propagated differently
    in comparison to basic events.

    If propagateComposedEvents is set to true, then composed events will be automatically
    propagated to other MouseAreas in the same location in the scene. Each event is propagated
    to the next \l enabled MouseArea beneath it in the stacking order, propagating down this visual
    hierarchy until a MouseArea accepts the event. Unlike \c pressed events, composed events will
    not be automatically accepted if no handler is present.

    For example, below is a yellow \l Rectangle that contains a blue \l Rectangle. The blue
    rectangle is the top-most item in the hierarchy of the visual stacking order; it will
    visually rendered above the yellow rectangle. Since the blue rectangle sets
    propagateComposedEvents to true, and also sets \l MouseEvent::accepted to false for all
    received \c clicked events, any \c clicked events it receives are propagated to the
    MouseArea of the yellow rectangle beneath it.

    \qml
    import QtQuick 2.0

    Rectangle {
        color: "yellow"
        width: 100; height: 100

        MouseArea {
            anchors.fill: parent
            onClicked: console.log("clicked yellow")
        }

        Rectangle {
            color: "blue"
            width: 50; height: 50

            MouseArea {
                anchors.fill: parent
                propagateComposedEvents: true
                onClicked: {
                    console.log("clicked blue")
                    mouse.accepted = false
                }
            }
        }
    }
    \endqml

    Clicking on the blue rectangle will cause the \c onClicked handler of its child MouseArea to
    be invoked; the event will then be propagated to the MouseArea of the yellow rectangle, causing
    its own \c onClicked handler to be invoked.

    This property greatly simplifies the usecase of when you want to have overlapping MouseAreas
    handling the composed events together. For example: if you want one MouseArea to handle \c clicked
    signals and the other to handle \c pressAndHold, or if you want one MouseArea to handle \c clicked most
    of the time, but pass it through when certain conditions are met.
*/
bool QQuickMouseArea::propagateComposedEvents() const
{
    Q_D(const QQuickMouseArea);
    return d->propagateComposedEvents;
}

void QQuickMouseArea::setPropagateComposedEvents(bool prevent)
{
    Q_D(QQuickMouseArea);
    if (prevent != d->propagateComposedEvents) {
        d->propagateComposedEvents = prevent;
        setKeepMouseGrab(d->propagateComposedEvents && d->enabled);
        emit propagateComposedEventsChanged();
    }
}

/*!
    \qmlproperty MouseButtons QtQuick::MouseArea::pressedButtons
    This property holds the mouse buttons currently pressed.

    It contains a bitwise combination of:
    \list
    \li Qt.LeftButton
    \li Qt.RightButton
    \li Qt.MiddleButton
    \endlist

    The code below displays "right" when the right mouse buttons is pressed:

    \snippet qml/mousearea/mousearea.qml mousebuttons

    \note this property only handles buttons specified in \l acceptedButtons.

    \sa acceptedButtons
*/
Qt::MouseButtons QQuickMouseArea::pressedButtons() const
{
    Q_D(const QQuickMouseArea);
    return d->pressed;
}

void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickMouseArea);
    d->moved = false;
    d->stealMouse = d->preventStealing;
    d->overThreshold = false;
    if (!d->enabled || !(event->button() & acceptedMouseButtons())) {
        QQuickItem::mousePressEvent(event);
    } else {
        d->longPress = false;
        d->saveEvent(event);
#if QT_CONFIG(quick_draganddrop)
        if (d->drag)
            d->drag->setActive(false);
#endif
        setHovered(true);
        d->startScene = event->windowPos();
        setKeepMouseGrab(d->stealMouse);
        event->setAccepted(setPressed(event->button(), true, event->source()));
        if (event->isAccepted())
            d->pressAndHoldTimer.start(pressAndHoldInterval(), this);
    }
}

void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QQuickMouseArea);
    if (!d->enabled && !d->pressed) {
        QQuickItem::mouseMoveEvent(event);
        return;
    }

    // ### we should skip this if these signals aren't used
    // ### can GV handle this for us?
    setHovered(contains(event->localPos()));

    if ((event->buttons() & acceptedMouseButtons()) == 0) {
        QQuickItem::mouseMoveEvent(event);
        return;
    }

    d->saveEvent(event);


#if QT_CONFIG(quick_draganddrop)
    if (d->drag && d->drag->target()) {
        if (!d->moved) {
            d->targetStartPos = d->drag->target()->parentItem()
                    ? d->drag->target()->parentItem()->mapToScene(d->drag->target()->position())
                    : d->drag->target()->position();
        }

        QPointF startLocalPos;
        QPointF curLocalPos;
        if (drag()->target()->parentItem()) {
            startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
            curLocalPos = drag()->target()->parentItem()->mapFromScene(event->windowPos());
        } else {
            startLocalPos = d->startScene;
            curLocalPos = event->windowPos();
        }

        if (keepMouseGrab() && d->stealMouse && d->overThreshold && !d->drag->active())
            d->drag->setActive(true);

        QPointF startPos = d->drag->target()->parentItem()
                ? d->drag->target()->parentItem()->mapFromScene(d->targetStartPos)
                : d->targetStartPos;

        bool dragX = drag()->axis() & QQuickDrag::XAxis;
        bool dragY = drag()->axis() & QQuickDrag::YAxis;

        QPointF dragPos = d->drag->target()->position();
        QPointF boundedDragPos = dragPos;
        if (dragX) {
            dragPos.setX(startPos.x() + curLocalPos.x() - startLocalPos.x());
            boundedDragPos.setX(qBound(
                    d->drag->xmin(),
                    dragPos.x(),
                    d->drag->xmax()));
        }
        if (dragY) {
            dragPos.setY(startPos.y() + curLocalPos.y() - startLocalPos.y());
            boundedDragPos.setY(qBound(
                    d->drag->ymin(),
                    dragPos.y(),
                    d->drag->ymax()));
        }

        QPointF targetPos = d->drag->target()->position();

        if (d->drag->active()) {
            d->drag->target()->setPosition(boundedDragPos);
            d->lastPos = mapFromScene(d->lastScenePos);
        }

        bool dragOverThresholdX = QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(),
                                                                         Qt::XAxis, event, d->drag->threshold());
        bool dragOverThresholdY = QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(),
                                                                         Qt::YAxis, event, d->drag->threshold());

        if (!d->overThreshold && (((targetPos.x() != boundedDragPos.x()) && dragOverThresholdX) ||
                                  ((targetPos.y() != boundedDragPos.y()) && dragOverThresholdY)))
        {
            d->overThreshold = true;
            if (d->drag->smoothed())
                d->startScene = event->windowPos();
        }

        if (!keepMouseGrab() && d->overThreshold) {
            setKeepMouseGrab(true);
            d->stealMouse = true;
        }

        d->moved = true;
    }
#endif

    QQuickMouseEvent &me = d->quickMouseEvent;
    me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, event->flags());
    me.setSource(event->source());
    emit mouseXChanged(&me);
    me.setPosition(d->lastPos);
    emit mouseYChanged(&me);
    me.setPosition(d->lastPos);
    emit positionChanged(&me);
}

void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QQuickMouseArea);
    d->stealMouse = false;
    d->overThreshold = false;
    if (!d->enabled && !d->pressed) {
        QQuickItem::mouseReleaseEvent(event);
    } else {
        d->saveEvent(event);
        setPressed(event->button(), false, event->source());
        if (!d->pressed) {
            // no other buttons are pressed
#if QT_CONFIG(quick_draganddrop)
            if (d->drag)
                d->drag->setActive(false);
#endif
            // If we don't accept hover, we need to reset containsMouse.
            if (!acceptHoverEvents())
                setHovered(false);
            QQuickWindow *w = window();
            if (w && w->mouseGrabberItem() == this)
                ungrabMouse();
            setKeepMouseGrab(false);
        }
    }
    d->doubleClick = false;
}

void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_D(QQuickMouseArea);
    if (d->enabled) {
        d->saveEvent(event);
        QQuickMouseEvent &me = d->quickMouseEvent;
        me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true,
                 false, event->flags());
        me.setSource(event->source());
        me.setAccepted(d->isDoubleClickConnected());
        emit this->doubleClicked(&me);
        if (!me.isAccepted())
            d->propagate(&me, QQuickMouseAreaPrivate::DoubleClick);
        d->doubleClick = d->isDoubleClickConnected() || me.isAccepted();
    }
    QQuickItem::mouseDoubleClickEvent(event);
}

void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event)
{
    Q_D(QQuickMouseArea);
    if (!d->enabled && !d->pressed) {
        QQuickItem::hoverEnterEvent(event);
    } else {
        d->lastPos = event->posF();
        d->lastModifiers = event->modifiers();
        setHovered(true);
        QQuickMouseEvent &me = d->quickMouseEvent;
        me.reset(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
        emit mouseXChanged(&me);
        me.setPosition(d->lastPos);
        emit mouseYChanged(&me);
        me.setPosition(d->lastPos);
    }
}

void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event)
{
    Q_D(QQuickMouseArea);
    if (!d->enabled && !d->pressed) {
        QQuickItem::hoverMoveEvent(event);
    } else if (d->lastPos != event->posF()) {
        d->lastPos = event->posF();
        d->lastModifiers = event->modifiers();
        QQuickMouseEvent &me = d->quickMouseEvent;
        me.reset(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
        emit mouseXChanged(&me);
        me.setPosition(d->lastPos);
        emit mouseYChanged(&me);
        me.setPosition(d->lastPos);
        emit positionChanged(&me);
    }
}

void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event)
{
    Q_D(QQuickMouseArea);
    if (!d->enabled && !d->pressed)
        QQuickItem::hoverLeaveEvent(event);
    else
        setHovered(false);
}

#if QT_CONFIG(wheelevent)
void QQuickMouseArea::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickMouseArea);
    if (!d->enabled || (!isScrollGestureEnabled() && event->source() != Qt::MouseEventNotSynthesized)) {
        QQuickItem::wheelEvent(event);
        return;
    }

    QQuickWheelEvent &we = d->quickWheelEvent;
    we.reset(event->position().x(), event->position().y(), event->angleDelta(), event->pixelDelta(),
             event->buttons(), event->modifiers(), event->inverted());
    we.setAccepted(d->isWheelConnected());
    emit wheel(&we);
    if (!we.isAccepted())
        QQuickItem::wheelEvent(event);
}
#endif

void QQuickMouseArea::ungrabMouse()
{
    Q_D(QQuickMouseArea);
    if (d->pressed) {
        // if our mouse grab has been removed (probably by Flickable), fix our
        // state
        d->pressed = Qt::NoButton;
        d->stealMouse = false;
        d->doubleClick = false;
        d->overThreshold = false;
        setKeepMouseGrab(false);

#if QT_CONFIG(quick_draganddrop)
        if (d->drag)
            d->drag->setActive(false);
#endif

        emit canceled();
        emit pressedChanged();
        emit containsPressChanged();
        emit pressedButtonsChanged();

        if (d->hovered && !isUnderMouse()) {
            d->hovered = false;
            emit hoveredChanged();
        }
    }
}

void QQuickMouseArea::mouseUngrabEvent()
{
    ungrabMouse();
}

void QQuickMouseArea::touchUngrabEvent()
{
    // allow a Pointer Handler to steal the grab from MouseArea
    ungrabMouse();
}

bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event)
{
    Q_D(QQuickMouseArea);
    QPointF localPos = mapFromScene(event->windowPos());

    QQuickWindow *c = window();
    QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr;
    bool stealThisEvent = d->stealMouse;
    if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) {
        QMouseEvent mouseEvent(event->type(), localPos, event->windowPos(), event->screenPos(),
                               event->button(), event->buttons(), event->modifiers());
        mouseEvent.setAccepted(false);

        switch (event->type()) {
        case QEvent::MouseMove:
            mouseMoveEvent(&mouseEvent);
            break;
        case QEvent::MouseButtonPress:
            mousePressEvent(&mouseEvent);
            break;
        case QEvent::MouseButtonRelease:
            mouseReleaseEvent(&mouseEvent);
            stealThisEvent = d->stealMouse;
            break;
        default:
            break;
        }
        grabber = c ? c->mouseGrabberItem() : nullptr;
        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
            grabMouse();

        return stealThisEvent;
    }
    if (event->type() == QEvent::MouseButtonRelease) {
        if (d->pressed) {
            d->pressed &= ~event->button();
            emit pressedButtonsChanged();
            if (!d->pressed) {
                // no other buttons are pressed
                d->stealMouse = false;
                d->overThreshold = false;
                if (c && c->mouseGrabberItem() == this)
                    ungrabMouse();
                emit canceled();
                emit pressedChanged();
                emit containsPressChanged();
                if (d->hovered) {
                    d->hovered = false;
                    emit hoveredChanged();
                }
            }
        }
    }
    return false;
}

bool QQuickMouseArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
    Q_D(QQuickMouseArea);
    if (!d->pressed &&
            (!d->enabled || !isVisible()
#if QT_CONFIG(quick_draganddrop)
             || !d->drag || !d->drag->filterChildren()
#endif
            )
       )
        return QQuickItem::childMouseEventFilter(i, e);
    switch (e->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        return sendMouseEvent(static_cast<QMouseEvent *>(e));
    default:
        break;
    }

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

void QQuickMouseArea::timerEvent(QTimerEvent *event)
{
    Q_D(QQuickMouseArea);
    if (event->timerId() == d->pressAndHoldTimer.timerId()) {
        d->pressAndHoldTimer.stop();
#if QT_CONFIG(quick_draganddrop)
        bool dragged = d->drag && d->drag->active();
#else
        bool dragged = false;
#endif
        if (d->pressed && dragged == false && d->hovered == true) {
            d->longPress = true;
            QQuickMouseEvent &me = d->quickMouseEvent;
            me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, d->lastFlags);
            me.setSource(Qt::MouseEventSynthesizedByQt);
            me.setAccepted(d->isPressAndHoldConnected());
            emit pressAndHold(&me);
            if (!me.isAccepted())
                d->propagate(&me, QQuickMouseAreaPrivate::PressAndHold);
            if (!me.isAccepted()) // no one handled the long press - allow click
                d->longPress = false;
        }
    }
}

void QQuickMouseArea::windowDeactivateEvent()
{
    ungrabMouse();
    QQuickItem::windowDeactivateEvent();
}

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

    if (d->lastScenePos.isNull)
        d->lastScenePos = mapToScene(d->lastPos);
    else if (newGeometry.x() != oldGeometry.x() || newGeometry.y() != oldGeometry.y())
        d->lastPos = mapFromScene(d->lastScenePos);
}

void QQuickMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
{
    Q_D(QQuickMouseArea);
    switch (change) {
    case ItemVisibleHasChanged:
        if (d->effectiveEnable && d->enabled && acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse())) {
            if (!d->hovered) {
                QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
                d->lastScenePos = d->window->mapFromGlobal(cursorPos.toPoint());
                d->lastPos = mapFromScene(d->lastScenePos);
            }
            setHovered(!d->hovered);
        }
        if (d->pressed && (!isVisible())) {
            // This happens when the mouse area sets itself disabled or hidden
            // inside the press handler. In that case we should not keep the internal
            // state as pressed, since we never became the mouse grabber.
            ungrabMouse();
        }
        break;
    default:
        break;
    }

    QQuickItem::itemChange(change, value);
}

/*!
    \qmlproperty bool QtQuick::MouseArea::hoverEnabled
    This property holds whether hover events are handled.

    By default, mouse events are only handled in response to a button event, or when a button is
    pressed.  Hover enables handling of all mouse events even when no mouse button is
    pressed.

    This property affects the containsMouse property and the onEntered, onExited and
    onPositionChanged signals.
*/
bool QQuickMouseArea::hoverEnabled() const
{
    return acceptHoverEvents();
}

void QQuickMouseArea::setHoverEnabled(bool h)
{
    if (h == acceptHoverEvents())
        return;

    setAcceptHoverEvents(h);
    emit hoverEnabledChanged();
}


/*!
    \qmlproperty bool QtQuick::MouseArea::containsMouse
    This property holds whether the mouse is currently inside the mouse area.

    \warning If hoverEnabled is false, containsMouse will only be valid
    when the mouse is pressed while the mouse cursor is inside the MouseArea.
*/
bool QQuickMouseArea::hovered() const
{
    Q_D(const QQuickMouseArea);
    return d->hovered;
}

/*!
    \qmlproperty bool QtQuick::MouseArea::pressed
    This property holds whether any of the \l acceptedButtons are currently pressed.
*/
bool QQuickMouseArea::pressed() const
{
    Q_D(const QQuickMouseArea);
    return d->pressed;
}

/*!
    \qmlproperty bool QtQuick::MouseArea::containsPress
    \since 5.4
    This is a convenience property equivalent to \c {pressed && containsMouse},
    i.e. it holds whether any of the \l acceptedButtons are currently pressed
    and the mouse is currently within the MouseArea.

    This property is particularly useful for highlighting an item while the mouse
    is pressed within its bounds.

    \sa pressed, containsMouse
*/
bool QQuickMouseArea::containsPress() const
{
    Q_D(const QQuickMouseArea);
    return d->pressed && d->hovered;
}

void QQuickMouseArea::setHovered(bool h)
{
    Q_D(QQuickMouseArea);
    if (d->hovered != h) {
        qCDebug(DBG_HOVER_TRACE) << this << d->hovered <<  "->" << h;
        d->hovered = h;
        emit hoveredChanged();
        d->hovered ? emit entered() : emit exited();
        if (d->pressed)
            emit containsPressChanged();
    }
}

/*!
    \qmlproperty Qt::MouseButtons QtQuick::MouseArea::acceptedButtons
    This property holds the mouse buttons that the mouse area reacts to.

    To specify that the MouseArea will react to multiple buttons,
    Qt::MouseButtons flag values are combined using the "|" (or) operator:

    \code
    MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton }
    \endcode

    To indicate that all possible mouse buttons are to be accepted,
    the special value 'Qt.AllButtons' may be used:

    \code
    MouseArea { acceptedButtons: Qt.AllButtons }
    \endcode

    The default value is \c Qt.LeftButton.
*/
Qt::MouseButtons QQuickMouseArea::acceptedButtons() const
{
    return acceptedMouseButtons();
}

void QQuickMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
{
    if (buttons != acceptedMouseButtons()) {
        setAcceptedMouseButtons(buttons);
        emit acceptedButtonsChanged();
    }
}

bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventSource source)
{
    Q_D(QQuickMouseArea);

#if QT_CONFIG(quick_draganddrop)
    bool dragged = d->drag && d->drag->active();
#else
    bool dragged = false;
#endif
    bool wasPressed = d->pressed & button;
    bool isclick = wasPressed && p == false && dragged == false && d->hovered == true;
    Qt::MouseButtons oldPressed = d->pressed;

    if (wasPressed != p) {
        QQuickMouseEvent &me = d->quickMouseEvent;
        me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress, d->lastFlags);
        me.setSource(source);
        if (p) {
            d->pressed |= button;
            if (!d->doubleClick)
                emit pressed(&me);
            me.setPosition(d->lastPos);
            emit mouseXChanged(&me);
            me.setPosition(d->lastPos);
            emit mouseYChanged(&me);

            if (!me.isAccepted()) {
                d->pressed = Qt::NoButton;
            }

            if (!oldPressed) {
                emit pressedChanged();
                emit containsPressChanged();
            }
            emit pressedButtonsChanged();
        } else {
            d->pressed &= ~button;
            emit released(&me);
            me.setPosition(d->lastPos);
            if (!d->pressed) {
                emit pressedChanged();
                emit containsPressChanged();
            }
            emit pressedButtonsChanged();
            if (isclick && !d->longPress && !d->doubleClick){
                me.setAccepted(d->isClickConnected());
                emit clicked(&me);
                if (!me.isAccepted())
                    d->propagate(&me, QQuickMouseAreaPrivate::Click);
            }
        }

        return me.isAccepted();
    }
    return false;
}


/*!
    \qmlproperty Qt::CursorShape QtQuick::MouseArea::cursorShape
    This property holds the cursor shape for this mouse area.
    Note that on platforms that do not display a mouse cursor this may have
    no effect.

    The available cursor shapes are:
    \list
    \li Qt.ArrowCursor
    \li Qt.UpArrowCursor
    \li Qt.CrossCursor
    \li Qt.WaitCursor
    \li Qt.IBeamCursor
    \li Qt.SizeVerCursor
    \li Qt.SizeHorCursor
    \li Qt.SizeBDiagCursor
    \li Qt.SizeFDiagCursor
    \li Qt.SizeAllCursor
    \li Qt.BlankCursor
    \li Qt.SplitVCursor
    \li Qt.SplitHCursor
    \li Qt.PointingHandCursor
    \li Qt.ForbiddenCursor
    \li Qt.WhatsThisCursor
    \li Qt.BusyCursor
    \li Qt.OpenHandCursor
    \li Qt.ClosedHandCursor
    \li Qt.DragCopyCursor
    \li Qt.DragMoveCursor
    \li Qt.DragLinkCursor
    \endlist

    In order to only set a mouse cursor shape for a region without reacting
    to mouse events set the acceptedButtons to none:

    \code
    MouseArea { cursorShape: Qt.IBeamCursor; acceptedButtons: Qt.NoButton }
    \endcode

    The default value is \c Qt.ArrowCursor.
    \sa Qt::CursorShape
*/

#if QT_CONFIG(cursor)
Qt::CursorShape QQuickMouseArea::cursorShape() const
{
    return cursor().shape();
}

void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
{
    if (cursor().shape() == shape)
        return;

    setCursor(shape);

    emit cursorShapeChanged();
}

#endif


/*!
    \qmlproperty int QtQuick::MouseArea::pressAndHoldInterval
    \since 5.9

    This property overrides the elapsed time in milliseconds before
    \c pressAndHold is emitted.

    If not explicitly set -- or after reset -- the value follows
    \c QStyleHints::mousePressAndHoldInterval.

    Typically it's sufficient to set this property globally using the
    application style hint. This property should be used when varying intervals
    are needed for certain MouseAreas.

    \sa pressAndHold
*/
int QQuickMouseArea::pressAndHoldInterval() const
{
    Q_D(const QQuickMouseArea);
    return d->pressAndHoldInterval > -1 ?
        d->pressAndHoldInterval : QGuiApplication::styleHints()->mousePressAndHoldInterval();
}

void QQuickMouseArea::setPressAndHoldInterval(int interval)
{
    Q_D(QQuickMouseArea);
    if (interval != d->pressAndHoldInterval) {
        d->pressAndHoldInterval = interval;
        emit pressAndHoldIntervalChanged();
    }
}

void QQuickMouseArea::resetPressAndHoldInterval()
{
    Q_D(QQuickMouseArea);
    if (d->pressAndHoldInterval > -1) {
        d->pressAndHoldInterval = -1;
        emit pressAndHoldIntervalChanged();
    }
}

/*!
    \qmlpropertygroup QtQuick::MouseArea::drag
    \qmlproperty Item QtQuick::MouseArea::drag.target
    \qmlproperty bool QtQuick::MouseArea::drag.active
    \qmlproperty enumeration QtQuick::MouseArea::drag.axis
    \qmlproperty real QtQuick::MouseArea::drag.minimumX
    \qmlproperty real QtQuick::MouseArea::drag.maximumX
    \qmlproperty real QtQuick::MouseArea::drag.minimumY
    \qmlproperty real QtQuick::MouseArea::drag.maximumY
    \qmlproperty bool QtQuick::MouseArea::drag.filterChildren
    \qmlproperty real QtQuick::MouseArea::drag.threshold
    \qmlproperty bool QtQuick::MouseArea::drag.smoothed

    \c drag provides a convenient way to make an item draggable.

    \list
    \li \c drag.target specifies the id of the item to drag.
    \li \c drag.active specifies if the target item is currently being dragged.
    \li \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XAndYAxis)
    \li \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
    \endlist

    The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
    of the rectangle is reduced when it is dragged to the right.

    \snippet qml/mousearea/mousearea.qml drag

    \note Items cannot be dragged if they are anchored for the requested
    \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
    for \c rect in the above example, it cannot be dragged along the X-axis.
    This can be avoided by settng the anchor value to \c undefined in
    an \l {pressed}{onPressed} handler.

    If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas.  This
    enables a parent MouseArea to handle drags, for example, while descendants handle clicks:

    \c drag.threshold determines the threshold in pixels of when the drag operation should
    start. By default this is bound to a platform dependent value. This property was added in
    Qt Quick 2.2.

    If \c drag.smoothed is \c true, the target will be moved only after the drag operation has
    started. If set to \c false, the target will be moved straight to the current mouse position.
    By default, this property is \c true. This property was added in Qt Quick 2.4

    See the \l Drag attached property and \l DropArea if you want to make a drop.

    \snippet qml/mousearea/mouseareadragfilter.qml dragfilter

*/

#if QT_CONFIG(quick_draganddrop)
QQuickDrag *QQuickMouseArea::drag()
{
    Q_D(QQuickMouseArea);
    if (!d->drag)
        d->drag = new QQuickDrag;
    return d->drag;
}
#endif

QSGNode *QQuickMouseArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{
    Q_UNUSED(data);
    Q_D(QQuickMouseArea);

    if (!qmlVisualTouchDebugging())
        return nullptr;

    QSGInternalRectangleNode *rectangle = static_cast<QSGInternalRectangleNode *>(oldNode);
    if (!rectangle) rectangle = d->sceneGraphContext()->createInternalRectangleNode();

    rectangle->setRect(QRectF(0, 0, width(), height()));
    rectangle->setColor(QColor(255, 0, 0, 50));
    rectangle->update();
    return rectangle;
}

QT_END_NAMESPACE

#include "moc_qquickmousearea_p.cpp"
