1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickanchors_p_p.h"
41
42#include "qquickitem_p.h"
43
44#include <qqmlinfo.h>
45
46QT_BEGIN_NAMESPACE
47
48static Q_ALWAYS_INLINE QQuickItem *readParentItem(const QQuickItem *item)
49{
50 return QQuickItemPrivate::get(item)->parentItem;
51}
52
53static Q_ALWAYS_INLINE qreal readX(const QQuickItem *item)
54{
55 return QQuickItemPrivate::get(item)->x;
56}
57
58static Q_ALWAYS_INLINE qreal readY(const QQuickItem *item)
59{
60 return QQuickItemPrivate::get(item)->y;
61}
62
63static Q_ALWAYS_INLINE qreal readWidth(const QQuickItem *item)
64{
65 return QQuickItemPrivate::get(item)->width;
66}
67
68static Q_ALWAYS_INLINE qreal readHeight(const QQuickItem *item)
69{
70 return QQuickItemPrivate::get(item)->height;
71}
72
73static Q_ALWAYS_INLINE qreal readBaselineOffset(const QQuickItem *item)
74{
75 return QQuickItemPrivate::get(item)->baselineOffset;
76}
77
78//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
79//TODO: support non-parent, non-sibling (need to find lowest common ancestor)
80
81static inline qreal hcenter(const QQuickItem *item)
82{
83 qreal width = readWidth(item);
84 if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
85 if (!QQuickAnchorsPrivate::get(o: anchors)->centerAligned)
86 return width / 2;
87 }
88 int iw = width;
89 if (iw % 2)
90 return (width + 1) / 2;
91 else
92 return width / 2;
93}
94
95static inline qreal vcenter(const QQuickItem *item)
96{
97 qreal height = readHeight(item);
98 if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
99 if (!QQuickAnchorsPrivate::get(o: anchors)->centerAligned)
100 return height / 2;
101 }
102 int ih = height;
103 if (ih % 2)
104 return (height + 1) / 2;
105 else
106 return height / 2;
107}
108
109//local position
110static inline qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
111{
112 qreal ret = 0.0;
113 switch (anchorLine) {
114 case QQuickAnchors::LeftAnchor:
115 ret = readX(item);
116 break;
117 case QQuickAnchors::RightAnchor:
118 ret = readX(item) + readWidth(item);
119 break;
120 case QQuickAnchors::TopAnchor:
121 ret = readY(item);
122 break;
123 case QQuickAnchors::BottomAnchor:
124 ret = readY(item) + readHeight(item);
125 break;
126 case QQuickAnchors::HCenterAnchor:
127 ret = readX(item) + hcenter(item);
128 break;
129 case QQuickAnchors::VCenterAnchor:
130 ret = readY(item) + vcenter(item);
131 break;
132 case QQuickAnchors::BaselineAnchor:
133 ret = readY(item) + readBaselineOffset(item);
134 break;
135 default:
136 break;
137 }
138
139 return ret;
140}
141
142//position when origin is 0,0
143static inline qreal adjustedPosition(QQuickItem *item, QQuickAnchors::Anchor anchorLine)
144{
145 qreal ret = 0.0;
146 switch (anchorLine) {
147 case QQuickAnchors::LeftAnchor:
148 ret = 0.0;
149 break;
150 case QQuickAnchors::RightAnchor:
151 ret = readWidth(item);
152 break;
153 case QQuickAnchors::TopAnchor:
154 ret = 0.0;
155 break;
156 case QQuickAnchors::BottomAnchor:
157 ret = readHeight(item);
158 break;
159 case QQuickAnchors::HCenterAnchor:
160 ret = hcenter(item);
161 break;
162 case QQuickAnchors::VCenterAnchor:
163 ret = vcenter(item);
164 break;
165 case QQuickAnchors::BaselineAnchor:
166 ret = readBaselineOffset(item);
167 break;
168 default:
169 break;
170 }
171
172 return ret;
173}
174
175QQuickAnchors::QQuickAnchors(QQuickItem *item, QObject *parent)
176: QObject(*new QQuickAnchorsPrivate(item), parent)
177{
178}
179
180QQuickAnchors::~QQuickAnchors()
181{
182 Q_D(QQuickAnchors);
183 d->inDestructor = true;
184 d->remDepend(d->fill);
185 d->remDepend(d->centerIn);
186 d->remDepend(d->leftAnchorItem);
187 d->remDepend(d->rightAnchorItem);
188 d->remDepend(d->topAnchorItem);
189 d->remDepend(d->bottomAnchorItem);
190 d->remDepend(d->vCenterAnchorItem);
191 d->remDepend(d->hCenterAnchorItem);
192 d->remDepend(d->baselineAnchorItem);
193}
194
195void QQuickAnchorsPrivate::fillChanged()
196{
197 Q_Q(QQuickAnchors);
198 if (!fill || !isItemComplete())
199 return;
200
201 if (updatingFill < 2) {
202 ++updatingFill;
203
204 qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
205
206 if (fill == readParentItem(item)) { //child-parent
207 setItemPos(QPointF(horizontalMargin, topMargin));
208 } else if (readParentItem(item: fill) == readParentItem(item)) { //siblings
209 setItemPos(QPointF(readX(item: fill)+horizontalMargin, readY(item: fill) + topMargin));
210 }
211 setItemSize(QSizeF(readWidth(item: fill) - leftMargin - rightMargin,
212 readHeight(item: fill) - topMargin - bottomMargin));
213
214 --updatingFill;
215 } else {
216 // ### Make this certain :)
217 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on fill.");
218 }
219
220}
221
222void QQuickAnchorsPrivate::centerInChanged()
223{
224 Q_Q(QQuickAnchors);
225 if (!centerIn || fill || !isItemComplete())
226 return;
227
228 if (updatingCenterIn < 2) {
229 ++updatingCenterIn;
230
231 qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
232 if (centerIn == readParentItem(item)) {
233 QPointF p(hcenter(item: readParentItem(item)) - hcenter(item) + effectiveHCenterOffset,
234 vcenter(item: readParentItem(item)) - vcenter(item) + vCenterOffset);
235 setItemPos(p);
236
237 } else if (readParentItem(item: centerIn) == readParentItem(item)) {
238 QPointF p(centerIn->x() + hcenter(item: centerIn) - hcenter(item) + effectiveHCenterOffset,
239 centerIn->y() + vcenter(item: centerIn) - vcenter(item) + vCenterOffset);
240 setItemPos(p);
241 }
242
243 --updatingCenterIn;
244 } else {
245 // ### Make this certain :)
246 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on centerIn.");
247 }
248}
249
250void QQuickAnchorsPrivate::clearItem(QQuickItem *item)
251{
252 if (!item)
253 return;
254 if (fill == item)
255 fill = nullptr;
256 if (centerIn == item)
257 centerIn = nullptr;
258 if (leftAnchorItem == item) {
259 leftAnchorItem = nullptr;
260 usedAnchors &= ~QQuickAnchors::LeftAnchor;
261 }
262 if (rightAnchorItem == item) {
263 rightAnchorItem = nullptr;
264 usedAnchors &= ~QQuickAnchors::RightAnchor;
265 }
266 if (topAnchorItem == item) {
267 topAnchorItem = nullptr;
268 usedAnchors &= ~QQuickAnchors::TopAnchor;
269 }
270 if (bottomAnchorItem == item) {
271 bottomAnchorItem = nullptr;
272 usedAnchors &= ~QQuickAnchors::BottomAnchor;
273 }
274 if (vCenterAnchorItem == item) {
275 vCenterAnchorItem = nullptr;
276 usedAnchors &= ~QQuickAnchors::VCenterAnchor;
277 }
278 if (hCenterAnchorItem == item) {
279 hCenterAnchorItem = nullptr;
280 usedAnchors &= ~QQuickAnchors::HCenterAnchor;
281 }
282 if (baselineAnchorItem == item) {
283 baselineAnchorItem = nullptr;
284 usedAnchors &= ~QQuickAnchors::BaselineAnchor;
285 }
286}
287
288QQuickGeometryChange QQuickAnchorsPrivate::calculateDependency(QQuickItem *controlItem) const
289{
290 QQuickGeometryChange dependency;
291
292 if (!controlItem || inDestructor)
293 return dependency;
294
295 if (fill == controlItem) {
296 if (controlItem == readParentItem(item))
297 dependency.setSizeChange(true);
298 else //sibling
299 dependency.setAllChanged(true);
300 return dependency; //exit early
301 }
302
303 if (centerIn == controlItem) {
304 if (controlItem == readParentItem(item))
305 dependency.setSizeChange(true);
306 else //sibling
307 dependency.setAllChanged(true);
308 return dependency; //exit early
309 }
310
311 if ((usedAnchors & QQuickAnchors::LeftAnchor && leftAnchorItem == controlItem) ||
312 (usedAnchors & QQuickAnchors::RightAnchor && rightAnchorItem == controlItem) ||
313 (usedAnchors & QQuickAnchors::HCenterAnchor && hCenterAnchorItem == controlItem)) {
314 if (controlItem == readParentItem(item))
315 dependency.setWidthChange(true);
316 else //sibling
317 dependency.setHorizontalChange(true);
318 }
319
320 if ((usedAnchors & QQuickAnchors::TopAnchor && topAnchorItem == controlItem) ||
321 (usedAnchors & QQuickAnchors::BottomAnchor && bottomAnchorItem == controlItem) ||
322 (usedAnchors & QQuickAnchors::VCenterAnchor && vCenterAnchorItem == controlItem) ||
323 (usedAnchors & QQuickAnchors::BaselineAnchor && baselineAnchorItem == controlItem)) {
324 if (controlItem == readParentItem(item))
325 dependency.setHeightChange(true);
326 else //sibling
327 dependency.setVerticalChange(true);
328 }
329
330 return dependency;
331}
332
333void QQuickAnchorsPrivate::addDepend(QQuickItem *item)
334{
335 if (!item || !componentComplete)
336 return;
337
338 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
339 p->updateOrAddGeometryChangeListener(listener: this, types: calculateDependency(controlItem: item));
340}
341
342void QQuickAnchorsPrivate::remDepend(QQuickItem *item)
343{
344 if (!item || !componentComplete)
345 return;
346
347 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
348 p->updateOrRemoveGeometryChangeListener(listener: this, types: calculateDependency(controlItem: item));
349}
350
351bool QQuickAnchors::mirrored()
352{
353 Q_D(QQuickAnchors);
354 return QQuickItemPrivate::get(item: d->item)->effectiveLayoutMirror;
355}
356
357bool QQuickAnchors::alignWhenCentered() const
358{
359 Q_D(const QQuickAnchors);
360 return d->centerAligned;
361}
362
363void QQuickAnchors::setAlignWhenCentered(bool aligned)
364{
365 Q_D(QQuickAnchors);
366 if (aligned == d->centerAligned)
367 return;
368 d->centerAligned = aligned;
369 emit centerAlignedChanged();
370 if (d->centerIn) {
371 d->centerInChanged();
372 } else {
373 if (d->usedAnchors & QQuickAnchors::VCenterAnchor)
374 d->updateVerticalAnchors();
375 else if (d->usedAnchors & QQuickAnchors::HCenterAnchor)
376 d->updateHorizontalAnchors();
377 }
378}
379
380bool QQuickAnchorsPrivate::isItemComplete() const
381{
382 return componentComplete;
383}
384
385void QQuickAnchors::classBegin()
386{
387 Q_D(QQuickAnchors);
388 d->componentComplete = false;
389}
390
391void QQuickAnchors::componentComplete()
392{
393 Q_D(QQuickAnchors);
394 d->componentComplete = true;
395}
396
397void QQuickAnchorsPrivate::setItemHeight(qreal v)
398{
399 updatingMe = true;
400 item->setHeight(v);
401 updatingMe = false;
402}
403
404void QQuickAnchorsPrivate::setItemWidth(qreal v)
405{
406 updatingMe = true;
407 item->setWidth(v);
408 updatingMe = false;
409}
410
411void QQuickAnchorsPrivate::setItemX(qreal v)
412{
413 updatingMe = true;
414 item->setX(v);
415 updatingMe = false;
416}
417
418void QQuickAnchorsPrivate::setItemY(qreal v)
419{
420 updatingMe = true;
421 item->setY(v);
422 updatingMe = false;
423}
424
425void QQuickAnchorsPrivate::setItemPos(const QPointF &v)
426{
427 updatingMe = true;
428 item->setPosition(v);
429 updatingMe = false;
430}
431
432void QQuickAnchorsPrivate::setItemSize(const QSizeF &v)
433{
434 updatingMe = true;
435 item->setSize(v);
436 updatingMe = false;
437}
438
439void QQuickAnchorsPrivate::updateMe()
440{
441 if (updatingMe) {
442 updatingMe = false;
443 return;
444 }
445
446 update();
447}
448
449void QQuickAnchorsPrivate::updateOnComplete()
450{
451 //optimization to only set initial dependencies once, at completion time
452 QQuickItem *dependencies[9];
453 dependencies[0] = fill;
454 dependencies[1] = centerIn;
455 dependencies[2] = leftAnchorItem;
456 dependencies[3] = rightAnchorItem;
457 dependencies[4] = hCenterAnchorItem;
458 dependencies[5] = topAnchorItem;
459 dependencies[6] = bottomAnchorItem;
460 dependencies[7] = vCenterAnchorItem;
461 dependencies[8] = baselineAnchorItem;
462
463 std::sort(first: dependencies, last: dependencies + 9);
464
465 QQuickItem *lastDependency = nullptr;
466 for (int i = 0; i < 9; ++i) {
467 QQuickItem *dependency = dependencies[i];
468 if (lastDependency != dependency) {
469 addDepend(item: dependency);
470 lastDependency = dependency;
471 }
472 }
473
474 update();
475}
476
477
478void QQuickAnchorsPrivate::update()
479{
480 if (!isItemComplete())
481 return;
482
483 if (fill) {
484 fillChanged();
485 } else if (centerIn) {
486 centerInChanged();
487 } else {
488 if (usedAnchors & QQuickAnchors::Horizontal_Mask)
489 updateHorizontalAnchors();
490 if (usedAnchors & QQuickAnchors::Vertical_Mask)
491 updateVerticalAnchors();
492 }
493}
494
495void QQuickAnchorsPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &)
496{
497 if (!isItemComplete())
498 return;
499
500 if (fill) {
501 fillChanged();
502 } else if (centerIn) {
503 centerInChanged();
504 } else {
505 if ((usedAnchors & QQuickAnchors::Horizontal_Mask) && change.horizontalChange())
506 updateHorizontalAnchors();
507 if ((usedAnchors & QQuickAnchors::Vertical_Mask) && change.verticalChange())
508 updateVerticalAnchors();
509 }
510}
511
512QQuickItem *QQuickAnchors::fill() const
513{
514 Q_D(const QQuickAnchors);
515 return d->fill;
516}
517
518void QQuickAnchors::setFill(QQuickItem *f)
519{
520 Q_D(QQuickAnchors);
521 if (d->fill == f)
522 return;
523
524 if (!f) {
525 QQuickItem *oldFill = d->fill;
526 d->fill = f;
527 d->remDepend(item: oldFill);
528 emit fillChanged();
529 return;
530 }
531 if (f != readParentItem(item: d->item) && readParentItem(item: f) != readParentItem(item: d->item)){
532 qmlWarning(me: d->item) << tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
533 return;
534 }
535 QQuickItem *oldFill = d->fill;
536 d->fill = f;
537 d->remDepend(item: oldFill);
538 d->addDepend(item: d->fill);
539 emit fillChanged();
540 d->fillChanged();
541}
542
543void QQuickAnchors::resetFill()
544{
545 setFill(nullptr);
546}
547
548QQuickItem *QQuickAnchors::centerIn() const
549{
550 Q_D(const QQuickAnchors);
551 return d->centerIn;
552}
553
554void QQuickAnchors::setCenterIn(QQuickItem* c)
555{
556 Q_D(QQuickAnchors);
557 if (d->centerIn == c)
558 return;
559
560 if (!c) {
561 QQuickItem *oldCI = d->centerIn;
562 d->centerIn = c;
563 d->remDepend(item: oldCI);
564 emit centerInChanged();
565 return;
566 }
567 if (c != readParentItem(item: d->item) && readParentItem(item: c) != readParentItem(item: d->item)){
568 qmlWarning(me: d->item) << tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
569 return;
570 }
571 QQuickItem *oldCI = d->centerIn;
572 d->centerIn = c;
573 d->remDepend(item: oldCI);
574 d->addDepend(item: d->centerIn);
575 emit centerInChanged();
576 d->centerInChanged();
577}
578
579void QQuickAnchors::resetCenterIn()
580{
581 setCenterIn(nullptr);
582}
583
584bool QQuickAnchorsPrivate::calcStretch(QQuickItem *edge1Item,
585 QQuickAnchors::Anchor edge1Line,
586 QQuickItem *edge2Item,
587 QQuickAnchors::Anchor edge2Line,
588 qreal offset1,
589 qreal offset2,
590 QQuickAnchors::Anchor line,
591 qreal &stretch) const
592{
593 bool edge1IsParent = (edge1Item == readParentItem(item));
594 bool edge2IsParent = (edge2Item == readParentItem(item));
595 bool edge1IsSibling = (readParentItem(item: edge1Item) == readParentItem(item));
596 bool edge2IsSibling = (readParentItem(item: edge2Item) == readParentItem(item));
597
598 bool invalid = false;
599 if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
600 stretch = (position(item: edge2Item, anchorLine: edge2Line) + offset2)
601 - (position(item: edge1Item, anchorLine: edge1Line) + offset1);
602 } else if (edge2IsParent && edge1IsSibling) {
603 stretch = (position(item: edge2Item, anchorLine: edge2Line) + offset2)
604 - (position(item: readParentItem(item), anchorLine: line)
605 + position(item: edge1Item, anchorLine: edge1Line) + offset1);
606 } else if (edge2IsSibling && edge1IsParent) {
607 stretch = (position(item: readParentItem(item), anchorLine: line) + position(item: edge2Item, anchorLine: edge2Line) + offset2)
608 - (position(item: edge1Item, anchorLine: edge1Line) + offset1);
609 } else
610 invalid = true;
611
612 return invalid;
613}
614
615void QQuickAnchorsPrivate::updateVerticalAnchors()
616{
617 if (fill || centerIn || !isItemComplete())
618 return;
619
620 if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
621 // ### Make this certain :)
622 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on vertical anchor.");
623 return;
624 }
625
626 ++updatingVerticalAnchor;
627 if (usedAnchors & QQuickAnchors::TopAnchor) {
628 //Handle stretching
629 bool invalid = true;
630 qreal height = 0.0;
631 if (usedAnchors & QQuickAnchors::BottomAnchor) {
632 invalid = calcStretch(edge1Item: topAnchorItem, edge1Line: topAnchorLine,
633 edge2Item: bottomAnchorItem, edge2Line: bottomAnchorLine,
634 offset1: topMargin, offset2: -bottomMargin, line: QQuickAnchors::TopAnchor, stretch&: height);
635 } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
636 invalid = calcStretch(edge1Item: topAnchorItem, edge1Line: topAnchorLine,
637 edge2Item: vCenterAnchorItem, edge2Line: vCenterAnchorLine,
638 offset1: topMargin, offset2: vCenterOffset, line: QQuickAnchors::TopAnchor, stretch&: height);
639 height *= 2;
640 }
641 if (!invalid)
642 setItemHeight(height);
643
644 //Handle top
645 if (topAnchorItem == readParentItem(item)) {
646 setItemY(adjustedPosition(item: topAnchorItem, anchorLine: topAnchorLine) + topMargin);
647 } else if (readParentItem(item: topAnchorItem) == readParentItem(item)) {
648 setItemY(position(item: topAnchorItem, anchorLine: topAnchorLine) + topMargin);
649 }
650 } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
651 //Handle stretching (top + bottom case is handled above)
652 if (usedAnchors & QQuickAnchors::VCenterAnchor) {
653 qreal height = 0.0;
654 bool invalid = calcStretch(edge1Item: vCenterAnchorItem, edge1Line: vCenterAnchorLine,
655 edge2Item: bottomAnchorItem, edge2Line: bottomAnchorLine,
656 offset1: vCenterOffset, offset2: -bottomMargin, line: QQuickAnchors::TopAnchor,
657 stretch&: height);
658 if (!invalid)
659 setItemHeight(height*2);
660 }
661
662 //Handle bottom
663 if (bottomAnchorItem == readParentItem(item)) {
664 setItemY(adjustedPosition(item: bottomAnchorItem, anchorLine: bottomAnchorLine) - readHeight(item) - bottomMargin);
665 } else if (readParentItem(item: bottomAnchorItem) == readParentItem(item)) {
666 setItemY(position(item: bottomAnchorItem, anchorLine: bottomAnchorLine) - readHeight(item) - bottomMargin);
667 }
668 } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
669 //(stetching handled above)
670
671 //Handle vCenter
672 if (vCenterAnchorItem == readParentItem(item)) {
673 setItemY(adjustedPosition(item: vCenterAnchorItem, anchorLine: vCenterAnchorLine)
674 - vcenter(item) + vCenterOffset);
675 } else if (readParentItem(item: vCenterAnchorItem) == readParentItem(item)) {
676 setItemY(position(item: vCenterAnchorItem, anchorLine: vCenterAnchorLine) - vcenter(item) + vCenterOffset);
677 }
678 } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
679 //Handle baseline
680 if (baselineAnchorItem == readParentItem(item)) {
681 setItemY(adjustedPosition(item: baselineAnchorItem, anchorLine: baselineAnchorLine)
682 - readBaselineOffset(item) + baselineOffset);
683 } else if (readParentItem(item: baselineAnchorItem) == readParentItem(item)) {
684 setItemY(position(item: baselineAnchorItem, anchorLine: baselineAnchorLine)
685 - readBaselineOffset(item) + baselineOffset);
686 }
687 }
688 --updatingVerticalAnchor;
689}
690
691static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)
692{
693 if (anchorLine == QQuickAnchors::LeftAnchor) {
694 return QQuickAnchors::RightAnchor;
695 } else if (anchorLine == QQuickAnchors::RightAnchor) {
696 return QQuickAnchors::LeftAnchor;
697 } else {
698 return anchorLine;
699 }
700}
701
702void QQuickAnchorsPrivate::updateHorizontalAnchors()
703{
704 Q_Q(QQuickAnchors);
705 if (fill || centerIn || !isItemComplete())
706 return;
707
708 if (updatingHorizontalAnchor < 3) {
709 ++updatingHorizontalAnchor;
710 qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
711 QQuickItem *effectiveLeftItem, *effectiveRightItem, *effectiveHorizontalCenterItem;
712 QQuickAnchors::Anchor effectiveLeftLine, effectiveRightLine, effectiveHorizontalCenterLine;
713 QQuickAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
714 if (q->mirrored()) {
715 effectiveLeftAnchor = QQuickAnchors::RightAnchor;
716 effectiveRightAnchor = QQuickAnchors::LeftAnchor;
717 effectiveLeftItem = rightAnchorItem;
718 effectiveLeftLine = reverseAnchorLine(anchorLine: rightAnchorLine);
719 effectiveRightItem = leftAnchorItem;
720 effectiveRightLine = reverseAnchorLine(anchorLine: leftAnchorLine);
721 effectiveHorizontalCenterItem = hCenterAnchorItem;
722 effectiveHorizontalCenterLine = reverseAnchorLine(anchorLine: hCenterAnchorLine);
723 effectiveLeftMargin = rightMargin;
724 effectiveRightMargin = leftMargin;
725 effectiveHorizontalCenterOffset = -hCenterOffset;
726 } else {
727 effectiveLeftAnchor = QQuickAnchors::LeftAnchor;
728 effectiveRightAnchor = QQuickAnchors::RightAnchor;
729 effectiveLeftItem = leftAnchorItem;
730 effectiveLeftLine = leftAnchorLine;
731 effectiveRightItem = rightAnchorItem;
732 effectiveRightLine = rightAnchorLine;
733 effectiveHorizontalCenterItem = hCenterAnchorItem;
734 effectiveHorizontalCenterLine = hCenterAnchorLine;
735 effectiveLeftMargin = leftMargin;
736 effectiveRightMargin = rightMargin;
737 effectiveHorizontalCenterOffset = hCenterOffset;
738 }
739
740 if (usedAnchors & effectiveLeftAnchor) {
741 //Handle stretching
742 bool invalid = true;
743 qreal width = 0.0;
744 if (usedAnchors & effectiveRightAnchor) {
745 invalid = calcStretch(edge1Item: effectiveLeftItem, edge1Line: effectiveLeftLine,
746 edge2Item: effectiveRightItem, edge2Line: effectiveRightLine,
747 offset1: effectiveLeftMargin, offset2: -effectiveRightMargin,
748 line: QQuickAnchors::LeftAnchor, stretch&: width);
749 } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
750 invalid = calcStretch(edge1Item: effectiveLeftItem, edge1Line: effectiveLeftLine,
751 edge2Item: effectiveHorizontalCenterItem, edge2Line: effectiveHorizontalCenterLine,
752 offset1: effectiveLeftMargin, offset2: effectiveHorizontalCenterOffset,
753 line: QQuickAnchors::LeftAnchor, stretch&: width);
754 width *= 2;
755 }
756 if (!invalid)
757 setItemWidth(width);
758
759 //Handle left
760 if (effectiveLeftItem == readParentItem(item)) {
761 setItemX(adjustedPosition(item: effectiveLeftItem, anchorLine: effectiveLeftLine) + effectiveLeftMargin);
762 } else if (readParentItem(item: effectiveLeftItem) == readParentItem(item)) {
763 setItemX(position(item: effectiveLeftItem, anchorLine: effectiveLeftLine) + effectiveLeftMargin);
764 }
765 } else if (usedAnchors & effectiveRightAnchor) {
766 //Handle stretching (left + right case is handled in updateLeftAnchor)
767 if (usedAnchors & QQuickAnchors::HCenterAnchor) {
768 qreal width = 0.0;
769 bool invalid = calcStretch(edge1Item: effectiveHorizontalCenterItem,
770 edge1Line: effectiveHorizontalCenterLine,
771 edge2Item: effectiveRightItem, edge2Line: effectiveRightLine,
772 offset1: effectiveHorizontalCenterOffset, offset2: -effectiveRightMargin,
773 line: QQuickAnchors::LeftAnchor, stretch&: width);
774 if (!invalid)
775 setItemWidth(width*2);
776 }
777
778 //Handle right
779 if (effectiveRightItem == readParentItem(item)) {
780 setItemX(adjustedPosition(item: effectiveRightItem, anchorLine: effectiveRightLine)
781 - readWidth(item) - effectiveRightMargin);
782 } else if (readParentItem(item: effectiveRightItem) == readParentItem(item)) {
783 setItemX(position(item: effectiveRightItem, anchorLine: effectiveRightLine)
784 - readWidth(item) - effectiveRightMargin);
785 }
786 } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
787 //Handle hCenter
788 if (effectiveHorizontalCenterItem == readParentItem(item)) {
789 setItemX(adjustedPosition(item: effectiveHorizontalCenterItem, anchorLine: effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
790 } else if (readParentItem(item: effectiveHorizontalCenterItem) == readParentItem(item)) {
791 setItemX(position(item: effectiveHorizontalCenterItem, anchorLine: effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
792 }
793 }
794 --updatingHorizontalAnchor;
795 } else {
796 // ### Make this certain :)
797 qmlWarning(me: item) << QQuickAnchors::tr(s: "Possible anchor loop detected on horizontal anchor.");
798 }
799}
800
801QQuickAnchorLine QQuickAnchors::top() const
802{
803 Q_D(const QQuickAnchors);
804 return QQuickAnchorLine(d->topAnchorItem, d->topAnchorLine);
805}
806
807void QQuickAnchors::setTop(const QQuickAnchorLine &edge)
808{
809 Q_D(QQuickAnchors);
810 if (!d->checkVAnchorValid(anchor: edge) ||
811 (d->topAnchorItem == edge.item && d->topAnchorLine == edge.anchorLine))
812 return;
813
814 d->usedAnchors |= TopAnchor;
815
816 if (!d->checkVValid()) {
817 d->usedAnchors &= ~TopAnchor;
818 return;
819 }
820
821 QQuickItem *oldTop = d->topAnchorItem;
822 d->topAnchorItem = edge.item;
823 d->topAnchorLine = edge.anchorLine;
824 d->remDepend(item: oldTop);
825 d->addDepend(item: d->topAnchorItem);
826 emit topChanged();
827 d->updateVerticalAnchors();
828}
829
830void QQuickAnchors::resetTop()
831{
832 Q_D(QQuickAnchors);
833 d->usedAnchors &= ~TopAnchor;
834 d->remDepend(item: d->topAnchorItem);
835 d->topAnchorItem = nullptr;
836 d->topAnchorLine = QQuickAnchors::InvalidAnchor;
837 emit topChanged();
838 d->updateVerticalAnchors();
839}
840
841QQuickAnchorLine QQuickAnchors::bottom() const
842{
843 Q_D(const QQuickAnchors);
844 return QQuickAnchorLine(d->bottomAnchorItem, d->bottomAnchorLine);
845}
846
847void QQuickAnchors::setBottom(const QQuickAnchorLine &edge)
848{
849 Q_D(QQuickAnchors);
850 if (!d->checkVAnchorValid(anchor: edge) ||
851 (d->bottomAnchorItem == edge.item && d->bottomAnchorLine == edge.anchorLine))
852 return;
853
854 d->usedAnchors |= BottomAnchor;
855
856 if (!d->checkVValid()) {
857 d->usedAnchors &= ~BottomAnchor;
858 return;
859 }
860
861 QQuickItem *oldBottom = d->bottomAnchorItem;
862 d->bottomAnchorItem = edge.item;
863 d->bottomAnchorLine = edge.anchorLine;
864 d->remDepend(item: oldBottom);
865 d->addDepend(item: d->bottomAnchorItem);
866 emit bottomChanged();
867 d->updateVerticalAnchors();
868}
869
870void QQuickAnchors::resetBottom()
871{
872 Q_D(QQuickAnchors);
873 d->usedAnchors &= ~BottomAnchor;
874 d->remDepend(item: d->bottomAnchorItem);
875 d->bottomAnchorItem = nullptr;
876 d->bottomAnchorLine = QQuickAnchors::InvalidAnchor;
877 emit bottomChanged();
878 d->updateVerticalAnchors();
879}
880
881QQuickAnchorLine QQuickAnchors::verticalCenter() const
882{
883 Q_D(const QQuickAnchors);
884 return QQuickAnchorLine(d->vCenterAnchorItem, d->vCenterAnchorLine);
885}
886
887void QQuickAnchors::setVerticalCenter(const QQuickAnchorLine &edge)
888{
889 Q_D(QQuickAnchors);
890 if (!d->checkVAnchorValid(anchor: edge) ||
891 (d->vCenterAnchorItem == edge.item && d->vCenterAnchorLine == edge.anchorLine))
892 return;
893
894 d->usedAnchors |= VCenterAnchor;
895
896 if (!d->checkVValid()) {
897 d->usedAnchors &= ~VCenterAnchor;
898 return;
899 }
900
901 QQuickItem *oldVCenter = d->vCenterAnchorItem;
902 d->vCenterAnchorItem = edge.item;
903 d->vCenterAnchorLine = edge.anchorLine;
904 d->remDepend(item: oldVCenter);
905 d->addDepend(item: d->vCenterAnchorItem);
906 emit verticalCenterChanged();
907 d->updateVerticalAnchors();
908}
909
910void QQuickAnchors::resetVerticalCenter()
911{
912 Q_D(QQuickAnchors);
913 d->usedAnchors &= ~VCenterAnchor;
914 d->remDepend(item: d->vCenterAnchorItem);
915 d->vCenterAnchorItem = nullptr;
916 d->vCenterAnchorLine = QQuickAnchors::InvalidAnchor;
917 emit verticalCenterChanged();
918 d->updateVerticalAnchors();
919}
920
921QQuickAnchorLine QQuickAnchors::baseline() const
922{
923 Q_D(const QQuickAnchors);
924 return QQuickAnchorLine(d->baselineAnchorItem, d->baselineAnchorLine);
925}
926
927void QQuickAnchors::setBaseline(const QQuickAnchorLine &edge)
928{
929 Q_D(QQuickAnchors);
930 if (!d->checkVAnchorValid(anchor: edge) ||
931 (d->baselineAnchorItem == edge.item && d->baselineAnchorLine == edge.anchorLine))
932 return;
933
934 d->usedAnchors |= BaselineAnchor;
935
936 if (!d->checkVValid()) {
937 d->usedAnchors &= ~BaselineAnchor;
938 return;
939 }
940
941 QQuickItem *oldBaseline = d->baselineAnchorItem;
942 d->baselineAnchorItem = edge.item;
943 d->baselineAnchorLine = edge.anchorLine;
944 d->remDepend(item: oldBaseline);
945 d->addDepend(item: d->baselineAnchorItem);
946 emit baselineChanged();
947 d->updateVerticalAnchors();
948}
949
950void QQuickAnchors::resetBaseline()
951{
952 Q_D(QQuickAnchors);
953 d->usedAnchors &= ~BaselineAnchor;
954 d->remDepend(item: d->baselineAnchorItem);
955 d->baselineAnchorItem = nullptr;
956 d->baselineAnchorLine = QQuickAnchors::InvalidAnchor;
957 emit baselineChanged();
958 d->updateVerticalAnchors();
959}
960
961QQuickAnchorLine QQuickAnchors::left() const
962{
963 Q_D(const QQuickAnchors);
964 return QQuickAnchorLine(d->leftAnchorItem, d->leftAnchorLine);
965}
966
967void QQuickAnchors::setLeft(const QQuickAnchorLine &edge)
968{
969 Q_D(QQuickAnchors);
970 if (!d->checkHAnchorValid(anchor: edge) ||
971 (d->leftAnchorItem == edge.item && d->leftAnchorLine == edge.anchorLine))
972 return;
973
974 d->usedAnchors |= LeftAnchor;
975
976 if (!d->checkHValid()) {
977 d->usedAnchors &= ~LeftAnchor;
978 return;
979 }
980
981 QQuickItem *oldLeft = d->leftAnchorItem;
982 d->leftAnchorItem = edge.item;
983 d->leftAnchorLine = edge.anchorLine;
984 d->remDepend(item: oldLeft);
985 d->addDepend(item: d->leftAnchorItem);
986 emit leftChanged();
987 d->updateHorizontalAnchors();
988}
989
990void QQuickAnchors::resetLeft()
991{
992 Q_D(QQuickAnchors);
993 d->usedAnchors &= ~LeftAnchor;
994 d->remDepend(item: d->leftAnchorItem);
995 d->leftAnchorItem = nullptr;
996 d->leftAnchorLine = QQuickAnchors::InvalidAnchor;
997 emit leftChanged();
998 d->updateHorizontalAnchors();
999}
1000
1001QQuickAnchorLine QQuickAnchors::right() const
1002{
1003 Q_D(const QQuickAnchors);
1004 return QQuickAnchorLine(d->rightAnchorItem, d->rightAnchorLine);
1005}
1006
1007void QQuickAnchors::setRight(const QQuickAnchorLine &edge)
1008{
1009 Q_D(QQuickAnchors);
1010 if (!d->checkHAnchorValid(anchor: edge) ||
1011 (d->rightAnchorItem == edge.item && d->rightAnchorLine == edge.anchorLine))
1012 return;
1013
1014 d->usedAnchors |= RightAnchor;
1015
1016 if (!d->checkHValid()) {
1017 d->usedAnchors &= ~RightAnchor;
1018 return;
1019 }
1020
1021 QQuickItem *oldRight = d->rightAnchorItem;
1022 d->rightAnchorItem = edge.item;
1023 d->rightAnchorLine = edge.anchorLine;
1024 d->remDepend(item: oldRight);
1025 d->addDepend(item: d->rightAnchorItem);
1026 emit rightChanged();
1027 d->updateHorizontalAnchors();
1028}
1029
1030void QQuickAnchors::resetRight()
1031{
1032 Q_D(QQuickAnchors);
1033 d->usedAnchors &= ~RightAnchor;
1034 d->remDepend(item: d->rightAnchorItem);
1035 d->rightAnchorItem = nullptr;
1036 d->rightAnchorLine = QQuickAnchors::InvalidAnchor;
1037 emit rightChanged();
1038 d->updateHorizontalAnchors();
1039}
1040
1041QQuickAnchorLine QQuickAnchors::horizontalCenter() const
1042{
1043 Q_D(const QQuickAnchors);
1044 return QQuickAnchorLine(d->hCenterAnchorItem, d->hCenterAnchorLine);
1045}
1046
1047void QQuickAnchors::setHorizontalCenter(const QQuickAnchorLine &edge)
1048{
1049 Q_D(QQuickAnchors);
1050 if (!d->checkHAnchorValid(anchor: edge) ||
1051 (d->hCenterAnchorItem == edge.item && d->hCenterAnchorLine == edge.anchorLine))
1052 return;
1053
1054 d->usedAnchors |= HCenterAnchor;
1055
1056 if (!d->checkHValid()) {
1057 d->usedAnchors &= ~HCenterAnchor;
1058 return;
1059 }
1060
1061 QQuickItem *oldHCenter = d->hCenterAnchorItem;
1062 d->hCenterAnchorItem = edge.item;
1063 d->hCenterAnchorLine = edge.anchorLine;
1064 d->remDepend(item: oldHCenter);
1065 d->addDepend(item: d->hCenterAnchorItem);
1066 emit horizontalCenterChanged();
1067 d->updateHorizontalAnchors();
1068}
1069
1070void QQuickAnchors::resetHorizontalCenter()
1071{
1072 Q_D(QQuickAnchors);
1073 d->usedAnchors &= ~HCenterAnchor;
1074 d->remDepend(item: d->hCenterAnchorItem);
1075 d->hCenterAnchorItem = nullptr;
1076 d->hCenterAnchorLine = QQuickAnchors::InvalidAnchor;
1077 emit horizontalCenterChanged();
1078 d->updateHorizontalAnchors();
1079}
1080
1081qreal QQuickAnchors::leftMargin() const
1082{
1083 Q_D(const QQuickAnchors);
1084 return d->leftMargin;
1085}
1086
1087void QQuickAnchors::setLeftMargin(qreal offset)
1088{
1089 Q_D(QQuickAnchors);
1090 d->leftMarginExplicit = true;
1091 if (d->leftMargin == offset)
1092 return;
1093 d->leftMargin = offset;
1094 if (d->fill)
1095 d->fillChanged();
1096 else
1097 d->updateHorizontalAnchors();
1098 emit leftMarginChanged();
1099}
1100
1101void QQuickAnchors::resetLeftMargin()
1102{
1103 Q_D(QQuickAnchors);
1104 d->leftMarginExplicit = false;
1105 if (d->leftMargin == d->margins)
1106 return;
1107 d->leftMargin = d->margins;
1108 if (d->fill)
1109 d->fillChanged();
1110 else
1111 d->updateHorizontalAnchors();
1112 emit leftMarginChanged();
1113}
1114
1115qreal QQuickAnchors::rightMargin() const
1116{
1117 Q_D(const QQuickAnchors);
1118 return d->rightMargin;
1119}
1120
1121void QQuickAnchors::setRightMargin(qreal offset)
1122{
1123 Q_D(QQuickAnchors);
1124 d->rightMarginExplicit = true;
1125 if (d->rightMargin == offset)
1126 return;
1127 d->rightMargin = offset;
1128 if (d->fill)
1129 d->fillChanged();
1130 else
1131 d->updateHorizontalAnchors();
1132 emit rightMarginChanged();
1133}
1134
1135void QQuickAnchors::resetRightMargin()
1136{
1137 Q_D(QQuickAnchors);
1138 d->rightMarginExplicit = false;
1139 if (d->rightMargin == d->margins)
1140 return;
1141 d->rightMargin = d->margins;
1142 if (d->fill)
1143 d->fillChanged();
1144 else
1145 d->updateHorizontalAnchors();
1146 emit rightMarginChanged();
1147}
1148
1149qreal QQuickAnchors::margins() const
1150{
1151 Q_D(const QQuickAnchors);
1152 return d->margins;
1153}
1154
1155void QQuickAnchors::setMargins(qreal offset)
1156{
1157 Q_D(QQuickAnchors);
1158 if (d->margins == offset)
1159 return;
1160 d->margins = offset;
1161
1162 bool updateHorizontal = false;
1163 bool updateVertical = false;
1164
1165 if (!d->rightMarginExplicit && d->rightMargin != offset) {
1166 d->rightMargin = offset;
1167 updateHorizontal = true;
1168 emit rightMarginChanged();
1169 }
1170 if (!d->leftMarginExplicit && d->leftMargin != offset) {
1171 d->leftMargin = offset;
1172 updateHorizontal = true;
1173 emit leftMarginChanged();
1174 }
1175 if (!d->topMarginExplicit && d->topMargin != offset) {
1176 d->topMargin = offset;
1177 updateVertical = true;
1178 emit topMarginChanged();
1179 }
1180 if (!d->bottomMarginExplicit && d->bottomMargin != offset) {
1181 d->bottomMargin = offset;
1182 updateVertical = true;
1183 emit bottomMarginChanged();
1184 }
1185
1186 if (d->fill) {
1187 if (updateHorizontal || updateVertical)
1188 d->fillChanged();
1189 } else {
1190 if (updateHorizontal)
1191 d->updateHorizontalAnchors();
1192 if (updateVertical)
1193 d->updateVerticalAnchors();
1194 }
1195
1196 emit marginsChanged();
1197}
1198
1199qreal QQuickAnchors::horizontalCenterOffset() const
1200{
1201 Q_D(const QQuickAnchors);
1202 return d->hCenterOffset;
1203}
1204
1205void QQuickAnchors::setHorizontalCenterOffset(qreal offset)
1206{
1207 Q_D(QQuickAnchors);
1208 if (d->hCenterOffset == offset)
1209 return;
1210 d->hCenterOffset = offset;
1211 if (d->centerIn)
1212 d->centerInChanged();
1213 else
1214 d->updateHorizontalAnchors();
1215 emit horizontalCenterOffsetChanged();
1216}
1217
1218qreal QQuickAnchors::topMargin() const
1219{
1220 Q_D(const QQuickAnchors);
1221 return d->topMargin;
1222}
1223
1224void QQuickAnchors::setTopMargin(qreal offset)
1225{
1226 Q_D(QQuickAnchors);
1227 d->topMarginExplicit = true;
1228 if (d->topMargin == offset)
1229 return;
1230 d->topMargin = offset;
1231 if (d->fill)
1232 d->fillChanged();
1233 else
1234 d->updateVerticalAnchors();
1235 emit topMarginChanged();
1236}
1237
1238void QQuickAnchors::resetTopMargin()
1239{
1240 Q_D(QQuickAnchors);
1241 d->topMarginExplicit = false;
1242 if (d->topMargin == d->margins)
1243 return;
1244 d->topMargin = d->margins;
1245 if (d->fill)
1246 d->fillChanged();
1247 else
1248 d->updateVerticalAnchors();
1249 emit topMarginChanged();
1250}
1251
1252qreal QQuickAnchors::bottomMargin() const
1253{
1254 Q_D(const QQuickAnchors);
1255 return d->bottomMargin;
1256}
1257
1258void QQuickAnchors::setBottomMargin(qreal offset)
1259{
1260 Q_D(QQuickAnchors);
1261 d->bottomMarginExplicit = true;
1262 if (d->bottomMargin == offset)
1263 return;
1264 d->bottomMargin = offset;
1265 if (d->fill)
1266 d->fillChanged();
1267 else
1268 d->updateVerticalAnchors();
1269 emit bottomMarginChanged();
1270}
1271
1272void QQuickAnchors::resetBottomMargin()
1273{
1274 Q_D(QQuickAnchors);
1275 d->bottomMarginExplicit = false;
1276 if (d->bottomMargin == d->margins)
1277 return;
1278 d->bottomMargin = d->margins;
1279 if (d->fill)
1280 d->fillChanged();
1281 else
1282 d->updateVerticalAnchors();
1283 emit bottomMarginChanged();
1284}
1285
1286qreal QQuickAnchors::verticalCenterOffset() const
1287{
1288 Q_D(const QQuickAnchors);
1289 return d->vCenterOffset;
1290}
1291
1292void QQuickAnchors::setVerticalCenterOffset(qreal offset)
1293{
1294 Q_D(QQuickAnchors);
1295 if (d->vCenterOffset == offset)
1296 return;
1297 d->vCenterOffset = offset;
1298 if (d->centerIn)
1299 d->centerInChanged();
1300 else
1301 d->updateVerticalAnchors();
1302 emit verticalCenterOffsetChanged();
1303}
1304
1305qreal QQuickAnchors::baselineOffset() const
1306{
1307 Q_D(const QQuickAnchors);
1308 return d->baselineOffset;
1309}
1310
1311void QQuickAnchors::setBaselineOffset(qreal offset)
1312{
1313 Q_D(QQuickAnchors);
1314 if (d->baselineOffset == offset)
1315 return;
1316 d->baselineOffset = offset;
1317 d->updateVerticalAnchors();
1318 emit baselineOffsetChanged();
1319}
1320
1321QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const
1322{
1323 Q_D(const QQuickAnchors);
1324 return static_cast<QQuickAnchors::Anchors>(d->usedAnchors);
1325}
1326
1327Qt::Orientations QQuickAnchors::activeDirections() const
1328{
1329 Q_D(const QQuickAnchors);
1330 if (d->fill || d->centerIn)
1331 return Qt::Horizontal | Qt::Vertical;
1332 Qt::Orientations o;
1333 if (d->usedAnchors & QQuickAnchors::Horizontal_Mask)
1334 o |= Qt::Horizontal;
1335 if (d->usedAnchors & QQuickAnchors::Vertical_Mask)
1336 o |= Qt::Vertical;
1337 return o;
1338}
1339
1340bool QQuickAnchorsPrivate::checkHValid() const
1341{
1342 if (usedAnchors & QQuickAnchors::LeftAnchor &&
1343 usedAnchors & QQuickAnchors::RightAnchor &&
1344 usedAnchors & QQuickAnchors::HCenterAnchor) {
1345 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot specify left, right, and horizontalCenter anchors at the same time.");
1346 return false;
1347 }
1348
1349 return true;
1350}
1351
1352bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const
1353{
1354 if (!anchor.item) {
1355 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to a null item.");
1356 return false;
1357 } else if (anchor.anchorLine & QQuickAnchors::Vertical_Mask) {
1358 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor a horizontal edge to a vertical edge.");
1359 return false;
1360 } else if (anchor.item != readParentItem(item)
1361 && readParentItem(item: anchor.item) != readParentItem(item)) {
1362 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
1363 return false;
1364 } else if (anchor.item == item) {
1365 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor item to self.");
1366 return false;
1367 }
1368
1369 return true;
1370}
1371
1372bool QQuickAnchorsPrivate::checkVValid() const
1373{
1374 if (usedAnchors & QQuickAnchors::TopAnchor &&
1375 usedAnchors & QQuickAnchors::BottomAnchor &&
1376 usedAnchors & QQuickAnchors::VCenterAnchor) {
1377 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot specify top, bottom, and verticalCenter anchors at the same time.");
1378 return false;
1379 } else if (usedAnchors & QQuickAnchors::BaselineAnchor &&
1380 (usedAnchors & QQuickAnchors::TopAnchor ||
1381 usedAnchors & QQuickAnchors::BottomAnchor ||
1382 usedAnchors & QQuickAnchors::VCenterAnchor)) {
1383 qmlWarning(me: item) << QQuickAnchors::tr(s: "Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
1384 return false;
1385 }
1386
1387 return true;
1388}
1389
1390bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
1391{
1392 if (!anchor.item) {
1393 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to a null item.");
1394 return false;
1395 } else if (anchor.anchorLine & QQuickAnchors::Horizontal_Mask) {
1396 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor a vertical edge to a horizontal edge.");
1397 return false;
1398 } else if (anchor.item != readParentItem(item)
1399 && readParentItem(item: anchor.item) != readParentItem(item)) {
1400 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor to an item that isn't a parent or sibling.");
1401 return false;
1402 } else if (anchor.item == item){
1403 qmlWarning(me: item) << QQuickAnchors::tr(s: "Cannot anchor item to self.");
1404 return false;
1405 }
1406
1407 return true;
1408}
1409
1410QT_END_NAMESPACE
1411
1412#include <moc_qquickanchors_p.cpp>
1413
1414

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