From 2654681dfd431cb5c051f2e99ec1187ad8d394f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20K=C3=BCgler?= Date: Fri, 25 Nov 2011 00:49:53 +0100 Subject: [PATCH] Add MouseEventListener from mobilecomponents We need this in some components to work around weaknesses in the standard MouseArea (such as conditional accepting of events). MouseEventListener basically provides wiretapping for mouse events, without blocking them, so they are still effective in the underlying widgets. --- .../qtextracomponents/CMakeLists.txt | 1 + .../qtextracomponents/mouseeventlistener.cpp | 101 ++++++++++++++++++ .../qtextracomponents/mouseeventlistener.h | 92 ++++++++++++++++ .../qtextracomponentsplugin.cpp | 2 + 4 files changed, 196 insertions(+) create mode 100644 declarativeimports/qtextracomponents/mouseeventlistener.cpp create mode 100644 declarativeimports/qtextracomponents/mouseeventlistener.h diff --git a/declarativeimports/qtextracomponents/CMakeLists.txt b/declarativeimports/qtextracomponents/CMakeLists.txt index a78644ff2..05a1195e9 100644 --- a/declarativeimports/qtextracomponents/CMakeLists.txt +++ b/declarativeimports/qtextracomponents/CMakeLists.txt @@ -7,6 +7,7 @@ set(qtextracomponents_SRCS qpixmapitem.cpp qimageitem.cpp qiconitem.cpp + mouseeventlistener.cpp ) INCLUDE_DIRECTORIES( diff --git a/declarativeimports/qtextracomponents/mouseeventlistener.cpp b/declarativeimports/qtextracomponents/mouseeventlistener.cpp new file mode 100644 index 000000000..bf24e71bd --- /dev/null +++ b/declarativeimports/qtextracomponents/mouseeventlistener.cpp @@ -0,0 +1,101 @@ +/* + Copyright 2011 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "mouseeventlistener.h" + +#include +#include + +#include + +MouseEventListener::MouseEventListener(QDeclarativeItem *parent) + : QDeclarativeItem(parent) +{ + setFiltersChildEvents(true); + setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton|Qt::MidButton|Qt::XButton1|Qt::XButton2); +} + +MouseEventListener::~MouseEventListener() +{ +} + +void MouseEventListener::mousePressEvent(QGraphicsSceneMouseEvent *me) +{ + //FIXME: when a popup window is visible: a click anywhere hides it: but the old qgraphicswidget will continue to think it's under the mouse + //doesn't seem to be any good way to properly reset this. + //this msolution will still caused a missed click after the popup is gone, but gets the situation unblocked. + if (!isUnderMouse()) { + me->ignore(); + return; + } + + QDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit pressed(&dme); +} + +void MouseEventListener::mouseMoveEvent(QGraphicsSceneMouseEvent *me) +{ + QDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit positionChanged(&dme); +} + +void MouseEventListener::mouseReleaseEvent(QGraphicsSceneMouseEvent *me) +{ + QDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit released(&dme); +} + +bool MouseEventListener::sceneEventFilter(QGraphicsItem *item, QEvent *event) +{ + if (!isEnabled()) { + return false; + } + + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: { + QGraphicsSceneMouseEvent *me = static_cast(event); + //the parent will receive events in its own coordinates + const QPointF myPos = item->mapToItem(this, me->pos()); + QDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit pressed(&dme); + break; + } + case QEvent::GraphicsSceneMouseMove: { + QGraphicsSceneMouseEvent *me = static_cast(event); + const QPointF myPos = item->mapToItem(this, me->pos()); + QDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit positionChanged(&dme); + break; + } + case QEvent::GraphicsSceneMouseRelease: { + QGraphicsSceneMouseEvent *me = static_cast(event); + const QPointF myPos = item->mapToItem(this, me->pos()); + QDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers()); + emit released(&dme); + break; + } + default: + break; + } + + return QDeclarativeItem::sceneEventFilter(item, event); +} + +#include "mouseeventlistener.moc" + diff --git a/declarativeimports/qtextracomponents/mouseeventlistener.h b/declarativeimports/qtextracomponents/mouseeventlistener.h new file mode 100644 index 000000000..4c21c4696 --- /dev/null +++ b/declarativeimports/qtextracomponents/mouseeventlistener.h @@ -0,0 +1,92 @@ +/* + Copyright 2011 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MOUSEEVENTLISTENER_H +#define MOUSEEVENTLISTENER_H + +#include + +class QDeclarativeMouseEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x) + Q_PROPERTY(int y READ y) + Q_PROPERTY(int screenX READ screenX) + Q_PROPERTY(int screenY READ screenY) + Q_PROPERTY(int button READ button) + Q_PROPERTY(int buttons READ buttons) + Q_PROPERTY(int modifiers READ modifiers) + +public: + QDeclarativeMouseEvent(int x, int y, int screenX, int screenY, + Qt::MouseButton button, + Qt::MouseButtons buttons, + Qt::KeyboardModifiers modifiers) + : m_x(x), + m_y(y), + m_screenX(screenX), + m_screenY(screenY), + m_button(button), + m_buttons(buttons), + m_modifiers(modifiers) + {} + + int x() const { return m_x; } + int y() const { return m_y; } + int screenX() const { return m_screenX; } + int screenY() const { return m_screenY; } + int button() const { return m_button; } + int buttons() const { return m_buttons; } + int modifiers() const { return m_modifiers; } + + // only for internal usage + void setX(int x) { m_x = x; } + void setY(int y) { m_y = y; } + +private: + int m_x; + int m_y; + int m_screenX; + int m_screenY; + Qt::MouseButton m_button; + Qt::MouseButtons m_buttons; + Qt::KeyboardModifiers m_modifiers; +}; + +class MouseEventListener : public QDeclarativeItem +{ + Q_OBJECT + +public: + MouseEventListener(QDeclarativeItem *parent=0); + ~MouseEventListener(); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + bool sceneEventFilter(QGraphicsItem *i, QEvent *e); + +Q_SIGNALS: + void pressed(QDeclarativeMouseEvent *mouse); + void positionChanged(QDeclarativeMouseEvent *mouse); + void released(QDeclarativeMouseEvent *mouse); +}; + +#endif diff --git a/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp b/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp index c0943493f..429282eaa 100644 --- a/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp +++ b/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp @@ -26,6 +26,7 @@ #include "qpixmapitem.h" #include "qimageitem.h" #include "qiconitem.h" +#include "mouseeventlistener.h" void QtExtraComponentsPlugin::registerTypes(const char *uri) @@ -35,6 +36,7 @@ void QtExtraComponentsPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 0, 1, "QPixmapItem"); qmlRegisterType(uri, 0, 1, "QImageItem"); qmlRegisterType(uri, 0, 1, "QIconItem"); + qmlRegisterType(uri, 0, 1, "MouseEventListener"); }