From b3c992c9b53d8f1630bdbc7472a29910f11ee035 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 19 Aug 2009 11:50:35 +1000 Subject: API improvements for MouseRegion and Drag --- demos/declarative/flickr/content/Slider.qml | 2 +- doc/src/snippets/declarative/drag.qml | 6 ++-- examples/declarative/dial/dial.qml | 2 +- examples/declarative/minehunt/Description.qml | 2 +- examples/declarative/mouseregion/mouse.qml | 3 +- examples/declarative/slideswitch/Switch.qml | 2 +- examples/declarative/velocity/Day.qml | 2 +- src/declarative/fx/qfxmouseregion.cpp | 40 +++++++++++++++++---------- src/declarative/fx/qfxmouseregion.h | 16 +++++++---- src/declarative/fx/qfxmouseregion_p.h | 1 - 10 files changed, 47 insertions(+), 29 deletions(-) diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/content/Slider.qml index a2ec420..24f6f90 100644 --- a/demos/declarative/flickr/content/Slider.qml +++ b/demos/declarative/flickr/content/Slider.qml @@ -29,7 +29,7 @@ Item { MouseRegion { anchors.fill: parent; drag.target: parent - drag.axis: "x"; drag.minimumX: 2; drag.maximumX: Slider.xMax+2 + drag.axis: "XAxis"; drag.minimumX: 2; drag.maximumX: Slider.xMax+2 onPositionChanged: { value = (maximum - minimum) * (Handle.x-2) / Slider.xMax + minimum; } } } diff --git a/doc/src/snippets/declarative/drag.qml b/doc/src/snippets/declarative/drag.qml index 2191b6f..8b1765b 100644 --- a/doc/src/snippets/declarative/drag.qml +++ b/doc/src/snippets/declarative/drag.qml @@ -9,9 +9,9 @@ Rect { MouseRegion { anchors.fill: parent drag.target: pic - drag.axis: "x" - drag.xmin: 0 - drag.xmax: blurtest.width-pic.width + drag.axis: "XAxis" + drag.minimumX: 0 + drag.maximumX: blurtest.width-pic.width } } } diff --git a/examples/declarative/dial/dial.qml b/examples/declarative/dial/dial.qml index 75bd9b1..75bd65c 100644 --- a/examples/declarative/dial/dial.qml +++ b/examples/declarative/dial/dial.qml @@ -26,7 +26,7 @@ Rect { } MouseRegion { anchors.fill: parent - drag.target: parent; drag.axis: "x"; drag.minimumX: 2; drag.maximumX: 128 + drag.target: parent; drag.axis: "XAxis"; drag.minimumX: 2; drag.maximumX: 128 } } } diff --git a/examples/declarative/minehunt/Description.qml b/examples/declarative/minehunt/Description.qml index cf02bff..2bc182f 100644 --- a/examples/declarative/minehunt/Description.qml +++ b/examples/declarative/minehunt/Description.qml @@ -7,7 +7,7 @@ Item { MouseRegion { anchors.fill: parent drag.target: Page - drag.axis: "xy" + drag.axis: "XandYAxis" drag.minimumX: 0 drag.maximumX: 1000 drag.minimumY: 0 diff --git a/examples/declarative/mouseregion/mouse.qml b/examples/declarative/mouseregion/mouse.qml index 34c6e66..0cb8bb9 100644 --- a/examples/declarative/mouseregion/mouse.qml +++ b/examples/declarative/mouseregion/mouse.qml @@ -8,6 +8,7 @@ Rect { color: "red" Text { text: "Click"; anchors.centerIn: parent } MouseRegion { + hoverEnabled: true onPressed: { print('press (x: ' + mouse.x + ' y: ' + mouse.y + ' button: ' + (mouse.button == Qt.RightButton ? 'right' : 'left') + ' Shift: ' + (mouse.modifiers & Qt.ShiftModifier ? 'true' : 'false') + ')') } onReleased: { print('release (x: ' + mouse.x + ' y: ' + mouse.y + ' isClick: ' + mouse.isClick + ' wasHeld: ' + mouse.wasHeld + ')') } onClicked: { print('click (x: ' + mouse.x + ' y: ' + mouse.y + ' wasHeld: ' + mouse.wasHeld + ')') } @@ -24,7 +25,7 @@ Rect { Text { text: "Drag"; anchors.centerIn: parent } MouseRegion { drag.target: parent - drag.axis: "x" + drag.axis: "XAxis" drag.minimumX: 0 drag.maximumX: 150 onPressed: { print('press') } diff --git a/examples/declarative/slideswitch/Switch.qml b/examples/declarative/slideswitch/Switch.qml index b5de9ec..b476be2 100644 --- a/examples/declarative/slideswitch/Switch.qml +++ b/examples/declarative/slideswitch/Switch.qml @@ -36,7 +36,7 @@ Item { anchors.fill: Knob onClicked: { toggle() } onReleased: { dorelease() } - drag.target: Knob; drag.axis: "x"; drag.minimumX: 1; drag.maximumX: 78 + drag.target: Knob; drag.axis: "XAxis"; drag.minimumX: 1; drag.maximumX: 78 } states: [ State { diff --git a/examples/declarative/velocity/Day.qml b/examples/declarative/velocity/Day.qml index c959b0c..d67eabe 100644 --- a/examples/declarative/velocity/Day.qml +++ b/examples/declarative/velocity/Day.qml @@ -70,7 +70,7 @@ Rect { onClicked: { MyText.focus = true } anchors.fill: parent drag.target: StickyPage - drag.axis: "xy" + drag.axis: "XandYAxis" drag.minimumY: 0 drag.maximumY: 500 drag.minimumX: 0 diff --git a/src/declarative/fx/qfxmouseregion.cpp b/src/declarative/fx/qfxmouseregion.cpp index 514701d..2a198f2 100644 --- a/src/declarative/fx/qfxmouseregion.cpp +++ b/src/declarative/fx/qfxmouseregion.cpp @@ -51,7 +51,7 @@ static const int PressAndHoldDelay = 800; QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Drag,QFxDrag) QFxDrag::QFxDrag(QObject *parent) -: QObject(parent), _target(0), _xmin(0), _xmax(0), _ymin(0), _ymax(0) +: QObject(parent), _target(0), _axis(XandYAxis), _xmin(0), _xmax(0), _ymin(0), _ymax(0) { } @@ -69,12 +69,12 @@ void QFxDrag::setTarget(QFxItem *t) _target = t; } -QString QFxDrag::axis() const +QFxDrag::Axis QFxDrag::axis() const { return _axis; } -void QFxDrag::setAxis(const QString &a) +void QFxDrag::setAxis(QFxDrag::Axis a) { _axis = a; } @@ -138,7 +138,7 @@ void QFxDrag::setYmax(qreal m) example extended so as to give a different color when you right click. \snippet doc/src/snippets/declarative/mouseregion.qml 1 - For basic key handling, see \l KeyActions. + For basic key handling, see the \l {Keys}{Keys attached property}. MouseRegion is an invisible item: it is never painted. @@ -287,8 +287,8 @@ void QFxMouseRegion::mousePressEvent(QGraphicsSceneMouseEvent *event) else { d->longPress = false; d->saveEvent(event); - d->dragX = drag()->axis().contains(QLatin1String("x")); - d->dragY = drag()->axis().contains(QLatin1String("y")); + d->dragX = drag()->axis() & QFxDrag::XAxis; + d->dragY = drag()->axis() & QFxDrag::YAxis; d->dragged = false; d->start = event->pos(); d->startScene = event->scenePos(); @@ -447,10 +447,22 @@ void QFxMouseRegion::timerEvent(QTimerEvent *event) } /*! + \qmlproperty bool hoverEnabled + This property holds whether hover events are handled. + + By default, mouse events are only handled in response to a button event, or when a button is + pressed. Hover enables handling of all mouse events even when no mouse button is + pressed. + + This property affects the containsMouse property and the onEntered, onExited and onPositionChanged signals. +*/ + +/*! \qmlproperty bool MouseRegion::containsMouse This property holds whether the mouse is currently inside the mouse region. - \warning This property is only partially implemented -- it is only valid when the mouse is pressed, and not for hover events. + \warning This property is only partially implemented -- it is only valid when the mouse is moved over the + region. If the region moves under the mouse, \e containsMouse will not change. */ bool QFxMouseRegion::hovered() const { @@ -540,18 +552,18 @@ QFxDrag *QFxMouseRegion::drag() /*! \qmlproperty Item MouseRegion::drag.target - \qmlproperty string MouseRegion::drag.axis - \qmlproperty real MouseRegion::drag.xmin - \qmlproperty real MouseRegion::drag.xmax - \qmlproperty real MouseRegion::drag.ymin - \qmlproperty real MouseRegion::drag.ymax + \qmlproperty Axis MouseRegion::drag.axis + \qmlproperty real MouseRegion::drag.minimumX + \qmlproperty real MouseRegion::drag.maximumX + \qmlproperty real MouseRegion::drag.minimumY + \qmlproperty real MouseRegion::drag.maximumY drag provides a convenient way to make an item draggable. \list \i \c target specifies the item to drag. - \i \c axis specifies whether dragging can be done horizontally (x), vertically (y), or both (x,y) - \i the min and max properties limit how far the target can be dragged along the corresponding axes. + \i \c axis specifies whether dragging can be done horizontally (XAxis), vertically (YAxis), or both (XandYAxis) + \i the minimum and maximum properties limit how far the target can be dragged along the corresponding axes. \endlist The following example uses drag to reduce the opacity of an image as it moves to the right: diff --git a/src/declarative/fx/qfxmouseregion.h b/src/declarative/fx/qfxmouseregion.h index f2d22d3..84bb493 100644 --- a/src/declarative/fx/qfxmouseregion.h +++ b/src/declarative/fx/qfxmouseregion.h @@ -54,21 +54,26 @@ class Q_DECLARATIVE_EXPORT QFxDrag : public QObject { Q_OBJECT + Q_ENUMS(Axis) Q_PROPERTY(QFxItem *target READ target WRITE setTarget) - Q_PROPERTY(QString axis READ axis WRITE setAxis) //### enum + Q_PROPERTY(Axis axis READ axis WRITE setAxis) Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin) Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax) Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin) Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax) //### consider drag and drop + public: QFxDrag(QObject *parent=0); ~QFxDrag(); QFxItem *target() const; void setTarget(QFxItem *); - QString axis() const; - void setAxis(const QString &); + + enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 }; + Axis axis() const; + void setAxis(Axis); + qreal xmin() const; void setXmin(qreal); qreal xmax() const; @@ -80,7 +85,7 @@ public: private: QFxItem *_target; - QString _axis; + Axis _axis; qreal _xmin; qreal _xmax; qreal _ymin; @@ -100,8 +105,9 @@ class Q_DECLARATIVE_EXPORT QFxMouseRegion : public QFxItem Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) + Q_PROPERTY(bool hoverEnabled READ acceptHoverEvents WRITE setAcceptHoverEvents) Q_PROPERTY(QFxDrag *drag READ drag) //### add flicking to QFxDrag or add a QFxFlick ??? - //### trackingEnabled? + public: QFxMouseRegion(QFxItem *parent=0); ~QFxMouseRegion(); diff --git a/src/declarative/fx/qfxmouseregion_p.h b/src/declarative/fx/qfxmouseregion_p.h index 1501a81..d981b85 100644 --- a/src/declarative/fx/qfxmouseregion_p.h +++ b/src/declarative/fx/qfxmouseregion_p.h @@ -74,7 +74,6 @@ public: { Q_Q(QFxMouseRegion); q->setAcceptedMouseButtons(Qt::LeftButton); - q->setAcceptHoverEvents(true); } void saveEvent(QGraphicsSceneMouseEvent *event) { -- cgit v0.12 From 84b76c452833f52891593f317a64bc78c7486bbf Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 19 Aug 2009 13:34:59 +1000 Subject: Make MouseRegion event propagation match GV. --- src/declarative/fx/qfxevents_p.h | 2 +- src/declarative/fx/qfxmouseregion.cpp | 42 +++++++++++++++++++++++++---------- src/declarative/fx/qfxmouseregion.h | 6 ++--- src/declarative/fx/qfxmouseregion_p.h | 13 +++++++++++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/declarative/fx/qfxevents_p.h b/src/declarative/fx/qfxevents_p.h index fbf0c5f..7b0c24c 100644 --- a/src/declarative/fx/qfxevents_p.h +++ b/src/declarative/fx/qfxevents_p.h @@ -105,7 +105,7 @@ public: QFxMouseEvent(int x, int y, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers , bool isClick=false, bool wasHeld=false) : _x(x), _y(y), _button(button), _buttons(buttons), _modifiers(modifiers) - , _wasHeld(wasHeld), _isClick(isClick), _accepted(false) {} + , _wasHeld(wasHeld), _isClick(isClick), _accepted(true) {} int x() const { return _x; } int y() const { return _y; } diff --git a/src/declarative/fx/qfxmouseregion.cpp b/src/declarative/fx/qfxmouseregion.cpp index 2a198f2..1125673 100644 --- a/src/declarative/fx/qfxmouseregion.cpp +++ b/src/declarative/fx/qfxmouseregion.cpp @@ -164,6 +164,8 @@ void QFxDrag::setYmax(qreal m) The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y position, and any buttons currently pressed. + + The \e accepted property of the MouseEvent parameter is ignored in this handler. */ /*! @@ -175,6 +177,8 @@ void QFxDrag::setYmax(qreal m) The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y position of the release of the click, and whether the click wasHeld. + + The \e accepted property of the MouseEvent parameter is ignored in this handler. */ /*! @@ -183,6 +187,12 @@ void QFxDrag::setYmax(qreal m) This handler is called when there is a press. The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y position and which button was pressed. + + The \e accepted property of the MouseEvent parameter determines whether this MouseRegion + will handle the press \b {and all future mouse events until release}. The default is to accept + the event and not allow other MouseRegions beneath this one to handle the event. If \e accepted + is set to false, \b {no further events will be sent to this MouseRegion} until the button is next + pressed. */ /*! @@ -191,6 +201,8 @@ void QFxDrag::setYmax(qreal m) This handler is called when there is a release. The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y position of the release of the click, and whether the click wasHeld. + + The \e accepted property of the MouseEvent parameter is ignored in this handler. */ /*! @@ -199,6 +211,8 @@ void QFxDrag::setYmax(qreal m) This handler is called when there is a long press (currently 800ms). The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y position of the press, and which button is pressed. + + The \e accepted property of the MouseEvent parameter is ignored in this handler. */ /*! @@ -207,6 +221,8 @@ void QFxDrag::setYmax(qreal m) This handler is called when there is a double-click (a press followed by a release followed by a press). The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y position of the release of the click, and whether the click wasHeld. + + The \e accepted property of the MouseEvent parameter is ignored in this handler. */ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,MouseRegion,QFxMouseRegion) @@ -292,11 +308,11 @@ void QFxMouseRegion::mousePressEvent(QGraphicsSceneMouseEvent *event) d->dragged = false; d->start = event->pos(); d->startScene = event->scenePos(); - // ### we should only start timer if pressAndHold is connected to (but connectNotify doesn't work) - d->pressAndHoldTimer.start(PressAndHoldDelay, this); + // we should only start timer if pressAndHold is connected to. + if (d->isConnected("pressAndHold(QFxMouseEvent*)")) + d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(false); - setPressed(true); - event->accept(); + event->setAccepted(setPressed(true)); } } @@ -366,7 +382,6 @@ void QFxMouseRegion::mouseMoveEvent(QGraphicsSceneMouseEvent *event) d->moved = true; QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); emit positionChanged(&me); - event->accept(); } @@ -378,7 +393,6 @@ void QFxMouseRegion::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) else { d->saveEvent(event); setPressed(false); - event->accept(); } } @@ -388,11 +402,13 @@ void QFxMouseRegion::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) if (!d->absorb) QFxItem::mouseDoubleClickEvent(event); else { - d->saveEvent(event); - setPressed(true); - QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false); - emit this->doubleClicked(&me); - event->accept(); + QFxItem::mouseDoubleClickEvent(event); + if (event->isAccepted()) { + // Only deliver the event if we have accepted the press. + d->saveEvent(event); + QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false); + emit this->doubleClicked(&me); + } } } @@ -523,7 +539,7 @@ void QFxMouseRegion::setAcceptedButtons(Qt::MouseButtons buttons) } } -void QFxMouseRegion::setPressed(bool p) +bool QFxMouseRegion::setPressed(bool p) { Q_D(QFxMouseRegion); bool isclick = d->pressed == true && p == false && d->dragged == false && d->hovered == true; @@ -541,7 +557,9 @@ void QFxMouseRegion::setPressed(bool p) } emit pressedChanged(); + return me.isAccepted(); } + return false; } QFxDrag *QFxMouseRegion::drag() diff --git a/src/declarative/fx/qfxmouseregion.h b/src/declarative/fx/qfxmouseregion.h index 84bb493..ae54ff6 100644 --- a/src/declarative/fx/qfxmouseregion.h +++ b/src/declarative/fx/qfxmouseregion.h @@ -121,9 +121,6 @@ public: bool hovered() const; bool pressed() const; - void setHovered(bool); - void setPressed(bool); - Qt::MouseButtons acceptedButtons() const; void setAcceptedButtons(Qt::MouseButtons buttons); @@ -145,6 +142,9 @@ Q_SIGNALS: void exited(); protected: + void setHovered(bool); + bool setPressed(bool); + void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/fx/qfxmouseregion_p.h b/src/declarative/fx/qfxmouseregion_p.h index d981b85..70df8d1 100644 --- a/src/declarative/fx/qfxmouseregion_p.h +++ b/src/declarative/fx/qfxmouseregion_p.h @@ -83,6 +83,19 @@ public: lastModifiers = event->modifiers(); } + bool isConnected(const char *signal) { + Q_Q(QFxMouseRegion); + int idx = QFxMouseRegion::staticMetaObject.indexOfSignal(signal); + if (idx < 32) { + quint32 mask = 1 << idx; + return QObjectPrivate::get(q)->connectedSignals[0] & mask; + } else if (idx < 64) { + quint32 mask = 1 << (idx-32); + return QObjectPrivate::get(q)->connectedSignals[1] & mask; + } + return false; + } + bool absorb : 1; bool hovered : 1; bool pressed : 1; -- cgit v0.12 From f51450571addf2cb9a55153b209b8c1a45898193 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 19 Aug 2009 13:35:29 +1000 Subject: Fix setting the id property the 'QString id' property wasn't getting set because we want id to be treated specially. Added the corresponding special treatment to where it should set the property. Reviewed-by: Michael Brasser To-be-reviewed-by: Aaron Kennedy --- src/declarative/qml/qmlcompiler.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index dea41ab..e04c876 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1201,9 +1201,13 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, // default property or to sub-objects (which are always in binding // sub-contexts) COMPILE_CHECK(buildIdProperty(prop, obj)); - if (prop->type == QVariant::String && - prop->values.at(0)->value.isString()) + if (prop->type == QVariant::String){ + if(!prop->values.at(0)->value.isString()){ + //Need to convert to string to assign to the QString id property + prop->values.at(0)->value = Variant(prop->values.at(0)->value.asString()); + } COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt)); + } } else if (isAttachedPropertyName(prop->name)) { @@ -1629,7 +1633,7 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop, // children: [ Item {}, Item {} ] // } // -// We allow assignming multiple values to single value properties +// We allow assigning multiple values to single value properties bool QmlCompiler::buildPropertyAssignment(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &ctxt) -- cgit v0.12