Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickstateoperations.cpp
Go to the documentation of this file.
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
5#include "qquickitem_p.h"
6
7#include <private/qquickstate_p_p.h>
8
9#include <QtQml/qqmlinfo.h>
10
11#include <QtCore/qmath.h>
12#include <QtCore/qpointer.h>
13
14#include <memory>
15
17
19{
20 Q_DECLARE_PUBLIC(QQuickParentChange)
21public:
22 QQuickItem *target = nullptr;
23 QPointer<QQuickItem> parent;
24
26 QPointer<QQuickItem> parent;
27 QPointer<QQuickItem> stackBefore;
28 qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0;
29 };
30
31 std::unique_ptr<StateSnapshot> orig;
32 std::unique_ptr<StateSnapshot> rewind;
33
34 QQmlNullableValue<QQmlScriptString> xString;
35 QQmlNullableValue<QQmlScriptString> yString;
36 QQmlNullableValue<QQmlScriptString> widthString;
37 QQmlNullableValue<QQmlScriptString> heightString;
38 QQmlNullableValue<QQmlScriptString> scaleString;
39 QQmlNullableValue<QQmlScriptString> rotationString;
40
41 void doChange(QQuickItem *targetParent);
42 void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot);
43};
44
46{
47 if (targetParent && target && target->parentItem()) {
49 bool ok;
50 const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
51 if (transform.type() >= QTransform::TxShear || !ok) {
52 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
53 ok = false;
54 }
55
56 qreal scale = 1;
57 qreal rotation = 0;
58 bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
59 if (ok && !isRotate) {
60 if (transform.m11() == transform.m22())
61 scale = transform.m11();
62 else {
63 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
64 ok = false;
65 }
66 } else if (ok && isRotate) {
67 if (transform.m11() == transform.m22())
68 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
69 else {
70 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
71 ok = false;
72 }
73
74 if (scale != 0)
75 rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
76 else {
77 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
78 ok = false;
79 }
80 }
81
82 const QPointF &point = transform.map(QPointF(target->x(),target->y()));
83 qreal x = point.x();
84 qreal y = point.y();
85
86 // setParentItem will update the transformOriginPoint if needed
87 target->setParentItem(targetParent);
88
89 if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
90 qreal tempxt = target->transformOriginPoint().x();
91 qreal tempyt = target->transformOriginPoint().y();
93 t.translate(-tempxt, -tempyt);
94 t.rotate(rotation);
96 t.translate(tempxt, tempyt);
97 const QPointF &offset = t.map(QPointF(0,0));
98 x += offset.x();
99 y += offset.y();
100 }
101
102 if (ok) {
103 //qDebug() << x << y << rotation << scale;
104 target->setPosition(QPointF(x, y));
105 target->setRotation(target->rotation() + rotation);
106 target->setScale(target->scale() * scale);
107 }
108 } else if (target) {
109 target->setParentItem(targetParent);
110 }
111}
112
148
160{
161 Q_D(const QQuickParentChange);
162 return d->xString.value();
163}
164
166{
168 d->xString = x;
169}
170
172{
173 Q_D(const QQuickParentChange);
174 return d->xString.isValid();
175}
176
178{
179 Q_D(const QQuickParentChange);
180 return d->yString.value();
181}
182
184{
186 d->yString = y;
187}
188
190{
191 Q_D(const QQuickParentChange);
192 return d->yString.isValid();
193}
194
196{
197 Q_D(const QQuickParentChange);
198 return d->widthString.value();
199}
200
202{
204 d->widthString = width;
205}
206
208{
209 Q_D(const QQuickParentChange);
210 return d->widthString.isValid();
211}
212
214{
215 Q_D(const QQuickParentChange);
216 return d->heightString.value();
217}
218
220{
222 d->heightString = height;
223}
224
226{
227 Q_D(const QQuickParentChange);
228 return d->heightString.isValid();
229}
230
232{
233 Q_D(const QQuickParentChange);
234 return d->scaleString.value();
235}
236
238{
240 d->scaleString = scale;
241}
242
244{
245 Q_D(const QQuickParentChange);
246 return d->scaleString.isValid();
247}
248
250{
251 Q_D(const QQuickParentChange);
252 return d->rotationString.value();
253}
254
256{
258 d->rotationString = rotation;
259}
260
262{
263 Q_D(const QQuickParentChange);
264 return d->rotationString.isValid();
265}
266
268{
269 Q_D(const QQuickParentChange);
270 return d->orig ? d->orig->parent : nullptr;
271}
272
278{
279 Q_D(const QQuickParentChange);
280 return d->target;
281}
282
288
294{
295 Q_D(const QQuickParentChange);
296 return d->parent;
297}
298
300{
302 d->parent = parent;
303}
304
306{
308 if (!d->target || !d->parent)
309 return ActionList();
310
312
314 a.event = this;
315 actions << a;
316
317 if (d->xString.isValid()) {
318 bool ok = false;
319 qreal x = d->xString.value().numberLiteral(&ok);
320 if (ok) {
321 QQuickStateAction xa(d->target, QLatin1String("x"), x);
322 actions << xa;
323 } else {
324 QQmlProperty property(d->target, QLatin1String("x"));
326 property, d->xString.value(), d->target, qmlContext(this));
328 xa.property = property;
329 xa.toBinding = newBinding;
330 xa.fromValue = xa.property.read();
331 xa.deletableToBinding = true;
332 actions << xa;
333 }
334 }
335
336 if (d->yString.isValid()) {
337 bool ok = false;
338 qreal y = d->yString.value().numberLiteral(&ok);
339 if (ok) {
340 QQuickStateAction ya(d->target, QLatin1String("y"), y);
341 actions << ya;
342 } else {
343 QQmlProperty property(d->target, QLatin1String("y"));
345 property, d->yString.value(), d->target, qmlContext(this));
347 ya.property = property;
348 ya.toBinding = newBinding;
349 ya.fromValue = ya.property.read();
350 ya.deletableToBinding = true;
351 actions << ya;
352 }
353 }
354
355 if (d->scaleString.isValid()) {
356 bool ok = false;
357 qreal scale = d->scaleString.value().numberLiteral(&ok);
358 if (ok) {
359 QQuickStateAction sa(d->target, QLatin1String("scale"), scale);
360 actions << sa;
361 } else {
362 QQmlProperty property(d->target, QLatin1String("scale"));
364 property, d->scaleString.value(), d->target, qmlContext(this));
366 sa.property = property;
367 sa.toBinding = newBinding;
368 sa.fromValue = sa.property.read();
369 sa.deletableToBinding = true;
370 actions << sa;
371 }
372 }
373
374 if (d->rotationString.isValid()) {
375 bool ok = false;
376 qreal rotation = d->rotationString.value().numberLiteral(&ok);
377 if (ok) {
378 QQuickStateAction ra(d->target, QLatin1String("rotation"), rotation);
379 actions << ra;
380 } else {
381 QQmlProperty property(d->target, QLatin1String("rotation"));
383 property, d->rotationString.value(), d->target, qmlContext(this));
385 ra.property = property;
386 ra.toBinding = newBinding;
387 ra.fromValue = ra.property.read();
388 ra.deletableToBinding = true;
389 actions << ra;
390 }
391 }
392
393 if (d->widthString.isValid()) {
394 bool ok = false;
395 qreal width = d->widthString.value().numberLiteral(&ok);
396 if (ok) {
397 QQuickStateAction wa(d->target, QLatin1String("width"), width);
398 actions << wa;
399 } else {
400 QQmlProperty property(d->target, QLatin1String("width"));
401 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->widthString, d->target, qmlContext(this));
403 wa.property = property;
404 wa.toBinding = newBinding;
405 wa.fromValue = wa.property.read();
406 wa.deletableToBinding = true;
407 actions << wa;
408 }
409 }
410
411 if (d->heightString.isValid()) {
412 bool ok = false;
413 qreal height = d->heightString.value().numberLiteral(&ok);
414 if (ok) {
415 QQuickStateAction ha(d->target, QLatin1String("height"), height);
416 actions << ha;
417 } else {
418 QQmlProperty property(d->target, QLatin1String("height"));
419 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->heightString, d->target, qmlContext(this));
421 ha.property = property;
422 ha.toBinding = newBinding;
423 ha.fromValue = ha.property.read();
424 ha.deletableToBinding = true;
425 actions << ha;
426 }
427 }
428
429 return actions;
430}
431
433{
436 if (!d->orig)
438 *d->orig = *d->rewind;
439}
440
442{
444 d->doChange(d->parent);
445}
446
448{
449 return true;
450}
451
452void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot)
453{
454 if (!target || !snapshot)
455 return;
456
457 // leave existing bindings alive; new bindings are applied in applyBindings
458 // setPosition and setSize update the geometry without invalidating bindings
459 target->setPosition(QPointF(snapshot->x, snapshot->y));
460 target->setSize(QSizeF(snapshot->width, snapshot->height));
461
462 target->setScale(snapshot->scale);
463 target->setRotation(snapshot->rotation);
464 target->setParentItem(snapshot->parent);
465 if (snapshot->stackBefore)
466 target->stackBefore(snapshot->stackBefore);
467}
468
469
471{
473 d->reverseRewindHelper(d->orig);
474}
475
480
482{
484 if (other->type() != ParentChange)
485 return false;
486 if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
487 return (d->target == otherPC->object());
488 return false;
489}
490
492{
494 if (!d->target) {
495 d->rewind = nullptr;
496 return;
497 }
498
500 d->rewind->x = d->target->x();
501 d->rewind->y = d->target->y();
502 d->rewind->scale = d->target->scale();
503 d->rewind->width = d->target->width();
504 d->rewind->height = d->target->height();
505 d->rewind->rotation = d->target->rotation();
506
507 d->rewind->parent = d->target->parentItem();
508 d->rewind->stackBefore = nullptr;
509
510 if (!d->rewind->parent)
511 return;
512
513 QList<QQuickItem *> children = d->rewind->parent->childItems();
514 for (int ii = 0; ii < children.size() - 1; ++ii) {
515 if (children.at(ii) == d->target) {
516 d->rewind->stackBefore = children.at(ii + 1);
517 break;
518 }
519 }
520}
521
523{
525 d->reverseRewindHelper(d->rewind);
526 d->rewind.reset();
527}
528
577
582
586
588{
589 Q_D(const QQuickAnchorSet);
590 return d->topScript;
591}
592
594{
595 Q_D(QQuickAnchorSet);
596 d->usedAnchors |= QQuickAnchors::TopAnchor;
597 d->topScript = edge;
598 if (edge.isUndefinedLiteral())
599 resetTop();
600}
601
603{
604 Q_D(QQuickAnchorSet);
605 d->usedAnchors &= ~QQuickAnchors::TopAnchor;
606 d->resetAnchors |= QQuickAnchors::TopAnchor;
607}
608
610{
611 Q_D(const QQuickAnchorSet);
612 return d->bottomScript;
613}
614
616{
617 Q_D(QQuickAnchorSet);
618 d->usedAnchors |= QQuickAnchors::BottomAnchor;
619 d->bottomScript = edge;
620 if (edge.isUndefinedLiteral())
621 resetBottom();
622}
623
625{
626 Q_D(QQuickAnchorSet);
627 d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
628 d->resetAnchors |= QQuickAnchors::BottomAnchor;
629}
630
632{
633 Q_D(const QQuickAnchorSet);
634 return d->vCenterScript;
635}
636
638{
639 Q_D(QQuickAnchorSet);
640 d->usedAnchors |= QQuickAnchors::VCenterAnchor;
641 d->vCenterScript = edge;
642 if (edge.isUndefinedLiteral())
644}
645
647{
648 Q_D(QQuickAnchorSet);
649 d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
650 d->resetAnchors |= QQuickAnchors::VCenterAnchor;
651}
652
654{
655 Q_D(const QQuickAnchorSet);
656 return d->baselineScript;
657}
658
660{
661 Q_D(QQuickAnchorSet);
662 d->usedAnchors |= QQuickAnchors::BaselineAnchor;
663 d->baselineScript = edge;
664 if (edge.isUndefinedLiteral())
666}
667
669{
670 Q_D(QQuickAnchorSet);
671 d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
672 d->resetAnchors |= QQuickAnchors::BaselineAnchor;
673}
674
676{
677 Q_D(const QQuickAnchorSet);
678 return d->leftScript;
679}
680
682{
683 Q_D(QQuickAnchorSet);
684 d->usedAnchors |= QQuickAnchors::LeftAnchor;
685 d->leftScript = edge;
686 if (edge.isUndefinedLiteral())
687 resetLeft();
688}
689
691{
692 Q_D(QQuickAnchorSet);
693 d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
694 d->resetAnchors |= QQuickAnchors::LeftAnchor;
695}
696
698{
699 Q_D(const QQuickAnchorSet);
700 return d->rightScript;
701}
702
704{
705 Q_D(QQuickAnchorSet);
706 d->usedAnchors |= QQuickAnchors::RightAnchor;
707 d->rightScript = edge;
708 if (edge.isUndefinedLiteral())
709 resetRight();
710}
711
713{
714 Q_D(QQuickAnchorSet);
715 d->usedAnchors &= ~QQuickAnchors::RightAnchor;
716 d->resetAnchors |= QQuickAnchors::RightAnchor;
717}
718
720{
721 Q_D(const QQuickAnchorSet);
722 return d->hCenterScript;
723}
724
726{
727 Q_D(QQuickAnchorSet);
728 d->usedAnchors |= QQuickAnchors::HCenterAnchor;
729 d->hCenterScript = edge;
730 if (edge.isUndefinedLiteral())
732}
733
735{
736 Q_D(QQuickAnchorSet);
737 d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
738 d->resetAnchors |= QQuickAnchors::HCenterAnchor;
739}
740
742{
743public:
750
753
761
769
777
782
787
792
800
801 QQmlNullableValue<qreal> origWidth;
802 QQmlNullableValue<qreal> origHeight;
805
813};
814
819
821{
823 //### ASSERT these are all 0?
824 d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
825 = d->bottomBinding = d->vCenterBinding = d->baselineBinding = nullptr;
826
827 d->leftProp = QQmlProperty(d->target, QLatin1String("anchors.left"));
828 d->rightProp = QQmlProperty(d->target, QLatin1String("anchors.right"));
829 d->hCenterProp = QQmlProperty(d->target, QLatin1String("anchors.horizontalCenter"));
830 d->topProp = QQmlProperty(d->target, QLatin1String("anchors.top"));
831 d->bottomProp = QQmlProperty(d->target, QLatin1String("anchors.bottom"));
832 d->vCenterProp = QQmlProperty(d->target, QLatin1String("anchors.verticalCenter"));
833 d->baselineProp = QQmlProperty(d->target, QLatin1String("anchors.baseline"));
834
835 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
836 d->leftBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->leftProp)->core, d->anchorSet->d_func()->leftScript, d->target, qmlContext(this));
837 d->leftBinding->setTarget(d->leftProp);
838 }
839 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
840 d->rightBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->rightProp)->core, d->anchorSet->d_func()->rightScript, d->target, qmlContext(this));
841 d->rightBinding->setTarget(d->rightProp);
842 }
843 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
844 d->hCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->hCenterProp)->core, d->anchorSet->d_func()->hCenterScript, d->target, qmlContext(this));
845 d->hCenterBinding->setTarget(d->hCenterProp);
846 }
847 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
848 d->topBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->topProp)->core, d->anchorSet->d_func()->topScript, d->target, qmlContext(this));
849 d->topBinding->setTarget(d->topProp);
850 }
851 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
852 d->bottomBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->bottomProp)->core, d->anchorSet->d_func()->bottomScript, d->target, qmlContext(this));
853 d->bottomBinding->setTarget(d->bottomProp);
854 }
855 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
856 d->vCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->vCenterProp)->core, d->anchorSet->d_func()->vCenterScript, d->target, qmlContext(this));
857 d->vCenterBinding->setTarget(d->vCenterProp);
858 }
859 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
860 d->baselineBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->baselineProp)->core, d->anchorSet->d_func()->baselineScript, d->target, qmlContext(this));
861 d->baselineBinding->setTarget(d->baselineProp);
862 }
863
865 a.event = this;
866 return ActionList() << a;
867}
868
870{
871 Q_D(const QQuickAnchorChanges);
872 return d->anchorSet;
873}
874
880{
881 Q_D(const QQuickAnchorChanges);
882 return d->target;
883}
884
890
914{
916 if (!d->target)
917 return;
918
919 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
920 //incorporate any needed "reverts"
921 if (d->applyOrigLeft) {
922 if (!d->origLeftBinding)
923 targetPrivate->anchors()->resetLeft();
924 QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
925 }
926 if (d->applyOrigRight) {
927 if (!d->origRightBinding)
928 targetPrivate->anchors()->resetRight();
929 QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
930 }
931 if (d->applyOrigHCenter) {
932 if (!d->origHCenterBinding)
933 targetPrivate->anchors()->resetHorizontalCenter();
934 QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
935 }
936 if (d->applyOrigTop) {
937 if (!d->origTopBinding)
938 targetPrivate->anchors()->resetTop();
939 QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
940 }
941 if (d->applyOrigBottom) {
942 if (!d->origBottomBinding)
943 targetPrivate->anchors()->resetBottom();
944 QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
945 }
946 if (d->applyOrigVCenter) {
947 if (!d->origVCenterBinding)
948 targetPrivate->anchors()->resetVerticalCenter();
949 QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
950 }
951 if (d->applyOrigBaseline) {
952 if (!d->origBaselineBinding)
953 targetPrivate->anchors()->resetBaseline();
954 QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
955 }
956
957 //reset any anchors that have been specified as "undefined"
958 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
959 targetPrivate->anchors()->resetLeft();
961 }
962 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
963 targetPrivate->anchors()->resetRight();
965 }
966 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
967 targetPrivate->anchors()->resetHorizontalCenter();
969 }
970 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
971 targetPrivate->anchors()->resetTop();
973 }
974 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
975 targetPrivate->anchors()->resetBottom();
977 }
978 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
979 targetPrivate->anchors()->resetVerticalCenter();
981 }
982 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
983 targetPrivate->anchors()->resetBaseline();
985 }
986
987 //set any anchors that have been specified
988 if (d->leftBinding)
989 QQmlPropertyPrivate::setBinding(d->leftBinding.data());
990 if (d->rightBinding)
991 QQmlPropertyPrivate::setBinding(d->rightBinding.data());
992 if (d->hCenterBinding)
993 QQmlPropertyPrivate::setBinding(d->hCenterBinding.data());
994 if (d->topBinding)
995 QQmlPropertyPrivate::setBinding(d->topBinding.data());
996 if (d->bottomBinding)
997 QQmlPropertyPrivate::setBinding(d->bottomBinding.data());
998 if (d->vCenterBinding)
999 QQmlPropertyPrivate::setBinding(d->vCenterBinding.data());
1000 if (d->baselineBinding)
1001 QQmlPropertyPrivate::setBinding(d->baselineBinding.data());
1002}
1003
1005{
1006 return true;
1007}
1008
1010{
1012 if (!d->target)
1013 return;
1014
1015 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1016 //reset any anchors set by the state
1017 if (d->leftBinding) {
1018 targetPrivate->anchors()->resetLeft();
1019 QQmlPropertyPrivate::removeBinding(d->leftBinding.data());
1020 }
1021 if (d->rightBinding) {
1022 targetPrivate->anchors()->resetRight();
1023 QQmlPropertyPrivate::removeBinding(d->rightBinding.data());
1024 }
1025 if (d->hCenterBinding) {
1026 targetPrivate->anchors()->resetHorizontalCenter();
1027 QQmlPropertyPrivate::removeBinding(d->hCenterBinding.data());
1028 }
1029 if (d->topBinding) {
1030 targetPrivate->anchors()->resetTop();
1031 QQmlPropertyPrivate::removeBinding(d->topBinding.data());
1032 }
1033 if (d->bottomBinding) {
1034 targetPrivate->anchors()->resetBottom();
1035 QQmlPropertyPrivate::removeBinding(d->bottomBinding.data());
1036 }
1037 if (d->vCenterBinding) {
1038 targetPrivate->anchors()->resetVerticalCenter();
1039 QQmlPropertyPrivate::removeBinding(d->vCenterBinding.data());
1040 }
1041 if (d->baselineBinding) {
1042 targetPrivate->anchors()->resetBaseline();
1043 QQmlPropertyPrivate::removeBinding(d->baselineBinding.data());
1044 }
1045
1046 //restore previous anchors
1047 if (d->origLeftBinding)
1048 QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
1049 if (d->origRightBinding)
1050 QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
1051 if (d->origHCenterBinding)
1052 QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
1053 if (d->origTopBinding)
1054 QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
1055 if (d->origBottomBinding)
1056 QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
1057 if (d->origVCenterBinding)
1058 QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
1059 if (d->origBaselineBinding)
1060 QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
1061
1062 //restore any absolute geometry changed by the state's anchors
1063 QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
1064 QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
1065 QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
1066 QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
1067
1068 const QRectF oldGeometry(d->target->position(), d->target->size());
1069 bool stateSetWidth = (stateHAnchors &&
1070 stateHAnchors != QQuickAnchors::LeftAnchor &&
1071 stateHAnchors != QQuickAnchors::RightAnchor &&
1072 stateHAnchors != QQuickAnchors::HCenterAnchor);
1073 // in case of an additive AnchorChange, we _did_ end up modifying the width
1074 stateSetWidth |= ((stateHAnchors & QQuickAnchors::LeftAnchor) && (origHAnchors & QQuickAnchors::RightAnchor)) ||
1075 ((stateHAnchors & QQuickAnchors::RightAnchor) && (origHAnchors & QQuickAnchors::LeftAnchor));
1076 bool origSetWidth = (origHAnchors &&
1077 origHAnchors != QQuickAnchors::LeftAnchor &&
1078 origHAnchors != QQuickAnchors::RightAnchor &&
1079 origHAnchors != QQuickAnchors::HCenterAnchor);
1080 if (d->origWidth.isValid() && stateSetWidth && !origSetWidth && !qt_is_nan(d->origWidth)) {
1081 targetPrivate->widthValidFlag = true;
1082 if (targetPrivate->width != d->origWidth)
1083 targetPrivate->width.setValueBypassingBindings(d->origWidth);
1084 }
1085
1086 bool stateSetHeight = (stateVAnchors &&
1087 stateVAnchors != QQuickAnchors::TopAnchor &&
1088 stateVAnchors != QQuickAnchors::BottomAnchor &&
1089 stateVAnchors != QQuickAnchors::VCenterAnchor &&
1090 stateVAnchors != QQuickAnchors::BaselineAnchor);
1091 // in case of an additive AnchorChange, we _did_ end up modifying the height
1092 stateSetHeight |= ((stateVAnchors & QQuickAnchors::TopAnchor) && (origVAnchors & QQuickAnchors::BottomAnchor)) ||
1093 ((stateVAnchors & QQuickAnchors::BottomAnchor) && (origVAnchors & QQuickAnchors::TopAnchor));
1094 bool origSetHeight = (origVAnchors &&
1095 origVAnchors != QQuickAnchors::TopAnchor &&
1096 origVAnchors != QQuickAnchors::BottomAnchor &&
1097 origVAnchors != QQuickAnchors::VCenterAnchor &&
1098 origVAnchors != QQuickAnchors::BaselineAnchor);
1099 if (d->origHeight.isValid() && stateSetHeight && !origSetHeight && !qt_is_nan(d->origHeight)) {
1100 targetPrivate->heightValidFlag = true;
1101 if (targetPrivate->height != d->origHeight)
1102 targetPrivate->height.setValueBypassingBindings(d->origHeight);
1103 }
1104
1105 if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x)
1106 targetPrivate->x.setValueBypassingBindings(d->origX);
1107
1108 if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y)
1109 targetPrivate->y.setValueBypassingBindings(d->origY);
1110
1111 const QRectF newGeometry(d->target->position(), d->target->size());
1112 if (newGeometry != oldGeometry) {
1113 QQuickItemPrivate::DirtyType dirtyFlags {};
1114 if (newGeometry.topLeft() != oldGeometry.topLeft())
1116 if (newGeometry.size() != oldGeometry.size())
1117 dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Size);
1118 targetPrivate->dirty(dirtyFlags);
1119 d->target->geometryChange(newGeometry, oldGeometry);
1120 }
1121}
1122
1127
1128QList<QQuickStateAction> QQuickAnchorChanges::additionalActions() const
1129{
1130 Q_D(const QQuickAnchorChanges);
1131 QList<QQuickStateAction> extra;
1132
1133 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
1134 bool hChange = combined & QQuickAnchors::Horizontal_Mask;
1135 bool vChange = combined & QQuickAnchors::Vertical_Mask;
1136
1137 if (d->target) {
1139 if (hChange && d->fromX != d->toX) {
1140 a.property = QQmlProperty(d->target, QLatin1String("x"));
1141 a.toValue = d->toX;
1142 extra << a;
1143 }
1144 if (vChange && d->fromY != d->toY) {
1145 a.property = QQmlProperty(d->target, QLatin1String("y"));
1146 a.toValue = d->toY;
1147 extra << a;
1148 }
1149 if (hChange && d->fromWidth != d->toWidth) {
1150 a.property = QQmlProperty(d->target, QLatin1String("width"));
1151 a.toValue = d->toWidth;
1152 extra << a;
1153 }
1154 if (vChange && d->fromHeight != d->toHeight) {
1155 a.property = QQmlProperty(d->target, QLatin1String("height"));
1156 a.toValue = d->toHeight;
1157 extra << a;
1158 }
1159 }
1160
1161 return extra;
1162}
1163
1165{
1166 return true;
1167}
1168
1170{
1172 if (!d->target)
1173 return;
1174
1175 d->origLeftBinding = QQmlPropertyPrivate::binding(d->leftProp);
1176 d->origRightBinding = QQmlPropertyPrivate::binding(d->rightProp);
1177 d->origHCenterBinding = QQmlPropertyPrivate::binding(d->hCenterProp);
1178 d->origTopBinding = QQmlPropertyPrivate::binding(d->topProp);
1179 d->origBottomBinding = QQmlPropertyPrivate::binding(d->bottomProp);
1180 d->origVCenterBinding = QQmlPropertyPrivate::binding(d->vCenterProp);
1181 d->origBaselineBinding = QQmlPropertyPrivate::binding(d->baselineProp);
1182
1183 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1184 if (targetPrivate->widthValid())
1185 d->origWidth = d->target->width();
1186 if (targetPrivate->heightValid())
1187 d->origHeight = d->target->height();
1188 d->origX = d->target->x();
1189 d->origY = d->target->y();
1190
1191 d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1192 = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1193
1195}
1196
1198{
1200 QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
1201 QQuickAnchorChangesPrivate *acp = ac->d_func();
1202
1203 QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1204 acp->anchorSet->d_func()->resetAnchors;
1205
1206 //probably also need to revert some things
1207 d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
1208 d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
1209 d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
1210 d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
1211 d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
1212 d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
1213 d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
1214
1215 d->origLeftBinding = acp->origLeftBinding;
1216 d->origRightBinding = acp->origRightBinding;
1217 d->origHCenterBinding = acp->origHCenterBinding;
1218 d->origTopBinding = acp->origTopBinding;
1219 d->origBottomBinding = acp->origBottomBinding;
1220 d->origVCenterBinding = acp->origVCenterBinding;
1221 d->origBaselineBinding = acp->origBaselineBinding;
1222
1223 d->origWidth = acp->origWidth;
1224 d->origHeight = acp->origHeight;
1225 d->origX = acp->origX;
1226 d->origY = acp->origY;
1227
1228 //clear old values from other
1229 //### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals?
1230 acp->leftBinding = nullptr;
1231 acp->rightBinding = nullptr;
1232 acp->hCenterBinding = nullptr;
1233 acp->topBinding = nullptr;
1234 acp->bottomBinding = nullptr;
1235 acp->vCenterBinding = nullptr;
1236 acp->baselineBinding = nullptr;
1237 acp->origLeftBinding = nullptr;
1238 acp->origRightBinding = nullptr;
1239 acp->origHCenterBinding = nullptr;
1240 acp->origTopBinding = nullptr;
1241 acp->origBottomBinding = nullptr;
1242 acp->origVCenterBinding = nullptr;
1243 acp->origBaselineBinding = nullptr;
1244
1246}
1247
1249{
1251 if (!d->target)
1252 return;
1253
1254 //### should this (saving "from" values) be moved to saveCurrentValues()?
1255 d->fromX = d->target->x();
1256 d->fromY = d->target->y();
1257 d->fromWidth = d->target->width();
1258 d->fromHeight = d->target->height();
1259
1260 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1261 //reset any anchors with corresponding reverts
1262 //reset any anchors that have been specified as "undefined"
1263 //reset any anchors that we'll be setting in the state
1264 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
1265 d->anchorSet->d_func()->usedAnchors;
1266 if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
1267 targetPrivate->anchors()->resetLeft();
1269 }
1270 if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
1271 targetPrivate->anchors()->resetRight();
1273 }
1274 if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
1275 targetPrivate->anchors()->resetHorizontalCenter();
1277 }
1278 if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
1279 targetPrivate->anchors()->resetTop();
1281 }
1282 if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
1283 targetPrivate->anchors()->resetBottom();
1285 }
1286 if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
1287 targetPrivate->anchors()->resetVerticalCenter();
1289 }
1290 if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
1291 targetPrivate->anchors()->resetBaseline();
1293 }
1294}
1295
1297{
1298 if (other->type() != AnchorChanges)
1299 return false;
1300 if (static_cast<QQuickStateActionEvent*>(this) == other)
1301 return true;
1302 if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
1303 return true;
1304 return false;
1305}
1306
1308{
1310 if (!d->target)
1311 return;
1312
1313 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1314 const QRectF oldGeometry(d->target->position(), d->target->size());
1315
1316 // Restore previous values (but not previous bindings, i.e. anchors).
1317 // Also, don't drop any new bindings.
1318 if (!qt_is_nan(d->rewindX) && d->rewindX != targetPrivate->x)
1319 targetPrivate->x.setValueBypassingBindings(d->rewindX);
1320 if (!qt_is_nan(d->rewindY) && d->rewindY != targetPrivate->y)
1321 targetPrivate->y.setValueBypassingBindings(d->rewindY);
1322
1323 if (targetPrivate->widthValid() && !qt_is_nan(d->rewindWidth)) {
1324 targetPrivate->widthValidFlag = true;
1325 if (d->rewindWidth != targetPrivate->width)
1326 targetPrivate->width.setValueBypassingBindings(d->rewindWidth);
1327 }
1328
1329 if (targetPrivate->heightValid() && !qt_is_nan(d->rewindHeight)) {
1330 targetPrivate->heightValidFlag = true;
1331 if (d->rewindHeight != targetPrivate->height)
1332 targetPrivate->height.setValueBypassingBindings(d->rewindHeight);
1333 }
1334
1335 const QRectF newGeometry(d->target->position(), d->target->size());
1336 if (newGeometry != oldGeometry) {
1337 targetPrivate->dirty(QQuickItemPrivate::Position);
1338 d->target->geometryChange(newGeometry, oldGeometry);
1339 }
1340}
1341
1343{
1345 if (!d->target)
1346 return;
1347
1348 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1349 d->rewindLeft = targetPrivate->anchors()->left();
1350 d->rewindRight = targetPrivate->anchors()->right();
1351 d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
1352 d->rewindTop = targetPrivate->anchors()->top();
1353 d->rewindBottom = targetPrivate->anchors()->bottom();
1354 d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
1355 d->rewindBaseline = targetPrivate->anchors()->baseline();
1356
1357 d->rewindX = d->target->x();
1358 d->rewindY = d->target->y();
1359 d->rewindWidth = d->target->width();
1360 d->rewindHeight = d->target->height();
1361}
1362
1364{
1366 if (!d->target)
1367 return;
1368
1369 d->toX = d->target->x();
1370 d->toY = d->target->y();
1371 d->toWidth = d->target->width();
1372 d->toHeight = d->target->height();
1373}
1374
1376
1377#include <moc_qquickstateoperations_p.cpp>
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
T value(qsizetype i) const
Definition qlist.h:664
\inmodule QtCore
Definition qobject.h:103
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:201
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
static QQmlAnyBinding createFromScriptString(const QQmlProperty &prop, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt)
static QQmlBinding * create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *)
static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags=None, QQmlPropertyData::WriteFlags writeFlags=QQmlPropertyData::DontRemoveBinding)
static void removeBinding(const QQmlProperty &that)
static QQmlPropertyPrivate * get(const QQmlProperty &p)
static QQmlAbstractBinding * binding(QObject *, QQmlPropertyIndex index)
The QQmlProperty class abstracts accessing properties on objects created from QML.
The QQmlScriptString class encapsulates a script and its context.
qreal numberLiteral(bool *ok) const
If the content of the QQmlScriptString is a number literal, returns that number and sets ok to true.
bool isUndefinedLiteral() const
Returns whether the content of the QQmlScriptString is the undefined literal.
QQmlAbstractBinding::Ptr origLeftBinding
QQmlAbstractBinding::Ptr origBottomBinding
QQmlAbstractBinding::Ptr origTopBinding
QQmlNullableValue< qreal > origWidth
QQmlAbstractBinding::Ptr origHCenterBinding
QQmlNullableValue< qreal > origHeight
QQmlAbstractBinding::Ptr origRightBinding
QQmlAbstractBinding::Ptr origVCenterBinding
QQmlAbstractBinding::Ptr origBaselineBinding
QQuickAnchorChanges(QObject *parent=nullptr)
QList< QQuickStateAction > additionalActions() const
void copyOriginals(QQuickStateActionEvent *) override
ActionList actions() override
void execute() override
\qmlpropertygroup QtQuick::AnchorChanges::anchors \qmlproperty AnchorLine QtQuick::AnchorChanges::anc...
EventType type() const override
QQuickItem * object() const
\qmlproperty Item QtQuick::AnchorChanges::target This property holds the \l Item for which the anchor...
bool mayOverride(QQuickStateActionEvent *other) override
QQuickAnchors::Anchors usedAnchors
QQuickAnchors::Anchors resetAnchors
QQmlScriptString baseline
QQuickAnchors::Anchors usedAnchors() const
QQuickAnchorSet(QObject *parent=nullptr)
QQmlScriptString verticalCenter
QQmlScriptString horizontalCenter
void setBottom(const QQmlScriptString &edge)
void setLeft(const QQmlScriptString &edge)
void setTop(const QQmlScriptString &edge)
void setHorizontalCenter(const QQmlScriptString &edge)
void setVerticalCenter(const QQmlScriptString &edge)
void setBaseline(const QQmlScriptString &edge)
void setRight(const QQmlScriptString &edge)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQmlNullableValue< QQmlScriptString > xString
QQmlNullableValue< QQmlScriptString > rotationString
void reverseRewindHelper(const std::unique_ptr< StateSnapshot > &snapshot)
QQmlNullableValue< QQmlScriptString > scaleString
void doChange(QQuickItem *targetParent)
std::unique_ptr< StateSnapshot > orig
QQmlNullableValue< QQmlScriptString > widthString
std::unique_ptr< StateSnapshot > rewind
QQmlNullableValue< QQmlScriptString > yString
QQmlNullableValue< QQmlScriptString > heightString
void setObject(QQuickItem *)
void setRotation(const QQmlScriptString &rotation)
void saveCurrentValues() override
EventType type() const override
ActionList actions() override
void setX(const QQmlScriptString &x)
QQuickItem * object() const
\qmlproperty Item QtQuick::ParentChange::target This property holds the item to be reparented
void setY(const QQmlScriptString &y)
void setHeight(const QQmlScriptString &height)
bool mayOverride(QQuickStateActionEvent *other) override
QQuickParentChange(QObject *parent=nullptr)
\qmltype ParentChange \instantiates QQuickParentChange \inqmlmodule QtQuick
void setWidth(const QQmlScriptString &width)
void setScale(const QQmlScriptString &scale)
void setParent(QQuickItem *)
QQuickItem * originalParent() const
QQmlProperty property
QQuickStateActionEvent * event
QList< QQuickStateAction > ActionList
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:511
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:735
\inmodule QtCore
Definition qsize.h:208
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & rotate(qreal a, Qt::Axis axis=Qt::ZAxis, qreal distanceToPlane=1024.0f)
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Combined button and popup list for selecting options.
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:289
constexpr float qRadiansToDegrees(float radians)
Definition qmath.h:281
auto qAtan2(T1 y, T2 x)
Definition qmath.h:90
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
Definition qnumeric_p.h:112
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei width
GLenum target
GLenum GLuint GLintptr offset
GLint y
GLuint GLenum GLenum transform
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLenum GLenum GLenum scale
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define ra
double qreal
Definition qtypes.h:187
const char property[13]
Definition qwizard.cpp:101
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]