diff --git a/src/declarativeimports/qtextracomponents/mouseeventlistener.cpp b/src/declarativeimports/qtextracomponents/mouseeventlistener.cpp index 8f925dda8..1819e993e 100644 --- a/src/declarativeimports/qtextracomponents/mouseeventlistener.cpp +++ b/src/declarativeimports/qtextracomponents/mouseeventlistener.cpp @@ -138,7 +138,9 @@ void MouseEventListener::mousePressEvent(QMouseEvent *me) m_buttonDownPos[me->button()] = me->pos(); KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); - m_pressAndHoldEvent = new KDeclarativeMouseEvent(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + if (!m_pressAndHoldEvent) { + m_pressAndHoldEvent = new KDeclarativeMouseEvent(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + } emit pressed(&dme); m_pressed = true; @@ -187,7 +189,9 @@ void MouseEventListener::handlePressAndHold() { if (m_pressed) { emit pressAndHold(m_pressAndHoldEvent); - //delete m_pressAndHoldEvent; + + delete m_pressAndHoldEvent; + m_pressAndHoldEvent = 0; } } @@ -218,7 +222,9 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event) //the parent will receive events in its own coordinates const QPointF myPos = item->mapToItem(this, me->pos()); KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); - m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + if (!m_pressAndHoldEvent) { + m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + } //qDebug() << "pressed in sceneEventFilter"; m_buttonDownPos[me->button()] = me->pos(); emit pressed(&dme); @@ -243,7 +249,6 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event) KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers(), 0); //qDebug() << "positionChanged..." << dme.x() << dme.y(); - m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers(),0); emit positionChanged(&dme); break; } @@ -257,7 +262,13 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event) const QPointF myPos = item->mapToItem(this, me->pos()); KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); //qDebug() << "positionChanged..." << dme.x() << dme.y(); - m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + + //if the mouse moves and we are waiting to emit a press and hold event, update the co-ordinates + //as there is no update function, delete the old event and create a new one + if (m_pressAndHoldEvent) { + delete m_pressAndHoldEvent; + m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos())); + } emit positionChanged(&dme); break; } diff --git a/src/declarativeimports/qtextracomponents/mouseeventlistener.h b/src/declarativeimports/qtextracomponents/mouseeventlistener.h index 794084696..6e3e1a80b 100644 --- a/src/declarativeimports/qtextracomponents/mouseeventlistener.h +++ b/src/declarativeimports/qtextracomponents/mouseeventlistener.h @@ -23,6 +23,15 @@ #include +/** + * This item spies on mouse events from all child objects including child MouseAreas regardless + * of whether the child MouseArea propegates events. It does not accept the event. + * + * In addition unlike MouseArea events include the mouse position in global co-ordinates and provides + * the sceen the mouse is in. + */ + + class KDeclarativeMouseEvent : public QObject { Q_OBJECT diff --git a/src/declarativeimports/qtextracomponents/tests/mouseeventlistenertest.qml b/src/declarativeimports/qtextracomponents/tests/mouseeventlistenertest.qml new file mode 100644 index 000000000..6166e653c --- /dev/null +++ b/src/declarativeimports/qtextracomponents/tests/mouseeventlistenertest.qml @@ -0,0 +1,76 @@ +import org.kde.qtextracomponents 2.0 +import QtQuick 2.1 +import QtQuick.Layouts 1.0 + + +Item +{ + width: 800 + height: 400 + Row { + anchors.fill: parent + MouseEventListener { + width: 400 + height: 400 + id: mouseListener + acceptedButtons: Qt.LeftButton + hoverEnabled: true + onPressed: { + updateDebug("Pressed", mouse); + } + onPressAndHold: { + updateDebug("Held", mouse); + } + onReleased: { + mouseState.text = ""; + mousePos.text = ""; + screenPos.text = ""; + } + + function updateDebug(state, mouse) { + mouseState.text = state + mousePos.text = mouse.x + "," + mouse.y + screenPos.text = mouse.screenX + "," + mouse.screenY + } + + Rectangle { + color: "red" + anchors.fill: parent + + //MouseEventListener should still get events, even though this has a mousearea + MouseArea { + anchors.fill: parent + } + } + } + + GridLayout { + width: 400 + columns: 2 + Text { + text: "Mouse status:" + } + Text { + id: mouseState + } + Text { + text: "Contains Mouse: " + } + Text { + text: mouseListener.containsMouse + } + Text { + text: "Mouse Position: " + } + Text { + id: mousePos + } + Text { + text: "Screen Position: " + } + Text { + id: screenPos + } + } + } +} \ No newline at end of file