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.cpp800
1 files changed, 800 insertions, 0 deletions
diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp
new file mode 100644
index 0000000000..887d78a64d
--- /dev/null
+++ b/src/declarative/items/qsgmousearea.cpp
@@ -0,0 +1,800 @@
+// Commit: e1ffbc04131dc6f76fa76821c297d08162e4b1ee
+/****************************************************************************
+**
+** 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 "qsgmousearea_p.h"
+#include "qsgmousearea_p_p.h"
+#include "qsgcanvas.h"
+#include "qsgevents_p_p.h"
+
+#include <QtGui/qgraphicssceneevent.h>
+#include <QtGui/qapplication.h>
+
+#include <float.h>
+
+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)
+{
+}
+
+QSGDrag::~QSGDrag()
+{
+}
+
+QSGItem *QSGDrag::target() const
+{
+ return _target;
+}
+
+void QSGDrag::setTarget(QSGItem *t)
+{
+ if (_target == t)
+ return;
+ _target = t;
+ emit targetChanged();
+}
+
+void QSGDrag::resetTarget()
+{
+ if (!_target)
+ return;
+ _target = 0;
+ emit targetChanged();
+}
+
+QSGDrag::Axis QSGDrag::axis() const
+{
+ return _axis;
+}
+
+void QSGDrag::setAxis(QSGDrag::Axis a)
+{
+ if (_axis == a)
+ return;
+ _axis = a;
+ emit axisChanged();
+}
+
+qreal QSGDrag::xmin() const
+{
+ return _xmin;
+}
+
+void QSGDrag::setXmin(qreal m)
+{
+ if (_xmin == m)
+ return;
+ _xmin = m;
+ emit minimumXChanged();
+}
+
+qreal QSGDrag::xmax() const
+{
+ return _xmax;
+}
+
+void QSGDrag::setXmax(qreal m)
+{
+ if (_xmax == m)
+ return;
+ _xmax = m;
+ emit maximumXChanged();
+}
+
+qreal QSGDrag::ymin() const
+{
+ return _ymin;
+}
+
+void QSGDrag::setYmin(qreal m)
+{
+ if (_ymin == m)
+ return;
+ _ymin = m;
+ emit minimumYChanged();
+}
+
+qreal QSGDrag::ymax() const
+{
+ return _ymax;
+}
+
+void QSGDrag::setYmax(qreal m)
+{
+ if (_ymax == m)
+ return;
+ _ymax = m;
+ emit maximumYChanged();
+}
+
+bool QSGDrag::active() const
+{
+ return _active;
+}
+
+void QSGDrag::setActive(bool drag)
+{
+ if (_active == drag)
+ return;
+ _active = drag;
+ emit activeChanged();
+}
+
+bool QSGDrag::filterChildren() const
+{
+ return _filterChildren;
+}
+
+void QSGDrag::setFilterChildren(bool filter)
+{
+ if (_filterChildren == filter)
+ return;
+ _filterChildren = filter;
+ emit filterChildrenChanged();
+}
+
+QSGMouseAreaPrivate::QSGMouseAreaPrivate()
+: absorb(true), hovered(false), pressed(false), longPress(false),
+ moved(false), stealMouse(false), doubleClick(false), preventStealing(false), drag(0)
+{
+ Q_Q(QSGMouseArea);
+ forwardTo = QDeclarativeListProperty<QSGItem>(q, forwardToList);
+}
+
+QSGMouseAreaPrivate::~QSGMouseAreaPrivate()
+{
+ delete drag;
+}
+
+void QSGMouseAreaPrivate::init()
+{
+ Q_Q(QSGMouseArea);
+ q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setFiltersChildMouseEvents(true);
+}
+
+void QSGMouseAreaPrivate::saveEvent(QGraphicsSceneMouseEvent *event)
+{
+ lastPos = event->pos();
+ lastScenePos = event->scenePos();
+ lastButton = event->button();
+ lastButtons = event->buttons();
+ lastModifiers = event->modifiers();
+}
+
+void QSGMouseAreaPrivate::forwardEvent(QGraphicsSceneMouseEvent* event)
+{
+ Q_Q(QSGMouseArea);
+ for(int i=0; i < forwardToList.count(); i++){
+ event->setPos(forwardToList[i]->mapFromScene(event->scenePos()));
+ forwardToList[i]->canvas()->sendEvent(forwardToList[i], event);
+ if(event->isAccepted())
+ break;
+ }
+ event->setPos(q->mapFromScene(event->scenePos()));
+}
+
+bool QSGMouseAreaPrivate::isPressAndHoldConnected()
+{
+ Q_Q(QSGMouseArea);
+ static int idx = QObjectPrivate::get(q)->signalIndex("pressAndHold(QSGMouseEvent*)");
+ return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+bool QSGMouseAreaPrivate::isDoubleClickConnected()
+{
+ Q_Q(QSGMouseArea);
+ static int idx = QObjectPrivate::get(q)->signalIndex("doubleClicked(QSGMouseEvent*)");
+ return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+bool QSGMouseAreaPrivate::isClickConnected()
+{
+ Q_Q(QSGMouseArea);
+ static int idx = QObjectPrivate::get(q)->signalIndex("clicked(QSGMouseEvent*)");
+ return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+void QSGMouseAreaPrivate::propagate(QSGMouseEvent* event, PropagateType t)
+{
+ Q_Q(QSGMouseArea);
+ QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y()));
+ propagateHelper(event, canvas->rootItem(), scenePos, t);
+}
+
+bool QSGMouseAreaPrivate::propagateHelper(QSGMouseEvent *ev, QSGItem *item,const QPointF &sp, PropagateType sig)
+{
+ //Based off of QSGCanvas::deliverInitialMousePressEvent
+ //But specific to MouseArea, so doesn't belong in canvas
+ Q_Q(const QSGMouseArea);
+ QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
+ if (itemPrivate->opacity == 0.0)
+ return false;
+
+ if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
+ QPointF p = item->mapFromScene(sp);
+ if (!QRectF(0, 0, item->width(), item->height()).contains(p))
+ return false;
+ }
+
+ QList<QSGItem *> children = itemPrivate->paintOrderChildItems();
+ for (int ii = children.count() - 1; ii >= 0; --ii) {
+ QSGItem *child = children.at(ii);
+ if (!child->isVisible() || !child->isEnabled())
+ continue;
+ if (propagateHelper(ev, child, sp, sig))
+ return true;
+ }
+
+ QSGMouseArea* ma = qobject_cast<QSGMouseArea*>(item);
+ if (ma && ma != q && 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 (QRectF(0, 0, item->width(), item->height()).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;
+
+}
+
+/*
+ Behavioral Change in QtQuick 2.0
+
+ From QtQuick 2.0, the signals clicked, doubleClicked and pressAndHold have a different interaction
+ model with regards to the delivery of events to multiple overlapping MouseAreas. These signals will now propagate
+ to all MouseAreas in the area, in painting order, until accepted by one of them. A signal is accepted by
+ default if there is a signal handler for it, use mouse.accepted = false; to ignore. This propagation
+ can send the signal to MouseAreas other than the one which accepted the press event, although that MouseArea
+ will receive the signal first.
+
+ Note that to get the same behavior as a QtQuick 1.0 MouseArea{} with regard to absorbing all mouse events, you will
+ now need to add empty signal handlers for these three signals.
+ */
+QSGMouseArea::QSGMouseArea(QSGItem *parent)
+ : QSGItem(*(new QSGMouseAreaPrivate), parent)
+{
+ Q_D(QSGMouseArea);
+ d->init();
+}
+
+QSGMouseArea::~QSGMouseArea()
+{
+}
+
+qreal QSGMouseArea::mouseX() const
+{
+ Q_D(const QSGMouseArea);
+ return d->lastPos.x();
+}
+
+qreal QSGMouseArea::mouseY() const
+{
+ Q_D(const QSGMouseArea);
+ return d->lastPos.y();
+}
+
+bool QSGMouseArea::isEnabled() const
+{
+ Q_D(const QSGMouseArea);
+ return d->absorb;
+}
+
+void QSGMouseArea::setEnabled(bool a)
+{
+ Q_D(QSGMouseArea);
+ if (a != d->absorb) {
+ d->absorb = a;
+ emit enabledChanged();
+ }
+}
+
+bool QSGMouseArea::preventStealing() const
+{
+ Q_D(const QSGMouseArea);
+ return d->preventStealing;
+}
+
+void QSGMouseArea::setPreventStealing(bool prevent)
+{
+ Q_D(QSGMouseArea);
+ if (prevent != d->preventStealing) {
+ d->preventStealing = prevent;
+ setKeepMouseGrab(d->preventStealing && d->absorb);
+ emit preventStealingChanged();
+ }
+}
+
+Qt::MouseButtons QSGMouseArea::pressedButtons() const
+{
+ Q_D(const QSGMouseArea);
+ return d->lastButtons;
+}
+
+void QSGMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QSGMouseArea);
+ d->moved = false;
+ d->stealMouse = d->preventStealing;
+ if (!d->absorb)
+ QSGItem::mousePressEvent(event);
+ else {
+ d->longPress = false;
+ d->saveEvent(event);
+ if (d->drag) {
+ d->dragX = drag()->axis() & QSGDrag::XAxis;
+ d->dragY = drag()->axis() & QSGDrag::YAxis;
+ }
+ if (d->drag)
+ d->drag->setActive(false);
+ setHovered(true);
+ d->startScene = event->scenePos();
+ d->pressAndHoldTimer.start(PressAndHoldDelay, this);
+ setKeepMouseGrab(d->stealMouse);
+ event->setAccepted(setPressed(true));
+
+ if(!event->isAccepted() && d->forwardToList.count())
+ d->forwardEvent(event);
+ }
+}
+
+void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb) {
+ QSGItem::mouseMoveEvent(event);
+ return;
+ }
+
+ d->saveEvent(event);
+
+ // ### we should skip this if these signals aren't used
+ // ### can GV handle this for us?
+ bool contains = boundingRect().contains(d->lastPos);
+ if (d->hovered && !contains)
+ setHovered(false);
+ else if (!d->hovered && contains)
+ setHovered(true);
+
+ if (d->drag && d->drag->target()) {
+ if (!d->moved) {
+ d->startX = drag()->target()->x();
+ d->startY = drag()->target()->y();
+ }
+
+ QPointF startLocalPos;
+ QPointF curLocalPos;
+ if (drag()->target()->parentItem()) {
+ startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
+ curLocalPos = drag()->target()->parentItem()->mapFromScene(event->scenePos());
+ } else {
+ startLocalPos = d->startScene;
+ curLocalPos = event->scenePos();
+ }
+
+ const int dragThreshold = QApplication::startDragDistance();
+ qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
+ qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
+
+ if (keepMouseGrab() && d->stealMouse)
+ d->drag->setActive(true);
+
+ if (d->dragX && d->drag->active()) {
+ qreal x = (curLocalPos.x() - startLocalPos.x()) + d->startX;
+ if (x < drag()->xmin())
+ x = drag()->xmin();
+ else if (x > drag()->xmax())
+ x = drag()->xmax();
+ drag()->target()->setX(x);
+ }
+ if (d->dragY && d->drag->active()) {
+ qreal y = (curLocalPos.y() - startLocalPos.y()) + d->startY;
+ if (y < drag()->ymin())
+ y = drag()->ymin();
+ else if (y > drag()->ymax())
+ y = drag()->ymax();
+ drag()->target()->setY(y);
+ }
+
+ if (!keepMouseGrab()) {
+ if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
+ || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold)
+ || (d->dragX && d->dragY && (dx > dragThreshold || dy > dragThreshold))) {
+ setKeepMouseGrab(true);
+ d->stealMouse = true;
+ }
+ }
+
+ d->moved = true;
+ }
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+ emit mousePositionChanged(&me);
+ me.setX(d->lastPos.x());
+ me.setY(d->lastPos.y());
+ emit positionChanged(&me);
+
+ if(!event->isAccepted() && d->forwardToList.count())
+ d->forwardEvent(event);
+}
+
+void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QSGMouseArea);
+ d->stealMouse = false;
+ if (!d->absorb) {
+ QSGItem::mouseReleaseEvent(event);
+ } else {
+ d->saveEvent(event);
+ setPressed(false);
+ if (d->drag)
+ d->drag->setActive(false);
+ // If we don't accept hover, we need to reset containsMouse.
+ if (!acceptHoverEvents())
+ setHovered(false);
+ QSGCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+
+ if(!event->isAccepted() && d->forwardToList.count())
+ d->forwardEvent(event);
+ }
+ d->doubleClick = false;
+}
+
+void QSGMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb) {
+ QSGItem::mouseDoubleClickEvent(event);
+ } else {
+ d->saveEvent(event);
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
+ me.setAccepted(d->isDoubleClickConnected());
+ emit this->doubleClicked(&me);
+ if (!me.isAccepted())
+ d->propagate(&me, QSGMouseAreaPrivate::DoubleClick);
+ d->doubleClick = d->isDoubleClickConnected() || me.isAccepted();
+ QSGItem::mouseDoubleClickEvent(event);
+ }
+}
+
+void QSGMouseArea::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb) {
+ QSGItem::hoverEnterEvent(event);
+ } else {
+ d->lastPos = event->pos();
+ setHovered(true);
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
+ emit mousePositionChanged(&me);
+ }
+}
+
+void QSGMouseArea::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb) {
+ QSGItem::hoverMoveEvent(event);
+ } else {
+ d->lastPos = event->pos();
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
+ emit mousePositionChanged(&me);
+ me.setX(d->lastPos.x());
+ me.setY(d->lastPos.y());
+ emit positionChanged(&me);
+ }
+}
+
+void QSGMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb)
+ QSGItem::hoverLeaveEvent(event);
+ else
+ setHovered(false);
+}
+
+void QSGMouseArea::mouseUngrabEvent()
+{
+ Q_D(QSGMouseArea);
+ if (d->pressed) {
+ // if our mouse grab has been removed (probably by Flickable), fix our
+ // state
+ d->pressed = false;
+ d->stealMouse = false;
+ setKeepMouseGrab(false);
+ emit canceled();
+ emit pressedChanged();
+ if (d->hovered) {
+ d->hovered = false;
+ emit hoveredChanged();
+ }
+ }
+}
+
+bool QSGMouseArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QSGMouseArea);
+ QGraphicsSceneMouseEvent mouseEvent(event->type());
+ QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+
+ QSGCanvas *c = canvas();
+ QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
+ bool stealThisEvent = d->stealMouse;
+ if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
+ mouseEvent.setAccepted(false);
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ if (event->buttons() & i) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
+ }
+ }
+ mouseEvent.setScenePos(event->scenePos());
+ mouseEvent.setLastScenePos(event->lastScenePos());
+ mouseEvent.setPos(mapFromScene(event->scenePos()));
+ mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
+
+ switch(mouseEvent.type()) {
+ case QEvent::GraphicsSceneMouseMove:
+ mouseMoveEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMousePress:
+ mousePressEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ mouseReleaseEvent(&mouseEvent);
+ break;
+ default:
+ break;
+ }
+ grabber = c->mouseGrabberItem();
+ if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+ grabMouse();
+
+ return stealThisEvent;
+ }
+ if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
+ if (d->pressed) {
+ d->pressed = false;
+ d->stealMouse = false;
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ emit canceled();
+ emit pressedChanged();
+ if (d->hovered) {
+ d->hovered = false;
+ emit hoveredChanged();
+ }
+ }
+ }
+ return false;
+}
+
+bool QSGMouseArea::childMouseEventFilter(QSGItem *i, QEvent *e)
+{
+ Q_D(QSGMouseArea);
+ if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())
+ return QSGItem::childMouseEventFilter(i, e);
+ switch (e->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
+ default:
+ break;
+ }
+
+ return QSGItem::childMouseEventFilter(i, e);
+}
+
+void QSGMouseArea::timerEvent(QTimerEvent *event)
+{
+ Q_D(QSGMouseArea);
+ if (event->timerId() == d->pressAndHoldTimer.timerId()) {
+ d->pressAndHoldTimer.stop();
+ bool dragged = d->drag && d->drag->active();
+ if (d->pressed && dragged == false && d->hovered == true) {
+ d->longPress = true;
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+ me.setAccepted(d->isPressAndHoldConnected());
+ emit pressAndHold(&me);
+ if (!me.isAccepted())
+ d->propagate(&me, QSGMouseAreaPrivate::PressAndHold);
+ }
+ }
+}
+
+void QSGMouseArea::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ Q_D(QSGMouseArea);
+ QSGItem::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 QSGMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_D(QSGMouseArea);
+ switch (change) {
+ case ItemVisibleHasChanged:
+ if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse()))
+ setHovered(!d->hovered);
+ break;
+ default:
+ break;
+ }
+
+ QSGItem::itemChange(change, value);
+}
+
+bool QSGMouseArea::hoverEnabled() const
+{
+ return acceptHoverEvents();
+}
+
+void QSGMouseArea::setHoverEnabled(bool h)
+{
+ Q_D(QSGMouseArea);
+ if (h == acceptHoverEvents())
+ return;
+
+ setAcceptHoverEvents(h);
+ emit hoverEnabledChanged();
+ if (d->hovered != isUnderMouse())
+ setHovered(!d->hovered);
+}
+
+bool QSGMouseArea::hovered() const
+{
+ Q_D(const QSGMouseArea);
+ return d->hovered;
+}
+
+bool QSGMouseArea::pressed() const
+{
+ Q_D(const QSGMouseArea);
+ return d->pressed;
+}
+
+void QSGMouseArea::setHovered(bool h)
+{
+ Q_D(QSGMouseArea);
+ if (d->hovered != h) {
+ d->hovered = h;
+ emit hoveredChanged();
+ d->hovered ? emit entered() : emit exited();
+ }
+}
+
+Qt::MouseButtons QSGMouseArea::acceptedButtons() const
+{
+ return acceptedMouseButtons();
+}
+
+void QSGMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
+{
+ if (buttons != acceptedMouseButtons()) {
+ setAcceptedMouseButtons(buttons);
+ emit acceptedButtonsChanged();
+ }
+}
+
+bool QSGMouseArea::setPressed(bool p)
+{
+ Q_D(QSGMouseArea);
+ bool dragged = d->drag && d->drag->active();
+ bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
+
+ if (d->pressed != p) {
+ d->pressed = p;
+ QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
+ if (d->pressed) {
+ if (!d->doubleClick)
+ emit pressed(&me);
+ me.setX(d->lastPos.x());
+ me.setY(d->lastPos.y());
+ emit mousePositionChanged(&me);
+ emit pressedChanged();
+ } else {
+ emit released(&me);
+ me.setX(d->lastPos.x());
+ me.setY(d->lastPos.y());
+ emit pressedChanged();
+ if (isclick && !d->longPress && !d->doubleClick){
+ me.setAccepted(d->isClickConnected());
+ emit clicked(&me);
+ if (!me.isAccepted())
+ d->propagate(&me, QSGMouseAreaPrivate::Click);
+ }
+ }
+
+ return me.isAccepted();
+ }
+ return false;
+}
+
+QSGDrag *QSGMouseArea::drag()
+{
+ Q_D(QSGMouseArea);
+ if (!d->drag)
+ d->drag = new QSGDrag;
+ return d->drag;
+}
+
+QDeclarativeListProperty<QSGItem> QSGMouseArea::forwardTo()
+{
+ Q_D(QSGMouseArea);
+ return d->forwardTo;
+}
+
+QT_END_NAMESPACE