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