1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquicktranslate_p.h"
41#include "qquickitem_p.h"
42
43QT_BEGIN_NAMESPACE
44
45class QQuickTranslatePrivate : public QQuickTransformPrivate
46{
47public:
48 QQuickTranslatePrivate()
49 : x(0), y(0) {}
50
51 qreal x;
52 qreal y;
53};
54
55
56/*!
57 \qmltype Translate
58 \instantiates QQuickTranslate
59 \inqmlmodule QtQuick
60 \ingroup qtquick-visual-transforms
61 \brief Provides a way to move an Item without changing its x or y properties.
62
63 The Translate type provides independent control over position in addition
64 to the Item's x and y properties.
65
66 The following example moves the Y axis of the \l Rectangle items while
67 still allowing the \l Row to lay the items out as if they had not been
68 transformed:
69
70 \qml
71 import QtQuick 2.0
72
73 Row {
74 Rectangle {
75 width: 100; height: 100
76 color: "blue"
77 transform: Translate { y: 20 }
78 }
79 Rectangle {
80 width: 100; height: 100
81 color: "red"
82 transform: Translate { y: -20 }
83 }
84 }
85 \endqml
86
87 \image translate.png
88*/
89QQuickTranslate::QQuickTranslate(QObject *parent)
90: QQuickTransform(*new QQuickTranslatePrivate, parent)
91{
92}
93
94
95QQuickTranslate::~QQuickTranslate()
96{
97}
98/*!
99 \qmlproperty real QtQuick::Translate::x
100
101 The translation along the X axis.
102
103 The default value is 0.0.
104*/
105qreal QQuickTranslate::x() const
106{
107 Q_D(const QQuickTranslate);
108 return d->x;
109}
110
111void QQuickTranslate::setX(qreal x)
112{
113 Q_D(QQuickTranslate);
114 if (d->x == x)
115 return;
116 d->x = x;
117 update();
118 emit xChanged();
119}
120
121/*!
122 \qmlproperty real QtQuick::Translate::y
123
124 The translation along the Y axis.
125
126 The default value is 0.0.
127*/
128qreal QQuickTranslate::y() const
129{
130 Q_D(const QQuickTranslate);
131 return d->y;
132}
133void QQuickTranslate::setY(qreal y)
134{
135 Q_D(QQuickTranslate);
136 if (d->y == y)
137 return;
138 d->y = y;
139 update();
140 emit yChanged();
141}
142
143void QQuickTranslate::applyTo(QMatrix4x4 *matrix) const
144{
145 Q_D(const QQuickTranslate);
146 matrix->translate(x: d->x, y: d->y, z: 0);
147}
148
149class QQuickScalePrivate : public QQuickTransformPrivate
150{
151public:
152 QQuickScalePrivate()
153 : xScale(1), yScale(1), zScale(1) {}
154 QVector3D origin;
155 qreal xScale;
156 qreal yScale;
157 qreal zScale;
158};
159
160/*!
161 \qmltype Scale
162 \instantiates QQuickScale
163 \inqmlmodule QtQuick
164 \ingroup qtquick-visual-transforms
165 \brief Provides a way to scale an Item.
166
167 The Scale type provides a way to scale an \l Item through a scale-type
168 transform.
169
170 It allows different scaling values for the x and y axes, and allows the
171 scale to be relative to an arbitrary point. This gives more control over
172 item scaling than the \l{Item::}{scale} property.
173
174 The following example scales the X axis of the Rectangle, relative to
175 its interior point (25, 25):
176
177 \qml
178 Rectangle {
179 width: 100; height: 100
180 color: "blue"
181 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
182 }
183 \endqml
184
185 \sa Rotation, Translate
186*/
187QQuickScale::QQuickScale(QObject *parent)
188 : QQuickTransform(*new QQuickScalePrivate, parent)
189{
190}
191
192QQuickScale::~QQuickScale()
193{
194}
195
196/*!
197 \qmlpropertygroup QtQuick::Scale::origin
198 \qmlproperty real QtQuick::Scale::origin.x
199 \qmlproperty real QtQuick::Scale::origin.y
200
201 This property holds the point that the item is scaled from (that is,
202 the point that stays fixed relative to the parent as the rest of the
203 item grows).
204
205 The default value of the origin is (0, 0).
206*/
207QVector3D QQuickScale::origin() const
208{
209 Q_D(const QQuickScale);
210 return d->origin;
211}
212void QQuickScale::setOrigin(const QVector3D &point)
213{
214 Q_D(QQuickScale);
215 if (d->origin == point)
216 return;
217 d->origin = point;
218 update();
219 emit originChanged();
220}
221
222/*!
223 \qmlproperty real QtQuick::Scale::xScale
224
225 The scaling factor for the X axis.
226
227 The default value is 1.0.
228*/
229qreal QQuickScale::xScale() const
230{
231 Q_D(const QQuickScale);
232 return d->xScale;
233}
234void QQuickScale::setXScale(qreal scale)
235{
236 Q_D(QQuickScale);
237 if (d->xScale == scale)
238 return;
239 d->xScale = scale;
240 update();
241 emit xScaleChanged();
242 emit scaleChanged();
243}
244
245/*!
246 \qmlproperty real QtQuick::Scale::yScale
247
248 The scaling factor for the Y axis.
249
250 The default value is 1.0.
251*/
252qreal QQuickScale::yScale() const
253{
254 Q_D(const QQuickScale);
255 return d->yScale;
256}
257void QQuickScale::setYScale(qreal scale)
258{
259 Q_D(QQuickScale);
260 if (d->yScale == scale)
261 return;
262 d->yScale = scale;
263 update();
264 emit yScaleChanged();
265 emit scaleChanged();
266}
267
268/*!
269 \qmlproperty real QtQuick::Scale::zScale
270 \internal
271
272 The scaling factor for the Z axis.
273
274 The default value is 1.0.
275*/
276qreal QQuickScale::zScale() const
277{
278 Q_D(const QQuickScale);
279 return d->zScale;
280}
281void QQuickScale::setZScale(qreal scale)
282{
283 Q_D(QQuickScale);
284 if (d->zScale == scale)
285 return;
286 d->zScale = scale;
287 update();
288 emit zScaleChanged();
289 emit scaleChanged();
290}
291
292void QQuickScale::applyTo(QMatrix4x4 *matrix) const
293{
294 Q_D(const QQuickScale);
295 matrix->translate(vector: d->origin);
296 matrix->scale(x: d->xScale, y: d->yScale, z: d->zScale);
297 matrix->translate(vector: -d->origin);
298}
299
300class QQuickRotationPrivate : public QQuickTransformPrivate
301{
302public:
303 QQuickRotationPrivate()
304 : angle(0), axis(0, 0, 1) {}
305 QVector3D origin;
306 qreal angle;
307 QVector3D axis;
308};
309
310/*!
311 \qmltype Rotation
312 \instantiates QQuickRotation
313 \inqmlmodule QtQuick
314 \ingroup qtquick-visual-transforms
315 \brief Provides a way to rotate an Item.
316
317 The Rotation type provides a way to rotate an \l Item through a
318 rotation-type transform.
319
320 It allows (z axis) rotation to be relative to an arbitrary point, and also
321 provides a way to specify 3D-like rotations for Items. This gives more
322 control over item rotation than the \l{Item::}{rotation} property.
323
324 The following example rotates a Rectangle around its interior point
325 (25, 25):
326
327 \qml
328 Rectangle {
329 width: 100; height: 100
330 color: "blue"
331 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
332 }
333 \endqml
334
335 For 3D-like item rotations, you must specify the axis of rotation in
336 addition to the origin point. The following example shows various 3D-like
337 rotations applied to an \l Image.
338
339 \snippet qml/rotation.qml 0
340
341 \image axisrotation.png
342
343 \sa {customitems/dialcontrol}{Dial Control example}, {Qt Quick Demo - Clocks}
344*/
345QQuickRotation::QQuickRotation(QObject *parent)
346 : QQuickTransform(*new QQuickRotationPrivate, parent)
347{
348}
349
350QQuickRotation::~QQuickRotation()
351{
352}
353
354/*!
355 \qmlpropertygroup QtQuick::Rotation::origin
356 \qmlproperty real QtQuick::Rotation::origin.x
357 \qmlproperty real QtQuick::Rotation::origin.y
358
359 The origin point of the rotation (i.e., the point that stays fixed
360 relative to the parent as the rest of the item rotates). By default
361 the origin is (0, 0).
362*/
363QVector3D QQuickRotation::origin() const
364{
365 Q_D(const QQuickRotation);
366 return d->origin;
367}
368
369void QQuickRotation::setOrigin(const QVector3D &point)
370{
371 Q_D(QQuickRotation);
372 if (d->origin == point)
373 return;
374 d->origin = point;
375 update();
376 emit originChanged();
377}
378
379/*!
380 \qmlproperty real QtQuick::Rotation::angle
381
382 The angle to rotate, in degrees clockwise.
383*/
384qreal QQuickRotation::angle() const
385{
386 Q_D(const QQuickRotation);
387 return d->angle;
388}
389void QQuickRotation::setAngle(qreal angle)
390{
391 Q_D(QQuickRotation);
392 if (d->angle == angle)
393 return;
394 d->angle = angle;
395 update();
396 emit angleChanged();
397}
398
399/*!
400 \qmlpropertygroup QtQuick::Rotation::axis
401 \qmlproperty real QtQuick::Rotation::axis.x
402 \qmlproperty real QtQuick::Rotation::axis.y
403 \qmlproperty real QtQuick::Rotation::axis.z
404
405 The axis to rotate around. For simple (2D) rotation around a point, you
406 do not need to specify an axis, as the default axis is the z axis
407 (\c{ axis { x: 0; y: 0; z: 1 } }).
408
409 For a typical 3D-like rotation you will usually specify both the origin
410 and the axis.
411
412 \image 3d-rotation-axis.png
413*/
414QVector3D QQuickRotation::axis() const
415{
416 Q_D(const QQuickRotation);
417 return d->axis;
418}
419void QQuickRotation::setAxis(const QVector3D &axis)
420{
421 Q_D(QQuickRotation);
422 if (d->axis == axis)
423 return;
424 d->axis = axis;
425 update();
426 emit axisChanged();
427}
428
429void QQuickRotation::setAxis(Qt::Axis axis)
430{
431 switch (axis)
432 {
433 case Qt::XAxis:
434 setAxis(QVector3D(1, 0, 0));
435 break;
436 case Qt::YAxis:
437 setAxis(QVector3D(0, 1, 0));
438 break;
439 case Qt::ZAxis:
440 setAxis(QVector3D(0, 0, 1));
441 break;
442 }
443}
444
445class QGraphicsRotation {
446public:
447 static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z)
448 {
449 matrix->projectedRotate(angle, x, y, z);
450 }
451};
452
453void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
454{
455 Q_D(const QQuickRotation);
456
457 if (d->angle == 0. || d->axis.isNull())
458 return;
459
460 matrix->translate(vector: d->origin);
461 QGraphicsRotation::projectedRotate(matrix, angle: d->angle, x: d->axis.x(), y: d->axis.y(), z: d->axis.z());
462 matrix->translate(vector: -d->origin);
463}
464
465class QQuickMatrix4x4Private : public QQuickTransformPrivate
466{
467public:
468 QQuickMatrix4x4Private()
469 : matrix() {}
470 QMatrix4x4 matrix;
471};
472
473/*!
474 \qmltype Matrix4x4
475 \instantiates QQuickMatrix4x4
476 \inqmlmodule QtQuick
477 \ingroup qtquick-visual-transforms
478 \since 5.3
479 \brief Provides a way to apply a 4x4 tranformation matrix to an \l Item.
480
481 The Matrix4x4 type provides a way to apply a transformation to an
482 \l Item through a 4x4 matrix.
483
484 It allows for a combination of rotation, scale, translatation and shearing
485 by using just one tranformation provided in a 4x4-matrix.
486
487 The following example rotates a Rectangle 45 degress (PI/4):
488
489 \qml
490 Rectangle {
491 width: 100
492 height: 100
493 color: "red"
494
495 transform: Matrix4x4 {
496 property real a: Math.PI / 4
497 matrix: Qt.matrix4x4(Math.cos(a), -Math.sin(a), 0, 0,
498 Math.sin(a), Math.cos(a), 0, 0,
499 0, 0, 1, 0,
500 0, 0, 0, 1)
501 }
502 }
503 \endqml
504*/
505QQuickMatrix4x4::QQuickMatrix4x4(QObject *parent)
506 : QQuickTransform(*new QQuickMatrix4x4Private, parent)
507{
508}
509
510QQuickMatrix4x4::~QQuickMatrix4x4()
511{
512}
513
514/*!
515 \qmlproperty QMatrix4x4 QtQuick::Matrix4x4::matrix
516
517 4x4-matrix which will be used in the tranformation of an \l Item
518*/
519QMatrix4x4 QQuickMatrix4x4::matrix() const
520{
521 Q_D(const QQuickMatrix4x4);
522 return d->matrix;
523}
524
525void QQuickMatrix4x4::setMatrix(const QMatrix4x4 &matrix)
526{
527 Q_D(QQuickMatrix4x4);
528 if (d->matrix == matrix)
529 return;
530 d->matrix = matrix;
531 update();
532 emit matrixChanged();
533}
534
535void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const
536{
537 Q_D(const QQuickMatrix4x4);
538 *matrix *= d->matrix;
539}
540
541QT_END_NAMESPACE
542
543#include "moc_qquicktranslate_p.cpp"
544

source code of qtdeclarative/src/quick/items/qquicktranslate.cpp