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
qquickanchors.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
4#include "qquickanchors_p_p.h"
5
6#include "qquickitem_p.h"
7
8#include <qqmlinfo.h>
9
11
13{
14 return QQuickItemPrivate::get(item)->parentItem;
15}
16
21
26
28{
29 return QQuickItemPrivate::get(item)->width;
30}
31
33{
34 return QQuickItemPrivate::get(item)->height;
35}
36
38{
39 return QQuickItemPrivate::get(item)->baselineOffset;
40}
41
42//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
43//TODO: support non-parent, non-sibling (need to find lowest common ancestor)
44
45static inline qreal hcenter(const QQuickItem *item)
46{
49 if (!QQuickAnchorsPrivate::get(anchors)->centerAligned)
50 return width / 2;
51 }
52 return qRound(width / 2);
53}
54
55static inline qreal vcenter(const QQuickItem *item)
56{
59 if (!QQuickAnchorsPrivate::get(anchors)->centerAligned)
60 return height / 2;
61 }
62 return qRound(height / 2);
63}
64
65//local position
66static inline qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
67{
68 qreal ret = 0.0;
69 switch (anchorLine) {
71 ret = readX(item);
72 break;
75 break;
77 ret = readY(item);
78 break;
81 break;
84 break;
87 break;
90 break;
91 default:
92 break;
93 }
94
95 return ret;
96}
97
98//position when origin is 0,0
100{
101 qreal ret = 0.0;
102 switch (anchorLine) {
104 ret = 0.0;
105 break;
107 ret = readWidth(item);
108 break;
110 ret = 0.0;
111 break;
114 break;
116 ret = hcenter(item);
117 break;
119 ret = vcenter(item);
120 break;
123 break;
124 default:
125 break;
126 }
127
128 return ret;
129}
130
135
137{
138 Q_D(QQuickAnchors);
139 d->inDestructor = true;
140 d->remDepend(d->fill);
141 d->remDepend(d->centerIn);
142 d->remDepend(d->leftAnchorItem);
143 d->remDepend(d->rightAnchorItem);
144 d->remDepend(d->topAnchorItem);
145 d->remDepend(d->bottomAnchorItem);
146 d->remDepend(d->vCenterAnchorItem);
147 d->remDepend(d->hCenterAnchorItem);
148 d->remDepend(d->baselineAnchorItem);
149}
150
152{
153 Q_Q(QQuickAnchors);
154 if (!fill || !isItemComplete())
155 return;
156
157 if (updatingFill < 2) {
158 ++updatingFill;
159
160 qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
161
162 if (fill == readParentItem(item)) { //child-parent
163 setItemPos(QPointF(horizontalMargin, topMargin));
164 } else if (readParentItem(fill) == readParentItem(item)) { //siblings
165 setItemPos(QPointF(readX(fill)+horizontalMargin, readY(fill) + topMargin));
166 }
169
170 --updatingFill;
171 } else {
172 // ### Make this certain :)
173 qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on fill.");
174 }
175
176}
177
179{
180 Q_Q(QQuickAnchors);
181 if (!centerIn || fill || !isItemComplete())
182 return;
183
184 if (updatingCenterIn < 2) {
186
187 qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
188 if (centerIn == readParentItem(item)) {
189 QPointF p(hcenter(readParentItem(item)) - hcenter(item) + effectiveHCenterOffset,
191 setItemPos(p);
192
193 } else if (readParentItem(centerIn) == readParentItem(item)) {
194 QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
196 setItemPos(p);
197 }
198
200 } else {
201 // ### Make this certain :)
202 qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn.");
203 }
204}
205
207{
208 if (!item)
209 return;
210 if (fill == item)
211 fill = nullptr;
212 if (centerIn == item)
213 centerIn = nullptr;
214 if (leftAnchorItem == item) {
215 leftAnchorItem = nullptr;
216 usedAnchors &= ~QQuickAnchors::LeftAnchor;
217 }
218 if (rightAnchorItem == item) {
219 rightAnchorItem = nullptr;
220 usedAnchors &= ~QQuickAnchors::RightAnchor;
221 }
222 if (topAnchorItem == item) {
223 topAnchorItem = nullptr;
224 usedAnchors &= ~QQuickAnchors::TopAnchor;
225 }
226 if (bottomAnchorItem == item) {
227 bottomAnchorItem = nullptr;
228 usedAnchors &= ~QQuickAnchors::BottomAnchor;
229 }
230 if (vCenterAnchorItem == item) {
231 vCenterAnchorItem = nullptr;
232 usedAnchors &= ~QQuickAnchors::VCenterAnchor;
233 }
234 if (hCenterAnchorItem == item) {
235 hCenterAnchorItem = nullptr;
236 usedAnchors &= ~QQuickAnchors::HCenterAnchor;
237 }
238 if (baselineAnchorItem == item) {
239 baselineAnchorItem = nullptr;
240 usedAnchors &= ~QQuickAnchors::BaselineAnchor;
241 }
242}
243
245{
246 QQuickGeometryChange dependency;
247
248 if (!controlItem || inDestructor)
249 return dependency;
250
251 if (fill == controlItem) {
252 if (controlItem == readParentItem(item))
253 dependency.setSizeChange(true);
254 else //sibling
255 dependency.setAllChanged(true);
256 return dependency; //exit early
257 }
258
259 if (centerIn == controlItem) {
260 if (controlItem == readParentItem(item))
261 dependency.setSizeChange(true);
262 else //sibling
263 dependency.setAllChanged(true);
264 return dependency; //exit early
265 }
266
267 if ((usedAnchors & QQuickAnchors::LeftAnchor && leftAnchorItem == controlItem) ||
270 if (controlItem == readParentItem(item))
271 dependency.setWidthChange(true);
272 else //sibling
273 dependency.setHorizontalChange(true);
274 }
275
276 if ((usedAnchors & QQuickAnchors::TopAnchor && topAnchorItem == controlItem) ||
280 if (controlItem == readParentItem(item))
281 dependency.setHeightChange(true);
282 else //sibling
283 dependency.setVerticalChange(true);
284 }
285
286 return dependency;
287}
288
290{
291 if (!item || !componentComplete)
292 return;
293
295 p->updateOrAddGeometryChangeListener(this, calculateDependency(item));
296}
297
299{
300 if (!item || !componentComplete)
301 return;
302
304 p->updateOrRemoveGeometryChangeListener(this, calculateDependency(item));
305}
306
308{
309 Q_D(QQuickAnchors);
310 return QQuickItemPrivate::get(d->item)->effectiveLayoutMirror;
311}
312
314{
315 Q_D(const QQuickAnchors);
316 return d->centerAligned;
317}
318
320{
321 Q_D(QQuickAnchors);
322 if (aligned == d->centerAligned)
323 return;
324 d->centerAligned = aligned;
326 if (d->centerIn) {
327 d->centerInChanged();
328 } else {
329 if (d->usedAnchors & QQuickAnchors::VCenterAnchor)
330 d->updateVerticalAnchors();
331 else if (d->usedAnchors & QQuickAnchors::HCenterAnchor)
332 d->updateHorizontalAnchors();
333 }
334}
335
340
342{
343 Q_D(QQuickAnchors);
344 d->componentComplete = false;
345}
346
348{
349 Q_D(QQuickAnchors);
350 d->componentComplete = true;
351}
352
354{
355 updatingMe = true;
356 item->setHeight(v);
357 updatingMe = false;
358}
359
361{
362 updatingMe = true;
363 item->setWidth(v);
364 updatingMe = false;
365}
366
368{
369 updatingMe = true;
370 item->setX(v);
371 updatingMe = false;
372}
373
375{
376 updatingMe = true;
377 item->setY(v);
378 updatingMe = false;
379}
380
382{
383 updatingMe = true;
385 updatingMe = false;
386}
387
389{
390 updatingMe = true;
391 item->setSize(v);
392 updatingMe = false;
393}
394
396{
397 if (updatingMe) {
398 updatingMe = false;
399 return;
400 }
401
402 update();
403}
404
406{
407 //optimization to only set initial dependencies once, at completion time
408 QQuickItem *dependencies[9];
409 dependencies[0] = fill;
410 dependencies[1] = centerIn;
411 dependencies[2] = leftAnchorItem;
412 dependencies[3] = rightAnchorItem;
413 dependencies[4] = hCenterAnchorItem;
414 dependencies[5] = topAnchorItem;
415 dependencies[6] = bottomAnchorItem;
416 dependencies[7] = vCenterAnchorItem;
417 dependencies[8] = baselineAnchorItem;
418
419 std::sort(dependencies, dependencies + 9);
420
421 QQuickItem *lastDependency = nullptr;
422 for (int i = 0; i < 9; ++i) {
423 QQuickItem *dependency = dependencies[i];
424 if (lastDependency != dependency) {
425 addDepend(dependency);
426 lastDependency = dependency;
427 }
428 }
429
430 update();
431}
432
433
435{
436 if (!isItemComplete())
437 return;
438
439 if (fill) {
440 fillChanged();
441 } else if (centerIn) {
443 } else {
448 }
449}
450
452{
453 if (!isItemComplete())
454 return;
455
456 if (fill) {
457 fillChanged();
458 } else if (centerIn) {
460 } else {
465 }
466}
467
469{
470 Q_D(const QQuickAnchors);
471 return d->fill;
472}
473
475{
476 Q_D(QQuickAnchors);
477 if (d->fill == f)
478 return;
479
480 if (!f) {
481 QQuickItem *oldFill = d->fill;
482 d->fill = f;
483 d->remDepend(oldFill);
485 return;
486 }
487 if (f != readParentItem(d->item) && readParentItem(f) != readParentItem(d->item)){
488 qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
489 return;
490 }
491 QQuickItem *oldFill = d->fill;
492 d->fill = f;
493 d->remDepend(oldFill);
494 d->addDepend(d->fill);
496 d->fillChanged();
497}
498
500{
501 setFill(nullptr);
502}
503
505{
506 Q_D(const QQuickAnchors);
507 return d->centerIn;
508}
509
511{
512 Q_D(QQuickAnchors);
513 if (d->centerIn == c)
514 return;
515
516 if (!c) {
517 QQuickItem *oldCI = d->centerIn;
518 d->centerIn = c;
519 d->remDepend(oldCI);
521 return;
522 }
523 if (c != readParentItem(d->item) && readParentItem(c) != readParentItem(d->item)){
524 qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
525 return;
526 }
527 QQuickItem *oldCI = d->centerIn;
528 d->centerIn = c;
529 d->remDepend(oldCI);
530 d->addDepend(d->centerIn);
532 d->centerInChanged();
533}
534
536{
537 setCenterIn(nullptr);
538}
539
541 QQuickAnchors::Anchor edge1Line,
542 QQuickItem *edge2Item,
543 QQuickAnchors::Anchor edge2Line,
544 qreal offset1,
545 qreal offset2,
547 qreal &stretch) const
548{
549 bool edge1IsParent = (edge1Item == readParentItem(item));
550 bool edge2IsParent = (edge2Item == readParentItem(item));
551 bool edge1IsSibling = (readParentItem(edge1Item) == readParentItem(item));
552 bool edge2IsSibling = (readParentItem(edge2Item) == readParentItem(item));
553
554 bool invalid = false;
555 if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
556 stretch = (position(edge2Item, edge2Line) + offset2)
557 - (position(edge1Item, edge1Line) + offset1);
558 } else if (edge2IsParent && edge1IsSibling) {
559 stretch = (position(edge2Item, edge2Line) + offset2)
561 + position(edge1Item, edge1Line) + offset1);
562 } else if (edge2IsSibling && edge1IsParent) {
563 stretch = (position(readParentItem(item), line) + position(edge2Item, edge2Line) + offset2)
564 - (position(edge1Item, edge1Line) + offset1);
565 } else
566 invalid = true;
567
568 return invalid;
569}
570
572{
573 if (fill || centerIn || !isItemComplete())
574 return;
575
577 // ### Make this certain :)
578 qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
579 return;
580 }
581
584 //Handle stretching
585 bool invalid = true;
586 qreal height = 0.0;
595 height *= 2;
596 }
597 if (!invalid)
599
600 //Handle top
605 }
607 //Handle stretching (top + bottom case is handled above)
609 qreal height = 0.0;
613 height);
614 if (!invalid)
616 }
617
618 //Handle bottom
623 }
625 //(stetching handled above)
626
627 //Handle vCenter
633 }
635 //Handle baseline
642 }
643 }
645}
646
648{
649 if (anchorLine == QQuickAnchors::LeftAnchor) {
651 } else if (anchorLine == QQuickAnchors::RightAnchor) {
653 } else {
654 return anchorLine;
655 }
656}
657
659{
660 Q_Q(QQuickAnchors);
661 if (fill || centerIn || !isItemComplete())
662 return;
663
664 if (updatingHorizontalAnchor < 3) {
666 qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
667 QQuickItem *effectiveLeftItem, *effectiveRightItem, *effectiveHorizontalCenterItem;
668 QQuickAnchors::Anchor effectiveLeftLine, effectiveRightLine, effectiveHorizontalCenterLine;
669 QQuickAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
670 if (q->mirrored()) {
671 effectiveLeftAnchor = QQuickAnchors::RightAnchor;
672 effectiveRightAnchor = QQuickAnchors::LeftAnchor;
673 effectiveLeftItem = rightAnchorItem;
674 effectiveLeftLine = reverseAnchorLine(rightAnchorLine);
675 effectiveRightItem = leftAnchorItem;
676 effectiveRightLine = reverseAnchorLine(leftAnchorLine);
677 effectiveHorizontalCenterItem = hCenterAnchorItem;
678 effectiveHorizontalCenterLine = reverseAnchorLine(hCenterAnchorLine);
679 effectiveLeftMargin = rightMargin;
680 effectiveRightMargin = leftMargin;
681 effectiveHorizontalCenterOffset = -hCenterOffset;
682 } else {
683 effectiveLeftAnchor = QQuickAnchors::LeftAnchor;
684 effectiveRightAnchor = QQuickAnchors::RightAnchor;
685 effectiveLeftItem = leftAnchorItem;
686 effectiveLeftLine = leftAnchorLine;
687 effectiveRightItem = rightAnchorItem;
688 effectiveRightLine = rightAnchorLine;
689 effectiveHorizontalCenterItem = hCenterAnchorItem;
690 effectiveHorizontalCenterLine = hCenterAnchorLine;
691 effectiveLeftMargin = leftMargin;
692 effectiveRightMargin = rightMargin;
693 effectiveHorizontalCenterOffset = hCenterOffset;
694 }
695
696 if (usedAnchors & effectiveLeftAnchor) {
697 //Handle stretching
698 bool invalid = true;
699 qreal width = 0.0;
700 if (usedAnchors & effectiveRightAnchor) {
701 invalid = calcStretch(effectiveLeftItem, effectiveLeftLine,
702 effectiveRightItem, effectiveRightLine,
703 effectiveLeftMargin, -effectiveRightMargin,
706 invalid = calcStretch(effectiveLeftItem, effectiveLeftLine,
707 effectiveHorizontalCenterItem, effectiveHorizontalCenterLine,
708 effectiveLeftMargin, effectiveHorizontalCenterOffset,
710 width *= 2;
711 }
712 if (!invalid)
714
715 //Handle left
716 if (effectiveLeftItem == readParentItem(item)) {
717 setItemX(adjustedPosition(effectiveLeftItem, effectiveLeftLine) + effectiveLeftMargin);
718 } else if (readParentItem(effectiveLeftItem) == readParentItem(item)) {
719 setItemX(position(effectiveLeftItem, effectiveLeftLine) + effectiveLeftMargin);
720 }
721 } else if (usedAnchors & effectiveRightAnchor) {
722 //Handle stretching (left + right case is handled in updateLeftAnchor)
724 qreal width = 0.0;
725 bool invalid = calcStretch(effectiveHorizontalCenterItem,
726 effectiveHorizontalCenterLine,
727 effectiveRightItem, effectiveRightLine,
728 effectiveHorizontalCenterOffset, -effectiveRightMargin,
730 if (!invalid)
732 }
733
734 //Handle right
735 if (effectiveRightItem == readParentItem(item)) {
736 setItemX(adjustedPosition(effectiveRightItem, effectiveRightLine)
737 - readWidth(item) - effectiveRightMargin);
738 } else if (readParentItem(effectiveRightItem) == readParentItem(item)) {
739 setItemX(position(effectiveRightItem, effectiveRightLine)
740 - readWidth(item) - effectiveRightMargin);
741 }
743 //Handle hCenter
744 if (effectiveHorizontalCenterItem == readParentItem(item)) {
745 setItemX(adjustedPosition(effectiveHorizontalCenterItem, effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
746 } else if (readParentItem(effectiveHorizontalCenterItem) == readParentItem(item)) {
747 setItemX(position(effectiveHorizontalCenterItem, effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
748 }
749 }
751 } else {
752 // ### Make this certain :)
753 qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor.");
754 }
755}
756
758{
759 Q_D(const QQuickAnchors);
760 return QQuickAnchorLine(d->topAnchorItem, d->topAnchorLine);
761}
762
764{
765 Q_D(QQuickAnchors);
766 if (!d->checkVAnchorValid(edge) ||
767 (d->topAnchorItem == edge.item && d->topAnchorLine == edge.anchorLine))
768 return;
769
770 d->usedAnchors |= TopAnchor;
771
772 if (!d->checkVValid()) {
773 d->usedAnchors &= ~TopAnchor;
774 return;
775 }
776
777 QQuickItem *oldTop = d->topAnchorItem;
778 d->topAnchorItem = edge.item;
779 d->topAnchorLine = edge.anchorLine;
780 d->remDepend(oldTop);
781 d->addDepend(d->topAnchorItem);
783 d->updateVerticalAnchors();
784}
785
787{
788 Q_D(QQuickAnchors);
789 d->usedAnchors &= ~TopAnchor;
790 d->remDepend(d->topAnchorItem);
791 d->topAnchorItem = nullptr;
792 d->topAnchorLine = QQuickAnchors::InvalidAnchor;
794 d->updateVerticalAnchors();
795}
796
798{
799 Q_D(const QQuickAnchors);
800 return QQuickAnchorLine(d->bottomAnchorItem, d->bottomAnchorLine);
801}
802
804{
805 Q_D(QQuickAnchors);
806 if (!d->checkVAnchorValid(edge) ||
807 (d->bottomAnchorItem == edge.item && d->bottomAnchorLine == edge.anchorLine))
808 return;
809
810 d->usedAnchors |= BottomAnchor;
811
812 if (!d->checkVValid()) {
813 d->usedAnchors &= ~BottomAnchor;
814 return;
815 }
816
817 QQuickItem *oldBottom = d->bottomAnchorItem;
818 d->bottomAnchorItem = edge.item;
819 d->bottomAnchorLine = edge.anchorLine;
820 d->remDepend(oldBottom);
821 d->addDepend(d->bottomAnchorItem);
823 d->updateVerticalAnchors();
824}
825
827{
828 Q_D(QQuickAnchors);
829 d->usedAnchors &= ~BottomAnchor;
830 d->remDepend(d->bottomAnchorItem);
831 d->bottomAnchorItem = nullptr;
832 d->bottomAnchorLine = QQuickAnchors::InvalidAnchor;
834 d->updateVerticalAnchors();
835}
836
838{
839 Q_D(const QQuickAnchors);
840 return QQuickAnchorLine(d->vCenterAnchorItem, d->vCenterAnchorLine);
841}
842
844{
845 Q_D(QQuickAnchors);
846 if (!d->checkVAnchorValid(edge) ||
847 (d->vCenterAnchorItem == edge.item && d->vCenterAnchorLine == edge.anchorLine))
848 return;
849
850 d->usedAnchors |= VCenterAnchor;
851
852 if (!d->checkVValid()) {
853 d->usedAnchors &= ~VCenterAnchor;
854 return;
855 }
856
857 QQuickItem *oldVCenter = d->vCenterAnchorItem;
858 d->vCenterAnchorItem = edge.item;
859 d->vCenterAnchorLine = edge.anchorLine;
860 d->remDepend(oldVCenter);
861 d->addDepend(d->vCenterAnchorItem);
863 d->updateVerticalAnchors();
864}
865
867{
868 Q_D(QQuickAnchors);
869 d->usedAnchors &= ~VCenterAnchor;
870 d->remDepend(d->vCenterAnchorItem);
871 d->vCenterAnchorItem = nullptr;
872 d->vCenterAnchorLine = QQuickAnchors::InvalidAnchor;
874 d->updateVerticalAnchors();
875}
876
878{
879 Q_D(const QQuickAnchors);
880 return QQuickAnchorLine(d->baselineAnchorItem, d->baselineAnchorLine);
881}
882
884{
885 Q_D(QQuickAnchors);
886 if (!d->checkVAnchorValid(edge) ||
887 (d->baselineAnchorItem == edge.item && d->baselineAnchorLine == edge.anchorLine))
888 return;
889
890 d->usedAnchors |= BaselineAnchor;
891
892 if (!d->checkVValid()) {
893 d->usedAnchors &= ~BaselineAnchor;
894 return;
895 }
896
897 QQuickItem *oldBaseline = d->baselineAnchorItem;
898 d->baselineAnchorItem = edge.item;
899 d->baselineAnchorLine = edge.anchorLine;
900 d->remDepend(oldBaseline);
901 d->addDepend(d->baselineAnchorItem);
903 d->updateVerticalAnchors();
904}
905
907{
908 Q_D(QQuickAnchors);
909 d->usedAnchors &= ~BaselineAnchor;
910 d->remDepend(d->baselineAnchorItem);
911 d->baselineAnchorItem = nullptr;
912 d->baselineAnchorLine = QQuickAnchors::InvalidAnchor;
914 d->updateVerticalAnchors();
915}
916
918{
919 Q_D(const QQuickAnchors);
920 return QQuickAnchorLine(d->leftAnchorItem, d->leftAnchorLine);
921}
922
924{
925 Q_D(QQuickAnchors);
926 if (!d->checkHAnchorValid(edge) ||
927 (d->leftAnchorItem == edge.item && d->leftAnchorLine == edge.anchorLine))
928 return;
929
930 d->usedAnchors |= LeftAnchor;
931
932 if (!d->checkHValid()) {
933 d->usedAnchors &= ~LeftAnchor;
934 return;
935 }
936
937 QQuickItem *oldLeft = d->leftAnchorItem;
938 d->leftAnchorItem = edge.item;
939 d->leftAnchorLine = edge.anchorLine;
940 d->remDepend(oldLeft);
941 d->addDepend(d->leftAnchorItem);
943 d->updateHorizontalAnchors();
944}
945
947{
948 Q_D(QQuickAnchors);
949 d->usedAnchors &= ~LeftAnchor;
950 d->remDepend(d->leftAnchorItem);
951 d->leftAnchorItem = nullptr;
952 d->leftAnchorLine = QQuickAnchors::InvalidAnchor;
954 d->updateHorizontalAnchors();
955}
956
958{
959 Q_D(const QQuickAnchors);
960 return QQuickAnchorLine(d->rightAnchorItem, d->rightAnchorLine);
961}
962
964{
965 Q_D(QQuickAnchors);
966 if (!d->checkHAnchorValid(edge) ||
967 (d->rightAnchorItem == edge.item && d->rightAnchorLine == edge.anchorLine))
968 return;
969
970 d->usedAnchors |= RightAnchor;
971
972 if (!d->checkHValid()) {
973 d->usedAnchors &= ~RightAnchor;
974 return;
975 }
976
977 QQuickItem *oldRight = d->rightAnchorItem;
978 d->rightAnchorItem = edge.item;
979 d->rightAnchorLine = edge.anchorLine;
980 d->remDepend(oldRight);
981 d->addDepend(d->rightAnchorItem);
983 d->updateHorizontalAnchors();
984}
985
987{
988 Q_D(QQuickAnchors);
989 d->usedAnchors &= ~RightAnchor;
990 d->remDepend(d->rightAnchorItem);
991 d->rightAnchorItem = nullptr;
992 d->rightAnchorLine = QQuickAnchors::InvalidAnchor;
994 d->updateHorizontalAnchors();
995}
996
998{
999 Q_D(const QQuickAnchors);
1000 return QQuickAnchorLine(d->hCenterAnchorItem, d->hCenterAnchorLine);
1001}
1002
1004{
1005 Q_D(QQuickAnchors);
1006 if (!d->checkHAnchorValid(edge) ||
1007 (d->hCenterAnchorItem == edge.item && d->hCenterAnchorLine == edge.anchorLine))
1008 return;
1009
1010 d->usedAnchors |= HCenterAnchor;
1011
1012 if (!d->checkHValid()) {
1013 d->usedAnchors &= ~HCenterAnchor;
1014 return;
1015 }
1016
1017 QQuickItem *oldHCenter = d->hCenterAnchorItem;
1018 d->hCenterAnchorItem = edge.item;
1019 d->hCenterAnchorLine = edge.anchorLine;
1020 d->remDepend(oldHCenter);
1021 d->addDepend(d->hCenterAnchorItem);
1023 d->updateHorizontalAnchors();
1024}
1025
1027{
1028 Q_D(QQuickAnchors);
1029 d->usedAnchors &= ~HCenterAnchor;
1030 d->remDepend(d->hCenterAnchorItem);
1031 d->hCenterAnchorItem = nullptr;
1032 d->hCenterAnchorLine = QQuickAnchors::InvalidAnchor;
1034 d->updateHorizontalAnchors();
1035}
1036
1038{
1039 Q_D(const QQuickAnchors);
1040 return d->leftMargin;
1041}
1042
1044{
1045 Q_D(QQuickAnchors);
1046 d->leftMarginExplicit = true;
1047 if (d->leftMargin == offset)
1048 return;
1049 d->leftMargin = offset;
1050 if (d->fill)
1051 d->fillChanged();
1052 else
1053 d->updateHorizontalAnchors();
1055}
1056
1058{
1059 Q_D(QQuickAnchors);
1060 d->leftMarginExplicit = false;
1061 if (d->leftMargin == d->margins)
1062 return;
1063 d->leftMargin = d->margins;
1064 if (d->fill)
1065 d->fillChanged();
1066 else
1067 d->updateHorizontalAnchors();
1069}
1070
1072{
1073 Q_D(const QQuickAnchors);
1074 return d->rightMargin;
1075}
1076
1078{
1079 Q_D(QQuickAnchors);
1080 d->rightMarginExplicit = true;
1081 if (d->rightMargin == offset)
1082 return;
1083 d->rightMargin = offset;
1084 if (d->fill)
1085 d->fillChanged();
1086 else
1087 d->updateHorizontalAnchors();
1089}
1090
1092{
1093 Q_D(QQuickAnchors);
1094 d->rightMarginExplicit = false;
1095 if (d->rightMargin == d->margins)
1096 return;
1097 d->rightMargin = d->margins;
1098 if (d->fill)
1099 d->fillChanged();
1100 else
1101 d->updateHorizontalAnchors();
1103}
1104
1106{
1107 Q_D(const QQuickAnchors);
1108 return d->margins;
1109}
1110
1112{
1113 Q_D(QQuickAnchors);
1114 if (d->margins == offset)
1115 return;
1116 d->margins = offset;
1117
1118 bool updateHorizontal = false;
1119 bool updateVertical = false;
1120
1121 if (!d->rightMarginExplicit && d->rightMargin != offset) {
1122 d->rightMargin = offset;
1123 updateHorizontal = true;
1125 }
1126 if (!d->leftMarginExplicit && d->leftMargin != offset) {
1127 d->leftMargin = offset;
1128 updateHorizontal = true;
1130 }
1131 if (!d->topMarginExplicit && d->topMargin != offset) {
1132 d->topMargin = offset;
1133 updateVertical = true;
1135 }
1136 if (!d->bottomMarginExplicit && d->bottomMargin != offset) {
1137 d->bottomMargin = offset;
1138 updateVertical = true;
1140 }
1141
1142 if (d->fill) {
1143 if (updateHorizontal || updateVertical)
1144 d->fillChanged();
1145 } else {
1146 if (updateHorizontal)
1147 d->updateHorizontalAnchors();
1148 if (updateVertical)
1149 d->updateVerticalAnchors();
1150 }
1151
1153}
1154
1156{
1157 Q_D(const QQuickAnchors);
1158 return d->hCenterOffset;
1159}
1160
1162{
1163 Q_D(QQuickAnchors);
1164 if (d->hCenterOffset == offset)
1165 return;
1166 d->hCenterOffset = offset;
1167 if (d->centerIn)
1168 d->centerInChanged();
1169 else
1170 d->updateHorizontalAnchors();
1172}
1173
1175{
1176 Q_D(const QQuickAnchors);
1177 return d->topMargin;
1178}
1179
1181{
1182 Q_D(QQuickAnchors);
1183 d->topMarginExplicit = true;
1184 if (d->topMargin == offset)
1185 return;
1186 d->topMargin = offset;
1187 if (d->fill)
1188 d->fillChanged();
1189 else
1190 d->updateVerticalAnchors();
1192}
1193
1195{
1196 Q_D(QQuickAnchors);
1197 d->topMarginExplicit = false;
1198 if (d->topMargin == d->margins)
1199 return;
1200 d->topMargin = d->margins;
1201 if (d->fill)
1202 d->fillChanged();
1203 else
1204 d->updateVerticalAnchors();
1206}
1207
1209{
1210 Q_D(const QQuickAnchors);
1211 return d->bottomMargin;
1212}
1213
1215{
1216 Q_D(QQuickAnchors);
1217 d->bottomMarginExplicit = true;
1218 if (d->bottomMargin == offset)
1219 return;
1220 d->bottomMargin = offset;
1221 if (d->fill)
1222 d->fillChanged();
1223 else
1224 d->updateVerticalAnchors();
1226}
1227
1229{
1230 Q_D(QQuickAnchors);
1231 d->bottomMarginExplicit = false;
1232 if (d->bottomMargin == d->margins)
1233 return;
1234 d->bottomMargin = d->margins;
1235 if (d->fill)
1236 d->fillChanged();
1237 else
1238 d->updateVerticalAnchors();
1240}
1241
1243{
1244 Q_D(const QQuickAnchors);
1245 return d->vCenterOffset;
1246}
1247
1249{
1250 Q_D(QQuickAnchors);
1251 if (d->vCenterOffset == offset)
1252 return;
1253 d->vCenterOffset = offset;
1254 if (d->centerIn)
1255 d->centerInChanged();
1256 else
1257 d->updateVerticalAnchors();
1259}
1260
1262{
1263 Q_D(const QQuickAnchors);
1264 return d->baselineOffset;
1265}
1266
1268{
1269 Q_D(QQuickAnchors);
1270 if (d->baselineOffset == offset)
1271 return;
1272 d->baselineOffset = offset;
1273 d->updateVerticalAnchors();
1275}
1276
1277QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const
1278{
1279 Q_D(const QQuickAnchors);
1280 return static_cast<QQuickAnchors::Anchors>(d->usedAnchors);
1281}
1282
1283Qt::Orientations QQuickAnchors::activeDirections() const
1284{
1285 Q_D(const QQuickAnchors);
1286 if (d->fill || d->centerIn)
1288 Qt::Orientations o;
1289 if (d->usedAnchors & QQuickAnchors::Horizontal_Mask)
1290 o |= Qt::Horizontal;
1291 if (d->usedAnchors & QQuickAnchors::Vertical_Mask)
1292 o |= Qt::Vertical;
1293 return o;
1294}
1295
1297{
1301 qmlWarning(item) << QQuickAnchors::tr("Cannot specify left, right, and horizontalCenter anchors at the same time.");
1302 return false;
1303 }
1304
1305 return true;
1306}
1307
1309{
1310 if (!anchor.item) {
1311 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
1312 return false;
1313 } else if (anchor.anchorLine & QQuickAnchors::Vertical_Mask) {
1314 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
1315 return false;
1316 } else if (anchor.item != readParentItem(item)
1317 && readParentItem(anchor.item) != readParentItem(item)) {
1318 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1319 return false;
1320 } else if (anchor.item == item) {
1321 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
1322 return false;
1323 }
1324
1325 return true;
1326}
1327
1329{
1333 qmlWarning(item) << QQuickAnchors::tr("Cannot specify top, bottom, and verticalCenter anchors at the same time.");
1334 return false;
1339 qmlWarning(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
1340 return false;
1341 }
1342
1343 return true;
1344}
1345
1347{
1348 if (!anchor.item) {
1349 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
1350 return false;
1351 } else if (anchor.anchorLine & QQuickAnchors::Horizontal_Mask) {
1352 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
1353 return false;
1354 } else if (anchor.item != readParentItem(item)
1355 && readParentItem(anchor.item) != readParentItem(item)) {
1356 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1357 return false;
1358 } else if (anchor.item == item){
1359 qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
1360 return false;
1361 }
1362
1363 return true;
1364}
1365
1367
1368#include "moc_qquickanchors_p_p.cpp"
1369
1370#include <moc_qquickanchors_p.cpp>
1371
\inmodule QtCore
Definition qobject.h:103
\inmodule QtCore\reentrant
Definition qpoint.h:217
QQuickAnchors::Anchor anchorLine
bool checkHAnchorValid(QQuickAnchorLine anchor) const
QQuickAnchors::Anchor baselineAnchorLine
QQuickAnchors::Anchor vCenterAnchorLine
QQuickAnchors::Anchor rightAnchorLine
QQuickAnchors::Anchor hCenterAnchorLine
bool isItemComplete() const
QQuickAnchors::Anchor bottomAnchorLine
void remDepend(QQuickItem *)
QQuickAnchors::Anchor leftAnchorLine
QQuickGeometryChange calculateDependency(QQuickItem *) const
bool checkVAnchorValid(QQuickAnchorLine anchor) const
void addDepend(QQuickItem *)
void setItemSize(const QSizeF &)
void clearItem(QQuickItem *)
static QQuickAnchorsPrivate * get(QQuickAnchors *o)
void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override
QQuickItem * baselineAnchorItem
bool calcStretch(QQuickItem *edge1Item, QQuickAnchors::Anchor edge1Line, QQuickItem *edge2Item, QQuickAnchors::Anchor edge2Line, qreal offset1, qreal offset2, QQuickAnchors::Anchor line, qreal &stretch) const
QQuickAnchors::Anchor topAnchorLine
void setItemPos(const QPointF &)
~QQuickAnchors() override
qreal verticalCenterOffset
void setLeftMargin(qreal)
void rightChanged()
void resetVerticalCenter()
void marginsChanged()
void horizontalCenterChanged()
void setHorizontalCenterOffset(qreal)
void bottomMarginChanged()
void centerAlignedChanged()
QQuickAnchorLine top
QQuickAnchorLine left
void setVerticalCenterOffset(qreal)
void topChanged()
void rightMarginChanged()
void verticalCenterOffsetChanged()
void setBottom(const QQuickAnchorLine &edge)
QQuickItem * fill
void setCenterIn(QQuickItem *)
void setTop(const QQuickAnchorLine &edge)
void setVerticalCenter(const QQuickAnchorLine &edge)
QQuickAnchorLine right
QQuickItem * centerIn
void bottomChanged()
void setHorizontalCenter(const QQuickAnchorLine &edge)
void setBaselineOffset(qreal)
void topMarginChanged()
void fillChanged()
void setRightMargin(qreal)
void horizontalCenterOffsetChanged()
void baselineOffsetChanged()
void baselineChanged()
void setTopMargin(qreal)
void setBaseline(const QQuickAnchorLine &edge)
void setAlignWhenCentered(bool)
void setFill(QQuickItem *)
QQuickAnchors(QQuickItem *item, QObject *parent=nullptr)
qreal horizontalCenterOffset
void verticalCenterChanged()
QQuickAnchorLine horizontalCenter
void leftChanged()
Anchors usedAnchors() const
void setBottomMargin(qreal)
void setRight(const QQuickAnchorLine &edge)
void leftMarginChanged()
QQuickAnchorLine baseline
Qt::Orientations activeDirections() const
QQuickAnchorLine verticalCenter
void resetHorizontalCenter()
QQuickAnchorLine bottom
void centerInChanged()
void setLeft(const QQuickAnchorLine &edge)
void setMargins(qreal)
void setVerticalChange(bool enabled)
void setHorizontalChange(bool enabled)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setSize(const QSizeF &size)
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
Definition qquickitem.h:72
qreal y
Defines the item's y position relative to its parent.
Definition qquickitem.h:73
void setHeight(qreal)
void setPosition(const QPointF &)
void setWidth(qreal)
void setX(qreal)
void setY(qreal)
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore
Definition qsize.h:208
Combined button and popup list for selecting options.
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
#define Q_UNLIKELY(x)
#define Q_ALWAYS_INLINE
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
return ret
GLsizei const GLfloat * v
[13]
GLint GLsizei GLsizei height
GLfloat GLfloat f
GLint GLsizei width
GLenum GLuint GLintptr offset
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static Q_ALWAYS_INLINE qreal readWidth(const QQuickItem *item)
static qreal hcenter(const QQuickItem *item)
static qreal vcenter(const QQuickItem *item)
static QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)
static qreal adjustedPosition(QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static QT_BEGIN_NAMESPACE Q_ALWAYS_INLINE QQuickItem * readParentItem(const QQuickItem *item)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static Q_ALWAYS_INLINE qreal readHeight(const QQuickItem *item)
static Q_ALWAYS_INLINE qreal readX(const QQuickItem *item)
static Q_ALWAYS_INLINE qreal readBaselineOffset(const QQuickItem *item)
static Q_ALWAYS_INLINE qreal readY(const QQuickItem *item)
QQuickAnchors * anchors(QQuickItem *item)
Int aligned(Int v, Int byteAlign)
#define tr(X)
#define emit
double qreal
Definition qtypes.h:187
QGraphicsItem * item