diff options
-rw-r--r-- | demos/declarative/mediabrowser/content/PhoneInfoContainer.qml | 10 | ||||
-rw-r--r-- | examples/declarative/minehunt/minehunt.qml | 12 | ||||
-rw-r--r-- | src/declarative/fx/qfxflipable.cpp | 133 | ||||
-rw-r--r-- | src/declarative/fx/qfxflipable.h | 10 | ||||
-rw-r--r-- | src/declarative/fx/qfxtransform.cpp | 25 |
5 files changed, 171 insertions, 19 deletions
diff --git a/demos/declarative/mediabrowser/content/PhoneInfoContainer.qml b/demos/declarative/mediabrowser/content/PhoneInfoContainer.qml index 5e387dd..34fd889 100644 --- a/demos/declarative/mediabrowser/content/PhoneInfoContainer.qml +++ b/demos/declarative/mediabrowser/content/PhoneInfoContainer.qml @@ -13,9 +13,9 @@ <Signal name="closed"/> </signals> - <transform> - <AxisRotation id="Axis" axis.startX="{Container.width / 2}" axis.endX="{Container.width / 2}" axis.endY="1" /> - </transform> + <axis> + <Axis startX="{Container.width / 2}" endX="{Container.width / 2}" endY="1" /> + </axis> <front> <Item id="ContainerFront" anchors.fill="{Container}"> @@ -53,13 +53,13 @@ <states> <State name="Back"> - <SetProperty target="{Axis}" property="angle" value="180"/> + <SetProperty target="{Container}" property="rotation" value="180"/> </State> </states> <transitions> <Transition> - <NumericAnimation easing="easeInOutQuad" properties="angle" duration="500"/> + <NumericAnimation easing="easeInOutQuad" properties="rotation" duration="500"/> </Transition> </transitions> diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml index 20c3874..5c1b071 100644 --- a/examples/declarative/minehunt/minehunt.qml +++ b/examples/declarative/minehunt/minehunt.qml @@ -6,9 +6,9 @@ <resources> <Component id="tile"> <Flipable id="flipable" width="40" height="40"> - <transform> - <AxisRotation id="axis" axis.startX="20" axis.endX="20" axis.startY="20" axis.endY="0" /> - </transform> + <axis> + <Axis startX="20" startY="20" endX="20" endY="0" /> + </axis> <front> <Image src="pics/front.png" width="40" height="40"> <Image anchors.horizontalCenter="{parent.horizontalCenter}" @@ -34,19 +34,19 @@ </back> <states> <State name="back" when="{modelData.flipped == true}"> - <SetProperty target="{axis}" property="angle" value="180" /> + <SetProperty target="{flipable}" property="rotation" value="180" /> </State> </states> <transitions> <Transition> <SequentialAnimation> <PauseAnimation duration="{var ret = Math.abs(flipable.parent.x-field.clickx) + Math.abs(flipable.parent.y-field.clicky); if (ret > 0) {if(modelData.hasMine==true && modelData.flipped==true){ret*3;}else{ret;}} else {0}}"/> - <NumericAnimation easing="easeInOutQuad" properties="angle"/> + <NumericAnimation easing="easeInOutQuad" properties="rotation"/> </SequentialAnimation> </Transition> </transitions> <MouseRegion anchors.fill="{parent}" - onClicked="field.clickx = flipable.parent.x; field.clicky = flipable.parent.y; row = Math.floor(index/9); col = index - (Math.floor(index/9) * 9); if(mouseButton==undefined || mouseButton=='Right'){flag(row,col);}else{flip(row,col);}" /> + onClicked="field.clickx = flipable.parent.x; field.clicky = flipable.parent.y; row = Math.floor(index/9); col = index - (Math.floor(index/9) * 9); if(mouse.button==undefined || mouse.button==Qt.RightButton){flag(row,col);}else{flip(row,col);}" /> </Flipable> </Component> </resources> diff --git a/src/declarative/fx/qfxflipable.cpp b/src/declarative/fx/qfxflipable.cpp index 9db0b57..1d15827 100644 --- a/src/declarative/fx/qfxflipable.cpp +++ b/src/declarative/fx/qfxflipable.cpp @@ -49,11 +49,17 @@ QML_DEFINE_TYPE(QFxFlipable,Flipable); class QFxFlipablePrivate : public QFxItemPrivate { public: - QFxFlipablePrivate() : current(QFxFlipable::Front), front(0), back(0) {} + QFxFlipablePrivate() : current(QFxFlipable::Front), front(0), back(0), axis(0), rotation(0) {} + + void setBackTransform(); + void _q_updateAxis(); QFxFlipable::Side current; QFxItem *front; QFxItem *back; + QFxAxis *axis; + QFxRotation axisRotation; + qreal rotation; }; /*! @@ -65,18 +71,18 @@ public: \code <Flipable id="flipable" width="40" height="40"> - <transform> - <Axis id="axis" xStart="20" xEnd="20" yStart="20" yEnd="0" /> - </transform> + <axis> + <Axis startX="20" startY="0" endX="20" endY="40" /> + </axis> <front> - <Image file="front.png"/> + <Image src="front.png"/> </front> <back> - <Image file="back.png"/> + <Image src="back.png"/> </back> <states> <State name="back"> - <SetProperty target="{axis}" property="rotation" value="180" /> + <SetProperty target="{flipable}" property="rotation" value="180" /> </State> </states> <transitions> @@ -153,6 +159,114 @@ void QFxFlipable::setBack(QFxItem *back) children()->append(d->back); if (Front == d->current) d->back->setOpacity(0.); + d->setBackTransform(); +} + +/*! + \qmlproperty Axis Flipable::axis + + The axis to flip around. See the \l Axis documentation for more + information on specifying an axis. +*/ + +QFxAxis *QFxFlipable::axis() +{ + Q_D(QFxFlipable); + return d->axis; +} + +void QFxFlipable::setAxis(QFxAxis *axis) +{ + Q_D(QFxFlipable); + //### disconnect if we are already connected? + if (d->axis) + disconnect(d->axis, SIGNAL(updated()), this, SLOT(_q_updateAxis())); + d->axis = axis; + connect(d->axis, SIGNAL(updated()), this, SLOT(_q_updateAxis())); + d->_q_updateAxis(); +} + +void QFxFlipablePrivate::_q_updateAxis() +{ + axisRotation.axis()->setStartX(axis->startX()); + axisRotation.axis()->setStartY(axis->startY()); + axisRotation.axis()->setEndX(axis->endX()); + axisRotation.axis()->setEndY(axis->endY()); + axisRotation.axis()->setEndZ(axis->endZ()); + + setBackTransform(); +} + +void QFxFlipablePrivate::setBackTransform() +{ + if (!back) + return; + + QPointF p1(0, 0); + QPointF p2(1, 0); + QPointF p3(1, 1); + + axisRotation.setAngle(180); + p1 = axisRotation.transform().map(p1); + p2 = axisRotation.transform().map(p2); + p3 = axisRotation.transform().map(p3); + axisRotation.setAngle(rotation); + + QSimpleCanvas::Matrix mat; +#ifdef QFX_RENDER_OPENGL + mat.translate(back->width()/2,back->height()/2, 0); + if (back->width() && p1.x() >= p2.x()) + mat.rotate(180, 0, 1, 0); + if (back->height() && p2.y() >= p3.y()) + mat.rotate(180, 1, 0, 0); + mat.translate(-back->width()/2,-back->height()/2, 0); +#else + mat.translate(back->width()/2,back->height()/2); + if (back->width() && p1.x() >= p2.x()) + mat.rotate(180, Qt::YAxis); + if (back->height() && p2.y() >= p3.y()) + mat.rotate(180, Qt::XAxis); + mat.translate(-back->width()/2,-back->height()/2); +#endif + back->setTransform(mat); +} + +/*! + \qmlproperty real Flipable::rotation + The angle to rotate the flipable. For example, to show the back side of the flipable + you can set the rotation to 180. +*/ +qreal QFxFlipable::rotation() const +{ + Q_D(const QFxFlipable); + return d->rotation; +} + +void QFxFlipable::setRotation(qreal angle) +{ + Q_D(QFxFlipable); + d->rotation = angle; + d->axisRotation.setAngle(angle); + setTransform(d->axisRotation.transform()); + + + int simpleAngle = int(angle) % 360; + + Side newSide; + if (simpleAngle < 91 || simpleAngle > 270) { + newSide = Front; + } else { + newSide = Back; + } + + if (newSide != d->current) { + d->current = newSide; + if (d->front) + d->front->setOpacity((d->current==Front)?1.:0.); + if (d->back) + d->back->setOpacity((d->current==Back)?1.:0.); + emit sideChanged(); + } } /*! @@ -167,6 +281,9 @@ QFxFlipable::Side QFxFlipable::side() const return d->current; } +//in some cases the user may want to specify a more complex transformation. +//in that case, we still allow the generic use of transform. +//(the logic here should be kept in sync with setBackTransform and setRotation) void QFxFlipable::transformChanged(const QSimpleCanvas::Matrix &trans) { Q_D(QFxFlipable); @@ -218,3 +335,5 @@ void QFxFlipable::transformChanged(const QSimpleCanvas::Matrix &trans) } QT_END_NAMESPACE + +#include "moc_qfxflipable.cpp" diff --git a/src/declarative/fx/qfxflipable.h b/src/declarative/fx/qfxflipable.h index 2c6c849..ef1832e 100644 --- a/src/declarative/fx/qfxflipable.h +++ b/src/declarative/fx/qfxflipable.h @@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class QFxAxis; class QFxFlipablePrivate; class Q_DECLARATIVE_EXPORT QFxFlipable : public QFxItem { @@ -63,6 +64,8 @@ class Q_DECLARATIVE_EXPORT QFxFlipable : public QFxItem Q_ENUMS(Side); Q_PROPERTY(QFxItem *front READ front WRITE setFront) Q_PROPERTY(QFxItem *back READ back WRITE setBack) + Q_PROPERTY(QFxAxis *axis READ axis WRITE setAxis) + Q_PROPERTY(qreal rotation READ rotation WRITE setRotation) Q_PROPERTY(Side side READ side NOTIFY sideChanged) public: QFxFlipable(QFxItem *parent=0); @@ -74,6 +77,12 @@ public: QFxItem *back(); void setBack(QFxItem *); + QFxAxis *axis(); + void setAxis(QFxAxis *axis); + + qreal rotation() const; + void setRotation(qreal angle); + enum Side { Front, Back }; Side side() const; @@ -84,6 +93,7 @@ Q_SIGNALS: void sideChanged(); private: + Q_PRIVATE_SLOT(d_func(), void _q_updateAxis()) Q_DISABLE_COPY(QFxFlipable) Q_DECLARE_PRIVATE(QFxFlipable) }; diff --git a/src/declarative/fx/qfxtransform.cpp b/src/declarative/fx/qfxtransform.cpp index 9f18413..c355158 100644 --- a/src/declarative/fx/qfxtransform.cpp +++ b/src/declarative/fx/qfxtransform.cpp @@ -85,7 +85,16 @@ void QFxTransform::update() /*! \qmlclass Axis - \brief An axis that can be used for rotation or translation. + \brief The Axis element defines an axis that can be used for rotation or translation. + + An axis is specified by 2 points in 3D space: a start point and + an end point. While technically the axis is the line running through these two points + (and thus many different sets of two points could define the same axis), the distance + between the points does matter for translation along an axis. + + \code + <Axis startX="0" startY="0" endX="20" endY="30"/> + \endcode */ QML_DEFINE_TYPE(QFxAxis, Axis); @@ -99,6 +108,13 @@ QFxAxis::~QFxAxis() { } +/*! + \qmlproperty real Axis::startX + \qmlproperty real Axis::startY + + The start point of the axis. The z-position of the start point is assumed to be 0, and cannot + be changed. +*/ qreal QFxAxis::startX() const { return _startX; @@ -121,6 +137,13 @@ void QFxAxis::setStartY(qreal y) emit updated(); } +/*! + \qmlproperty real Axis::endX + \qmlproperty real Axis::endY + \qmlproperty real Axis::endZ + + The end point of the axis. +*/ qreal QFxAxis::endX() const { return _endX; |