--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ height: 700
+ width: 485
+ color: "#333333"
+
+ Column {
+ anchors.centerIn: parent
+ spacing: 2
+
+ Repeater {
+ model: ["#9ACD32", "#EEEEEE", "#FFD700", "#87CEEB"]
+
+ Rectangle {
+ property real scaleFactor: 1
+
+ height: 40 * scaleFactor
+ width: 60 * scaleFactor
+ color: modelData
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ MouseArea {
+ anchors.fill: parent
+ onWheel: {
+ if (wheel.modifiers & Qt.ControlModifier) {
+ if (wheel.angleDelta.y > 0)
+ parent.scaleFactor += 0.2;
+ else if (parent.scaleFactor - 0.2 >= 0.2)
+ parent.scaleFactor -= 0.2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Text {
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "#FFD700"
+ text: "Rotate the mouse wheel pressing <Control> to resize the squares."
+ }
+}
QPointF p = item->mapFromScene(event->posF());
if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
- QWheelEvent wheel(p, event->delta(), event->buttons(), event->modifiers(), event->orientation());
+ QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(),
+ event->orientation(), event->buttons(), event->modifiers());
wheel.accept();
q->sendEvent(item, &wheel);
if (wheel.isAccepted()) {
*/
+/*!
+ \qmlclass WheelEvent QQuickWheelEvent
+ \inqmlmodule QtQuick 2
+ \ingroup qml-event-elements
+
+ \brief The WheelEvent object provides information about a mouse wheel event.
+
+ The position of the mouse can be found via the \l x and \l y properties.
+
+ \sa MouseArea
+*/
+
+/*!
+ \internal
+ \class QQuickWheelEvent
+*/
+
+/*!
+ \qmlproperty int QtQuick2::WheelEvent::x
+ \qmlproperty int QtQuick2::WheelEvent::y
+
+ These properties hold the coordinates of the position supplied by the wheel event.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::WheelEvent::accepted
+
+ Setting \a accepted to true prevents the wheel event from being
+ propagated to items below this item.
+
+ Generally, if the item acts on the wheel event then it should be accepted
+ so that items lower in the stacking order do not also respond to the same event.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::WheelEvent::buttons
+
+ This property holds the mouse buttons pressed when the wheel event was generated.
+
+ It contains a bitwise combination of:
+ \list
+ \o Qt.LeftButton
+ \o Qt.RightButton
+ \o Qt.MiddleButton
+ \endlist
+*/
+
+/*!
+ \qmlproperty point QtQuick2::WheelEvent::angleDelta
+
+ This property holds the distance that the wheel is rotated in wheel degrees.
+ The x and y cordinate of this property holds the delta in horizontal and
+ vertical orientation.
+
+ A positive value indicates that the wheel was rotated up/right;
+ a negative value indicates that the wheel was rotated down/left.
+
+ Most mouse types work in steps of 15 degrees, in which case the delta value is a
+ multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
+*/
+
+/*!
+ \qmlproperty point QtQuick2::WheelEvent::pixelDelta
+
+ This property holds the delta in screen pixels and is available in plataforms that
+ have high-resolution trackpads, such as Mac OS X.
+ The x and y cordinate of this property holds the delta in horizontal and
+ vertical orientation. The value should be used directly to scroll content on screen.
+
+ For platforms without high-resolution trackpad support, pixelDelta will always be (0,0),
+ and angleDelta should be used instead.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::WheelEvent::modifiers
+
+ This property holds the keyboard modifier flags that existed immediately
+ before the event occurred.
+
+ It contains a bitwise combination of:
+ \list
+ \o Qt.NoModifier - No modifier key is pressed.
+ \o Qt.ShiftModifier - A Shift key on the keyboard is pressed.
+ \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed.
+ \o Qt.AltModifier - An Alt key on the keyboard is pressed.
+ \o Qt.MetaModifier - A Meta key on the keyboard is pressed.
+ \o Qt.KeypadModifier - A keypad button is pressed.
+ \endlist
+
+ For example, to react to a Control key pressed during the wheel event:
+ \qml
+ MouseArea {
+ onWheel: {
+ if (wheel.modifiers & Qt.ControlModifier) {
+ if (wheel.angleDelta.y > 0)
+ zoomIn();
+ else
+ zoomOut();
+ }
+ }
+ }
+ \endqml
+*/
+
QT_END_NAMESPACE
};
+class QQuickWheelEvent : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal x READ x)
+ Q_PROPERTY(qreal y READ y)
+ Q_PROPERTY(QPoint angleDelta READ angleDelta)
+ Q_PROPERTY(QPoint pixelDelta READ pixelDelta)
+ Q_PROPERTY(int buttons READ buttons)
+ Q_PROPERTY(int modifiers READ modifiers)
+ Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+
+public:
+ QQuickWheelEvent(qreal x, qreal y, const QPoint& angleDelta, const QPoint& pixelDelta,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
+ : _x(x), _y(y), _angleDelta(angleDelta), _pixelDelta(pixelDelta), _buttons(buttons),
+ _modifiers(modifiers), _accepted(true) {}
+
+ qreal x() const { return _x; }
+ qreal y() const { return _y; }
+ QPoint angleDelta() const { return _angleDelta; }
+ QPoint pixelDelta() const { return _pixelDelta; }
+ int buttons() const { return _buttons; }
+ int modifiers() const { return _modifiers; }
+
+ bool isAccepted() { return _accepted; }
+ void setAccepted(bool accepted) { _accepted = accepted; }
+
+private:
+ qreal _x;
+ qreal _y;
+ QPoint _angleDelta;
+ QPoint _pixelDelta;
+ Qt::MouseButtons _buttons;
+ Qt::KeyboardModifiers _modifiers;
+ bool _accepted;
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickKeyEvent)
QML_DECLARE_TYPE(QQuickMouseEvent)
+QML_DECLARE_TYPE(QQuickWheelEvent)
#endif // QQUICKEVENTS_P_P_H
qmlRegisterType<QQuickAnchors>();
qmlRegisterType<QQuickKeyEvent>();
qmlRegisterType<QQuickMouseEvent>();
+ qmlRegisterType<QQuickWheelEvent>();
qmlRegisterType<QQuickTransform>();
qmlRegisterType<QQuickPathElement>();
qmlRegisterType<QQuickCurve>();
return QObjectPrivate::get(q)->isSignalConnected(idx);
}
+bool QQuickMouseAreaPrivate::isWheelConnected()
+{
+ Q_Q(QQuickMouseArea);
+ static int idx = QObjectPrivate::get(q)->signalIndex("wheel(QQuickWheelEvent*)");
+ return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t)
{
Q_Q(QQuickMouseArea);
Information about the mouse position and button clicks are provided via
signals for which event handler properties are defined. The most commonly
used involved handling mouse presses and clicks: onClicked, onDoubleClicked,
- onPressed, onReleased and onPressAndHold.
+ onPressed, onReleased and onPressAndHold. It's also possible to handle mouse
+ wheel events via the onWheel signal.
By default, MouseArea items only report mouse clicks and not changes to the
position of the mouse cursor. Setting the hoverEnabled property ensures that
the logic when the MouseArea has lost the mouse handling to the \l Flickable,
\c onCanceled should be used in addition to onReleased.
*/
+
+/*!
+ \qmlsignal QtQuick2::MouseArea::onWheel(WheelEvent mouse)
+
+ This handler is called in response to both mouse wheel and trackpad scroll gestures.
+
+ The \l {WheelEvent}{wheel} parameter provides information about the event, including the x and y
+ position, any buttons currently pressed, and information about the wheel movement, including
+ angleDelta and pixelDelta.
+*/
+
QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
: QQuickItem(*(new QQuickMouseAreaPrivate), parent)
{
setHovered(false);
}
+void QQuickMouseArea::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickMouseArea);
+ if (!d->absorb) {
+ QQuickItem::wheelEvent(event);
+ return;
+ }
+
+ QQuickWheelEvent we(event->posF().x(), event->posF().y(), event->angleDelta(),
+ event->pixelDelta(), event->buttons(), event->modifiers());
+ we.setAccepted(d->isWheelConnected());
+ emit wheel(&we);
+ if (!we.isAccepted())
+ QQuickItem::wheelEvent(event);
+}
+
void QQuickMouseArea::ungrabMouse()
{
Q_D(QQuickMouseArea);
};
class QQuickMouseAreaPrivate;
+class QQuickWheelEvent;
// used in QtLocation
class Q_QUICK_EXPORT QQuickMouseArea : public QQuickItem
{
void released(QQuickMouseEvent *mouse);
void clicked(QQuickMouseEvent *mouse);
void doubleClicked(QQuickMouseEvent *mouse);
+ void wheel(QQuickWheelEvent *wheel);
void entered();
void exited();
void canceled();
virtual void hoverEnterEvent(QHoverEvent *event);
virtual void hoverMoveEvent(QHoverEvent *event);
virtual void hoverLeaveEvent(QHoverEvent *event);
+ virtual void wheelEvent(QWheelEvent *event);
virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e);
virtual void timerEvent(QTimerEvent *event);
virtual void windowDeactivateEvent();
bool isPressAndHoldConnected();
bool isDoubleClickConnected();
bool isClickConnected();
+ bool isWheelConnected();
bool absorb : 1;
bool hovered : 1;
--- /dev/null
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ property var angleDeltaY
+ property real mouseX
+ property real mouseY
+ property bool controlPressed
+
+ width: 400
+ height: 400
+
+ MouseArea {
+ anchors.fill: parent
+
+ onWheel: {
+ root.angleDeltaY = wheel.angleDelta.y;
+ root.mouseX = wheel.x;
+ root.mouseY = wheel.y;
+ root.controlPressed = wheel.modifiers & Qt.ControlModifier;
+ }
+ }
+}
void hoverPropagation();
void hoverVisible();
void disableAfterPress();
+ void onWheel();
private:
QQuickView *createView();
delete canvas;
}
+void tst_QQuickMouseArea::onWheel()
+{
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("wheel.qml"));
+
+ QQuickItem *root = canvas->rootObject();
+ QVERIFY(root != 0);
+
+ QWheelEvent wheelEvent(QPoint(10, 32), QPoint(10, 32), QPoint(60, 20), QPoint(0, 120),
+ 0, Qt::Vertical,Qt::NoButton, Qt::ControlModifier);
+ QGuiApplication::sendEvent(canvas, &wheelEvent);
+
+ QCOMPARE(root->property("angleDeltaY").toInt(), 120);
+ QCOMPARE(root->property("mouseX").toReal(), qreal(10));
+ QCOMPARE(root->property("mouseY").toReal(), qreal(32));
+ QCOMPARE(root->property("controlPressed").toBool(), true);
+
+ delete canvas;
+}
+
QTEST_MAIN(tst_QQuickMouseArea)
#include "tst_qquickmousearea.moc"