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
10QT_BEGIN_NAMESPACE
11
12static Q_ALWAYS_INLINE QQuickItem *readParentItem(const QQuickItem *item)
13{
14 return QQuickItemPrivate::get(item)->parentItem;
15}
16
17static Q_ALWAYS_INLINE qreal readX(const QQuickItem *item)
18{
19 return QQuickItemPrivate::get(item)->x;
20}
21
22static Q_ALWAYS_INLINE qreal readY(const QQuickItem *item)
23{
24 return QQuickItemPrivate::get(item)->y;
25}
26
27static Q_ALWAYS_INLINE qreal readWidth(const QQuickItem *item)
28{
29 return QQuickItemPrivate::get(item)->width;
30}
31
32static Q_ALWAYS_INLINE qreal readHeight(const QQuickItem *item)
33{
34 return QQuickItemPrivate::get(item)->height;
35}
36
37static Q_ALWAYS_INLINE qreal readBaselineOffset(const QQuickItem *item)
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{
47 qreal width = readWidth(item);
48 if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
49 if (!QQuickAnchorsPrivate::get(o: anchors)->centerAligned)
50 return width / 2;
51 }
52 return qRound(d: width / 2);
53}
54
55static inline qreal vcenter(const QQuickItem *item)
56{
57 qreal height = readHeight(item);
58 if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
59 if (!QQuickAnchorsPrivate::get(o: anchors)->centerAligned)
60 return height / 2;
61 }
62 return qRound(d: 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) {
70 case QQuickAnchors::LeftAnchor:
71 ret = readX(item);
72 break;
73 case QQuickAnchors::RightAnchor:
74 ret = readX(item) + readWidth(item);
75 break;
76 case QQuickAnchors::TopAnchor:
77 ret = readY(item);
78 break;
79 case QQuickAnchors::BottomAnchor:
80 ret = readY(item) + readHeight(item);
81 break;
82 case QQuickAnchors::HCenterAnchor:
83 ret = readX(item) + hcenter(item);
84 break;
85 case QQuickAnchors::VCenterAnchor:
86 ret = readY(item) + vcenter(item);
87 break;
88 case QQuickAnchors::BaselineAnchor:
89 ret = readY(item) + readBaselineOffset(item);
90 break;
91 default:
92 break;
93 }
94
95 return ret;
96}
97
98//position when origin is 0,0
99static inline qreal adjustedPosition(QQuickItem *item, QQuickAnchors::Anchor anchorLine)
100{
101 qreal ret = 0.0;
102 switch (anchorLine) {
103 case QQuickAnchors::LeftAnchor:
104 ret = 0.0;
105 break;
106 case QQuickAnchors::RightAnchor:
107 ret = readWidth(item);
108 break;
109 case QQuickAnchors::TopAnchor:
110 ret = 0.0;
111 break;
112 case QQuickAnchors::BottomAnchor:
113 ret = readHeight(item);
114 break;
115 case QQuickAnchors::HCenterAnchor:
116 ret = hcenter(item);
117 break;
118 case QQuickAnchors::VCenterAnchor:
119 ret = vcenter(item);
120 break;
121 case QQuickAnchors::BaselineAnchor:
122 ret = readBaselineOffset(item);
123 break;
124 default:
125 break;
126 }
127
128 return ret;
129}
130
131QQuickAnchors::QQuickAnchors(QQuickItem *item, QObject *parent)
132: QObject(*new QQuickAnchorsPrivate(item), parent)
133{
134}
135
136QQuickAnchors::~QQuickAnchors()
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
151void QQuickAnchorsPrivate::fillChanged()
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(item: fill) == readParentItem(item)) { //siblings
165 setItemPos(QPointF(readX(item: fill)+horizontalMargin, readY(item: fill) + topMargin));
166 }
167 setItemSize(QSizeF(readWidth(item: fill) - leftMargin - rightMargin,
168 readHeight(item: fill) - topMargin - bottomMargin));
169
170 --updatingFill;
171 } else {
172 // ### Make this certain :)
173 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on fill.");
174 }
175
176}
177
178void QQuickAnchorsPrivate::centerInChanged()
179{
180 Q_Q(QQuickAnchors);
181 if (!centerIn || fill || !isItemComplete())
182 return;
183
184 if (updatingCenterIn < 2) {
185 ++updatingCenterIn;
186
187 qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
188 if (centerIn == readParentItem(item)) {
189 QPointF p(hcenter(item: readParentItem(item)) - hcenter(item) + effectiveHCenterOffset,
190 vcenter(item: readParentItem(item)) - vcenter(item) + vCenterOffset);
191 setItemPos(p);
192
193 } else if (readParentItem(item: centerIn) == readParentItem(item)) {
194 QPointF p(centerIn->x() + hcenter(item: centerIn) - hcenter(item) + effectiveHCenterOffset,
195 centerIn->y() + vcenter(item: centerIn) - vcenter(item) + vCenterOffset);
196 setItemPos(p);
197 }
198
199 --updatingCenterIn;
200 } else {
201 // ### Make this certain :)
202 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on centerIn.");
203 }
204}
205
206void QQuickAnchorsPrivate::clearItem(QQuickItem *item)
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
244QQuickGeometryChange QQuickAnchorsPrivate::calculateDependency(QQuickItem *controlItem) const
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) ||
268 (usedAnchors & QQuickAnchors::RightAnchor && rightAnchorItem == controlItem) ||
269 (usedAnchors & QQuickAnchors::HCenterAnchor && hCenterAnchorItem == 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) ||
277 (usedAnchors & QQuickAnchors::BottomAnchor && bottomAnchorItem == controlItem) ||
278 (usedAnchors & QQuickAnchors::VCenterAnchor && vCenterAnchorItem == controlItem) ||
279 (usedAnchors & QQuickAnchors::BaselineAnchor && baselineAnchorItem == controlItem)) {
280 if (controlItem == readParentItem(item))
281 dependency.setHeightChange(true);
282 else //sibling
283 dependency.setVerticalChange(true);
284 }
285
286 return dependency;
287}
288
289void QQuickAnchorsPrivate::addDepend(QQuickItem *item)
290{
291 if (!item || !componentComplete)
292 return;
293
294 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
295 p->updateOrAddGeometryChangeListener(listener: this, types: calculateDependency(controlItem: item));
296}
297
298void QQuickAnchorsPrivate::remDepend(QQuickItem *item)
299{
300 if (!item || !componentComplete)
301 return;
302
303 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
304 p->updateOrRemoveGeometryChangeListener(listener: this, types: calculateDependency(controlItem: item));
305}
306
307bool QQuickAnchors::mirrored()
308{
309 Q_D(QQuickAnchors);
310 return QQuickItemPrivate::get(item: d->item)->effectiveLayoutMirror;
311}
312
313bool QQuickAnchors::alignWhenCentered() const
314{
315 Q_D(const QQuickAnchors);
316 return d->centerAligned;
317}
318
319void QQuickAnchors::setAlignWhenCentered(bool aligned)
320{
321 Q_D(QQuickAnchors);
322 if (aligned == d->centerAligned)
323 return;
324 d->centerAligned = aligned;
325 emit centerAlignedChanged();
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
336bool QQuickAnchorsPrivate::isItemComplete() const
337{
338 return componentComplete;
339}
340
341void QQuickAnchors::classBegin()
342{
343 Q_D(QQuickAnchors);
344 d->componentComplete = false;
345}
346
347void QQuickAnchors::componentComplete()
348{
349 Q_D(QQuickAnchors);
350 d->componentComplete = true;
351}
352
353void QQuickAnchorsPrivate::setItemHeight(qreal v)
354{
355 updatingMe = true;
356 item->setHeight(v);
357 updatingMe = false;
358}
359
360void QQuickAnchorsPrivate::setItemWidth(qreal v)
361{
362 updatingMe = true;
363 item->setWidth(v);
364 updatingMe = false;
365}
366
367void QQuickAnchorsPrivate::setItemX(qreal v)
368{
369 updatingMe = true;
370 item->setX(v);
371 updatingMe = false;
372}
373
374void QQuickAnchorsPrivate::setItemY(qreal v)
375{
376 updatingMe = true;
377 item->setY(v);
378 updatingMe = false;
379}
380
381void QQuickAnchorsPrivate::setItemPos(const QPointF &v)
382{
383 updatingMe = true;
384 item->setPosition(v);
385 updatingMe = false;
386}
387
388void QQuickAnchorsPrivate::setItemSize(const QSizeF &v)
389{
390 updatingMe = true;
391 item->setSize(v);
392 updatingMe = false;
393}
394
395void QQuickAnchorsPrivate::updateMe()
396{
397 if (updatingMe) {
398 updatingMe = false;
399 return;
400 }
401
402 update();
403}
404
405void QQuickAnchorsPrivate::updateOnComplete()
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(first: dependencies, last: 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(item: dependency);
426 lastDependency = dependency;
427 }
428 }
429
430 update();
431}
432
433
434void QQuickAnchorsPrivate::update()
435{
436 if (!isItemComplete())
437 return;
438
439 if (fill) {
440 fillChanged();
441 } else if (centerIn) {
442 centerInChanged();
443 } else {
444 if (usedAnchors & QQuickAnchors::Horizontal_Mask)
445 updateHorizontalAnchors();
446 if (usedAnchors & QQuickAnchors::Vertical_Mask)
447 updateVerticalAnchors();
448 }
449}
450
451void QQuickAnchorsPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &)
452{
453 if (!isItemComplete())
454 return;
455
456 if (fill) {
457 fillChanged();
458 } else if (centerIn) {
459 centerInChanged();
460 } else {
461 if ((usedAnchors & QQuickAnchors::Horizontal_Mask) && change.horizontalChange())
462 updateHorizontalAnchors();
463 if ((usedAnchors & QQuickAnchors::Vertical_Mask) && change.verticalChange())
464 updateVerticalAnchors();
465 }
466}
467
468QQuickItem *QQuickAnchors::fill() const
469{
470 Q_D(const QQuickAnchors);
471 return d->fill;
472}
473
474void QQuickAnchors::setFill(QQuickItem *f)
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(item: oldFill);
484 emit fillChanged();
485 return;
486 }
487 if (f != readParentItem(item: d->item) && readParentItem(item: f) != readParentItem(item: d->item)){
488 qmlWarning(me: d->item) << tr(s: "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(item: oldFill);
494 d->addDepend(item: d->fill);
495 emit fillChanged();
496 d->fillChanged();
497}
498
499void QQuickAnchors::resetFill()
500{
501 setFill(nullptr);
502}
503
504QQuickItem *QQuickAnchors::centerIn() const
505{
506 Q_D(const QQuickAnchors);
507 return d->centerIn;
508}
509
510void QQuickAnchors::setCenterIn(QQuickItem* c)
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(item: oldCI);
520 emit centerInChanged();
521 return;
522 }
523 if (c != readParentItem(item: d->item) && readParentItem(item: c) != readParentItem(item: d->item)){
524 qmlWarning(me: d->item) << tr(s: "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(item: oldCI);
530 d->addDepend(item: d->centerIn);
531 emit centerInChanged();
532 d->centerInChanged();
533}
534
535void QQuickAnchors::resetCenterIn()
536{
537 setCenterIn(nullptr);
538}
539
540bool QQuickAnchorsPrivate::calcStretch(QQuickItem *edge1Item,
541 QQuickAnchors::Anchor edge1Line,
542 QQuickItem *edge2Item,
543 QQuickAnchors::Anchor edge2Line,
544 qreal offset1,
545 qreal offset2,
546 QQuickAnchors::Anchor line,
547 qreal &stretch) const
548{
549 bool edge1IsParent = (edge1Item == readParentItem(item));
550 bool edge2IsParent = (edge2Item == readParentItem(item));
551 bool edge1IsSibling = (readParentItem(item: edge1Item) == readParentItem(item));
552 bool edge2IsSibling = (readParentItem(item: edge2Item) == readParentItem(item));
553
554 bool invalid = false;
555 if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
556 stretch = (position(item: edge2Item, anchorLine: edge2Line) + offset2)
557 - (position(item: edge1Item, anchorLine: edge1Line) + offset1);
558 } else if (edge2IsParent && edge1IsSibling) {
559 stretch = (position(item: edge2Item, anchorLine: edge2Line) + offset2)
560 - (position(item: readParentItem(item), anchorLine: line)
561 + position(item: edge1Item, anchorLine: edge1Line) + offset1);
562 } else if (edge2IsSibling && edge1IsParent) {
563 stretch = (position(item: readParentItem(item), anchorLine: line) + position(item: edge2Item, anchorLine: edge2Line) + offset2)
564 - (position(item: edge1Item, anchorLine: edge1Line) + offset1);
565 } else
566 invalid = true;
567
568 return invalid;
569}
570
571void QQuickAnchorsPrivate::updateVerticalAnchors()
572{
573 if (fill || centerIn || !isItemComplete())
574 return;
575
576 if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
577 // ### Make this certain :)
578 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on vertical anchor.");
579 return;
580 }
581
582 ++updatingVerticalAnchor;
583 if (usedAnchors & QQuickAnchors::TopAnchor) {
584 //Handle stretching
585 bool invalid = true;
586 qreal height = 0.0;
587 if (usedAnchors & QQuickAnchors::BottomAnchor) {
588 invalid = calcStretch(edge1Item: topAnchorItem, edge1Line: topAnchorLine,
589 edge2Item: bottomAnchorItem, edge2Line: bottomAnchorLine,
590 offset1: topMargin, offset2: -bottomMargin, line: QQuickAnchors::TopAnchor, stretch&: height);
591 } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
592 invalid = calcStretch(edge1Item: topAnchorItem, edge1Line: topAnchorLine,
593 edge2Item: vCenterAnchorItem, edge2Line: vCenterAnchorLine,
594 offset1: topMargin, offset2: vCenterOffset, line: QQuickAnchors::TopAnchor, stretch&: height);
595 height *= 2;
596 }
597 if (!invalid)
598 setItemHeight(height);
599
600 //Handle top
601 if (topAnchorItem == readParentItem(item)) {
602 setItemY(adjustedPosition(item: topAnchorItem, anchorLine: topAnchorLine) + topMargin);
603 } else if (readParentItem(item: topAnchorItem) == readParentItem(item)) {
604 setItemY(position(item: topAnchorItem, anchorLine: topAnchorLine) + topMargin);
605 }
606 } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
607 //Handle stretching (top + bottom case is handled above)
608 if (usedAnchors & QQuickAnchors::VCenterAnchor) {
609 qreal height = 0.0;
610 bool invalid = calcStretch(edge1Item: vCenterAnchorItem, edge1Line: vCenterAnchorLine,
611 edge2Item: bottomAnchorItem, edge2Line: bottomAnchorLine,
612 offset1: vCenterOffset, offset2: -bottomMargin, line: QQuickAnchors::TopAnchor,
613 stretch&: height);
614 if (!invalid)
615 setItemHeight(height*2);
616 }
617
618 //Handle bottom
619 if (bottomAnchorItem == readParentItem(item)) {
620 setItemY(adjustedPosition(item: bottomAnchorItem, anchorLine: bottomAnchorLine) - readHeight(item) - bottomMargin);
621 } else if (readParentItem(item: bottomAnchorItem) == readParentItem(item)) {
622 setItemY(position(item: bottomAnchorItem, anchorLine: bottomAnchorLine) - readHeight(item) - bottomMargin);
623 }
624 } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
625 //(stetching handled above)
626
627 //Handle vCenter
628 if (vCenterAnchorItem == readParentItem(item)) {
629 setItemY(adjustedPosition(item: vCenterAnchorItem, anchorLine: vCenterAnchorLine)
630 - vcenter(item) + vCenterOffset);
631 } else if (readParentItem(item: vCenterAnchorItem) == readParentItem(item)) {
632 setItemY(position(item: vCenterAnchorItem, anchorLine: vCenterAnchorLine) - vcenter(item) + vCenterOffset);
633 }
634 } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
635 //Handle baseline
636 if (baselineAnchorItem == readParentItem(item)) {
637 setItemY(adjustedPosition(item: baselineAnchorItem, anchorLine: baselineAnchorLine)
638 - readBaselineOffset(item) + baselineOffset);
639 } else if (readParentItem(item: baselineAnchorItem) == readParentItem(item)) {
640 setItemY(position(item: baselineAnchorItem, anchorLine: baselineAnchorLine)
641 - readBaselineOffset(item) + baselineOffset);
642 }
643 }
644 --updatingVerticalAnchor;
645}
646
647static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)
648{
649 if (anchorLine == QQuickAnchors::LeftAnchor) {
650 return QQuickAnchors::RightAnchor;
651 } else if (anchorLine == QQuickAnchors::RightAnchor) {
652 return QQuickAnchors::LeftAnchor;
653 } else {
654 return anchorLine;
655 }
656}
657
658void QQuickAnchorsPrivate::updateHorizontalAnchors()
659{
660 Q_Q(QQuickAnchors);
661 if (fill || centerIn || !isItemComplete())
662 return;
663
664 if (updatingHorizontalAnchor < 3) {
665 ++updatingHorizontalAnchor;
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(anchorLine: rightAnchorLine);
675 effectiveRightItem = leftAnchorItem;
676 effectiveRightLine = reverseAnchorLine(anchorLine: leftAnchorLine);
677 effectiveHorizontalCenterItem = hCenterAnchorItem;
678 effectiveHorizontalCenterLine = reverseAnchorLine(anchorLine: 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(edge1Item: effectiveLeftItem, edge1Line: effectiveLeftLine,
702 edge2Item: effectiveRightItem, edge2Line: effectiveRightLine,
703 offset1: effectiveLeftMargin, offset2: -effectiveRightMargin,
704 line: QQuickAnchors::LeftAnchor, stretch&: width);
705 } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
706 invalid = calcStretch(edge1Item: effectiveLeftItem, edge1Line: effectiveLeftLine,
707 edge2Item: effectiveHorizontalCenterItem, edge2Line: effectiveHorizontalCenterLine,
708 offset1: effectiveLeftMargin, offset2: effectiveHorizontalCenterOffset,
709 line: QQuickAnchors::LeftAnchor, stretch&: width);
710 width *= 2;
711 }
712 if (!invalid)
713 setItemWidth(width);
714
715 //Handle left
716 if (effectiveLeftItem == readParentItem(item)) {
717 setItemX(adjustedPosition(item: effectiveLeftItem, anchorLine: effectiveLeftLine) + effectiveLeftMargin);
718 } else if (readParentItem(item: effectiveLeftItem) == readParentItem(item)) {
719 setItemX(position(item: effectiveLeftItem, anchorLine: effectiveLeftLine) + effectiveLeftMargin);
720 }
721 } else if (usedAnchors & effectiveRightAnchor) {
722 //Handle stretching (left + right case is handled in updateLeftAnchor)
723 if (usedAnchors & QQuickAnchors::HCenterAnchor) {
724 qreal width = 0.0;
725 bool invalid = calcStretch(edge1Item: effectiveHorizontalCenterItem,
726 edge1Line: effectiveHorizontalCenterLine,
727 edge2Item: effectiveRightItem, edge2Line: effectiveRightLine,
728 offset1: effectiveHorizontalCenterOffset, offset2: -effectiveRightMargin,
729 line: QQuickAnchors::LeftAnchor, stretch&: width);
730 if (!invalid)
731 setItemWidth(width*2);
732 }
733
734 //Handle right
735 if (effectiveRightItem == readParentItem(item)) {
736 setItemX(adjustedPosition(item: effectiveRightItem, anchorLine: effectiveRightLine)
737 - readWidth(item) - effectiveRightMargin);
738 } else if (readParentItem(item: effectiveRightItem) == readParentItem(item)) {
739 setItemX(position(item: effectiveRightItem, anchorLine: effectiveRightLine)
740 - readWidth(item) - effectiveRightMargin);
741 }
742 } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
743 //Handle hCenter
744 if (effectiveHorizontalCenterItem == readParentItem(item)) {
745 setItemX(adjustedPosition(item: effectiveHorizontalCenterItem, anchorLine: effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
746 } else if (readParentItem(item: effectiveHorizontalCenterItem) == readParentItem(item)) {
747 setItemX(position(item: effectiveHorizontalCenterItem, anchorLine: effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
748 }
749 }
750 --updatingHorizontalAnchor;
751 } else {
752 // ### Make this certain :)
753 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on horizontal anchor.");
754 }
755}
756
757QQuickAnchorLine QQuickAnchors::top() const
758{
759 Q_D(const QQuickAnchors);
760 return QQuickAnchorLine(d->topAnchorItem, d->topAnchorLine);
761}
762
763void QQuickAnchors::setTop(const QQuickAnchorLine &edge)
764{
765 Q_D(QQuickAnchors);
766 if (!d->checkVAnchorValid(anchor: 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(item: oldTop);
781 d->addDepend(item: d->topAnchorItem);
782 emit topChanged();
783 d->updateVerticalAnchors();
784}
785
786void QQuickAnchors::resetTop()
787{
788 Q_D(QQuickAnchors);
789 d->usedAnchors &= ~TopAnchor;
790 d->remDepend(item: d->topAnchorItem);
791 d->topAnchorItem = nullptr;
792 d->topAnchorLine = QQuickAnchors::InvalidAnchor;
793 emit topChanged();
794 d->updateVerticalAnchors();
795}
796
797QQuickAnchorLine QQuickAnchors::bottom() const
798{
799 Q_D(const QQuickAnchors);
800 return QQuickAnchorLine(d->bottomAnchorItem, d->bottomAnchorLine);
801}
802
803void QQuickAnchors::setBottom(const QQuickAnchorLine &edge)
804{
805 Q_D(QQuickAnchors);
806 if (!d->checkVAnchorValid(anchor: 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(item: oldBottom);
821 d->addDepend(item: d->bottomAnchorItem);
822 emit bottomChanged();
823 d->updateVerticalAnchors();
824}
825
826void QQuickAnchors::resetBottom()
827{
828 Q_D(QQuickAnchors);
829 d->usedAnchors &= ~BottomAnchor;
830 d->remDepend(item: d->bottomAnchorItem);
831 d->bottomAnchorItem = nullptr;
832 d->bottomAnchorLine = QQuickAnchors::InvalidAnchor;
833 emit bottomChanged();
834 d->updateVerticalAnchors();
835}
836
837QQuickAnchorLine QQuickAnchors::verticalCenter() const
838{
839 Q_D(const QQuickAnchors);
840 return QQuickAnchorLine(d->vCenterAnchorItem, d->vCenterAnchorLine);
841}
842
843void QQuickAnchors::setVerticalCenter(const QQuickAnchorLine &edge)
844{
845 Q_D(QQuickAnchors);
846 if (!d->checkVAnchorValid(anchor: 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(item: oldVCenter);
861 d->addDepend(item: d->vCenterAnchorItem);
862 emit verticalCenterChanged();
863 d->updateVerticalAnchors();
864}
865
866void QQuickAnchors::resetVerticalCenter()
867{
868 Q_D(QQuickAnchors);
869 d->usedAnchors &= ~VCenterAnchor;
870 d->remDepend(item: d->vCenterAnchorItem);
871 d->vCenterAnchorItem = nullptr;
872 d->vCenterAnchorLine = QQuickAnchors::InvalidAnchor;
873 emit verticalCenterChanged();
874 d->updateVerticalAnchors();
875}
876
877QQuickAnchorLine QQuickAnchors::baseline() const
878{
879 Q_D(const QQuickAnchors);
880 return QQuickAnchorLine(d->baselineAnchorItem, d->baselineAnchorLine);
881}
882
883void QQuickAnchors::setBaseline(const QQuickAnchorLine &edge)
884{
885 Q_D(QQuickAnchors);
886 if (!d->checkVAnchorValid(anchor: 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(item: oldBaseline);
901 d->addDepend(item: d->baselineAnchorItem);
902 emit baselineChanged();
903 d->updateVerticalAnchors();
904}
905
906void QQuickAnchors::resetBaseline()
907{
908 Q_D(QQuickAnchors);
909 d->usedAnchors &= ~BaselineAnchor;
910 d->remDepend(item: d->baselineAnchorItem);
911 d->baselineAnchorItem = nullptr;
912 d->baselineAnchorLine = QQuickAnchors::InvalidAnchor;
913 emit baselineChanged();
914 d->updateVerticalAnchors();
915}
916
917QQuickAnchorLine QQuickAnchors::left() const
918{
919 Q_D(const QQuickAnchors);
920 return QQuickAnchorLine(d->leftAnchorItem, d->leftAnchorLine);
921}
922
923void QQuickAnchors::setLeft(const QQuickAnchorLine &edge)
924{
925 Q_D(QQuickAnchors);
926 if (!d->checkHAnchorValid(anchor: 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(item: oldLeft);
941 d->addDepend(item: d->leftAnchorItem);
942 emit leftChanged();
943 d->updateHorizontalAnchors();
944}
945
946void QQuickAnchors::resetLeft()
947{
948 Q_D(QQuickAnchors);
949 d->usedAnchors &= ~LeftAnchor;
950 d->remDepend(item: d->leftAnchorItem);
951 d->leftAnchorItem = nullptr;
952 d->leftAnchorLine = QQuickAnchors::InvalidAnchor;
953 emit leftChanged();
954 d->updateHorizontalAnchors();
955}
956
957QQuickAnchorLine QQuickAnchors::right() const
958{
959 Q_D(const QQuickAnchors);
960 return QQuickAnchorLine(d->rightAnchorItem, d->rightAnchorLine);
961}
962
963void QQuickAnchors::setRight(const QQuickAnchorLine &edge)
964{
965 Q_D(QQuickAnchors);
966 if (!d->checkHAnchorValid(anchor: 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(item: oldRight);
981 d->addDepend(item: d->rightAnchorItem);
982 emit rightChanged();
983 d->updateHorizontalAnchors();
984}
985
986void QQuickAnchors::resetRight()
987{
988 Q_D(QQuickAnchors);
989 d->usedAnchors &= ~RightAnchor;
990 d->remDepend(item: d->rightAnchorItem);
991 d->rightAnchorItem = nullptr;
992 d->rightAnchorLine = QQuickAnchors::InvalidAnchor;
993 emit rightChanged();
994 d->updateHorizontalAnchors();
995}
996
997QQuickAnchorLine QQuickAnchors::horizontalCenter() const
998{
999 Q_D(const QQuickAnchors);
1000 return QQuickAnchorLine(d->hCenterAnchorItem, d->hCenterAnchorLine);
1001}
1002
1003void QQuickAnchors::setHorizontalCenter(const QQuickAnchorLine &edge)
1004{
1005 Q_D(QQuickAnchors);
1006 if (!d->checkHAnchorValid(anchor: 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(item: oldHCenter);
1021 d->addDepend(item: d->hCenterAnchorItem);
1022 emit horizontalCenterChanged();
1023 d->updateHorizontalAnchors();
1024}
1025
1026void QQuickAnchors::resetHorizontalCenter()
1027{
1028 Q_D(QQuickAnchors);
1029 d->usedAnchors &= ~HCenterAnchor;
1030 d->remDepend(item: d->hCenterAnchorItem);
1031 d->hCenterAnchorItem = nullptr;
1032 d->hCenterAnchorLine = QQuickAnchors::InvalidAnchor;
1033 emit horizontalCenterChanged();
1034 d->updateHorizontalAnchors();
1035}
1036
1037qreal QQuickAnchors::leftMargin() const
1038{
1039 Q_D(const QQuickAnchors);
1040 return d->leftMargin;
1041}
1042
1043void QQuickAnchors::setLeftMargin(qreal offset)
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();
1054 emit leftMarginChanged();
1055}
1056
1057void QQuickAnchors::resetLeftMargin()
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();
1068 emit leftMarginChanged();
1069}
1070
1071qreal QQuickAnchors::rightMargin() const
1072{
1073 Q_D(const QQuickAnchors);
1074 return d->rightMargin;
1075}
1076
1077void QQuickAnchors::setRightMargin(qreal offset)
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();
1088 emit rightMarginChanged();
1089}
1090
1091void QQuickAnchors::resetRightMargin()
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();
1102 emit rightMarginChanged();
1103}
1104
1105qreal QQuickAnchors::margins() const
1106{
1107 Q_D(const QQuickAnchors);
1108 return d->margins;
1109}
1110
1111void QQuickAnchors::setMargins(qreal offset)
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;
1124 emit rightMarginChanged();
1125 }
1126 if (!d->leftMarginExplicit && d->leftMargin != offset) {
1127 d->leftMargin = offset;
1128 updateHorizontal = true;
1129 emit leftMarginChanged();
1130 }
1131 if (!d->topMarginExplicit && d->topMargin != offset) {
1132 d->topMargin = offset;
1133 updateVertical = true;
1134 emit topMarginChanged();
1135 }
1136 if (!d->bottomMarginExplicit && d->bottomMargin != offset) {
1137 d->bottomMargin = offset;
1138 updateVertical = true;
1139 emit bottomMarginChanged();
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
1152 emit marginsChanged();
1153}
1154
1155qreal QQuickAnchors::horizontalCenterOffset() const
1156{
1157 Q_D(const QQuickAnchors);
1158 return d->hCenterOffset;
1159}
1160
1161void QQuickAnchors::setHorizontalCenterOffset(qreal offset)
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();
1171 emit horizontalCenterOffsetChanged();
1172}
1173
1174qreal QQuickAnchors::topMargin() const
1175{
1176 Q_D(const QQuickAnchors);
1177 return d->topMargin;
1178}
1179
1180void QQuickAnchors::setTopMargin(qreal offset)
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();
1191 emit topMarginChanged();
1192}
1193
1194void QQuickAnchors::resetTopMargin()
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();
1205 emit topMarginChanged();
1206}
1207
1208qreal QQuickAnchors::bottomMargin() const
1209{
1210 Q_D(const QQuickAnchors);
1211 return d->bottomMargin;
1212}
1213
1214void QQuickAnchors::setBottomMargin(qreal offset)
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();
1225 emit bottomMarginChanged();
1226}
1227
1228void QQuickAnchors::resetBottomMargin()
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();
1239 emit bottomMarginChanged();
1240}
1241
1242qreal QQuickAnchors::verticalCenterOffset() const
1243{
1244 Q_D(const QQuickAnchors);
1245 return d->vCenterOffset;
1246}
1247
1248void QQuickAnchors::setVerticalCenterOffset(qreal offset)
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();
1258 emit verticalCenterOffsetChanged();
1259}
1260
1261qreal QQuickAnchors::baselineOffset() const
1262{
1263 Q_D(const QQuickAnchors);
1264 return d->baselineOffset;
1265}
1266
1267void QQuickAnchors::setBaselineOffset(qreal offset)
1268{
1269 Q_D(QQuickAnchors);
1270 if (d->baselineOffset == offset)
1271 return;
1272 d->baselineOffset = offset;
1273 d->updateVerticalAnchors();
1274 emit baselineOffsetChanged();
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)
1287 return Qt::Horizontal | Qt::Vertical;
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
1296bool QQuickAnchorsPrivate::checkHValid() const
1297{
1298 if (usedAnchors & QQuickAnchors::LeftAnchor &&
1299 usedAnchors & QQuickAnchors::RightAnchor &&
1300 usedAnchors & QQuickAnchors::HCenterAnchor) {
1301 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot specify left, right, and horizontalCenter anchors at the same time.");
1302 return false;
1303 }
1304
1305 return true;
1306}
1307
1308bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const
1309{
1310 if (!anchor.item) {
1311 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to a null item.");
1312 return false;
1313 } else if (anchor.anchorLine & QQuickAnchors::Vertical_Mask) {
1314 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor a horizontal edge to a vertical edge.");
1315 return false;
1316 } else if (anchor.item != readParentItem(item)
1317 && readParentItem(item: anchor.item) != readParentItem(item)) {
1318 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
1319 return false;
1320 } else if (anchor.item == item) {
1321 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor item to self.");
1322 return false;
1323 }
1324
1325 return true;
1326}
1327
1328bool QQuickAnchorsPrivate::checkVValid() const
1329{
1330 if (usedAnchors & QQuickAnchors::TopAnchor &&
1331 usedAnchors & QQuickAnchors::BottomAnchor &&
1332 usedAnchors & QQuickAnchors::VCenterAnchor) {
1333 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot specify top, bottom, and verticalCenter anchors at the same time.");
1334 return false;
1335 } else if (usedAnchors & QQuickAnchors::BaselineAnchor &&
1336 (usedAnchors & QQuickAnchors::TopAnchor ||
1337 usedAnchors & QQuickAnchors::BottomAnchor ||
1338 usedAnchors & QQuickAnchors::VCenterAnchor)) {
1339 qmlWarning(me: item) << QQuickAnchors::tr(s: "Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
1340 return false;
1341 }
1342
1343 return true;
1344}
1345
1346bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
1347{
1348 if (!anchor.item) {
1349 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to a null item.");
1350 return false;
1351 } else if (anchor.anchorLine & QQuickAnchors::Horizontal_Mask) {
1352 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor a vertical edge to a horizontal edge.");
1353 return false;
1354 } else if (anchor.item != readParentItem(item)
1355 && readParentItem(item: anchor.item) != readParentItem(item)) {
1356 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
1357 return false;
1358 } else if (anchor.item == item){
1359 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor item to self.");
1360 return false;
1361 }
1362
1363 return true;
1364}
1365
1366QT_END_NAMESPACE
1367
1368#include "moc_qquickanchors_p_p.cpp"
1369
1370#include <moc_qquickanchors_p.cpp>
1371
1372

source code of qtdeclarative/src/quick/items/qquickanchors.cpp