diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-04-28 04:29:34 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-04-28 04:29:34 (GMT) |
commit | 72dfac4fbe7a45ca84ce233eb68161c685bdc31c (patch) | |
tree | 2efcc2784df8197d61088bf95cfb72657b09d872 | |
parent | 7e3aee5b4f50733fa8d88def28b4fce78070f9e2 (diff) | |
download | Qt-72dfac4fbe7a45ca84ce233eb68161c685bdc31c.zip Qt-72dfac4fbe7a45ca84ce233eb68161c685bdc31c.tar.gz Qt-72dfac4fbe7a45ca84ce233eb68161c685bdc31c.tar.bz2 |
API and documentation work on the transform elements.
Axis has been split into Axis, AxisRotation, and AxisTranslation. Basic
docs (in some cases just a stub) have been added for these, Perspective,
and Squish.
Flipable has moved to its own file.
-rw-r--r-- | demos/declarative/mediabrowser/content/MovieInfoContainer.qml | 6 | ||||
-rw-r--r-- | doc/src/declarative/pics/axisrotation.png | bin | 0 -> 3425 bytes | |||
-rw-r--r-- | examples/declarative/minehunt/minehunt.qml | 6 | ||||
-rw-r--r-- | src/declarative/fx/fx.pri | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxflipable.cpp | 220 | ||||
-rw-r--r-- | src/declarative/fx/qfxflipable.h | 96 | ||||
-rw-r--r-- | src/declarative/fx/qfxtransform.cpp | 504 | ||||
-rw-r--r-- | src/declarative/fx/qfxtransform.h | 174 |
8 files changed, 705 insertions, 303 deletions
diff --git a/demos/declarative/mediabrowser/content/MovieInfoContainer.qml b/demos/declarative/mediabrowser/content/MovieInfoContainer.qml index c53fab6..8ffc76e 100644 --- a/demos/declarative/mediabrowser/content/MovieInfoContainer.qml +++ b/demos/declarative/mediabrowser/content/MovieInfoContainer.qml @@ -12,7 +12,7 @@ </signals> <transform> - <Axis id="Axis" xStart="{Container.width / 2}" xEnd="{Container.width / 2}" yEnd="1" /> + <AxisRotation id="Axis" axis.startX="{Container.width / 2}" axis.endX="{Container.width / 2}" axis.endY="1" /> </transform> <front> @@ -47,13 +47,13 @@ <states> <State name="Back"> - <SetProperty target="{Axis}" property="rotation" value="180"/> + <SetProperty target="{Axis}" property="angle" value="180"/> </State> </states> <transitions> <Transition> - <NumericAnimation easing="easeInOutQuad" properties="rotation" duration="500"/> + <NumericAnimation easing="easeInOutQuad" properties="angle" duration="500"/> </Transition> </transitions> diff --git a/doc/src/declarative/pics/axisrotation.png b/doc/src/declarative/pics/axisrotation.png Binary files differnew file mode 100644 index 0000000..409a9e9 --- /dev/null +++ b/doc/src/declarative/pics/axisrotation.png diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml index 9db0e84..20c3874 100644 --- a/examples/declarative/minehunt/minehunt.qml +++ b/examples/declarative/minehunt/minehunt.qml @@ -7,7 +7,7 @@ <Component id="tile"> <Flipable id="flipable" width="40" height="40"> <transform> - <Axis id="axis" xStart="20" xEnd="20" yStart="20" yEnd="0" /> + <AxisRotation id="axis" axis.startX="20" axis.endX="20" axis.startY="20" axis.endY="0" /> </transform> <front> <Image src="pics/front.png" width="40" height="40"> @@ -34,14 +34,14 @@ </back> <states> <State name="back" when="{modelData.flipped == true}"> - <SetProperty target="{axis}" property="rotation" value="180" /> + <SetProperty target="{axis}" property="angle" 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="rotation"/> + <NumericAnimation easing="easeInOutQuad" properties="angle"/> </SequentialAnimation> </Transition> </transitions> diff --git a/src/declarative/fx/fx.pri b/src/declarative/fx/fx.pri index b8b62b9..fc20371 100644 --- a/src/declarative/fx/fx.pri +++ b/src/declarative/fx/fx.pri @@ -10,6 +10,7 @@ HEADERS += \ fx/qfxcontentwrapper_p.h \ fx/qfxflickable.h \ fx/qfxflickable_p.h \ + fx/qfxflipable.h \ fx/qfxfocuspanel.h \ fx/qfxfocusrealm.h \ fx/qfxgridview.h \ @@ -58,6 +59,7 @@ SOURCES += \ fx/qfxcomponentinstance.cpp \ fx/qfxcontentwrapper.cpp \ fx/qfxflickable.cpp \ + fx/qfxflipable.cpp \ fx/qfxfocuspanel.cpp \ fx/qfxfocusrealm.cpp \ fx/qfxgridview.cpp \ diff --git a/src/declarative/fx/qfxflipable.cpp b/src/declarative/fx/qfxflipable.cpp new file mode 100644 index 0000000..ee14348 --- /dev/null +++ b/src/declarative/fx/qfxflipable.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfxflipable.h" +#include "private/qfxitem_p.h" +#include "qfxtransform.h" +#include <QtDeclarative/qmlinfo.h> + +QML_DEFINE_TYPE(QFxFlipable,Flipable); + +class QFxFlipablePrivate : public QFxItemPrivate +{ +public: + QFxFlipablePrivate() : current(QFxFlipable::Front), front(0), back(0) {} + + QFxFlipable::Side current; + QFxItem *front; + QFxItem *back; +}; + +/*! + \qmlclass Flipable QFxFlipable + \brief The Flipable element provides a surface that can be flipped. + \inherits Item + + Flipable allows you to specify a front and a back and then flip between those sides. + + \code + <Flipable id="flipable" width="40" height="40"> + <transform> + <Axis id="axis" xStart="20" xEnd="20" yStart="20" yEnd="0" /> + </transform> + <front> + <Image file="front.png"/> + </front> + <back> + <Image file="back.png"/> + </back> + <states> + <State name="back"> + <SetProperty target="{axis}" property="rotation" value="180" /> + </State> + </states> + <transitions> + <Transition> + <NumericAnimation easing="easeInOutQuad" properties="rotation"/> + </Transition> + </transitions> + </Flipable> + \endcode + + \image flipable.gif +*/ + +/*! + \internal + \class QFxFlipable + \brief The QFxFlipable class provides a flipable surface. + + \ingroup group_widgets + + QFxFlipable allows you to specify a front and a back, as well as an + axis for the flip. +*/ + +QFxFlipable::QFxFlipable(QFxItem *parent) +: QFxItem(*(new QFxFlipablePrivate), parent) +{ +} + +QFxFlipable::~QFxFlipable() +{ +} + +/*! + \qmlproperty Item Flipable::front + \qmlproperty Item Flipable::back + + The front and back sides of the flipable. +*/ + +QFxItem *QFxFlipable::front() +{ + Q_D(const QFxFlipable); + return d->front; +} + +void QFxFlipable::setFront(QFxItem *front) +{ + Q_D(QFxFlipable); + if(d->front) { + qmlInfo(this) << "front is a write-once property"; + return; + } + d->front = front; + children()->append(d->front); + if(Back == d->current) + d->front->setOpacity(0.); +} + +QFxItem *QFxFlipable::back() +{ + Q_D(const QFxFlipable); + return d->back; +} + +void QFxFlipable::setBack(QFxItem *back) +{ + Q_D(QFxFlipable); + if(d->back) { + qmlInfo(this) << "back is a write-once property"; + return; + } + d->back = back; + children()->append(d->back); + if(Front == d->current) + d->back->setOpacity(0.); +} + +/*! + \qmlproperty enumeration Flipable::side + + The side of the Flippable currently visible. Possible values are \c + Front and \c Back. +*/ +QFxFlipable::Side QFxFlipable::side() const +{ + Q_D(const QFxFlipable); + return d->current; +} + +void QFxFlipable::transformChanged(const QSimpleCanvas::Matrix &trans) +{ + Q_D(QFxFlipable); + QPointF p1(0, 0); + QPointF p2(1, 0); + QPointF p3(1, 1); + + p1 = trans.map(p1); + p2 = trans.map(p2); + p3 = trans.map(p3); + + qreal cross = (p1.x() - p2.x()) * (p3.y() - p2.y()) - + (p1.y() - p2.y()) * (p3.x() - p2.x()); + + Side newSide; + if(cross > 0) { + newSide = Back; + } else { + newSide = Front; + } + + if(newSide != d->current) { + d->current = newSide; + if (d->current==Back) { + QSimpleCanvas::Matrix mat; +#ifdef QFX_RENDER_OPENGL + mat.translate(d->back->width()/2,d->back->height()/2, 0); + if(d->back->width() && p1.x() >= p2.x()) + mat.rotate(180, 0, 1, 0); + if(d->back->height() && p2.y() >= p3.y()) + mat.rotate(180, 1, 0, 0); + mat.translate(-d->back->width()/2,-d->back->height()/2, 0); +#else + mat.translate(d->back->width()/2,d->back->height()/2); + if(d->back->width() && p1.x() >= p2.x()) + mat.rotate(180, Qt::YAxis); + if(d->back->height() && p2.y() >= p3.y()) + mat.rotate(180, Qt::XAxis); + mat.translate(-d->back->width()/2,-d->back->height()/2); +#endif + d->back->setTransform(mat); + } + if(d->front) + d->front->setOpacity((d->current==Front)?1.:0.); + if(d->back) + d->back->setOpacity((d->current==Back)?1.:0.); + emit sideChanged(); + } +} + +QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxflipable.h b/src/declarative/fx/qfxflipable.h new file mode 100644 index 0000000..2c6c849 --- /dev/null +++ b/src/declarative/fx/qfxflipable.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFXFLIPABLE_H +#define QFXFLIPABLE_H + +#include <QObject> +#include <QTransform> +#if defined(QFX_RENDER_OPENGL) +#include <QtGui/qmatrix4x4.h> +#endif +#include <qfxitem.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QFxFlipablePrivate; +class Q_DECLARATIVE_EXPORT QFxFlipable : public QFxItem +{ + Q_OBJECT + + Q_ENUMS(Side); + Q_PROPERTY(QFxItem *front READ front WRITE setFront) + Q_PROPERTY(QFxItem *back READ back WRITE setBack) + Q_PROPERTY(Side side READ side NOTIFY sideChanged) +public: + QFxFlipable(QFxItem *parent=0); + ~QFxFlipable(); + + QFxItem *front(); + void setFront(QFxItem *); + + QFxItem *back(); + void setBack(QFxItem *); + + enum Side { Front, Back }; + Side side() const; + +protected: + virtual void transformChanged(const QSimpleCanvas::Matrix &); + +Q_SIGNALS: + void sideChanged(); + +private: + Q_DISABLE_COPY(QFxFlipable) + Q_DECLARE_PRIVATE(QFxFlipable) +}; +QML_DECLARE_TYPE(QFxFlipable); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QFXFLIPABLE_H diff --git a/src/declarative/fx/qfxtransform.cpp b/src/declarative/fx/qfxtransform.cpp index a001214..3f54949 100644 --- a/src/declarative/fx/qfxtransform.cpp +++ b/src/declarative/fx/qfxtransform.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE #define M_PI 3.14159265358979323846 #endif -QML_DEFINE_TYPE(QFxTransform,Transform); +QML_DEFINE_NOCREATE_TYPE(QFxTransform); /*! \qmlclass Transform @@ -62,6 +62,10 @@ QFxTransform::QFxTransform(QObject *parent) : { } +QFxTransform::~QFxTransform() +{ +} + bool QFxTransform::isIdentity() const { return true; @@ -79,132 +83,181 @@ void QFxTransform::update() item->updateTransform(); } -QML_DEFINE_TYPE(QFxAxis,Axis); +/*! + \qmlclass Axis + \brief An axis that can be used for rotation or translation. +*/ + +QML_DEFINE_TYPE(QFxAxis, Axis); QFxAxis::QFxAxis(QObject *parent) -: QFxTransform(parent), _xStart(0), _yStart(0), _xEnd(0), _yEnd(0), _zEnd(0), _rotation(0), - _translation(0), _distanceToPlane(1024.), _dirty(true) +: QObject(parent), _startX(0), _startY(0), _endX(0), _endY(0), _endZ(0) { } -qreal QFxAxis::xStart() const +QFxAxis::~QFxAxis() { - return _xStart; } -void QFxAxis::setXStart(qreal x) +qreal QFxAxis::startX() const { - _xStart = x; - update(); + return _startX; } -qreal QFxAxis::yStart() const +void QFxAxis::setStartX(qreal x) { - return _yStart; + _startX = x; + emit updated(); } -void QFxAxis::setYStart(qreal y) +qreal QFxAxis::startY() const { - _yStart = y; - update(); + return _startY; } -qreal QFxAxis::xEnd() const +void QFxAxis::setStartY(qreal y) { - return _xEnd; + _startY = y; + emit updated(); } -void QFxAxis::setXEnd(qreal x) +qreal QFxAxis::endX() const { - _xEnd = x; - update(); + return _endX; } -qreal QFxAxis::yEnd() const +void QFxAxis::setEndX(qreal x) { - return _yEnd; + _endX = x; + emit updated(); } -void QFxAxis::setYEnd(qreal y) +qreal QFxAxis::endY() const { - _yEnd = y; - update(); + return _endY; } -qreal QFxAxis::zEnd() const +void QFxAxis::setEndY(qreal y) { - return _zEnd; + _endY = y; + emit updated(); } -void QFxAxis::setZEnd(qreal z) +qreal QFxAxis::endZ() const { -#if !defined(QFX_RENDER_OPENGL) - if(z != 0. && translation() != 0.) { - qmlInfo(this) << "QTransform cannot translate along Z-axis"; - return; - } -#endif + return _endZ; +} - _zEnd = z; - update(); +void QFxAxis::setEndZ(qreal z) +{ + _endZ = z; + emit updated(); } -qreal QFxAxis::rotation() const +/*! + \qmlclass AxisRotation + \brief The AxisRotation element provides a way to rotate an Item around an axis. + + Here is an example of various rotations applied to an \l Image. + \code + <HorizontalLayout margin="10" spacing="10"> + <Image src="qt.png"/> + <Image src="qt.png"> + <transform> + <AxisRotation axis.startX="30" axis.endX="30" axis.endY="60" angle="18"/> + </transform> + </Image> + <Image src="qt.png"> + <transform> + <AxisRotation axis.startX="30" axis.endX="30" axis.endY="60" angle="36"/> + </transform> + </Image> + <Image src="qt.png"> + <transform> + <AxisRotation axis.startX="30" axis.endX="30" axis.endY="60" angle="54"/> + </transform> + </Image> + <Image src="qt.png"> + <transform> + <AxisRotation axis.startX="30" axis.endX="30" axis.endY="60" angle="72"/> + </transform> + </Image> + </HorizontalLayout> + \endcode + + \image axisrotation.png +*/ + +QML_DEFINE_TYPE(QFxRotation,AxisRotation); + +QFxRotation::QFxRotation(QObject *parent) +: QFxTransform(parent), _angle(0), _distanceToPlane(1024.), _dirty(true) { - return _rotation; + connect(&_axis, SIGNAL(updated()), this, SLOT(update())); } -void QFxAxis::setRotation(qreal r) +QFxRotation::~QFxRotation() { - _rotation = r; - update(); } -qreal QFxAxis::translation() const +/*! + \qmlproperty real AxisRotation::axis.startX + \qmlproperty real AxisRotation::axis.startY + \qmlproperty real AxisRotation::axis.endX + \qmlproperty real AxisRotation::axis.endY + \qmlproperty real AxisRotation::axis.endZ + + A rotation axis is specified by 2 points in 3D space: a start point and + an end point. The z-position of the start point is assumed to be 0, and cannot + be changed. +*/ +QFxAxis *QFxRotation::axis() { - return _translation; + return &_axis; } -void QFxAxis::setTranslation(qreal t) +/*! + \qmlproperty real AxisRotation::angle + + The angle, in degrees, to rotate around the specified axis. +*/ +qreal QFxRotation::angle() const { -#if !defined(QFX_RENDER_OPENGL) - if(zEnd() != 0. && t != 0.) { - qmlInfo(this) << "QTransform cannot translate along Z-axis"; - return; - } -#endif + return _angle; +} - _translation = t; +void QFxRotation::setAngle(qreal angle) +{ + _angle = angle; update(); } -bool QFxAxis::isIdentity() const +bool QFxRotation::isIdentity() const { - return (_rotation == 0. && _translation == 0.) || - (zEnd() == 0. && yEnd() == yStart() && xEnd() == xStart()); + return (_angle == 0.) || (_axis.endZ() == 0. && _axis.endY() == _axis.startY() && _axis.endX() == _axis.startX()); } #if defined(QFX_RENDER_QPAINTER) const qreal inv_dist_to_plane = 1. / 1024.; -QTransform QFxAxis::transform() const +QTransform QFxRotation::transform() const { if(_dirty) { _transform = QTransform(); if(!isIdentity()) { - if(rotation() != 0.) { + if(angle() != 0.) { QTransform rotTrans; - rotTrans.translate(-xStart(), -yStart()); + rotTrans.translate(-_axis.startX(), -_axis.startY()); QTransform rotTrans2; - rotTrans2.translate(xStart(), yStart()); + rotTrans2.translate(_axis.startX(), _axis.startY()); - qreal rad = rotation() * 2. * M_PI / 360.; + qreal rad = angle() * 2. * M_PI / 360.; qreal c = ::cos(rad); qreal s = ::sin(rad); - qreal x = xEnd() - xStart(); - qreal y = yEnd() - yStart(); - qreal z = zEnd(); + qreal x = _axis.endX() - _axis.startX(); + qreal y = _axis.endY() - _axis.startY(); + qreal z = _axis.endZ(); qreal idtp = inv_dist_to_plane; if(distanceToPlane() != 1024.) @@ -226,13 +279,6 @@ QTransform QFxAxis::transform() const _transform *= rot; _transform *= rotTrans2; } - - if(translation() != 0.) { - QTransform trans; - trans.translate((xEnd() - xStart()) * translation(), - (yEnd() - yStart()) * translation()); - _transform *= trans; - } } _dirty = false; @@ -241,27 +287,22 @@ QTransform QFxAxis::transform() const return _transform; } #elif defined(QFX_RENDER_OPENGL) -QMatrix4x4 QFxAxis::transform() const +QMatrix4x4 QFxRotation::transform() const { if(_dirty) { _dirty = false; _transform = QMatrix4x4(); if(!isIdentity()) { - if(rotation() != 0.) { - qreal x = xEnd() - xStart(); - qreal y = yEnd() - yStart(); - qreal z = zEnd(); - - _transform.translate(xStart(), yStart(), 0); - _transform.rotate(rotation(), x, y, z); - _transform.translate(-xStart(), -yStart(), 0); + if(angle() != 0.) { + qreal x = _axis.endX() - _axis.startX(); + qreal y = _axis.endY() - _axis.startY(); + qreal z = _axis.endZ(); + + _transform.translate(_axis.startX(), _axis.startY(), 0); + _transform.rotate(angle(), x, y, z); + _transform.translate(-_axis.startX(), -_axis.startY(), 0); } - - if(translation() != 0.) - _transform.translate((xEnd() - xStart()) * translation(), - (yEnd() - yStart()) * translation(), - (zEnd()) * translation()); } } @@ -269,18 +310,21 @@ QMatrix4x4 QFxAxis::transform() const } #endif -qreal QFxAxis::distanceToPlane() const +/*! + \qmlproperty real AxisRotation::distanceToPlane +*/ +qreal QFxRotation::distanceToPlane() const { return _distanceToPlane; } -void QFxAxis::setDistanceToPlane(qreal d) +void QFxRotation::setDistanceToPlane(qreal d) { _distanceToPlane = d; update(); } -void QFxAxis::update() +void QFxRotation::update() { _dirty = true; QFxItem *item = qobject_cast<QFxItem *>(parent()); @@ -288,179 +332,139 @@ void QFxAxis::update() item->updateTransform(); } -QML_DEFINE_TYPE(QFxFlipable,Flipable); - -class QFxFlipablePrivate : public QFxItemPrivate -{ -public: - QFxFlipablePrivate() : current(QFxFlipable::Front), front(0), back(0) {} - - QFxFlipable::Side current; - QFxItem *front; - QFxItem *back; -}; - /*! - \qmlclass Flipable QFxFlipable - \brief The Flipable element provides a surface that can be flipped. - \inherits Item - - Flipable allows you to specify a front and a back and then flip between those sides. + \qmlclass AxisTranslation + \brief The AxisTranslation element provides a way to move an Item along an axis. + The following example translates the image to 10, 3. \code - <Flipable id="flipable" width="40" height="40"> + <Image src="logo.png"> <transform> - <Axis id="axis" xStart="20" xEnd="20" yStart="20" yEnd="0" /> + <AxisTranslation axis.startX="0" axis.startY="0" axis.endX="1" axis.endY=".3" distance="10"/> </transform> - <front> - <Image file="front.png"/> - </front> - <back> - <Image file="back.png"/> - </back> - <states> - <State name="back"> - <SetProperty target="{axis}" property="rotation" value="180" /> - </State> - </states> - <transitions> - <Transition> - <NumericAnimation easing="easeInOutQuad" properties="rotation"/> - </Transition> - </transitions> - </Flipable> + </Image> \endcode - - \image flipable.gif */ -/*! - \internal - \class QFxFlipable - \brief The QFxFlipable class provides a flipable surface. +QML_DEFINE_TYPE(QFxTranslation,AxisTranslation); - \ingroup group_widgets - - QFxFlipable allows you to specify a front and a back, as well as an - axis for the flip. -*/ +QFxTranslation::QFxTranslation(QObject *parent) +: QFxTransform(parent), _distance(0), _dirty(true) +{ + connect(&_axis, SIGNAL(updated()), this, SLOT(update())); +} -QFxFlipable::QFxFlipable(QFxItem *parent) -: QFxItem(*(new QFxFlipablePrivate), parent) +QFxTranslation::~QFxTranslation() { } -QFxFlipable::~QFxFlipable() +/*! + \qmlproperty real AxisTranslation::axis.startX + \qmlproperty real AxisTranslation::axis.startY + \qmlproperty real AxisTranslation::axis.endX + \qmlproperty real AxisTranslation::axis.endY + \qmlproperty real AxisTranslation::axis.endZ + + A translation axis is specified by 2 points in 3D space: a start point and + an end point. The z-position of the start point is assumed to be 0, and cannot + be changed. Changing the z-position of the end point is only valid when running + under OpenGL. +*/ +QFxAxis *QFxTranslation::axis() { + return &_axis; } /*! - \qmlproperty Item Flipable::front - \qmlproperty Item Flipable::back + \qmlproperty real AxisTranslation::distance - The front and back sides of the flipable. -*/ + The distance to translate along the specified axis. distance is a multiplier; + in the example below, a distance of 1 would translate to 100, 50, while a distance + of 0.5 would translate to 50, 25. -QFxItem *QFxFlipable::front() + \code + <AxisTranslation axis.startX="0" axis.startY="0" axis.endX="100" axis.endY="50"/> + \endcode +*/ +qreal QFxTranslation::distance() const { - Q_D(const QFxFlipable); - return d->front; + return _distance; } -void QFxFlipable::setFront(QFxItem *front) +void QFxTranslation::setDistance(qreal distance) { - Q_D(QFxFlipable); - if(d->front) { - qmlInfo(this) << "front is a write-once property"; - return; - } - d->front = front; - children()->append(d->front); - if(Back == d->current) - d->front->setOpacity(0.); + _distance = distance; + update(); } -QFxItem *QFxFlipable::back() +bool QFxTranslation::isIdentity() const { - Q_D(const QFxFlipable); - return d->back; + return (_distance == 0.) || (_axis.endZ() == 0. && _axis.endY() == _axis.startY() && _axis.endX() == _axis.startX()); } -void QFxFlipable::setBack(QFxItem *back) +#if defined(QFX_RENDER_QPAINTER) +QTransform QFxTranslation::transform() const { - Q_D(QFxFlipable); - if(d->back) { - qmlInfo(this) << "back is a write-once property"; - return; - } - d->back = back; - children()->append(d->back); - if(Front == d->current) - d->back->setOpacity(0.); -} + if(_dirty) { + _transform = QTransform(); -/*! - \qmlproperty enumeration Flipable::side + if(!isIdentity()) { + if(distance() != 0.) { + QTransform trans; + trans.translate((_axis.endX() - _axis.startX()) * distance(), + (_axis.endY() - _axis.startY()) * distance()); + _transform *= trans; + } + } - The side of the Flippable currently visible. Possible values are \c - Front and \c Back. -*/ -QFxFlipable::Side QFxFlipable::side() const -{ - Q_D(const QFxFlipable); - return d->current; -} + _dirty = false; + } -void QFxFlipable::transformChanged(const QSimpleCanvas::Matrix &trans) + return _transform; +} +#elif defined(QFX_RENDER_OPENGL) +QMatrix4x4 QFxRotation::transform() const { - Q_D(QFxFlipable); - QPointF p1(0, 0); - QPointF p2(1, 0); - QPointF p3(1, 1); - - p1 = trans.map(p1); - p2 = trans.map(p2); - p3 = trans.map(p3); + if(_dirty) { + _dirty = false; + _transform = QMatrix4x4(); - qreal cross = (p1.x() - p2.x()) * (p3.y() - p2.y()) - - (p1.y() - p2.y()) * (p3.x() - p2.x()); + if(!isIdentity()) { + if(distance() != 0.) + _transform.translate((_axis.endX() - _axis.startX()) * distance(), + (_axis.endY() - _axis.startY()) * distance(), + (_axis.endZ()) * distance()); - Side newSide; - if(cross > 0) { - newSide = Back; - } else { - newSide = Front; + } } - if(newSide != d->current) { - d->current = newSide; - if (d->current==Back) { - QSimpleCanvas::Matrix mat; -#ifdef QFX_RENDER_OPENGL - mat.translate(d->back->width()/2,d->back->height()/2, 0); - if(d->back->width() && p1.x() >= p2.x()) - mat.rotate(180, 0, 1, 0); - if(d->back->height() && p2.y() >= p3.y()) - mat.rotate(180, 1, 0, 0); - mat.translate(-d->back->width()/2,-d->back->height()/2, 0); -#else - mat.translate(d->back->width()/2,d->back->height()/2); - if(d->back->width() && p1.x() >= p2.x()) - mat.rotate(180, Qt::YAxis); - if(d->back->height() && p2.y() >= p3.y()) - mat.rotate(180, Qt::XAxis); - mat.translate(-d->back->width()/2,-d->back->height()/2); + return _transform; +} #endif - d->back->setTransform(mat); - } - if(d->front) - d->front->setOpacity((d->current==Front)?1.:0.); - if(d->back) - d->back->setOpacity((d->current==Back)?1.:0.); - emit sideChanged(); + +void QFxTranslation::update() +{ + _dirty = true; + +#if !defined(QFX_RENDER_OPENGL) + if(_axis.endZ() != 0. && distance() != 0.) { + qmlInfo(this) << "QTransform cannot translate along Z-axis."; } +#endif + + QFxItem *item = qobject_cast<QFxItem *>(parent()); + if(item) + item->updateTransform(); } +/*! + \qmlclass Perspective + \brief The Perspective element specifies a perspective transformation. + + A Perspective transform only affects an item when running under OpenGL; when running under software + rasterization it has no effect. +*/ + QML_DEFINE_TYPE(QFxPerspective,Perspective); QFxPerspective::QFxPerspective(QObject *parent) @@ -468,6 +472,10 @@ QFxPerspective::QFxPerspective(QObject *parent) { } +QFxPerspective::~QFxPerspective() +{ +} + #if defined(QFX_RENDER_OPENGL) bool QFxPerspective::isIdentity() const { @@ -486,6 +494,33 @@ QMatrix4x4 QFxPerspective::transform() const } #endif +/*! + \qmlproperty real Perspective::angle +*/ + +/*! + \qmlproperty real Perspective::aspect +*/ + +/*! + \qmlproperty real Perspective::x +*/ + +/*! + \qmlproperty real Perspective::y +*/ + +/*! + \qmlproperty real Perspective::scale +*/ + +/*! + \qmlclass Squish + \brief The Squish element allows you to distort an items appearance by 'squishing' it. + + A Squish transform only affects an item when running under OpenGL; when running under software + rasterization it has no effect. +*/ QML_DEFINE_TYPE(QFxSquish,Squish); QFxSquish::QFxSquish(QObject *parent) @@ -493,6 +528,13 @@ QFxSquish::QFxSquish(QObject *parent) { } +QFxSquish::~QFxSquish() +{ +} + +/*! + \qmlproperty real Squish::x +*/ qreal QFxSquish::x() const { return p.x(); @@ -504,6 +546,9 @@ void QFxSquish::setX(qreal v) update(); } +/*! + \qmlproperty real Squish::y +*/ qreal QFxSquish::y() const { return p.y(); @@ -515,6 +560,9 @@ void QFxSquish::setY(qreal v) update(); } +/*! + \qmlproperty real Squish::width +*/ qreal QFxSquish::width() const { return s.width(); @@ -526,6 +574,9 @@ void QFxSquish::setWidth(qreal v) update(); } +/*! + \qmlproperty real Squish::height +*/ qreal QFxSquish::height() const { return s.height(); @@ -537,6 +588,10 @@ void QFxSquish::setHeight(qreal v) update(); } +/*! + \qmlproperty real Squish::topLeftX + \qmlproperty real Squish::topLeftY +*/ qreal QFxSquish::topLeft_x() const { return p1.x(); @@ -559,6 +614,10 @@ void QFxSquish::settopLeft_y(qreal v) update(); } +/*! + \qmlproperty real Squish::topRightX + \qmlproperty real Squish::topRightY +*/ qreal QFxSquish::topRight_x() const { return p2.x(); @@ -581,6 +640,10 @@ void QFxSquish::settopRight_y(qreal v) update(); } +/*! + \qmlproperty real Squish::bottomLeftX + \qmlproperty real Squish::bottomLeftY +*/ qreal QFxSquish::bottomLeft_x() const { return p3.x(); @@ -603,6 +666,10 @@ void QFxSquish::setbottomLeft_y(qreal v) update(); } +/*! + \qmlproperty real Squish::bottomRightX + \qmlproperty real Squish::bottomRightY +*/ qreal QFxSquish::bottomRight_x() const { return p4.x(); @@ -652,5 +719,6 @@ QMatrix4x4 QFxSquish::transform() const return rv; } -QT_END_NAMESPACE #endif + +QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxtransform.h b/src/declarative/fx/qfxtransform.h index 129a4b4..8a4eab1 100644 --- a/src/declarative/fx/qfxtransform.h +++ b/src/declarative/fx/qfxtransform.h @@ -49,17 +49,18 @@ #endif #include <qfxitem.h> - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE QT_MODULE(Declarative) + class Q_DECLARATIVE_EXPORT QFxTransform : public QObject { Q_OBJECT public: QFxTransform(QObject *parent=0); + ~QFxTransform(); void update(); @@ -68,37 +69,61 @@ public: }; QML_DECLARE_TYPE(QFxTransform); -class Q_DECLARATIVE_EXPORT QFxAxis : public QFxTransform +class Q_DECLARATIVE_EXPORT QFxAxis : public QObject { Q_OBJECT - Q_PROPERTY(qreal xStart READ xStart WRITE setXStart) - Q_PROPERTY(qreal yStart READ yStart WRITE setYStart) - Q_PROPERTY(qreal xEnd READ xEnd WRITE setXEnd) - Q_PROPERTY(qreal yEnd READ yEnd WRITE setYEnd) - Q_PROPERTY(qreal zEnd READ zEnd WRITE setZEnd) - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation) - Q_PROPERTY(qreal translation READ translation WRITE setTranslation) - Q_PROPERTY(qreal distanceToPlane READ distanceToPlane WRITE setDistanceToPlane) + Q_PROPERTY(qreal startX READ startX WRITE setStartX) + Q_PROPERTY(qreal startY READ startY WRITE setStartY) + Q_PROPERTY(qreal endX READ endX WRITE setEndX) + Q_PROPERTY(qreal endY READ endY WRITE setEndY) + Q_PROPERTY(qreal endZ READ endZ WRITE setEndZ) public: QFxAxis(QObject *parent=0); + ~QFxAxis(); + + qreal startX() const; + void setStartX(qreal); + + qreal startY() const; + void setStartY(qreal); + + qreal endX() const; + void setEndX(qreal); + + qreal endY() const; + void setEndY(qreal); + + qreal endZ() const; + void setEndZ(qreal); + +Q_SIGNALS: + void updated(); + +private: + qreal _startX; + qreal _startY; + qreal _endX; + qreal _endY; + qreal _endZ; +}; +QML_DECLARE_TYPE(QFxAxis); + +class Q_DECLARATIVE_EXPORT QFxRotation : public QFxTransform +{ + Q_OBJECT - qreal xStart() const; - void setXStart(qreal); - qreal yStart() const; - void setYStart(qreal); + Q_PROPERTY(QFxAxis *axis READ axis) + Q_PROPERTY(qreal angle READ angle WRITE setAngle) + Q_PROPERTY(qreal distanceToPlane READ distanceToPlane WRITE setDistanceToPlane) +public: + QFxRotation(QObject *parent=0); + ~QFxRotation(); - qreal xEnd() const; - void setXEnd(qreal); - qreal yEnd() const; - void setYEnd(qreal); - qreal zEnd() const; - void setZEnd(qreal); + QFxAxis *axis(); - qreal rotation() const; - void setRotation(qreal); - qreal translation() const; - void setTranslation(qreal); + qreal angle() const; + void setAngle(qreal); qreal distanceToPlane() const; void setDistanceToPlane(qreal); @@ -106,22 +131,46 @@ public: virtual bool isIdentity() const; virtual QSimpleCanvas::Matrix transform() const; -private: +private Q_SLOTS: void update(); - - qreal _xStart; - qreal _yStart; - qreal _xEnd; - qreal _yEnd; - qreal _zEnd; - qreal _rotation; - qreal _translation; +private: + QFxAxis _axis; + qreal _angle; qreal _distanceToPlane; mutable bool _dirty; mutable QSimpleCanvas::Matrix _transform; }; -QML_DECLARE_TYPE(QFxAxis); +QML_DECLARE_TYPE(QFxRotation); + +class Q_DECLARATIVE_EXPORT QFxTranslation : public QFxTransform +{ + Q_OBJECT + + Q_PROPERTY(QFxAxis *axis READ axis) + Q_PROPERTY(qreal distance READ distance WRITE setDistance) +public: + QFxTranslation(QObject *parent=0); + ~QFxTranslation(); + + QFxAxis *axis(); + + qreal distance() const; + void setDistance(qreal); + + virtual bool isIdentity() const; + virtual QSimpleCanvas::Matrix transform() const; + +private Q_SLOTS: + void update(); +private: + QFxAxis _axis; + qreal _distance; + + mutable bool _dirty; + mutable QSimpleCanvas::Matrix _transform; +}; +QML_DECLARE_TYPE(QFxTranslation); class Q_DECLARATIVE_EXPORT QFxPerspective : public QFxTransform { @@ -134,6 +183,7 @@ class Q_DECLARATIVE_EXPORT QFxPerspective : public QFxTransform Q_PROPERTY(qreal scale READ scale WRITE setScale) public: QFxPerspective(QObject *parent=0); + ~QFxPerspective(); qreal angle() const { return _angle; } void setAngle(qreal v) { _angle = v; update(); } @@ -171,16 +221,17 @@ class Q_DECLARATIVE_EXPORT QFxSquish : public QFxTransform Q_PROPERTY(qreal y READ y WRITE setY) Q_PROPERTY(qreal width READ width WRITE setWidth) Q_PROPERTY(qreal height READ height WRITE setHeight) - Q_PROPERTY(qreal topLeft_x READ topLeft_x WRITE settopLeft_x) - Q_PROPERTY(qreal topLeft_y READ topLeft_y WRITE settopLeft_y) - Q_PROPERTY(qreal topRight_x READ topRight_x WRITE settopRight_x) - Q_PROPERTY(qreal topRight_y READ topRight_y WRITE settopRight_y) - Q_PROPERTY(qreal bottomLeft_x READ bottomLeft_x WRITE setbottomLeft_x) - Q_PROPERTY(qreal bottomLeft_y READ bottomLeft_y WRITE setbottomLeft_y) - Q_PROPERTY(qreal bottomRight_y READ bottomRight_y WRITE setbottomRight_y) - Q_PROPERTY(qreal bottomRight_x READ bottomRight_x WRITE setbottomRight_x) + Q_PROPERTY(qreal topLeftX READ topLeft_x WRITE settopLeft_x) + Q_PROPERTY(qreal topLeftY READ topLeft_y WRITE settopLeft_y) + Q_PROPERTY(qreal topRightX READ topRight_x WRITE settopRight_x) + Q_PROPERTY(qreal topRightY READ topRight_y WRITE settopRight_y) + Q_PROPERTY(qreal bottomLeftX READ bottomLeft_x WRITE setbottomLeft_x) + Q_PROPERTY(qreal bottomLeftY READ bottomLeft_y WRITE setbottomLeft_y) + Q_PROPERTY(qreal bottomRightX READ bottomRight_x WRITE setbottomRight_x) + Q_PROPERTY(qreal bottomRightY READ bottomRight_y WRITE setbottomRight_y) public: QFxSquish(QObject *parent=0); + ~QFxSquish(); qreal x() const; void setX(qreal); @@ -230,45 +281,10 @@ private: QSizeF s; QPointF p1, p2, p3, p4; }; - QML_DECLARE_TYPE(QFxSquish); -class QFxFlipablePrivate; -class Q_DECLARATIVE_EXPORT QFxFlipable : public QFxItem -{ - Q_OBJECT - - Q_ENUMS(Side); - Q_PROPERTY(QFxItem *front READ front WRITE setFront) - Q_PROPERTY(QFxItem *back READ back WRITE setBack) - Q_PROPERTY(Side side READ side NOTIFY sideChanged) -public: - QFxFlipable(QFxItem *parent=0); - ~QFxFlipable(); - - QFxItem *front(); - void setFront(QFxItem *); - - QFxItem *back(); - void setBack(QFxItem *); - - enum Side { Front, Back }; - Side side() const; - -protected: - virtual void transformChanged(const QSimpleCanvas::Matrix &); - -Q_SIGNALS: - void sideChanged(); - -private: - Q_DISABLE_COPY(QFxFlipable) - Q_DECLARE_PRIVATE(QFxFlipable) -}; -QML_DECLARE_TYPE(QFxFlipable); - - QT_END_NAMESPACE QT_END_HEADER -#endif // _TRANSFORM_H_ + +#endif // QFXTRANSFORM_H |