diff options
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/graphicsview.pri | 4 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 339 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 42 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 39 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicstransform.cpp | 479 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicstransform.h | 168 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 33 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.h | 8 |
8 files changed, 782 insertions, 330 deletions
diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 0c0747e..9d232e4 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -16,12 +16,13 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ + graphicsview/qgraphicstransform.h \ + graphicsview/qgraphicstransform_p.h \ graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ graphicsview/qgridlayoutengine_p.h - SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsitemanimation.cpp \ @@ -36,6 +37,7 @@ SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicssceneevent.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicsscenelinearindex.cpp \ + graphicsview/qgraphicstransform.cpp \ graphicsview/qgraphicsview.cpp \ graphicsview/qgraphicswidget.cpp \ graphicsview/qgraphicswidget_p.cpp \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 06f26a1..6770206 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1197,6 +1197,13 @@ QGraphicsItem::~QGraphicsItem() else d_ptr->setParentItemHelper(0); + if (d_ptr->transformData) { + for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) { + QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i); + static_cast<QGraphicsTransformPrivate *>(t->d_ptr)->item = 0; + delete t; + } + } delete d_ptr->transformData; delete d_ptr; @@ -2980,94 +2987,19 @@ QTransform QGraphicsItem::transform() const /*! \since 4.6 - Returns the rotation around the X axis. - - The default is 0 - - \warning The value doesn't take in account any rotation set with - the setTransform() method. - - \sa setXRotation(), {Transformations} -*/ -qreal QGraphicsItem::xRotation() const -{ - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->xRotation; -} - -/*! - \since 4.6 - - Sets the rotation around the X axis to \a angle degrees. - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa xRotation(), setTransformOrigin(), {Transformations} -*/ -void QGraphicsItem::setXRotation(qreal angle) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xRotation = angle; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - Returns the rotation around the Y axis. - - The default is 0 - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa setYRotation(), {Transformations} -*/ -qreal QGraphicsItem::yRotation() const -{ - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->yRotation; -} - -/*! - \since 4.6 - - Sets the rotation around the Y axis to \a angle degrees. - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa yRotation(), setTransformOrigin() {Transformations} -*/ -void QGraphicsItem::setYRotation(qreal angle) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->yRotation = angle; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - Returns the rotation around the Z axis. The default is 0 \warning The value doesn't take in account any rotation set with the setTransform() method. - \sa setZRotation(), {Transformations} + \sa setRotation(), {Transformations} */ -qreal QGraphicsItem::zRotation() const +qreal QGraphicsItem::rotation() const { if (!d_ptr->transformData) return 0; - return d_ptr->transformData->zRotation; + return d_ptr->transformData->rotation; } /*! @@ -3077,224 +3009,107 @@ qreal QGraphicsItem::zRotation() const \warning The value doesn't take in account any rotation set with the setTransform() method. - \sa zRotation(), setTransformOrigin(), {Transformations} + \sa rotation(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setZRotation(qreal angle) +void QGraphicsItem::setRotation(qreal angle) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->zRotation = angle; + d_ptr->transformData->rotation = angle; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - This convenience function set the rotation angles around the 3 axes - to \a x, \a y and \a z. - - \sa setXRotation(), setYRotation(), setZRotation(), {Transformations} -*/ -void QGraphicsItem::setRotation(qreal x, qreal y, qreal z) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xRotation = x; - d_ptr->transformData->yRotation = y; - d_ptr->transformData->zRotation = z; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + if (d_ptr->isObject) + emit static_cast<QGraphicsObject *>(this)->rotationChanged(); } /*! \since 4.6 - Returns the scale factor on the X axis. + Returns the scale factor of the item. The default is 1 \warning The value doesn't take in account any scaling set with the setTransform() method. - \sa setXScale(), {Transformations} + \sa setScale(), {Transformations} */ -qreal QGraphicsItem::xScale() const +qreal QGraphicsItem::scale() const { if (!d_ptr->transformData) - return 1; - return d_ptr->transformData->xScale; + return 1.; + return d_ptr->transformData->scale; } /*! \since 4.6 - Sets the scale factor on the X axis to \a factor. + Sets the scale factor of the item to \a factor. \warning The value doesn't take in account any scaling set with the setTransform() method. - \sa xScale(), setTransformOrigin(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setXScale(qreal factor) +void QGraphicsItem::setScale(qreal factor) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xScale = factor; + d_ptr->transformData->scale = factor; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - Returns the scale factor on the Y axis. - - The default is 1 - - \warning The value doesn't take in account any scaling set with the setTransform() method. - - \sa setYScale(), {Transformations} -*/ -qreal QGraphicsItem::yScale() const -{ - if (!d_ptr->transformData) - return 1; - return d_ptr->transformData->yScale; -} - -/*! - \since 4.6 - - Sets the scale factor on the Y axis to \a factor. - \warning The value doesn't take in account any scaling set with the setTransform() method. - - \sa yScale(), setTransformOrigin(), {Transformations} -*/ -void QGraphicsItem::setYScale(qreal factor) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->yScale = factor; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + if (d_ptr->isObject) + emit static_cast<QGraphicsObject *>(this)->scaleChanged(); } -/*! - \since 4.6 - - This convenience function set the scaling factors on X and Y axis to \a sx and \a sy. - - \warning The value doesn't take in account any scaling set with the setTransform() method. - - \sa setXScale(), setYScale(), {Transformations} -*/ -void QGraphicsItem::setScale(qreal sx, qreal sy) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xScale = sx; - d_ptr->transformData->yScale = sy; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} /*! \since 4.6 - Returns the horizontal shear. - - The default is 0 - - \warning The value doesn't take in account any shearing set with the setTransform() method. + returns list of graphics transformations on the item. - \sa setHorizontalShear(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -qreal QGraphicsItem::horizontalShear() const +QList<QGraphicsTransform *> QGraphicsItem::transformations() const { if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->horizontalShear; + return QList<QGraphicsTransform *>(); + return d_ptr->transformData->graphicsTransforms; } /*! \since 4.6 - Sets the horizontal shear to \a shear. - - \warning The value doesn't take in account any shearing set with the setTransform() method. + Sets a list of graphics transformations on the item to \a transformations. - \sa horizontalShear(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setHorizontalShear(qreal shear) +void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->horizontalShear = shear; + d_ptr->transformData->graphicsTransforms = transformations; + for (int i = 0; i < transformations.size(); ++i) + transformations.at(i)->d_func()->setItem(this); d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; } -/*! - \since 4.6 - - Returns the vertical shear. - - The default is 0 - - \warning The value doesn't take in account any shearing set with the setTransform() method. - \sa setHorizontalShear(), {Transformations} -*/ -qreal QGraphicsItem::verticalShear() const +void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t) { - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->verticalShear; -} + if (!transformData) + transformData = new QGraphicsItemPrivate::TransformData; + if (!transformData->graphicsTransforms.contains(t)) + transformData->graphicsTransforms.append(t); -/*! - \since 4.6 - - Sets the vertical shear to \a shear. - - \warning The value doesn't take in account any shearing set with the setTransform() method. - - \sa verticalShear(), {Transformations} -*/ -void QGraphicsItem::setVerticalShear(qreal shear) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->verticalShear = shear; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - This convenience function sets the horizontal shear to \a sh and the vertical shear to \a sv. - - \warning The value doesn't take in account any shearing set with the setTransform() method. - - \sa setHorizontalShear(), setVerticalShear() -*/ -void QGraphicsItem::setShear(qreal sh, qreal sv) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->horizontalShear = sh; - d_ptr->transformData->verticalShear = sv; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + Q_Q(QGraphicsItem); + t->d_func()->setItem(q); + transformData->onlyTransform = false; + dirtySceneTransform = 1; } /*! @@ -3304,9 +3119,9 @@ void QGraphicsItem::setShear(qreal sh, qreal sv) The default is QPointF(0,0). - \sa setTransformOrigin(), {Transformations} + \sa setTransformOriginPoint(), {Transformations} */ -QPointF QGraphicsItem::transformOrigin() const +QPointF QGraphicsItem::transformOriginPoint() const { if (!d_ptr->transformData) return QPointF(0,0); @@ -3318,9 +3133,9 @@ QPointF QGraphicsItem::transformOrigin() const Sets the \a origin point for the transformation in item coordinates. - \sa transformOrigin(), {Transformations} + \sa transformOriginPoint(), {Transformations} */ -void QGraphicsItem::setTransformOrigin(const QPointF &origin) +void QGraphicsItem::setTransformOriginPoint(const QPointF &origin) { prepareGeometryChange(); if (!d_ptr->transformData) @@ -3332,15 +3147,15 @@ void QGraphicsItem::setTransformOrigin(const QPointF &origin) } /*! - \fn void QGraphicsItem::setTransformOrigin(qreal x, qreal y) + \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y) \since 4.6 \overload Sets the origin point for the transformation in item coordinates. - This is equivalent to calling setTransformOrigin(QPointF(\a x, \a y)). + This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)). - \sa setTransformOrigin(), {Transformations} + \sa setTransformOriginPoint(), {Transformations} */ @@ -3619,7 +3434,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) \warning using this function doesnt affect the value of the transformation properties - \sa transform(), setRotation(), setScale(), setShear(), setTransformOrigin(), {The Graphics View Coordinate System}, {Transformations} + \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations} */ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) { @@ -3733,7 +3548,7 @@ void QGraphicsItem::shear(qreal sh, qreal sv) /*! \obsolete - Use setPos() or setTransformOrigin() instead. + Use setPos() or setTransformOriginPoint() instead. Translates the current item transformation by (\a dx, \a dy). @@ -6857,6 +6672,41 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent \sa pos() */ +/*! + \property QGraphicsObject::rotation + This property holds the rotation of the item in degrees. + + This specifies how many degrees to rotate the item around its transformOrigin. + The default rotation is 0 degrees (i.e. not rotated at all). +*/ + +/*! + \fn QGraphicsObject::rotationChanged() + + This signal gets emitted whenever the roation of the item changes. +*/ + +/*! + \property QGraphicsObject::scale + This property holds the scale of the item. + + A scale of less than 1 means the item will be displayed smaller than + normal, and a scale of greater than 1 means the item will be + displayed larger than normal. A negative scale means the item will + be mirrored. + + By default, items are displayed at a scale of 1 (i.e. at their + normal size). + + Scaling is from the item's transformOrigin. +*/ + +/*! + \fn void QGraphicsObject::scaleChanged() + + This signal is emitted when the scale of the item changes. +*/ + /*! \property QGraphicsObject::enabled @@ -6896,6 +6746,15 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent \sa visible */ +/*! + \property QGraphicsObject::transformOriginPoint + \brief the transformation origin + + This property sets a specific point in the items coordiante system as the + origin for scale and rotation. + + \sa scale, rotation, QGraphicsItem::transformOriginPoint() +*/ /*! diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 0e21a47..945163f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -71,6 +71,7 @@ class QGraphicsSceneHoverEvent; class QGraphicsSceneMouseEvent; class QGraphicsSceneWheelEvent; class QGraphicsScene; +class QGraphicsTransform; class QGraphicsWidget; class QInputMethodEvent; class QKeyEvent; @@ -268,34 +269,19 @@ public: void shear(qreal sh, qreal sv); // ### obsolete void translate(qreal dx, qreal dy); // ### obsolete - qreal xRotation() const; - void setXRotation(qreal angle); + void setRotation(qreal angle); + qreal rotation() const; - qreal yRotation() const; - void setYRotation(qreal angle); + void setScale(qreal scale); + qreal scale() const; - qreal zRotation() const; - void setZRotation(qreal angle); - void setRotation(qreal x, qreal y, qreal z); + QList<QGraphicsTransform *> transformations() const; + void setTransformations(const QList<QGraphicsTransform *> &transformations); - qreal xScale() const; - void setXScale(qreal factor); - - qreal yScale() const; - void setYScale(qreal factor); - void setScale(qreal sx, qreal sy); - - qreal horizontalShear() const; - void setHorizontalShear(qreal shear); - - qreal verticalShear() const; - void setVerticalShear(qreal shear); - void setShear(qreal sh, qreal sv); - - QPointF transformOrigin() const; - void setTransformOrigin(const QPointF &origin); - inline void setTransformOrigin(qreal x, qreal y) - { setTransformOrigin(QPointF(x,y)); } + QPointF transformOriginPoint() const; + void setTransformOriginPoint(const QPointF &origin); + inline void setTransformOriginPoint(qreal x, qreal y) + { setTransformOriginPoint(QPointF(x,y)); } virtual void advance(int phase); @@ -456,6 +442,7 @@ private: friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; friend class QGraphicsSceneBspTreeIndexPrivate; + friend class QGraphicsTransformPrivate; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); @@ -521,6 +508,9 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged) + Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) + Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) + Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) public: QGraphicsObject(QGraphicsItem *parent = 0); @@ -532,6 +522,8 @@ Q_SIGNALS: void xChanged(); void yChanged(); void zChanged(); + void rotationChanged(); + void scaleChanged(); protected: QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c208b99..b8d98c1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -57,6 +57,8 @@ #include "qset.h" #include "qpixmapcache.h" #include "qgraphicsview_p.h" +#include "qgraphicstransform.h" +#include "qgraphicstransform_p.h" #include <QtCore/qpoint.h> @@ -192,7 +194,7 @@ public: void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const; void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const; - void updateSceneTransformFromParent(); + virtual void updateSceneTransformFromParent(); // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4. virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const; @@ -200,6 +202,7 @@ public: void setPosHelper(const QPointF &pos); void setTransformHelper(const QTransform &transform); + void appendGraphicsTransform(QGraphicsTransform *t); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, @@ -467,45 +470,35 @@ public: struct QGraphicsItemPrivate::TransformData { QTransform transform; - qreal xScale; - qreal yScale; - qreal xRotation; - qreal yRotation; - qreal zRotation; - qreal horizontalShear; - qreal verticalShear; + qreal scale; + qreal rotation; qreal xOrigin; qreal yOrigin; + QList<QGraphicsTransform *> graphicsTransforms; bool onlyTransform; TransformData() : - xScale(1.0), yScale(1.0), xRotation(0.0), yRotation(0.0), zRotation(0.0), - horizontalShear(0.0), verticalShear(0.0), xOrigin(0.0), yOrigin(0.0), + scale(1.0), rotation(0.0), + xOrigin(0.0), yOrigin(0.0), onlyTransform(true) {} QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const { if (onlyTransform) { - if (!postmultiplyTransform) - return transform; - if (postmultiplyTransform->isIdentity()) + if (!postmultiplyTransform || postmultiplyTransform->isIdentity()) return transform; if (transform.isIdentity()) return *postmultiplyTransform; - QTransform x(transform); - x *= *postmultiplyTransform; - return x; + return transform * *postmultiplyTransform; } QTransform x(transform); - if (xOrigin != 0 || yOrigin != 0) - x *= QTransform::fromTranslate(xOrigin, yOrigin); - x.rotate(xRotation, Qt::XAxis); - x.rotate(yRotation, Qt::YAxis); - x.rotate(zRotation, Qt::ZAxis); - x.shear(horizontalShear, verticalShear); - x.scale(xScale, yScale); + for (int i = 0; i < graphicsTransforms.size(); ++i) + graphicsTransforms.at(i)->applyTo(&x); + x.translate(xOrigin, yOrigin); + x.rotate(rotation, Qt::ZAxis); + x.scale(scale, scale); x.translate(-xOrigin, -yOrigin); if (postmultiplyTransform) x *= *postmultiplyTransform; diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp new file mode 100644 index 0000000..f18752a --- /dev/null +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -0,0 +1,479 @@ +/**************************************************************************** +** +** 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 "qgraphicstransform.h" +#include "qgraphicsitem_p.h" +#include "qgraphicstransform_p.h" +#include <QDebug> + +#include <math.h> +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +QT_BEGIN_NAMESPACE + + +void QGraphicsTransformPrivate::setItem(QGraphicsItem *i) +{ + if (item == i) + return; + + if (item) { + Q_Q(QGraphicsTransform); + QGraphicsItemPrivate *d_ptr = item->d_ptr; + + item->prepareGeometryChange(); + Q_ASSERT(d_ptr->transformData); + d_ptr->transformData->graphicsTransforms.remove(q); + d_ptr->dirtySceneTransform = 1; + item = 0; + } + + item = i; +} + +void QGraphicsTransformPrivate::updateItem(QGraphicsItem *item) +{ + item->prepareGeometryChange(); + item->d_ptr->dirtySceneTransform = 1; +} + +void QGraphicsTransform::update() +{ + Q_D(QGraphicsTransform); + if (d->item) + d->updateItem(d->item); +} + +/*! + returns this object as a QTransform. +*/ +QTransform QGraphicsTransform::transform() const +{ + QTransform t; + applyTo(&t); + return t; +} + +/*! + \class QGraphicsTransform + \brief The QGraphicsTransform class is an abstract base class for tranformations on QGraphicsItems. + \since 4.6 + + The classes that inherit QGraphicsTransform express different types of transformations + that can be applied to graphics items. + + A list of these transformations can be applied to any graphics item. These + transformations are then easily modifyable and usable from e.g. within animations. + + QGraphicsTransform is an abstract base class that is implemented by QGraphicsScale, + QGraphicsRotation and QGraphicsRotation3D. Subclasses have to implement the applyTo method. + + \sa QGraphicsItem::transform(), QGraphicsScale, QGraphicsRotation, QGraphicsRotation3D +*/ + +/*! + Constructs a new QGraphicsTransform with \a parent. +*/ +QGraphicsTransform::QGraphicsTransform(QObject *parent) : + QObject(*new QGraphicsTransformPrivate, parent) +{ +} + +/*! + Destructs the graphics transform. +*/ +QGraphicsTransform::~QGraphicsTransform() +{ + Q_D(QGraphicsTransform); + d->setItem(0); +} + +/*! + \internal +*/ +QGraphicsTransform::QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent) + : QObject(p, parent) +{ +} + +/*! \fn void QGraphicsTransform::applyTo(QTransform *transform) const + + This pure virtual method has to be reimplemented in derived classes. + + It applies this transformation to \a transform. +*/ + + +/*! + \class QGraphicsScale + \brief The QGraphicsScale class provides a way to scale a graphics item in 2 dimensions. + \since 4.6 + + QGraphicsScale contains an \a origin around which the scaling happens, and two + scale factors, xScale and yScale, the x and one for the y axis. +*/ + +class QGraphicsScalePrivate : public QGraphicsTransformPrivate +{ +public: + QGraphicsScalePrivate() + : xScale(1), yScale(1) {} + QPointF origin; + qreal xScale; + qreal yScale; +}; + +/*! + Constructs a new graphics scale object with \a parent. +*/ +QGraphicsScale::QGraphicsScale(QObject *parent) + : QGraphicsTransform(*new QGraphicsScalePrivate, parent) +{ +} + +/*! + Destroys the object +*/ +QGraphicsScale::~QGraphicsScale() +{ +} + +/*! + \property QGraphicsScale::origin + The origin of the scale. All scaling will be done relative to this point. + + The \a origin is in other words the fixed point for the transformation. +*/ +QPointF QGraphicsScale::origin() const +{ + Q_D(const QGraphicsScale); + return d->origin; +} + +void QGraphicsScale::setOrigin(const QPointF &point) +{ + Q_D(QGraphicsScale); + d->origin = point; + update(); + emit originChanged(); +} + +/*! + \fn QGraphicsScale::originChanged() + + This signal is emitted whenever the origin of the object + changes. +*/ + +/*! + \property QGraphicsScale::xScale + + The scale factor in x direction. The x direction is + in the graphics items logical coordinates. + + \sa yScale +*/ +qreal QGraphicsScale::xScale() const +{ + Q_D(const QGraphicsScale); + return d->xScale; +} + +void QGraphicsScale::setXScale(qreal scale) +{ + Q_D(QGraphicsScale); + if (d->xScale == scale) + return; + d->xScale = scale; + update(); + emit scaleChanged(); +} + +/*! + \property QGraphicsScale::yScale + + The scale factor in y direction. The y direction is + in the graphics items logical coordinates. + + \sa xScale +*/ +qreal QGraphicsScale::yScale() const +{ + Q_D(const QGraphicsScale); + return d->yScale; +} + +void QGraphicsScale::setYScale(qreal scale) +{ + Q_D(QGraphicsScale); + if (d->yScale == scale) + return; + d->yScale = scale; + update(); + emit scaleChanged(); +} + +/*! + \fn QGraphicsScale::scaleChanged() + + This signal is emitted whenever the xScale or yScale of the object + changes. +*/ + +/*! + \reimp +*/ +void QGraphicsScale::applyTo(QTransform *transform) const +{ + Q_D(const QGraphicsScale); + transform->translate(d->origin.x(), d->origin.y()); + transform->scale(d->xScale, d->yScale); + transform->translate(-d->origin.x(), -d->origin.y()); +} + +/*! + \class QGraphicsRotation + \brief The QGraphicsRotation class provides a way to rotate a graphics item in 2 dimensions. + \since 4.6 + + QGraphicsRotation contains an \a origin around which the rotation happens, and one + angle in degrees describing the amount of the rotation. +*/ + +class QGraphicsRotationPrivate : public QGraphicsTransformPrivate +{ +public: + QGraphicsRotationPrivate() + : angle(0) {} + QPointF origin; + qreal originY; + qreal angle; +}; + +/*! + Constructs a new graphics rotation with \a parent. +*/ +QGraphicsRotation::QGraphicsRotation(QObject *parent) + : QGraphicsTransform(*new QGraphicsRotationPrivate, parent) +{ +} + +/*! + \internal +*/ +QGraphicsRotation::QGraphicsRotation(QGraphicsRotationPrivate &p, QObject *parent) + : QGraphicsTransform(p, parent) +{ +} + +/*! + Destructs the object +*/ +QGraphicsRotation::~QGraphicsRotation() +{ +} + +/*! + \property QGraphicsRotation::origin + The origin around which this object will rotate the graphics item. + + The \a origin is in other words the fixed point for the transformation. +*/ +QPointF QGraphicsRotation::origin() const +{ + Q_D(const QGraphicsRotation); + return d->origin; +} + +void QGraphicsRotation::setOrigin(const QPointF &point) +{ + Q_D(QGraphicsRotation); + d->origin = point; + update(); + emit originChanged(); +} + +/*! + \fn QGraphicsRotation::originChanged() + + This signal is emitted whenever the origin of the object + changes. +*/ + +/*! + \property QGraphicsRotation::angle + The angle, in degrees, of the rotation. +*/ +qreal QGraphicsRotation::angle() const +{ + Q_D(const QGraphicsRotation); + return d->angle; +} + +void QGraphicsRotation::setAngle(qreal angle) +{ + Q_D(QGraphicsRotation); + if (d->angle == angle) + return; + d->angle = angle; + update(); + emit angleChanged(); +} + +/*! + \fn void QGraphicsRotation::angleChanged() + + This signal is emitted whenever the angle of the object + changes. +*/ + +/*! + \reimp +*/ +void QGraphicsRotation::applyTo(QTransform *t) const +{ + Q_D(const QGraphicsRotation); + if(d->angle) { + t->translate(d->origin.x(), d->origin.y()); + t->rotate(d->angle); + t->translate(-d->origin.x(), -d->origin.y()); + } +} + + +/*! + \class QGraphicsRotation3D + \brief The QGraphicsRotation3D class provides a way to rotate a graphics item in 3 dimensions. + \since 4.6 + + In addition to the origin and angle of a simple QGraphicsRotation, QGraphicsRotation3D contains + also an axis that describes around which axis in space the rotation is supposed to happen. +*/ + +class QGraphicsRotation3DPrivate : public QGraphicsRotationPrivate +{ +public: + QGraphicsRotation3DPrivate() {} + + QVector3D axis; +}; + +/*! + Constructs a new 3D rotation with \a parent. +*/ +QGraphicsRotation3D::QGraphicsRotation3D(QObject *parent) + : QGraphicsRotation(*new QGraphicsRotation3DPrivate, parent) +{ +} + +/*! + Destroys the object +*/ +QGraphicsRotation3D::~QGraphicsRotation3D() +{ +} + +/*! + \property QGraphicsRotation3D::axis + + A rotation axis is specified by a vector in 3D space. +*/ +QVector3D QGraphicsRotation3D::axis() +{ + Q_D(QGraphicsRotation3D); + return d->axis; +} + +void QGraphicsRotation3D::setAxis(const QVector3D &axis) +{ + Q_D(QGraphicsRotation3D); + d->axis = axis; + update(); +} + +/*! + \fn void QGraphicsRotation3D::axisChanged() + + This signal is emitted whenever the axis of the object + changes. +*/ + +const qreal inv_dist_to_plane = 1. / 1024.; + +/*! + \reimp +*/ +void QGraphicsRotation3D::applyTo(QTransform *t) const +{ + Q_D(const QGraphicsRotation3D); + + if (d->angle == 0. || + (d->axis.z() == 0. && d->axis.y() == 0 && d->axis.x() == 0)) + return; + + qreal rad = d->angle * 2. * M_PI / 360.; + qreal c = ::cos(rad); + qreal s = ::sin(rad); + + qreal x = d->axis.x(); + qreal y = d->axis.y(); + qreal z = d->axis.z(); + + qreal len = x * x + y * y + z * z; + if (len != 1.) { + len = 1./::sqrt(len); + x *= len; + y *= len; + z *= len; + } + + t->translate(d->origin.x(), d->origin.y()); + *t = QTransform(x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s*inv_dist_to_plane, + y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s*inv_dist_to_plane, + 0, 0, 1) * *t; + t->translate(-d->origin.x(), -d->origin.y()); +} + +#include "moc_qgraphicstransform.cpp" + +QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h new file mode 100644 index 0000000..adf9438 --- /dev/null +++ b/src/gui/graphicsview/qgraphicstransform.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 QGRAPHICSTRANSFORM_H +#define QGRAPHICSTRANSFORM_H + +#include <QtCore/QObject> +#include <QtGui/QTransform> +#include <QtGui/QVector3D> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QGraphicsItem; +class QGraphicsTransformPrivate; + +class Q_GUI_EXPORT QGraphicsTransform : public QObject +{ + Q_OBJECT +public: + QGraphicsTransform(QObject *parent = 0); + ~QGraphicsTransform(); + + QTransform transform() const; + virtual void applyTo(QTransform *transform) const = 0; + +protected slots: + void update(); + +protected: + QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent); +private: + friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + Q_DECLARE_PRIVATE(QGraphicsTransform) +}; + +class QGraphicsScalePrivate; + +class Q_GUI_EXPORT QGraphicsScale : public QGraphicsTransform +{ + Q_OBJECT + + Q_PROPERTY(QPointF origin READ origin WRITE setOrigin NOTIFY originChanged) + Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY scaleChanged) + Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY scaleChanged) +public: + QGraphicsScale(QObject *parent = 0); + ~QGraphicsScale(); + + QPointF origin() const; + void setOrigin(const QPointF &point); + + qreal xScale() const; + void setXScale(qreal); + + qreal yScale() const; + void setYScale(qreal); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void originChanged(); + void scaleChanged(); + +private: + Q_DECLARE_PRIVATE(QGraphicsScale) +}; + +class QGraphicsRotationPrivate; + +class Q_GUI_EXPORT QGraphicsRotation : public QGraphicsTransform +{ + Q_OBJECT + + Q_PROPERTY(QPointF origin READ origin WRITE setOrigin NOTIFY originChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) +public: + QGraphicsRotation(QObject *parent = 0); + ~QGraphicsRotation(); + + QPointF origin() const; + void setOrigin(const QPointF &point); + + qreal angle() const; + void setAngle(qreal); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void originChanged(); + void angleChanged(); + +protected: + QGraphicsRotation(QGraphicsRotationPrivate &p, QObject *parent); +private: + Q_DECLARE_PRIVATE(QGraphicsRotation) +}; + +class QGraphicsRotation3DPrivate; + +class Q_GUI_EXPORT QGraphicsRotation3D : public QGraphicsRotation +{ + Q_OBJECT + + Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged) +public: + QGraphicsRotation3D(QObject *parent = 0); + ~QGraphicsRotation3D(); + + QVector3D axis(); + void setAxis(const QVector3D &axis); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void axisChanged(); + +private: + Q_DECLARE_PRIVATE(QGraphicsRotation3D) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QFXTRANSFORM_H diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 6f56b84..3ea80ce 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1728,39 +1728,6 @@ QGraphicsWidget *QGraphicsWidget::focusWidget() const return 0; } -/*! \property QGraphicsWidget::horizontalShear - \brief This property holds the horizontal shear value for the item. - */ - -/*! \property QGraphicsWidget::transformOrigin - \brief This property holds the origin point used for transformations - in item coordinates. - */ - -/*! \property QGraphicsWidget::verticalShear - \brief This property holds the vertical shear value for the item. - */ - -/*! \property QGraphicsWidget::xRotation - \brief This property holds the value for rotation around the x axis. - */ - -/*! \property QGraphicsWidget::xScale - \brief This property holds the scale factor for the x axis. - */ - -/*! \property QGraphicsWidget::yRotation - \brief This property holds the value for rotation around the y axis. - */ - -/*! \property QGraphicsWidget::yScale - \brief This property holds the scale factor for the y axis. - */ - -/*! \property QGraphicsWidget::zRotation - \brief This property holds the value for rotation around the z axis. - */ - #ifndef QT_NO_SHORTCUT /*! \since 4.5 diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index b72ec9f..d03a637 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -77,14 +77,6 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) - Q_PROPERTY(QPointF transformOrigin READ transformOrigin WRITE setTransformOrigin) - Q_PROPERTY(qreal xRotation READ xRotation WRITE setXRotation) - Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation) - Q_PROPERTY(qreal zRotation READ zRotation WRITE setZRotation) - Q_PROPERTY(qreal xScale READ xScale WRITE setXScale) - Q_PROPERTY(qreal yScale READ yScale WRITE setYScale) - Q_PROPERTY(qreal horizontalShear READ horizontalShear WRITE setHorizontalShear) - Q_PROPERTY(qreal verticalShear READ verticalShear WRITE setVerticalShear) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); |