diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/doc/images/x-shear.png | bin | 0 -> 970 bytes | |||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquicktranslate.cpp | 212 | ||||
-rw-r--r-- | src/quick/items/qquicktranslate_p.h | 43 |
4 files changed, 256 insertions, 0 deletions
diff --git a/src/quick/doc/images/x-shear.png b/src/quick/doc/images/x-shear.png Binary files differnew file mode 100644 index 0000000000..21ef7eb663 --- /dev/null +++ b/src/quick/doc/images/x-shear.png diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index ac9e0e9306..a3b57672bc 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -106,6 +106,7 @@ static void setActiveFocus(QQuickItem *item, Qt::FocusReason reason) \li \l Rotation \li \l Scale \li \l Translate + \li \l Shear \li \l Matrix4x4 \endlist diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp index 09a5dcbbe4..12c60369f0 100644 --- a/src/quick/items/qquicktranslate.cpp +++ b/src/quick/items/qquicktranslate.cpp @@ -406,6 +406,218 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const matrix->translate(-d->origin); } +/*! + \qmltype Shear + \nativetype QQuickShear + \inqmlmodule QtQuick + \ingroup qtquick-visual-transforms + \since 6.9 + \brief Provides a way to shear an Item. + + The Shear type provides a way to transform an \l Item by a two-dimensional shear-type + matrix, sometimes known as a \e skew transform. + + \qml + Rectangle { + width: 100; height: 100 + color: "blue" + transform: Shear { + xFactor: 1.0 + } + } + \endqml + + This shears the item by a factor of \c 1.0 along the x-axis without modifying anything along the + y-axis. Each point \c P is displaced by \c{xFactor(P.y - origin.y)} (the signed vertical + distance to the \l{origin} multiplied with the \l{xFactor}). Setting the \l{yFactor} shears the + item along the y-axis and proportionally to the horizontal distance. + + \image x-shear.png + + Since the default origin is at \c{(0, 0)}, the top of the item remains untransformed, whereas + the bottom is displaced 100 pixels to the right (corresponding to the height of the item.) + + This code is equivalent to the following: + + \qml + Rectangle { + width: 100; height: 100 + color: "blue" + transform: Shear { + xAngle: 45.0 + } + } + \endqml + + \note If both \c{xFactor}/\c{yFactor} and \c{xAngle}/\c{yAngle} are set, then the sum of the + two displacements will be used. +*/ +class QQuickShearPrivate : public QQuickTransformPrivate +{ +public: + QVector3D origin; + qreal xFactor = 0.0; + qreal yFactor = 0.0; + qreal xAngle = 0.0; + qreal yAngle = 0.0; +}; + +QQuickShear::QQuickShear(QObject *parent) + : QQuickTransform(*new QQuickShearPrivate, parent) +{ +} + +/*! + \qmlpropertygroup QtQuick::Shear::origin + \qmlproperty real QtQuick::Shear::origin.x + \qmlproperty real QtQuick::Shear::origin.y + + The origin point of the transformation (i.e., the point that stays fixed relative to the parent + as the rest of the item is sheared). + + By default the origin is \c (0, 0). +*/ +QVector3D QQuickShear::origin() const +{ + Q_D(const QQuickShear); + return d->origin; +} + +void QQuickShear::setOrigin(const QVector3D &point) +{ + Q_D(QQuickShear); + if (d->origin == point) + return; + d->origin = point; + update(); + emit originChanged(); +} + +/*! + \qmlproperty real QtQuick::Shear::xFactor + + The factor by which to shear the item's coordinate system along the x-axis. Each point \c P is + displaced by \c{xFactor(P.y - origin.y)} + + This corresponds to the \c sh parameter in \l{QTransform::shear()} and the \c xShear parameter + in calls to \l{PlanarTransform.fromShear()}. + + The default value is \c 0.0. + + \sa xAngle +*/ +qreal QQuickShear::xFactor() const +{ + Q_D(const QQuickShear); + return d->xFactor; +} +void QQuickShear::setXFactor(qreal xFactor) +{ + Q_D(QQuickShear); + if (d->xFactor == xFactor) + return; + d->xFactor = xFactor; + update(); + emit xFactorChanged(); +} + +/*! + \qmlproperty real QtQuick::Shear::yFactor + + The factor by which to shear the item's coordinate system along the y-axis. The factor by which + to shear the item's coordinate system along the x-axis. Each point \c P is displaced by + \c{xFactor(P.y - origin.y)} + + This corresponds to the \c sv parameter in \l{QTransform::shear()} and the \c yShear parameter + in calls to \l{PlanarTransform.fromShear()}. + + The default value is \c 0.0. + + \sa yAngle +*/ +qreal QQuickShear::yFactor() const +{ + Q_D(const QQuickShear); + return d->yFactor; +} +void QQuickShear::setYFactor(qreal yFactor) +{ + Q_D(QQuickShear); + if (d->yFactor == yFactor) + return; + d->yFactor = yFactor; + update(); + emit yFactorChanged(); +} + +/*! + \qmlproperty real QtQuick::Shear::xAngle + + The angle (in degrees) by which to shear the item's coordinate system along the x-axis. This + is equivalent to setting \l{xFactor} to \c{tan(xAngle)}. + + The default value is \c 0.0. + + \sa xFactor +*/ +qreal QQuickShear::xAngle() const +{ + Q_D(const QQuickShear); + return d->xAngle; +} +void QQuickShear::setXAngle(qreal xAngle) +{ + Q_D(QQuickShear); + if (d->xAngle == xAngle) + return; + d->xAngle = xAngle; + update(); + emit xAngleChanged(); +} + +/*! + \qmlproperty real QtQuick::Shear::yAngle + + The angle (in degrees) by which to shear the item's coordinate system along the y-axis. This + is equivalent to setting \l{yFactor} to \c{tan(yAngle)}. + + The default value is \c 0.0. + + \sa yFactor +*/ +qreal QQuickShear::yAngle() const +{ + Q_D(const QQuickShear); + return d->yAngle; +} +void QQuickShear::setYAngle(qreal yAngle) +{ + Q_D(QQuickShear); + if (d->yAngle == yAngle) + return; + d->yAngle = yAngle; + update(); + emit yAngleChanged(); +} + +void QQuickShear::applyTo(QMatrix4x4 *matrix) const +{ + Q_D(const QQuickShear); + if (d->xFactor == 0.0 && d->yFactor == 0.0 && d->xAngle == 0.0 && d->yAngle == 0.0) + return; + + const qreal xShear = qTan(qDegreesToRadians(d->xAngle)) + d->xFactor; + const qreal yShear = qTan(qDegreesToRadians(d->yAngle)) + d->yFactor; + + matrix->translate(d->origin); + *matrix *= QMatrix4x4(1.0, xShear, 0.0, 0.0, + yShear, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + matrix->translate(-d->origin); +} + + class QQuickMatrix4x4Private : public QQuickTransformPrivate { public: diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h index 496a115d3f..ed152dbe48 100644 --- a/src/quick/items/qquicktranslate_p.h +++ b/src/quick/items/qquicktranslate_p.h @@ -125,6 +125,49 @@ private: Q_DECLARE_PRIVATE(QQuickRotation) }; +class QQuickShearPrivate; +class Q_QUICK_EXPORT QQuickShear : public QQuickTransform +{ + Q_OBJECT + + Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged) + Q_PROPERTY(qreal xFactor READ xFactor WRITE setXFactor NOTIFY xFactorChanged) + Q_PROPERTY(qreal yFactor READ yFactor WRITE setYFactor NOTIFY yFactorChanged) + Q_PROPERTY(qreal xAngle READ xAngle WRITE setXAngle NOTIFY xAngleChanged) + Q_PROPERTY(qreal yAngle READ yAngle WRITE setYAngle NOTIFY yAngleChanged) + QML_NAMED_ELEMENT(Shear) + QML_ADDED_IN_VERSION(6, 9) +public: + QQuickShear(QObject *parent = nullptr); + + QVector3D origin() const; + void setOrigin(const QVector3D &point); + + qreal xFactor() const; + void setXFactor(qreal); + + qreal yFactor() const; + void setYFactor(qreal); + + qreal xAngle() const; + void setXAngle(qreal); + + qreal yAngle() const; + void setYAngle(qreal); + + void applyTo(QMatrix4x4 *matrix) const override; + +Q_SIGNALS: + void originChanged(); + void xFactorChanged(); + void yFactorChanged(); + void xAngleChanged(); + void yAngleChanged(); + +private: + Q_DECLARE_PRIVATE(QQuickShear) +}; + class QQuickMatrix4x4Private; class Q_QUICK_EXPORT QQuickMatrix4x4 : public QQuickTransform { |