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 | |
43 | QT_BEGIN_NAMESPACE |
44 | |
45 | class QQuickTranslatePrivate : public QQuickTransformPrivate |
46 | { |
47 | public: |
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 | */ |
89 | QQuickTranslate::QQuickTranslate(QObject *parent) |
90 | : QQuickTransform(*new QQuickTranslatePrivate, parent) |
91 | { |
92 | } |
93 | |
94 | |
95 | QQuickTranslate::~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 | */ |
105 | qreal QQuickTranslate::x() const |
106 | { |
107 | Q_D(const QQuickTranslate); |
108 | return d->x; |
109 | } |
110 | |
111 | void 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 | */ |
128 | qreal QQuickTranslate::y() const |
129 | { |
130 | Q_D(const QQuickTranslate); |
131 | return d->y; |
132 | } |
133 | void 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 | |
143 | void QQuickTranslate::applyTo(QMatrix4x4 *matrix) const |
144 | { |
145 | Q_D(const QQuickTranslate); |
146 | matrix->translate(x: d->x, y: d->y, z: 0); |
147 | } |
148 | |
149 | class QQuickScalePrivate : public QQuickTransformPrivate |
150 | { |
151 | public: |
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 | */ |
187 | QQuickScale::QQuickScale(QObject *parent) |
188 | : QQuickTransform(*new QQuickScalePrivate, parent) |
189 | { |
190 | } |
191 | |
192 | QQuickScale::~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 | */ |
207 | QVector3D QQuickScale::origin() const |
208 | { |
209 | Q_D(const QQuickScale); |
210 | return d->origin; |
211 | } |
212 | void 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 | */ |
229 | qreal QQuickScale::xScale() const |
230 | { |
231 | Q_D(const QQuickScale); |
232 | return d->xScale; |
233 | } |
234 | void 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 | */ |
252 | qreal QQuickScale::yScale() const |
253 | { |
254 | Q_D(const QQuickScale); |
255 | return d->yScale; |
256 | } |
257 | void 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 | */ |
276 | qreal QQuickScale::zScale() const |
277 | { |
278 | Q_D(const QQuickScale); |
279 | return d->zScale; |
280 | } |
281 | void 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 | |
292 | void 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 | |
300 | class QQuickRotationPrivate : public QQuickTransformPrivate |
301 | { |
302 | public: |
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 | */ |
345 | QQuickRotation::QQuickRotation(QObject *parent) |
346 | : QQuickTransform(*new QQuickRotationPrivate, parent) |
347 | { |
348 | } |
349 | |
350 | QQuickRotation::~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 | */ |
363 | QVector3D QQuickRotation::origin() const |
364 | { |
365 | Q_D(const QQuickRotation); |
366 | return d->origin; |
367 | } |
368 | |
369 | void 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 | */ |
384 | qreal QQuickRotation::angle() const |
385 | { |
386 | Q_D(const QQuickRotation); |
387 | return d->angle; |
388 | } |
389 | void 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 | */ |
414 | QVector3D QQuickRotation::axis() const |
415 | { |
416 | Q_D(const QQuickRotation); |
417 | return d->axis; |
418 | } |
419 | void 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 | |
429 | void 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 | |
445 | class QGraphicsRotation { |
446 | public: |
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 | |
453 | void 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 | |
465 | class QQuickMatrix4x4Private : public QQuickTransformPrivate |
466 | { |
467 | public: |
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 | */ |
505 | QQuickMatrix4x4::QQuickMatrix4x4(QObject *parent) |
506 | : QQuickTransform(*new QQuickMatrix4x4Private, parent) |
507 | { |
508 | } |
509 | |
510 | QQuickMatrix4x4::~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 | */ |
519 | QMatrix4x4 QQuickMatrix4x4::matrix() const |
520 | { |
521 | Q_D(const QQuickMatrix4x4); |
522 | return d->matrix; |
523 | } |
524 | |
525 | void 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 | |
535 | void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const |
536 | { |
537 | Q_D(const QQuickMatrix4x4); |
538 | *matrix *= d->matrix; |
539 | } |
540 | |
541 | QT_END_NAMESPACE |
542 | |
543 | #include "moc_qquicktranslate_p.cpp" |
544 | |