From 635d02e7c29e7bd2dbabd31c8798fa66dcf7f727 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Sat, 21 Dec 2013 19:40:45 +0100 Subject: [PATCH 1/3] Add documentation for MouseEventListener --- .../qtextracomponents/mouseeventlistener.h | 9 +++++++++ 1 file changed, 9 insertions(+) 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 From 04f2f8bd8dd4c0c91eafd3552fb411951db3d4b0 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Sat, 21 Dec 2013 19:59:46 +0100 Subject: [PATCH 2/3] Fix memory issues in MouseEventListener Delete KDeclarativeMouseEvent when emitted Do not leak KDeclarativeMouseEvent press and hold events when the mouse moves. Do not create KDeclarativeMouseEvent when the mouse is hovered. It's pointless. --- .../qtextracomponents/mouseeventlistener.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) 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; } From 919954ab9044f7b20c7d4711c66fb856072aa557 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Sat, 21 Dec 2013 19:59:59 +0100 Subject: [PATCH 3/3] Add a simple manual test for MouseEventListener --- .../tests/mouseeventlistenertest.qml | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/declarativeimports/qtextracomponents/tests/mouseeventlistenertest.qml 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