Qt 6.x
The Qt SDK
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#include <QtCore/qmath.h>
11#include <memory>
12
14
16{
17 Q_DECLARE_PUBLIC(QQuickParentChange)
18public:
19 QQuickItem *target = nullptr;
21
25 qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0;
26 };
27
28 std::unique_ptr<StateSnapshot> orig;
29 std::unique_ptr<StateSnapshot> rewind;
30
37
38 void doChange(QQuickItem *targetParent);
39 void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot);
40};
41
43{
44 if (targetParent && target && target->parentItem()) {
46 bool ok;
47 const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
48 if (transform.type() >= QTransform::TxShear || !ok) {
49 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
50 ok = false;
51 }
52
53 qreal scale = 1;
54 qreal rotation = 0;
55 bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
56 if (ok && !isRotate) {
57 if (transform.m11() == transform.m22())
58 scale = transform.m11();
59 else {
60 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
61 ok = false;
62 }
63 } else if (ok && isRotate) {
64 if (transform.m11() == transform.m22())
65 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
66 else {
67 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
68 ok = false;
69 }
70
71 if (scale != 0)
72 rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
73 else {
74 qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
75 ok = false;
76 }
77 }
78
79 const QPointF &point = transform.map(QPointF(target->x(),target->y()));
80 qreal x = point.x();
81 qreal y = point.y();
82
83 // setParentItem will update the transformOriginPoint if needed
84 target->setParentItem(targetParent);
85
86 if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
87 qreal tempxt = target->transformOriginPoint().x();
88 qreal tempyt = target->transformOriginPoint().y();
90 t.translate(-tempxt, -tempyt);
91 t.rotate(rotation);
92 t.scale(scale, scale);
93 t.translate(tempxt, tempyt);
94 const QPointF &offset = t.map(QPointF(0,0));
95 x += offset.x();
96 y += offset.y();
97 }
98
99 if (ok) {
100 //qDebug() << x << y << rotation << scale;
101 target->setPosition(QPointF(x, y));
102 target->setRotation(target->rotation() + rotation);
103 target->setScale(target->scale() * scale);
104 }
105 } else if (target) {
106 target->setParentItem(targetParent);
107 }
108}
109
143{
144}
145
157{
158 Q_D(const QQuickParentChange);
159 return d->xString.value;
160}
161
163{
165 d->xString = x;
166}
167
169{
170 Q_D(const QQuickParentChange);
171 return d->xString.isValid();
172}
173
175{
176 Q_D(const QQuickParentChange);
177 return d->yString.value;
178}
179
181{
183 d->yString = y;
184}
185
187{
188 Q_D(const QQuickParentChange);
189 return d->yString.isValid();
190}
191
193{
194 Q_D(const QQuickParentChange);
195 return d->widthString.value;
196}
197
199{
201 d->widthString = width;
202}
203
205{
206 Q_D(const QQuickParentChange);
207 return d->widthString.isValid();
208}
209
211{
212 Q_D(const QQuickParentChange);
213 return d->heightString.value;
214}
215
217{
219 d->heightString = height;
220}
221
223{
224 Q_D(const QQuickParentChange);
225 return d->heightString.isValid();
226}
227
229{
230 Q_D(const QQuickParentChange);
231 return d->scaleString.value;
232}
233
235{
237 d->scaleString = scale;
238}
239
241{
242 Q_D(const QQuickParentChange);
243 return d->scaleString.isValid();
244}
245
247{
248 Q_D(const QQuickParentChange);
249 return d->rotationString.value;
250}
251
253{
255 d->rotationString = rotation;
256}
257
259{
260 Q_D(const QQuickParentChange);
261 return d->rotationString.isValid();
262}
263
265{
266 Q_D(const QQuickParentChange);
267 return d->orig ? d->orig->parent : nullptr;
268}
269
275{
276 Q_D(const QQuickParentChange);
277 return d->target;
278}
279
281{
283 d->target = target;
284}
285
291{
292 Q_D(const QQuickParentChange);
293 return d->parent;
294}
295
297{
299 d->parent = parent;
300}
301
303{
305 if (!d->target || !d->parent)
306 return ActionList();
307
309
311 a.event = this;
312 actions << a;
313
314 if (d->xString.isValid()) {
315 bool ok = false;
316 qreal x = d->xString.value.numberLiteral(&ok);
317 if (ok) {
318 QQuickStateAction xa(d->target, QLatin1String("x"), x);
319 actions << xa;
320 } else {
321 QQmlProperty property(d->target, QLatin1String("x"));
322 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->xString.value, d->target, qmlContext(this));
324 xa.property = property;
325 xa.toBinding = newBinding;
326 xa.fromValue = xa.property.read();
327 xa.deletableToBinding = true;
328 actions << xa;
329 }
330 }
331
332 if (d->yString.isValid()) {
333 bool ok = false;
334 qreal y = d->yString.value.numberLiteral(&ok);
335 if (ok) {
336 QQuickStateAction ya(d->target, QLatin1String("y"), y);
337 actions << ya;
338 } else {
339 QQmlProperty property(d->target, QLatin1String("y"));
340 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->yString.value, d->target, qmlContext(this));
342 ya.property = property;
343 ya.toBinding = newBinding;
344 ya.fromValue = ya.property.read();
345 ya.deletableToBinding = true;
346 actions << ya;
347 }
348 }
349
350 if (d->scaleString.isValid()) {
351 bool ok = false;
352 qreal scale = d->scaleString.value.numberLiteral(&ok);
353 if (ok) {
354 QQuickStateAction sa(d->target, QLatin1String("scale"), scale);
355 actions << sa;
356 } else {
357 QQmlProperty property(d->target, QLatin1String("scale"));
358 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->scaleString.value, d->target, qmlContext(this));
360 sa.property = property;
361 sa.toBinding = newBinding;
362 sa.fromValue = sa.property.read();
363 sa.deletableToBinding = true;
364 actions << sa;
365 }
366 }
367
368 if (d->rotationString.isValid()) {
369 bool ok = false;
370 qreal rotation = d->rotationString.value.numberLiteral(&ok);
371 if (ok) {
372 QQuickStateAction ra(d->target, QLatin1String("rotation"), rotation);
373 actions << ra;
374 } else {
375 QQmlProperty property(d->target, QLatin1String("rotation"));
376 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->rotationString.value, d->target, qmlContext(this));
378 ra.property = property;
379 ra.toBinding = newBinding;
380 ra.fromValue = ra.property.read();
381 ra.deletableToBinding = true;
382 actions << ra;
383 }
384 }
385
386 if (d->widthString.isValid()) {
387 bool ok = false;
388 qreal width = d->widthString.value.numberLiteral(&ok);
389 if (ok) {
390 QQuickStateAction wa(d->target, QLatin1String("width"), width);
391 actions << wa;
392 } else {
393 QQmlProperty property(d->target, QLatin1String("width"));
394 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->widthString, d->target, qmlContext(this));
396 wa.property = property;
397 wa.toBinding = newBinding;
398 wa.fromValue = wa.property.read();
399 wa.deletableToBinding = true;
400 actions << wa;
401 }
402 }
403
404 if (d->heightString.isValid()) {
405 bool ok = false;
406 qreal height = d->heightString.value.numberLiteral(&ok);
407 if (ok) {
408 QQuickStateAction ha(d->target, QLatin1String("height"), height);
409 actions << ha;
410 } else {
411 QQmlProperty property(d->target, QLatin1String("height"));
412 auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->heightString, d->target, qmlContext(this));
414 ha.property = property;
415 ha.toBinding = newBinding;
416 ha.fromValue = ha.property.read();
417 ha.deletableToBinding = true;
418 actions << ha;
419 }
420 }
421
422 return actions;
423}
424
426{
429 if (!d->orig)
431 *d->orig = *d->rewind;
432}
433
435{
437 d->doChange(d->parent);
438}
439
441{
442 return true;
443}
444
445void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot)
446{
447 if (!target || !snapshot)
448 return;
449
450 // leave existing bindings alive; new bindings are applied in applyBindings
451 // setPosition and setSize update the geometry without invalidating bindings
452 target->setPosition(QPointF(snapshot->x, snapshot->y));
453 target->setSize(QSizeF(snapshot->width, snapshot->height));
454
455 target->setScale(snapshot->scale);
456 target->setRotation(snapshot->rotation);
457 target->setParentItem(snapshot->parent);
458 if (snapshot->stackBefore)
459 target->stackBefore(snapshot->stackBefore);
460}
461
462
464{
466 d->reverseRewindHelper(d->orig);
467}
468
470{
471 return ParentChange;
472}
473
475{
477 if (other->type() != ParentChange)
478 return false;
479 if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
480 return (d->target == otherPC->object());
481 return false;
482}
483
485{
487 if (!d->target) {
488 d->rewind = nullptr;
489 return;
490 }
491
493 d->rewind->x = d->target->x();
494 d->rewind->y = d->target->y();
495 d->rewind->scale = d->target->scale();
496 d->rewind->width = d->target->width();
497 d->rewind->height = d->target->height();
498 d->rewind->rotation = d->target->rotation();
499
500 d->rewind->parent = d->target->parentItem();
501 d->rewind->stackBefore = nullptr;
502
503 if (!d->rewind->parent)
504 return;
505
506 QList<QQuickItem *> children = d->rewind->parent->childItems();
507 for (int ii = 0; ii < children.size() - 1; ++ii) {
508 if (children.at(ii) == d->target) {
509 d->rewind->stackBefore = children.at(ii + 1);
510 break;
511 }
512 }
513}
514
516{
518 d->reverseRewindHelper(d->rewind);
519 d->rewind.reset();
520}
521
556{
557 Q_DECLARE_PUBLIC(QQuickAnchorSet)
558public:
559 QQuickAnchors::Anchors usedAnchors;
560 QQuickAnchors::Anchors resetAnchors;
561
569};
570
573{
574}
575
577{
578}
579
581{
582 Q_D(const QQuickAnchorSet);
583 return d->topScript;
584}
585
587{
588 Q_D(QQuickAnchorSet);
589 d->usedAnchors |= QQuickAnchors::TopAnchor;
590 d->topScript = edge;
591 if (edge.isUndefinedLiteral())
592 resetTop();
593}
594
596{
597 Q_D(QQuickAnchorSet);
598 d->usedAnchors &= ~QQuickAnchors::TopAnchor;
599 d->resetAnchors |= QQuickAnchors::TopAnchor;
600}
601
603{
604 Q_D(const QQuickAnchorSet);
605 return d->bottomScript;
606}
607
609{
610 Q_D(QQuickAnchorSet);
611 d->usedAnchors |= QQuickAnchors::BottomAnchor;
612 d->bottomScript = edge;
613 if (edge.isUndefinedLiteral())
614 resetBottom();
615}
616
618{
619 Q_D(QQuickAnchorSet);
620 d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
621 d->resetAnchors |= QQuickAnchors::BottomAnchor;
622}
623
625{
626 Q_D(const QQuickAnchorSet);
627 return d->vCenterScript;
628}
629
631{
632 Q_D(QQuickAnchorSet);
633 d->usedAnchors |= QQuickAnchors::VCenterAnchor;
634 d->vCenterScript = edge;
635 if (edge.isUndefinedLiteral())
637}
638
640{
641 Q_D(QQuickAnchorSet);
642 d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
643 d->resetAnchors |= QQuickAnchors::VCenterAnchor;
644}
645
647{
648 Q_D(const QQuickAnchorSet);
649 return d->baselineScript;
650}
651
653{
654 Q_D(QQuickAnchorSet);
655 d->usedAnchors |= QQuickAnchors::BaselineAnchor;
656 d->baselineScript = edge;
657 if (edge.isUndefinedLiteral())
659}
660
662{
663 Q_D(QQuickAnchorSet);
664 d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
665 d->resetAnchors |= QQuickAnchors::BaselineAnchor;
666}
667
669{
670 Q_D(const QQuickAnchorSet);
671 return d->leftScript;
672}
673
675{
676 Q_D(QQuickAnchorSet);
677 d->usedAnchors |= QQuickAnchors::LeftAnchor;
678 d->leftScript = edge;
679 if (edge.isUndefinedLiteral())
680 resetLeft();
681}
682
684{
685 Q_D(QQuickAnchorSet);
686 d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
687 d->resetAnchors |= QQuickAnchors::LeftAnchor;
688}
689
691{
692 Q_D(const QQuickAnchorSet);
693 return d->rightScript;
694}
695
697{
698 Q_D(QQuickAnchorSet);
699 d->usedAnchors |= QQuickAnchors::RightAnchor;
700 d->rightScript = edge;
701 if (edge.isUndefinedLiteral())
702 resetRight();
703}
704
706{
707 Q_D(QQuickAnchorSet);
708 d->usedAnchors &= ~QQuickAnchors::RightAnchor;
709 d->resetAnchors |= QQuickAnchors::RightAnchor;
710}
711
713{
714 Q_D(const QQuickAnchorSet);
715 return d->hCenterScript;
716}
717
719{
720 Q_D(QQuickAnchorSet);
721 d->usedAnchors |= QQuickAnchors::HCenterAnchor;
722 d->hCenterScript = edge;
723 if (edge.isUndefinedLiteral())
725}
726
728{
729 Q_D(QQuickAnchorSet);
730 d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
731 d->resetAnchors |= QQuickAnchors::HCenterAnchor;
732}
733
735{
736public:
739 {
740
741 }
743
746
754
762
770
775
780
785
793
798
806};
807
810{
811}
812
814{
816 //### ASSERT these are all 0?
817 d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
818 = d->bottomBinding = d->vCenterBinding = d->baselineBinding = nullptr;
819
820 d->leftProp = QQmlProperty(d->target, QLatin1String("anchors.left"));
821 d->rightProp = QQmlProperty(d->target, QLatin1String("anchors.right"));
822 d->hCenterProp = QQmlProperty(d->target, QLatin1String("anchors.horizontalCenter"));
823 d->topProp = QQmlProperty(d->target, QLatin1String("anchors.top"));
824 d->bottomProp = QQmlProperty(d->target, QLatin1String("anchors.bottom"));
825 d->vCenterProp = QQmlProperty(d->target, QLatin1String("anchors.verticalCenter"));
826 d->baselineProp = QQmlProperty(d->target, QLatin1String("anchors.baseline"));
827
828 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
829 d->leftBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->leftProp)->core, d->anchorSet->d_func()->leftScript, d->target, qmlContext(this));
830 d->leftBinding->setTarget(d->leftProp);
831 }
832 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
833 d->rightBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->rightProp)->core, d->anchorSet->d_func()->rightScript, d->target, qmlContext(this));
834 d->rightBinding->setTarget(d->rightProp);
835 }
836 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
837 d->hCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->hCenterProp)->core, d->anchorSet->d_func()->hCenterScript, d->target, qmlContext(this));
838 d->hCenterBinding->setTarget(d->hCenterProp);
839 }
840 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
841 d->topBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->topProp)->core, d->anchorSet->d_func()->topScript, d->target, qmlContext(this));
842 d->topBinding->setTarget(d->topProp);
843 }
844 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
845 d->bottomBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->bottomProp)->core, d->anchorSet->d_func()->bottomScript, d->target, qmlContext(this));
846 d->bottomBinding->setTarget(d->bottomProp);
847 }
848 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
849 d->vCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->vCenterProp)->core, d->anchorSet->d_func()->vCenterScript, d->target, qmlContext(this));
850 d->vCenterBinding->setTarget(d->vCenterProp);
851 }
852 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
853 d->baselineBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->baselineProp)->core, d->anchorSet->d_func()->baselineScript, d->target, qmlContext(this));
854 d->baselineBinding->setTarget(d->baselineProp);
855 }
856
858 a.event = this;
859 return ActionList() << a;
860}
861
863{
864 Q_D(const QQuickAnchorChanges);
865 return d->anchorSet;
866}
867
873{
874 Q_D(const QQuickAnchorChanges);
875 return d->target;
876}
877
879{
881 d->target = target;
882}
883
907{
909 if (!d->target)
910 return;
911
912 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
913 //incorporate any needed "reverts"
914 if (d->applyOrigLeft) {
915 if (!d->origLeftBinding)
916 targetPrivate->anchors()->resetLeft();
917 QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
918 }
919 if (d->applyOrigRight) {
920 if (!d->origRightBinding)
921 targetPrivate->anchors()->resetRight();
922 QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
923 }
924 if (d->applyOrigHCenter) {
925 if (!d->origHCenterBinding)
926 targetPrivate->anchors()->resetHorizontalCenter();
927 QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
928 }
929 if (d->applyOrigTop) {
930 if (!d->origTopBinding)
931 targetPrivate->anchors()->resetTop();
932 QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
933 }
934 if (d->applyOrigBottom) {
935 if (!d->origBottomBinding)
936 targetPrivate->anchors()->resetBottom();
937 QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
938 }
939 if (d->applyOrigVCenter) {
940 if (!d->origVCenterBinding)
941 targetPrivate->anchors()->resetVerticalCenter();
942 QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
943 }
944 if (d->applyOrigBaseline) {
945 if (!d->origBaselineBinding)
946 targetPrivate->anchors()->resetBaseline();
947 QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
948 }
949
950 //reset any anchors that have been specified as "undefined"
951 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
952 targetPrivate->anchors()->resetLeft();
954 }
955 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
956 targetPrivate->anchors()->resetRight();
958 }
959 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
960 targetPrivate->anchors()->resetHorizontalCenter();
962 }
963 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
964 targetPrivate->anchors()->resetTop();
966 }
967 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
968 targetPrivate->anchors()->resetBottom();
970 }
971 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
972 targetPrivate->anchors()->resetVerticalCenter();
974 }
975 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
976 targetPrivate->anchors()->resetBaseline();
978 }
979
980 //set any anchors that have been specified
981 if (d->leftBinding)
982 QQmlPropertyPrivate::setBinding(d->leftBinding.data());
983 if (d->rightBinding)
984 QQmlPropertyPrivate::setBinding(d->rightBinding.data());
985 if (d->hCenterBinding)
986 QQmlPropertyPrivate::setBinding(d->hCenterBinding.data());
987 if (d->topBinding)
988 QQmlPropertyPrivate::setBinding(d->topBinding.data());
989 if (d->bottomBinding)
990 QQmlPropertyPrivate::setBinding(d->bottomBinding.data());
991 if (d->vCenterBinding)
992 QQmlPropertyPrivate::setBinding(d->vCenterBinding.data());
993 if (d->baselineBinding)
994 QQmlPropertyPrivate::setBinding(d->baselineBinding.data());
995}
996
998{
999 return true;
1000}
1001
1003{
1005 if (!d->target)
1006 return;
1007
1008 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1009 //reset any anchors set by the state
1010 if (d->leftBinding) {
1011 targetPrivate->anchors()->resetLeft();
1012 QQmlPropertyPrivate::removeBinding(d->leftBinding.data());
1013 }
1014 if (d->rightBinding) {
1015 targetPrivate->anchors()->resetRight();
1016 QQmlPropertyPrivate::removeBinding(d->rightBinding.data());
1017 }
1018 if (d->hCenterBinding) {
1019 targetPrivate->anchors()->resetHorizontalCenter();
1020 QQmlPropertyPrivate::removeBinding(d->hCenterBinding.data());
1021 }
1022 if (d->topBinding) {
1023 targetPrivate->anchors()->resetTop();
1024 QQmlPropertyPrivate::removeBinding(d->topBinding.data());
1025 }
1026 if (d->bottomBinding) {
1027 targetPrivate->anchors()->resetBottom();
1028 QQmlPropertyPrivate::removeBinding(d->bottomBinding.data());
1029 }
1030 if (d->vCenterBinding) {
1031 targetPrivate->anchors()->resetVerticalCenter();
1032 QQmlPropertyPrivate::removeBinding(d->vCenterBinding.data());
1033 }
1034 if (d->baselineBinding) {
1035 targetPrivate->anchors()->resetBaseline();
1036 QQmlPropertyPrivate::removeBinding(d->baselineBinding.data());
1037 }
1038
1039 //restore previous anchors
1040 if (d->origLeftBinding)
1041 QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
1042 if (d->origRightBinding)
1043 QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
1044 if (d->origHCenterBinding)
1045 QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
1046 if (d->origTopBinding)
1047 QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
1048 if (d->origBottomBinding)
1049 QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
1050 if (d->origVCenterBinding)
1051 QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
1052 if (d->origBaselineBinding)
1053 QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
1054
1055 //restore any absolute geometry changed by the state's anchors
1056 QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
1057 QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
1058 QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
1059 QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
1060
1061 const QRectF oldGeometry(d->target->position(), d->target->size());
1062 bool stateSetWidth = (stateHAnchors &&
1063 stateHAnchors != QQuickAnchors::LeftAnchor &&
1064 stateHAnchors != QQuickAnchors::RightAnchor &&
1065 stateHAnchors != QQuickAnchors::HCenterAnchor);
1066 // in case of an additive AnchorChange, we _did_ end up modifying the width
1067 stateSetWidth |= ((stateHAnchors & QQuickAnchors::LeftAnchor) && (origHAnchors & QQuickAnchors::RightAnchor)) ||
1068 ((stateHAnchors & QQuickAnchors::RightAnchor) && (origHAnchors & QQuickAnchors::LeftAnchor));
1069 bool origSetWidth = (origHAnchors &&
1070 origHAnchors != QQuickAnchors::LeftAnchor &&
1071 origHAnchors != QQuickAnchors::RightAnchor &&
1072 origHAnchors != QQuickAnchors::HCenterAnchor);
1073 if (d->origWidth.isValid() && stateSetWidth && !origSetWidth && !qt_is_nan(d->origWidth)) {
1074 targetPrivate->widthValidFlag = true;
1075 if (targetPrivate->width != d->origWidth)
1076 targetPrivate->width.setValueBypassingBindings(d->origWidth);
1077 }
1078
1079 bool stateSetHeight = (stateVAnchors &&
1080 stateVAnchors != QQuickAnchors::TopAnchor &&
1081 stateVAnchors != QQuickAnchors::BottomAnchor &&
1082 stateVAnchors != QQuickAnchors::VCenterAnchor &&
1083 stateVAnchors != QQuickAnchors::BaselineAnchor);
1084 // in case of an additive AnchorChange, we _did_ end up modifying the height
1085 stateSetHeight |= ((stateVAnchors & QQuickAnchors::TopAnchor) && (origVAnchors & QQuickAnchors::BottomAnchor)) ||
1086 ((stateVAnchors & QQuickAnchors::BottomAnchor) && (origVAnchors & QQuickAnchors::TopAnchor));
1087 bool origSetHeight = (origVAnchors &&
1088 origVAnchors != QQuickAnchors::TopAnchor &&
1089 origVAnchors != QQuickAnchors::BottomAnchor &&
1090 origVAnchors != QQuickAnchors::VCenterAnchor &&
1091 origVAnchors != QQuickAnchors::BaselineAnchor);
1092 if (d->origHeight.isValid() && stateSetHeight && !origSetHeight && !qt_is_nan(d->origHeight)) {
1093 targetPrivate->heightValidFlag = true;
1094 if (targetPrivate->height != d->origHeight)
1095 targetPrivate->height.setValueBypassingBindings(d->origHeight);
1096 }
1097
1098 if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x)
1099 targetPrivate->x.setValueBypassingBindings(d->origX);
1100
1101 if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y)
1102 targetPrivate->y.setValueBypassingBindings(d->origY);
1103
1104 const QRectF newGeometry(d->target->position(), d->target->size());
1105 if (newGeometry != oldGeometry) {
1106 QQuickItemPrivate::DirtyType dirtyFlags {};
1107 if (newGeometry.topLeft() != oldGeometry.topLeft())
1109 if (newGeometry.size() != oldGeometry.size())
1110 dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Size);
1111 targetPrivate->dirty(dirtyFlags);
1112 d->target->geometryChange(newGeometry, oldGeometry);
1113 }
1114}
1115
1117{
1118 return AnchorChanges;
1119}
1120
1122{
1123 Q_D(const QQuickAnchorChanges);
1125
1126 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
1127 bool hChange = combined & QQuickAnchors::Horizontal_Mask;
1128 bool vChange = combined & QQuickAnchors::Vertical_Mask;
1129
1130 if (d->target) {
1132 if (hChange && d->fromX != d->toX) {
1133 a.property = QQmlProperty(d->target, QLatin1String("x"));
1134 a.toValue = d->toX;
1135 extra << a;
1136 }
1137 if (vChange && d->fromY != d->toY) {
1138 a.property = QQmlProperty(d->target, QLatin1String("y"));
1139 a.toValue = d->toY;
1140 extra << a;
1141 }
1142 if (hChange && d->fromWidth != d->toWidth) {
1143 a.property = QQmlProperty(d->target, QLatin1String("width"));
1144 a.toValue = d->toWidth;
1145 extra << a;
1146 }
1147 if (vChange && d->fromHeight != d->toHeight) {
1148 a.property = QQmlProperty(d->target, QLatin1String("height"));
1149 a.toValue = d->toHeight;
1150 extra << a;
1151 }
1152 }
1153
1154 return extra;
1155}
1156
1158{
1159 return true;
1160}
1161
1163{
1165 if (!d->target)
1166 return;
1167
1168 d->origLeftBinding = QQmlPropertyPrivate::binding(d->leftProp);
1169 d->origRightBinding = QQmlPropertyPrivate::binding(d->rightProp);
1170 d->origHCenterBinding = QQmlPropertyPrivate::binding(d->hCenterProp);
1171 d->origTopBinding = QQmlPropertyPrivate::binding(d->topProp);
1172 d->origBottomBinding = QQmlPropertyPrivate::binding(d->bottomProp);
1173 d->origVCenterBinding = QQmlPropertyPrivate::binding(d->vCenterProp);
1174 d->origBaselineBinding = QQmlPropertyPrivate::binding(d->baselineProp);
1175
1176 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1177 if (targetPrivate->widthValid())
1178 d->origWidth = d->target->width();
1179 if (targetPrivate->heightValid())
1180 d->origHeight = d->target->height();
1181 d->origX = d->target->x();
1182 d->origY = d->target->y();
1183
1184 d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1185 = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1186
1188}
1189
1191{
1193 QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
1194 QQuickAnchorChangesPrivate *acp = ac->d_func();
1195
1196 QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1197 acp->anchorSet->d_func()->resetAnchors;
1198
1199 //probably also need to revert some things
1200 d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
1201 d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
1202 d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
1203 d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
1204 d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
1205 d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
1206 d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
1207
1208 d->origLeftBinding = acp->origLeftBinding;
1209 d->origRightBinding = acp->origRightBinding;
1210 d->origHCenterBinding = acp->origHCenterBinding;
1211 d->origTopBinding = acp->origTopBinding;
1212 d->origBottomBinding = acp->origBottomBinding;
1213 d->origVCenterBinding = acp->origVCenterBinding;
1214 d->origBaselineBinding = acp->origBaselineBinding;
1215
1216 d->origWidth = acp->origWidth;
1217 d->origHeight = acp->origHeight;
1218 d->origX = acp->origX;
1219 d->origY = acp->origY;
1220
1221 //clear old values from other
1222 //### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals?
1223 acp->leftBinding = nullptr;
1224 acp->rightBinding = nullptr;
1225 acp->hCenterBinding = nullptr;
1226 acp->topBinding = nullptr;
1227 acp->bottomBinding = nullptr;
1228 acp->vCenterBinding = nullptr;
1229 acp->baselineBinding = nullptr;
1230 acp->origLeftBinding = nullptr;
1231 acp->origRightBinding = nullptr;
1232 acp->origHCenterBinding = nullptr;
1233 acp->origTopBinding = nullptr;
1234 acp->origBottomBinding = nullptr;
1235 acp->origVCenterBinding = nullptr;
1236 acp->origBaselineBinding = nullptr;
1237
1239}
1240
1242{
1244 if (!d->target)
1245 return;
1246
1247 //### should this (saving "from" values) be moved to saveCurrentValues()?
1248 d->fromX = d->target->x();
1249 d->fromY = d->target->y();
1250 d->fromWidth = d->target->width();
1251 d->fromHeight = d->target->height();
1252
1253 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1254 //reset any anchors with corresponding reverts
1255 //reset any anchors that have been specified as "undefined"
1256 //reset any anchors that we'll be setting in the state
1257 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
1258 d->anchorSet->d_func()->usedAnchors;
1259 if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
1260 targetPrivate->anchors()->resetLeft();
1262 }
1263 if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
1264 targetPrivate->anchors()->resetRight();
1266 }
1267 if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
1268 targetPrivate->anchors()->resetHorizontalCenter();
1270 }
1271 if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
1272 targetPrivate->anchors()->resetTop();
1274 }
1275 if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
1276 targetPrivate->anchors()->resetBottom();
1278 }
1279 if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
1280 targetPrivate->anchors()->resetVerticalCenter();
1282 }
1283 if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
1284 targetPrivate->anchors()->resetBaseline();
1286 }
1287}
1288
1290{
1291 if (other->type() != AnchorChanges)
1292 return false;
1293 if (static_cast<QQuickStateActionEvent*>(this) == other)
1294 return true;
1295 if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
1296 return true;
1297 return false;
1298}
1299
1301{
1303 if (!d->target)
1304 return;
1305
1306 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1307 const QRectF oldGeometry(d->target->position(), d->target->size());
1308
1309 // Restore previous values (but not previous bindings, i.e. anchors).
1310 // Also, don't drop any new bindings.
1311 if (!qt_is_nan(d->rewindX) && d->rewindX != targetPrivate->x)
1312 targetPrivate->x.setValueBypassingBindings(d->rewindX);
1313 if (!qt_is_nan(d->rewindY) && d->rewindY != targetPrivate->y)
1314 targetPrivate->y.setValueBypassingBindings(d->rewindY);
1315
1316 if (targetPrivate->widthValid() && !qt_is_nan(d->rewindWidth)) {
1317 targetPrivate->widthValidFlag = true;
1318 if (d->rewindWidth != targetPrivate->width)
1319 targetPrivate->width.setValueBypassingBindings(d->rewindWidth);
1320 }
1321
1322 if (targetPrivate->heightValid() && !qt_is_nan(d->rewindHeight)) {
1323 targetPrivate->heightValidFlag = true;
1324 if (d->rewindHeight != targetPrivate->height)
1325 targetPrivate->height.setValueBypassingBindings(d->rewindHeight);
1326 }
1327
1328 const QRectF newGeometry(d->target->position(), d->target->size());
1329 if (newGeometry != oldGeometry) {
1330 targetPrivate->dirty(QQuickItemPrivate::Position);
1331 d->target->geometryChange(newGeometry, oldGeometry);
1332 }
1333}
1334
1336{
1338 if (!d->target)
1339 return;
1340
1341 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1342 d->rewindLeft = targetPrivate->anchors()->left();
1343 d->rewindRight = targetPrivate->anchors()->right();
1344 d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
1345 d->rewindTop = targetPrivate->anchors()->top();
1346 d->rewindBottom = targetPrivate->anchors()->bottom();
1347 d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
1348 d->rewindBaseline = targetPrivate->anchors()->baseline();
1349
1350 d->rewindX = d->target->x();
1351 d->rewindY = d->target->y();
1352 d->rewindWidth = d->target->width();
1353 d->rewindHeight = d->target->height();
1354}
1355
1357{
1359 if (!d->target)
1360 return;
1361
1362 d->toX = d->target->x();
1363 d->toY = d->target->y();
1364 d->toWidth = d->target->width();
1365 d->toHeight = d->target->height();
1366}
1367
1369
1370#include <moc_qquickstateoperations_p.cpp>
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
\inmodule QtCore
Definition qobject.h:90
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:171
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
\inmodule QtCore
Definition qpointer.h:18
static QQmlAnyBinding createFromScriptString(const QQmlProperty &prop, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt)
static QQmlBinding * create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *)
QQmlPropertyData core
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.
QVariant read() const
Returns the property value.
The QQmlScriptString class encapsulates a script and its context.
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)
void resetVerticalCenter()
QQuickAnchorLine top
QQuickAnchorLine left
QQuickAnchorLine right
QQuickAnchorLine horizontalCenter
Anchors usedAnchors() const
QQuickAnchorLine baseline
QQuickAnchorLine verticalCenter
void resetHorizontalCenter()
QQuickAnchorLine bottom
QQuickAnchors * anchors() const
\qmlpropertygroup QtQuick::Item::anchors \qmlproperty AnchorLine QtQuick::Item::anchors....
bool widthValid() const
void dirty(DirtyType)
bool heightValid() const
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
QQuickItem * parentItem() const
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
QQmlAnyBinding toBinding
QList< QQuickStateAction > ActionList
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:510
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:721
\inmodule QtCore
Definition qsize.h:207
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
Combined button and popup list for selecting options.
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:243
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:106
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:71
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define ra
double qreal
Definition qtypes.h:92
const char property[13]
Definition qwizard.cpp:101
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent