/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickdrawer_p.h"
#include "qquickdrawer_p_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickpopuppositioner_p_p.h"

#include <QtGui/qstylehints.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuick/private/qquickanimation_p.h>
#include <QtQuick/private/qquicktransition_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype Drawer
    \inherits Popup
//!     \instantiates QQuickDrawer
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-navigation
    \ingroup qtquickcontrols2-popups
    \brief Side panel that can be opened and closed using a swipe gesture.

    Drawer provides a swipe-based side panel, similar to those often used in
    touch interfaces to provide a central location for navigation.

    \image qtquickcontrols2-drawer.gif

    Drawer can be positioned at any of the four edges of the content item.
    The drawer above is positioned against the left edge of the window. The
    drawer is then opened by \e "dragging" it out from the left edge of the
    window.

    \code \QtMinorVersion
    import QtQuick 2.\1
    import QtQuick.Controls 2.\1

    ApplicationWindow {
        id: window
        visible: true

        Drawer {
            id: drawer
            width: 0.66 * window.width
            height: window.height

            Label {
                text: "Content goes here!"
                anchors.centerIn: parent
            }
        }
    }
    \endcode

    Drawer is a special type of popup that resides at one of the window \l {edge}{edges}.
    By default, Drawer re-parents itself to the window \l {ApplicationWindow::}{overlay},
    and therefore operates on window coordinates. It is also possible to manually set the
    \l {Popup::}{parent} to something else to make the drawer operate in a specific
    coordinate space.

    Drawer can be configured to cover only part of its window edge. The following example
    illustrates how Drawer can be positioned to appear below a window header:

    \code \QtMinorVersion
    import QtQuick 2.\1
    import QtQuick.Controls 2.\1

    ApplicationWindow {
        id: window
        visible: true

        header: ToolBar { }

        Drawer {
            y: header.height
            width: window.width * 0.6
            height: window.height - header.height
        }
    }
    \endcode

    The \l position property determines how much of the drawer is visible, as
    a value between \c 0.0 and \c 1.0. It is not possible to set the x-coordinate
    (or horizontal margins) of a drawer at the left or right window edge, or the
    y-coordinate (or vertical margins) of a drawer at the top or bottom window edge.

    In the image above, the application's contents are \e "pushed" across the
    screen. This is achieved by applying a translation to the contents:

    \code \QtMinorVersion
    import QtQuick 2.\1
    import QtQuick.Controls 2.\1

    ApplicationWindow {
        id: window
        width: 200
        height: 228
        visible: true

        Drawer {
            id: drawer
            width: 0.66 * window.width
            height: window.height
        }

        Label {
            id: content

            text: "Aa"
            font.pixelSize: 96
            anchors.fill: parent
            verticalAlignment: Label.AlignVCenter
            horizontalAlignment: Label.AlignHCenter

            transform: Translate {
                x: drawer.position * content.width * 0.33
            }
        }
    }
    \endcode

    If you would like the application's contents to stay where they are when
    the drawer is opened, don't apply a translation.

    Drawer can be configured as a non-closable persistent side panel by
    making the Drawer \l {Popup::modal}{non-modal} and \l {interactive}
    {non-interactive}. See the \l {Qt Quick Controls 2 - Side Panel}{Side Panel}
    example for more details.

    \note On some platforms, certain edges may be reserved for system
    gestures and therefore cannot be used with Drawer. For example, the
    top and bottom edges may be reserved for system notifications and
    control centers on Android and iOS.

    \sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Popup Controls}
*/

class QQuickDrawerPositioner : public QQuickPopupPositioner
{
public:
    QQuickDrawerPositioner(QQuickDrawer *drawer) : QQuickPopupPositioner(drawer) { }

    void reposition() override;
};

qreal QQuickDrawerPrivate::offsetAt(const QPointF &point) const
{
    qreal offset = positionAt(point) - position;

    // don't jump when dragged open
    if (offset > 0 && position > 0 && !contains(point))
        offset = 0;

    return offset;
}

qreal QQuickDrawerPrivate::positionAt(const QPointF &point) const
{
    Q_Q(const QQuickDrawer);
    QQuickWindow *window = q->window();
    if (!window)
        return 0;

    switch (edge) {
    case Qt::TopEdge:
        return point.y() / q->height();
    case Qt::LeftEdge:
        return point.x() / q->width();
    case Qt::RightEdge:
        return (window->width() - point.x()) / q->width();
    case Qt::BottomEdge:
        return (window->height() - point.y()) / q->height();
    default:
        return 0;
    }
}

QQuickPopupPositioner *QQuickDrawerPrivate::getPositioner()
{
    Q_Q(QQuickDrawer);
    if (!positioner)
        positioner = new QQuickDrawerPositioner(q);
    return positioner;
}

void QQuickDrawerPositioner::reposition()
{
    if (m_positioning)
        return;

    QQuickDrawer *drawer = static_cast<QQuickDrawer*>(popup());
    QQuickWindow *window = drawer->window();
    if (!window)
        return;

    const qreal position = drawer->position();
    QQuickItem *popupItem = drawer->popupItem();
    switch (drawer->edge()) {
    case Qt::LeftEdge:
        popupItem->setX((position - 1.0) * popupItem->width());
        break;
    case Qt::RightEdge:
        popupItem->setX(window->width() - position * popupItem->width());
        break;
    case Qt::TopEdge:
        popupItem->setY((position - 1.0) * popupItem->height());
        break;
    case Qt::BottomEdge:
        popupItem->setY(window->height() - position * popupItem->height());
        break;
    }

    QQuickPopupPositioner::reposition();
}

void QQuickDrawerPrivate::showOverlay()
{
    // managed in setPosition()
}

void QQuickDrawerPrivate::hideOverlay()
{
    // managed in setPosition()
}

void QQuickDrawerPrivate::resizeOverlay()
{
    if (!dimmer || !window)
        return;

    QRectF geometry(0, 0, window->width(), window->height());

    if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
        geometry.setY(popupItem->y());
        geometry.setHeight(popupItem->height());
    } else {
        geometry.setX(popupItem->x());
        geometry.setWidth(popupItem->width());
    }

    dimmer->setPosition(geometry.topLeft());
    dimmer->setSize(geometry.size());
}

static bool isWithinDragMargin(const QQuickDrawer *drawer, const QPointF &pos)
{
    switch (drawer->edge()) {
    case Qt::LeftEdge:
        return pos.x() <= drawer->dragMargin();
    case Qt::RightEdge:
        return pos.x() >= drawer->window()->width() - drawer->dragMargin();
    case Qt::TopEdge:
        return pos.y() <= drawer->dragMargin();
    case Qt::BottomEdge:
        return pos.y() >= drawer->window()->height() - drawer->dragMargin();
    default:
        Q_UNREACHABLE();
        break;
    }
    return false;
}

bool QQuickDrawerPrivate::startDrag(QEvent *event)
{
    Q_Q(QQuickDrawer);
    if (!window || !interactive || dragMargin < 0.0 || qFuzzyIsNull(dragMargin))
        return false;

    switch (event->type()) {
    case QEvent::MouseButtonPress:
        if (isWithinDragMargin(q, static_cast<QMouseEvent *>(event)->windowPos())) {
            prepareEnterTransition();
            reposition();
            return handleMouseEvent(window->contentItem(), static_cast<QMouseEvent *>(event));
        }
        break;

#if QT_CONFIG(quicktemplates2_multitouch)
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
        for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->touchPoints()) {
            if (point.state() == Qt::TouchPointPressed && isWithinDragMargin(q, point.scenePos())) {
                prepareEnterTransition();
                reposition();
                return handleTouchEvent(window->contentItem(), static_cast<QTouchEvent *>(event));
            }
        }
        break;
#endif

    default:
        break;
    }

    return false;
}

static inline bool keepGrab(QQuickItem *item)
{
    return item->keepMouseGrab() || item->keepTouchGrab();
}

bool QQuickDrawerPrivate::grabMouse(QQuickItem *item, QMouseEvent *event)
{
    Q_Q(QQuickDrawer);
    handleMouseEvent(item, event);

    if (!window || !interactive || keepGrab(popupItem) || keepGrab(item))
        return false;

    const QPointF movePoint = event->windowPos();

    // Flickable uses a hard-coded threshold of 15 for flicking, and
    // QStyleHints::startDragDistance for dragging. Drawer uses a bit
    // larger threshold to avoid being too eager to steal touch (QTBUG-50045)
    const int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5);
    bool overThreshold = false;
    if (position > 0 || dragMargin > 0) {
        const bool xOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event, threshold);
        const bool yOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event, threshold);
        if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
            overThreshold = xOverThreshold && !yOverThreshold;
        else
            overThreshold = yOverThreshold && !xOverThreshold;
    }

    // Don't be too eager to steal presses outside the drawer (QTBUG-53929)
    if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !contains(movePoint)) {
        if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
            overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin;
        else
            overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin;
    }

    if (overThreshold) {
        popupItem->grabMouse();
        popupItem->setKeepMouseGrab(true);
        offset = offsetAt(movePoint);
    }

    return overThreshold;
}

#if QT_CONFIG(quicktemplates2_multitouch)
bool QQuickDrawerPrivate::grabTouch(QQuickItem *item, QTouchEvent *event)
{
    Q_Q(QQuickDrawer);
    bool handled = handleTouchEvent(item, event);

    if (!window || !interactive || keepGrab(popupItem) || keepGrab(item) || !event->touchPointStates().testFlag(Qt::TouchPointMoved))
        return handled;

    bool overThreshold = false;
    for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
        if (!acceptTouch(point) || point.state() != Qt::TouchPointMoved)
            continue;

        const QPointF movePoint = point.scenePos();

        // Flickable uses a hard-coded threshold of 15 for flicking, and
        // QStyleHints::startDragDistance for dragging. Drawer uses a bit
        // larger threshold to avoid being too eager to steal touch (QTBUG-50045)
        const int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5);
        if (position > 0 || dragMargin > 0) {
            const bool xOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, &point, threshold);
            const bool yOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, &point, threshold);
            if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
                overThreshold = xOverThreshold && !yOverThreshold;
            else
                overThreshold = yOverThreshold && !xOverThreshold;
        }

        // Don't be too eager to steal presses outside the drawer (QTBUG-53929)
        if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !contains(movePoint)) {
            if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
                overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin;
            else
                overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin;
        }

        if (overThreshold) {
            popupItem->grabTouchPoints(QVector<int>() << touchId);
            popupItem->setKeepTouchGrab(true);
            offset = offsetAt(movePoint);
        }
    }

    return overThreshold;
}
#endif

static const qreal openCloseVelocityThreshold = 300;

bool QQuickDrawerPrivate::blockInput(QQuickItem *item, const QPointF &point) const
{
    Q_Q(const QQuickDrawer);

    // We want all events, if mouse/touch is already grabbed.
    if (popupItem->keepMouseGrab() || popupItem->keepTouchGrab())
        return true;

    // Don't block input to drawer's children/content.
    if (popupItem->isAncestorOf(item))
        return false;

    // Don't block outside a drawer's background dimming
    if (dimmer && !dimmer->contains(dimmer->mapFromScene(point)))
        return false;

    // Accept all events within drag area.
    if (isWithinDragMargin(q, point))
        return true;

    // Accept all other events if drawer is modal.
    return modal;
}

bool QQuickDrawerPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp)
{
    offset = 0;
    velocityCalculator.startMeasuring(point, timestamp);

    if (!QQuickPopupPrivate::handlePress(item, point, timestamp))
        return false;

    return true;
}

bool QQuickDrawerPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp)
{
    Q_Q(QQuickDrawer);
    if (!QQuickPopupPrivate::handleMove(item, point, timestamp))
        return false;

    // limit/reset the offset to the edge of the drawer when pushed from the outside
    if (qFuzzyCompare(position, qreal(1.0)) && !contains(point))
        offset = 0;

    bool isGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab();
    if (isGrabbed)
        q->setPosition(positionAt(point) - offset);

    return isGrabbed;
}

bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp)
{
    if (!popupItem->keepMouseGrab() && !popupItem->keepTouchGrab()) {
        velocityCalculator.reset();
        return QQuickPopupPrivate::handleRelease(item, point, timestamp);
    }

    velocityCalculator.stopMeasuring(point, timestamp);

    qreal velocity = 0;
    if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
        velocity = velocityCalculator.velocity().x();
    else
        velocity = velocityCalculator.velocity().y();

    // the velocity is calculated so that swipes from left to right
    // and top to bottom have positive velocity, and swipes from right
    // to left and bottom to top have negative velocity.
    //
    // - top/left edge: positive velocity opens, negative velocity closes
    // - bottom/right edge: negative velocity opens, positive velocity closes
    //
    // => invert the velocity for bottom and right edges, for the threshold comparison below
    if (edge == Qt::RightEdge || edge == Qt::BottomEdge)
        velocity = -velocity;

    if (position > 0.7 || velocity > openCloseVelocityThreshold) {
        transitionManager.transitionEnter();
    } else if (position < 0.3 || velocity < -openCloseVelocityThreshold) {
        transitionManager.transitionExit();
    } else {
        switch (edge) {
        case Qt::LeftEdge:
            if (point.x() - pressPoint.x() > 0)
                transitionManager.transitionEnter();
            else
                transitionManager.transitionExit();
            break;
        case Qt::RightEdge:
            if (point.x() - pressPoint.x() < 0)
                transitionManager.transitionEnter();
            else
                transitionManager.transitionExit();
            break;
        case Qt::TopEdge:
            if (point.y() - pressPoint.y() > 0)
                transitionManager.transitionEnter();
            else
                transitionManager.transitionExit();
            break;
        case Qt::BottomEdge:
            if (point.y() - pressPoint.y() < 0)
                transitionManager.transitionEnter();
            else
                transitionManager.transitionExit();
            break;
        }
    }

    bool wasGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab();
    popupItem->setKeepMouseGrab(false);
    popupItem->setKeepTouchGrab(false);

    pressPoint = QPointF();
    touchId = -1;

    return wasGrabbed;
}

void QQuickDrawerPrivate::handleUngrab()
{
    QQuickPopupPrivate::handleUngrab();

    velocityCalculator.reset();
}

static QList<QQuickStateAction> prepareTransition(QQuickDrawer *drawer, QQuickTransition *transition, qreal to)
{
    QList<QQuickStateAction> actions;
    if (!transition || !QQuickPopupPrivate::get(drawer)->window || !transition->enabled())
        return actions;

    qmlExecuteDeferred(transition);

    QQmlProperty defaultTarget(drawer, QLatin1String("position"));
    QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations();
    int count = animations.count(&animations);
    for (int i = 0; i < count; ++i) {
        QQuickAbstractAnimation *anim = animations.at(&animations, i);
        anim->setDefaultTarget(defaultTarget);
    }

    actions << QQuickStateAction(drawer, QLatin1String("position"), to);
    return actions;
}

bool QQuickDrawerPrivate::prepareEnterTransition()
{
    Q_Q(QQuickDrawer);
    enterActions = prepareTransition(q, enter, 1.0);
    return QQuickPopupPrivate::prepareEnterTransition();
}

bool QQuickDrawerPrivate::prepareExitTransition()
{
    Q_Q(QQuickDrawer);
    exitActions = prepareTransition(q, exit, 0.0);
    return QQuickPopupPrivate::prepareExitTransition();
}

bool QQuickDrawerPrivate::setEdge(Qt::Edge e)
{
    Q_Q(QQuickDrawer);
    switch (e) {
    case Qt::LeftEdge:
    case Qt::RightEdge:
        allowVerticalMove = true;
        allowVerticalResize = true;
        allowHorizontalMove = false;
        allowHorizontalResize = false;
        break;
    case Qt::TopEdge:
    case Qt::BottomEdge:
        allowVerticalMove = false;
        allowVerticalResize = false;
        allowHorizontalMove = true;
        allowHorizontalResize = true;
        break;
    default:
        qmlWarning(q) << "invalid edge value - valid values are: "
            << "Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge";
        return false;
    }

    edge = e;
    return true;
}

QQuickDrawer::QQuickDrawer(QObject *parent)
    : QQuickPopup(*(new QQuickDrawerPrivate), parent)
{
    Q_D(QQuickDrawer);
    d->dragMargin = QGuiApplication::styleHints()->startDragDistance();
    d->setEdge(Qt::LeftEdge);

    setFocus(true);
    setModal(true);
    setFiltersChildMouseEvents(true);
    setClosePolicy(CloseOnEscape | CloseOnReleaseOutside);
}

/*!
    \qmlproperty enumeration QtQuick.Controls::Drawer::edge

    This property holds the edge of the window at which the drawer will
    open from. The acceptable values are:

    \value Qt.TopEdge     The top edge of the window.
    \value Qt.LeftEdge    The left edge of the window (default).
    \value Qt.RightEdge   The right edge of the window.
    \value Qt.BottomEdge  The bottom edge of the window.
*/
Qt::Edge QQuickDrawer::edge() const
{
    Q_D(const QQuickDrawer);
    return d->edge;
}

void QQuickDrawer::setEdge(Qt::Edge edge)
{
    Q_D(QQuickDrawer);
    if (d->edge == edge)
        return;

    if (!d->setEdge(edge))
        return;

    if (isComponentComplete())
        d->reposition();
    emit edgeChanged();
}

/*!
    \qmlproperty real QtQuick.Controls::Drawer::position

    This property holds the position of the drawer relative to its final
    destination. That is, the position will be \c 0.0 when the drawer
    is fully closed, and \c 1.0 when fully open.
*/
qreal QQuickDrawer::position() const
{
    Q_D(const QQuickDrawer);
    return d->position;
}

void QQuickDrawer::setPosition(qreal position)
{
    Q_D(QQuickDrawer);
    position = qBound<qreal>(0.0, position, 1.0);
    if (qFuzzyCompare(d->position, position))
        return;

    d->position = position;
    if (isComponentComplete())
        d->reposition();
    if (d->dimmer)
        d->dimmer->setOpacity(position);
    emit positionChanged();
}

/*!
    \qmlproperty real QtQuick.Controls::Drawer::dragMargin

    This property holds the distance from the screen edge within which
    drag actions will open the drawer. Setting the value to \c 0 or less
    prevents opening the drawer by dragging.

    The default value is \c Qt.styleHints.startDragDistance.

    \sa interactive
*/
qreal QQuickDrawer::dragMargin() const
{
    Q_D(const QQuickDrawer);
    return d->dragMargin;
}

void QQuickDrawer::setDragMargin(qreal margin)
{
    Q_D(QQuickDrawer);
    if (qFuzzyCompare(d->dragMargin, margin))
        return;

    d->dragMargin = margin;
    emit dragMarginChanged();
}

void QQuickDrawer::resetDragMargin()
{
    setDragMargin(QGuiApplication::styleHints()->startDragDistance());
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::Drawer::interactive

    This property holds whether the drawer is interactive. A non-interactive
    drawer does not react to swipes.

    The default value is \c true.

    \sa dragMargin
*/
bool QQuickDrawer::isInteractive() const
{
    Q_D(const QQuickDrawer);
    return d->interactive;
}

void QQuickDrawer::setInteractive(bool interactive)
{
    Q_D(QQuickDrawer);
    if (d->interactive == interactive)
        return;

    setFiltersChildMouseEvents(interactive);
    d->interactive = interactive;
    emit interactiveChanged();
}

bool QQuickDrawer::childMouseEventFilter(QQuickItem *child, QEvent *event)
{
    Q_D(QQuickDrawer);
    switch (event->type()) {
#if QT_CONFIG(quicktemplates2_multitouch)
    case QEvent::TouchUpdate:
        return d->grabTouch(child, static_cast<QTouchEvent *>(event));
#endif
    case QEvent::MouseMove:
        return d->grabMouse(child, static_cast<QMouseEvent *>(event));
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
        return d->handleMouseEvent(child, static_cast<QMouseEvent *>(event));
    default:
        break;
    }
    return false;
}

void QQuickDrawer::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QQuickDrawer);
    d->grabMouse(d->popupItem, event);
}

bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event)
{
    Q_D(QQuickDrawer);
    switch (event->type()) {
#if QT_CONFIG(quicktemplates2_multitouch)
    case QEvent::TouchUpdate:
        return d->grabTouch(item, static_cast<QTouchEvent *>(event));
#endif
    case QEvent::MouseMove:
        return d->grabMouse(item, static_cast<QMouseEvent *>(event));
    default:
        break;
    }
    return QQuickPopup::overlayEvent(item, event);
}

#if QT_CONFIG(quicktemplates2_multitouch)
void QQuickDrawer::touchEvent(QTouchEvent *event)
{
    Q_D(QQuickDrawer);
    d->grabTouch(d->popupItem, event);
}
#endif

void QQuickDrawer::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    Q_D(QQuickDrawer);
    QQuickPopup::geometryChanged(newGeometry, oldGeometry);
    d->resizeOverlay();
}

QT_END_NAMESPACE
