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.
This commit is contained in:
Sebastian Kügler 2011-11-25 00:49:53 +01:00
parent af56e24141
commit 2654681dfd
4 changed files with 196 additions and 0 deletions

View File

@ -7,6 +7,7 @@ set(qtextracomponents_SRCS
qpixmapitem.cpp
qimageitem.cpp
qiconitem.cpp
mouseeventlistener.cpp
)
INCLUDE_DIRECTORIES(

View File

@ -0,0 +1,101 @@
/*
Copyright 2011 Marco Martin <notmart@gmail.com>
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 <QEvent>
#include <QGraphicsSceneMouseEvent>
#include <KDebug>
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<QGraphicsSceneMouseEvent *>(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<QGraphicsSceneMouseEvent *>(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<QGraphicsSceneMouseEvent *>(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"

View File

@ -0,0 +1,92 @@
/*
Copyright 2011 Marco Martin <notmart@gmail.com>
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 <QDeclarativeItem>
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

View File

@ -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<QPixmapItem>(uri, 0, 1, "QPixmapItem");
qmlRegisterType<QImageItem>(uri, 0, 1, "QImageItem");
qmlRegisterType<QIconItem>(uri, 0, 1, "QIconItem");
qmlRegisterType<MouseEventListener>(uri, 0, 1, "MouseEventListener");
}