diff options
Diffstat (limited to 'src/declarative/items/qsgdragtarget.cpp')
-rw-r--r-- | src/declarative/items/qsgdragtarget.cpp | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/src/declarative/items/qsgdragtarget.cpp b/src/declarative/items/qsgdragtarget.cpp new file mode 100644 index 0000000000..c1ed167ee6 --- /dev/null +++ b/src/declarative/items/qsgdragtarget.cpp @@ -0,0 +1,361 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgdragtarget_p.h" +#include "qsgitem_p.h" +#include "qsgcanvas.h" + +/*! + \qmlclass DragEvent QSGDragEvent + \brief The DragEvent object provides information about a drag event. + + The position of the drag event can be obtained from the \l x and \l + properties, the \l keys property identifies the drag keys of the event + source and the \l data property contains the payload of the drag event. +*/ + +/*! + \qmlproperty real DragEvent::x + + This property holds the x coordinate of a drag event. +*/ + +/*! + \qmlproperty real DragEvent::y + + This property holds the y coordinate of a drag event. +*/ + +/*! + \qmlproperty stringlist DragEvent::keys + + This property holds a list of keys identifying the data type or source of a + drag event. +*/ + +/*! + \qmlproperty variant DragEvent::data + + This property holds data payload of a drag event. +*/ + +/*! + \qmlproperty real DragEvent::accepted + + This property holds whether the drag event was accepted by a handler. + + The default value is true. +*/ + +class QSGDragTargetPrivate : public QSGItemPrivate +{ + Q_DECLARE_PUBLIC(QSGDragTarget) + +public: + QSGDragTargetPrivate(); + ~QSGDragTargetPrivate(); + + bool hasMatchingKey(const QStringList &keys) const; + + QStringList keys; + QRegExp keyRegExp; + QVariant dragData; + QPointF dragPosition; + QSGItem *dropItem; + bool containsDrag : 1; +}; + +QSGDragTargetPrivate::QSGDragTargetPrivate() + : dropItem(0) + , containsDrag(false) +{ +} + +QSGDragTargetPrivate::~QSGDragTargetPrivate() +{ +} + +/*! + \qmlclass DragTarget QSGDragTarget + \brief The DragTarget item provides drag and drop handling. + + A DragTarget is an invisible item which receives events when another item + is dragged over it. + + A MouseArea item can be used to drag items. + + The \l keys property can be used to filter drag events which don't include + a matching key. + + The \l dropItem property is communicated to the source of a drag event as + the recipient of a drop on the drag target. + + The \l delegate property provides a means to specify a component to be + instantiated for each active drag over a drag target. +*/ + +QSGDragTarget::QSGDragTarget(QSGItem *parent) + : QSGItem(*new QSGDragTargetPrivate, parent) +{ +} + +QSGDragTarget::~QSGDragTarget() +{ +} + +/*! + \qmlproperty bool DragTarget::containsDrag + + This property identifies whether the DragTarget currently contains any + dragged items. +*/ + +bool QSGDragTarget::containsDrag() const +{ + Q_D(const QSGDragTarget); + return d->containsDrag; +} + +/*! + \qmlproperty stringlist DragTarget::keys + + This property holds a list of drag keys a DragTarget will accept. +*/ + +QStringList QSGDragTarget::keys() const +{ + Q_D(const QSGDragTarget); + return d->keys; +} + +void QSGDragTarget::setKeys(const QStringList &keys) +{ + Q_D(QSGDragTarget); + if (d->keys != keys) { + d->keys = keys; + + if (keys.isEmpty()) { + d->keyRegExp = QRegExp(); + } else { + QString pattern = QLatin1Char('(') + QRegExp::escape(keys.first()); + for (int i = 1; i < keys.count(); ++i) + pattern += QLatin1Char('|') + QRegExp::escape(keys.at(i)); + pattern += QLatin1Char(')'); + d->keyRegExp = QRegExp(pattern.replace(QLatin1String("\\*"), QLatin1String(".+"))); + } + emit keysChanged(); + } +} + +/*! + \qmlproperty Item DragTarget::dropItem + + This property identifies an item as the recipient of a drop event within + a DragTarget. + + \sa MouseArea::drag.dropItem +*/ + +QSGItem *QSGDragTarget::dropItem() const +{ + Q_D(const QSGDragTarget); + return d->dropItem; +} + +void QSGDragTarget::setDropItem(QSGItem *item) +{ + Q_D(QSGDragTarget); + if (d->dropItem != item) { + d->dropItem = item; + emit dropItemChanged(); + } +} + +void QSGDragTarget::resetDropItem() +{ + Q_D(QSGDragTarget); + if (d->dropItem) { + d->dropItem = 0; + emit dropItemChanged(); + } +} + +qreal QSGDragTarget::dragX() const +{ + Q_D(const QSGDragTarget); + return d->dragPosition.x(); +} + +qreal QSGDragTarget::dragY() const +{ + Q_D(const QSGDragTarget); + return d->dragPosition.y(); +} + +QVariant QSGDragTarget::dragData() const +{ + Q_D(const QSGDragTarget); + return d->dragData; +} + +/*! + \qmlsignal DragTarget::onPositionChanged(DragEvent drag) + \qmlattachedsignal DragTarget::onPositionChanged(DragEvent drag) + + This handler is called when the position of a drag has changed. +*/ + +void QSGDragTarget::dragMoveEvent(QSGDragEvent *event) +{ + Q_D(QSGDragTarget); + if (!d->containsDrag) { + event->setAccepted(false); + return; + } + + event->setDropItem(d->dropItem); + + d->dragPosition = event->position(); + emit dragPositionChanged(); + + QSGDragTargetEvent dragTargetEvent(event); + emit positionChanged(&dragTargetEvent); +} + +bool QSGDragTargetPrivate::hasMatchingKey(const QStringList &keys) const +{ + if (keyRegExp.isEmpty()) + return true; + + foreach (const QString &key, keys) { + if (keyRegExp.exactMatch(key)) + return true; + } + return false; +} + +/*! + \qmlsignal DragTarget::onEntered(DragEvent drag) + \qmlattachedsignal DragTarget::onEntered(DragEvent drag) + + This handler is called when a drag enters the bounds of a DragTarget. +*/ + +void QSGDragTarget::dragEnterEvent(QSGDragEvent *event) +{ + Q_D(QSGDragTarget); + if (!d->effectiveEnable || !d->hasMatchingKey(event->keys()) || d->containsDrag) { + event->setAccepted(false); + return; + } + + event->setDropItem(d->dropItem); + + QSGDragTargetEvent dragTargetEvent(event); + emit entered(&dragTargetEvent); + + if (event->isAccepted()) { + + d->dragData = event->data(); + d->containsDrag = true; + if (!d->dragData.isNull()) + emit dragDataChanged(); + emit containsDragChanged(); + } +} + +/*! + \qmlsignal DragTarget::onExited(DragEvent drag) + \qmlattachedsignal DragTarget::onExited(DragEvent drag) + + This handler is called when a drag exits the bounds of a DragTarget. +*/ + +void QSGDragTarget::dragExitEvent(QSGDragEvent *event) +{ + Q_D(QSGDragTarget); + if (!d->containsDrag) { + event->setAccepted(false); + return; + } + + QSGDragTargetEvent dragTargetEvent(event); + emit exited(&dragTargetEvent); + + d->containsDrag = false; + emit containsDragChanged(); + if (!d->dragData.isNull()) { + d->dragData = QVariant(); + emit dragDataChanged(); + } +} + +/*! + \qmlsignal DragTarget::onDropped(DragEvent drag) + \qmlattachedsignal DragTarget::onDropped(DragEvent drag) + + This handler is called when a drop event occurs within the bounds of a + a DragTarget. +*/ + +void QSGDragTarget::dragDropEvent(QSGDragEvent *event) +{ + Q_D(QSGDragTarget); + if (!d->containsDrag) { + event->setAccepted(false); + return; + } + + event->setDropItem(d->dropItem); + + QSGDragTargetEvent dragTargetEvent(event); + emit dropped(&dragTargetEvent); + + d->containsDrag = false; + emit containsDragChanged(); + if (!d->dragData.isNull()) { + d->dragData = QVariant(); + emit dragDataChanged(); + } +} + +QT_END_NAMESPACE + |