aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qsgmousearea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qsgmousearea.cpp')
-rw-r--r--src/declarative/items/qsgmousearea.cpp153
1 files changed, 142 insertions, 11 deletions
diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp
index 62b149567a..6886ccca35 100644
--- a/src/declarative/items/qsgmousearea.cpp
+++ b/src/declarative/items/qsgmousearea.cpp
@@ -42,6 +42,7 @@
#include "qsgmousearea_p.h"
#include "qsgmousearea_p_p.h"
#include "qsgcanvas.h"
+#include "qsgevent.h"
#include "qsgevents_p_p.h"
#include <QtGui/qgraphicssceneevent.h>
@@ -53,8 +54,8 @@ QT_BEGIN_NAMESPACE
static const int PressAndHoldDelay = 800;
QSGDrag::QSGDrag(QObject *parent)
-: QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX), _xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX),
-_active(false), _filterChildren(false)
+: QObject(parent), _target(0), _dropItem(0), _grabItem(0), _axis(XandYAxis), _xmin(-FLT_MAX),
+_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
{
}
@@ -77,12 +78,70 @@ void QSGDrag::setTarget(QSGItem *t)
void QSGDrag::resetTarget()
{
- if (!_target)
+ if (_target == 0)
return;
_target = 0;
emit targetChanged();
}
+/*!
+ \qmlproperty Item MouseArea::drag.dropItem
+
+ This property holds the item an active drag will be dropped on if released
+ at the current position.
+*/
+
+QSGItem *QSGDrag::dropItem() const
+{
+ return _dropItem;
+}
+
+void QSGDrag::setDropItem(QSGItem *item)
+{
+ if (_dropItem != item) {
+ _dropItem = item;
+ emit dropItemChanged();
+ }
+}
+
+QSGItem *QSGDrag::grabItem() const
+{
+ return _grabItem;
+}
+
+void QSGDrag::setGrabItem(QSGItem *item)
+{
+ _grabItem = item;
+}
+
+/*!
+ \qmlproperty variant MouseArea::drag.data
+
+ This property holds the data sent to recipients of drag events generated
+ by a MouseArea.
+*/
+
+QVariant QSGDrag::data() const
+{
+ return _data;
+}
+
+void QSGDrag::setData(const QVariant &data)
+{
+ if (_data != data) {
+ _data = data;
+ emit dataChanged();
+ }
+}
+
+void QSGDrag::resetData()
+{
+ if (!_data.isNull()) {
+ _data = QVariant();
+ emit dataChanged();
+ }
+}
+
QSGDrag::Axis QSGDrag::axis() const
{
return _axis;
@@ -174,9 +233,30 @@ void QSGDrag::setFilterChildren(bool filter)
emit filterChildrenChanged();
}
+/*!
+ \qmlproperty stringlist MouseArea::drag.keys
+
+ This property holds a list of keys drag recipients can use to identify the
+ source or data type of a drag event.
+*/
+
+QStringList QSGDrag::keys() const
+{
+ return _keys;
+}
+
+void QSGDrag::setKeys(const QStringList &keys)
+{
+ if (_keys != keys) {
+ _keys = keys;
+ emit keysChanged();
+ }
+}
+
QSGMouseAreaPrivate::QSGMouseAreaPrivate()
: absorb(true), hovered(false), pressed(false), longPress(false),
- moved(false), stealMouse(false), doubleClick(false), preventStealing(false), drag(0)
+ moved(false), stealMouse(false), doubleClick(false), preventStealing(false), dragRejected(false),
+ drag(0)
{
Q_Q(QSGMouseArea);
forwardTo = QDeclarativeListProperty<QSGItem>(q, forwardToList);
@@ -383,6 +463,7 @@ void QSGMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
QSGItem::mousePressEvent(event);
else {
d->longPress = false;
+ d->dragRejected = false;
d->saveEvent(event);
if (d->drag) {
d->dragX = drag()->axis() & QSGDrag::XAxis;
@@ -420,9 +501,11 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
setHovered(true);
if (d->drag && d->drag->target()) {
+
if (!d->moved) {
- d->startX = drag()->target()->x();
- d->startY = drag()->target()->y();
+ d->targetStartPos = d->drag->target()->parentItem()
+ ? d->drag->target()->parentItem()->mapToScene(d->drag->target()->pos())
+ : d->drag->target()->pos();
}
QPointF startLocalPos;
@@ -439,11 +522,31 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
- if (keepMouseGrab() && d->stealMouse)
- d->drag->setActive(true);
+ if (keepMouseGrab() && d->stealMouse && !d->dragRejected && !d->drag->active()) {
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+ d->drag->emitDragged(&me);
+ if (me.isAccepted()) {
+ d->drag->setActive(true);
+ QSGDragEvent dragEvent(
+ QSGEvent::SGDragEnter,
+ d->startScene,
+ d->drag->data(),
+ d->drag->keys());
+ QCoreApplication::sendEvent(canvas(), &dragEvent);
+
+ d->drag->setGrabItem(dragEvent.grabItem());
+ d->drag->setDropItem(dragEvent.dropItem());
+ } else {
+ d->dragRejected = true;
+ }
+ }
+
+ QPointF startPos = d->drag->target()->parentItem()
+ ? d->drag->target()->parentItem()->mapFromScene(d->targetStartPos)
+ : d->targetStartPos;
if (d->dragX && d->drag->active()) {
- qreal x = (curLocalPos.x() - startLocalPos.x()) + d->startX;
+ qreal x = (curLocalPos.x() - startLocalPos.x()) + startPos.x();
if (x < drag()->xmin())
x = drag()->xmin();
else if (x > drag()->xmax())
@@ -451,7 +554,7 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
drag()->target()->setX(x);
}
if (d->dragY && d->drag->active()) {
- qreal y = (curLocalPos.y() - startLocalPos.y()) + d->startY;
+ qreal y = (curLocalPos.y() - startLocalPos.y()) + startPos.y();
if (y < drag()->ymin())
y = drag()->ymin();
else if (y > drag()->ymax())
@@ -469,6 +572,18 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
d->moved = true;
+
+ if (d->drag->active()) {
+ QSGDragEvent dragEvent(
+ QSGEvent::SGDragMove,
+ event->scenePos(),
+ d->drag->data(),
+ d->drag->keys(),
+ d->drag->grabItem());
+ QCoreApplication::sendEvent(canvas(), &dragEvent);
+ d->drag->setGrabItem(dragEvent.grabItem());
+ d->drag->setDropItem(dragEvent.dropItem());
+ }
}
QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
emit mousePositionChanged(&me);
@@ -489,8 +604,24 @@ void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
} else {
d->saveEvent(event);
setPressed(false);
- if (d->drag)
+ if (d->drag && d->drag->active()) {
+ QSGDragEvent dragEvent(
+ QSGEvent::SGDragDrop,
+ event->scenePos(),
+ d->drag->data(),
+ d->drag->keys(),
+ d->drag->grabItem());
+ QCoreApplication::sendEvent(canvas(), &dragEvent);
+ d->drag->setGrabItem(0);
+ if (dragEvent.isAccepted()) {
+ d->drag->setDropItem(dragEvent.dropItem());
+ d->drag->emitDropped(dragEvent.dropItem());
+ } else {
+ d->drag->emitCanceled();
+ }
+ d->drag->setDropItem(0);
d->drag->setActive(false);
+ }
// If we don't accept hover, we need to reset containsMouse.
if (!acceptHoverEvents())
setHovered(false);