1 // Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
2 /****************************************************************************
4 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 ** All rights reserved.
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 ** This file is part of the QtDeclarative module of the Qt Toolkit.
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** No Commercial Usage
12 ** This file contains pre-release code and may not be distributed.
13 ** You may use this file in accordance with the terms and conditions
14 ** contained in the Technology Preview License Agreement accompanying
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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
41 ****************************************************************************/
43 #include "qsganchors_p_p.h"
46 #include "qsgitem_p.h"
48 #include <qdeclarativeinfo.h>
52 //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
53 //TODO: support non-parent, non-sibling (need to find lowest common ancestor)
55 static qreal hcenter(QSGItem *item)
57 qreal width = item->width();
60 return (width + 1) / 2;
65 static qreal vcenter(QSGItem *item)
67 qreal height = item->height();
70 return (height + 1) / 2;
77 static qreal position(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
81 case QSGAnchorLine::Left:
84 case QSGAnchorLine::Right:
85 ret = item->x() + item->width();
87 case QSGAnchorLine::Top:
90 case QSGAnchorLine::Bottom:
91 ret = item->y() + item->height();
93 case QSGAnchorLine::HCenter:
94 ret = item->x() + hcenter(item);
96 case QSGAnchorLine::VCenter:
97 ret = item->y() + vcenter(item);
99 case QSGAnchorLine::Baseline:
100 ret = item->y() + item->baselineOffset();
109 //position when origin is 0,0
110 static qreal adjustedPosition(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
114 case QSGAnchorLine::Left:
117 case QSGAnchorLine::Right:
120 case QSGAnchorLine::Top:
123 case QSGAnchorLine::Bottom:
124 ret = item->height();
126 case QSGAnchorLine::HCenter:
129 case QSGAnchorLine::VCenter:
132 case QSGAnchorLine::Baseline:
133 ret = item->baselineOffset();
142 QSGAnchors::QSGAnchors(QSGItem *item, QObject *parent)
143 : QObject(*new QSGAnchorsPrivate(item), parent)
147 QSGAnchors::~QSGAnchors()
150 d->remDepend(d->fill);
151 d->remDepend(d->centerIn);
152 d->remDepend(d->left.item);
153 d->remDepend(d->right.item);
154 d->remDepend(d->top.item);
155 d->remDepend(d->bottom.item);
156 d->remDepend(d->vCenter.item);
157 d->remDepend(d->hCenter.item);
158 d->remDepend(d->baseline.item);
161 void QSGAnchorsPrivate::fillChanged()
164 if (!fill || !isItemComplete())
167 if (updatingFill < 2) {
170 qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
172 if (fill == item->parentItem()) { //child-parent
173 setItemPos(QPointF(horizontalMargin, topMargin));
174 } else if (fill->parentItem() == item->parentItem()) { //siblings
175 setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin));
177 setItemSize(QSizeF(fill->width()-leftMargin-rightMargin, fill->height()-topMargin-bottomMargin));
181 // ### Make this certain :)
182 qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on fill.");
187 void QSGAnchorsPrivate::centerInChanged()
190 if (!centerIn || fill || !isItemComplete())
193 if (updatingCenterIn < 2) {
196 qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
197 if (centerIn == item->parentItem()) {
198 QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset,
199 vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
202 } else if (centerIn->parentItem() == item->parentItem()) {
203 QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
204 centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
210 // ### Make this certain :)
211 qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on centerIn.");
215 void QSGAnchorsPrivate::clearItem(QSGItem *item)
221 if (centerIn == item)
223 if (left.item == item) {
225 usedAnchors &= ~QSGAnchors::LeftAnchor;
227 if (right.item == item) {
229 usedAnchors &= ~QSGAnchors::RightAnchor;
231 if (top.item == item) {
233 usedAnchors &= ~QSGAnchors::TopAnchor;
235 if (bottom.item == item) {
237 usedAnchors &= ~QSGAnchors::BottomAnchor;
239 if (vCenter.item == item) {
241 usedAnchors &= ~QSGAnchors::VCenterAnchor;
243 if (hCenter.item == item) {
245 usedAnchors &= ~QSGAnchors::HCenterAnchor;
247 if (baseline.item == item) {
249 usedAnchors &= ~QSGAnchors::BaselineAnchor;
253 void QSGAnchorsPrivate::addDepend(QSGItem *item)
258 QSGItemPrivate *p = QSGItemPrivate::get(item);
259 p->addItemChangeListener(this, QSGItemPrivate::Geometry);
262 void QSGAnchorsPrivate::remDepend(QSGItem *item)
267 QSGItemPrivate *p = QSGItemPrivate::get(item);
268 p->removeItemChangeListener(this, QSGItemPrivate::Geometry);
271 bool QSGAnchors::mirrored()
274 return QSGItemPrivate::get(d->item)->effectiveLayoutMirror;
277 bool QSGAnchorsPrivate::isItemComplete() const
279 return componentComplete;
282 void QSGAnchors::classBegin()
285 d->componentComplete = false;
288 void QSGAnchors::componentComplete()
291 d->componentComplete = true;
294 void QSGAnchorsPrivate::setItemHeight(qreal v)
301 void QSGAnchorsPrivate::setItemWidth(qreal v)
308 void QSGAnchorsPrivate::setItemX(qreal v)
315 void QSGAnchorsPrivate::setItemY(qreal v)
322 void QSGAnchorsPrivate::setItemPos(const QPointF &v)
329 void QSGAnchorsPrivate::setItemSize(const QSizeF &v)
336 void QSGAnchorsPrivate::updateMe()
345 updateHorizontalAnchors();
346 updateVerticalAnchors();
349 void QSGAnchorsPrivate::updateOnComplete()
353 updateHorizontalAnchors();
354 updateVerticalAnchors();
357 void QSGAnchorsPrivate::itemGeometryChanged(QSGItem *, const QRectF &newG, const QRectF &oldG)
361 if (newG.x() != oldG.x() || newG.width() != oldG.width())
362 updateHorizontalAnchors();
363 if (newG.y() != oldG.y() || newG.height() != oldG.height())
364 updateVerticalAnchors();
367 QSGItem *QSGAnchors::fill() const
369 Q_D(const QSGAnchors);
373 void QSGAnchors::setFill(QSGItem *f)
380 d->remDepend(d->fill);
385 if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){
386 qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
389 d->remDepend(d->fill);
391 d->addDepend(d->fill);
396 void QSGAnchors::resetFill()
401 QSGItem *QSGAnchors::centerIn() const
403 Q_D(const QSGAnchors);
407 void QSGAnchors::setCenterIn(QSGItem* c)
410 if (d->centerIn == c)
414 d->remDepend(d->centerIn);
416 emit centerInChanged();
419 if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){
420 qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
424 d->remDepend(d->centerIn);
426 d->addDepend(d->centerIn);
427 emit centerInChanged();
428 d->centerInChanged();
431 void QSGAnchors::resetCenterIn()
436 bool QSGAnchorsPrivate::calcStretch(const QSGAnchorLine &edge1,
437 const QSGAnchorLine &edge2,
440 QSGAnchorLine::AnchorLine line,
443 bool edge1IsParent = (edge1.item == item->parentItem());
444 bool edge2IsParent = (edge2.item == item->parentItem());
445 bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem());
446 bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem());
448 bool invalid = false;
449 if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
450 stretch = (position(edge2.item, edge2.anchorLine) + offset2)
451 - (position(edge1.item, edge1.anchorLine) + offset1);
452 } else if (edge2IsParent && edge1IsSibling) {
453 stretch = (position(edge2.item, edge2.anchorLine) + offset2)
454 - (position(item->parentItem(), line)
455 + position(edge1.item, edge1.anchorLine) + offset1);
456 } else if (edge2IsSibling && edge1IsParent) {
457 stretch = (position(item->parentItem(), line) + position(edge2.item, edge2.anchorLine) + offset2)
458 - (position(edge1.item, edge1.anchorLine) + offset1);
465 void QSGAnchorsPrivate::updateVerticalAnchors()
467 if (fill || centerIn || !isItemComplete())
470 if (updatingVerticalAnchor < 2) {
471 ++updatingVerticalAnchor;
472 if (usedAnchors & QSGAnchors::TopAnchor) {
476 if (usedAnchors & QSGAnchors::BottomAnchor) {
477 invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QSGAnchorLine::Top, height);
478 } else if (usedAnchors & QSGAnchors::VCenterAnchor) {
479 invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QSGAnchorLine::Top, height);
483 setItemHeight(height);
486 if (top.item == item->parentItem()) {
487 setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin);
488 } else if (top.item->parentItem() == item->parentItem()) {
489 setItemY(position(top.item, top.anchorLine) + topMargin);
491 } else if (usedAnchors & QSGAnchors::BottomAnchor) {
492 //Handle stretching (top + bottom case is handled above)
493 if (usedAnchors & QSGAnchors::VCenterAnchor) {
495 bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
496 QSGAnchorLine::Top, height);
498 setItemHeight(height*2);
502 if (bottom.item == item->parentItem()) {
503 setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
504 } else if (bottom.item->parentItem() == item->parentItem()) {
505 setItemY(position(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
507 } else if (usedAnchors & QSGAnchors::VCenterAnchor) {
508 //(stetching handled above)
511 if (vCenter.item == item->parentItem()) {
512 setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
513 - vcenter(item) + vCenterOffset);
514 } else if (vCenter.item->parentItem() == item->parentItem()) {
515 setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
517 } else if (usedAnchors & QSGAnchors::BaselineAnchor) {
519 if (baseline.item == item->parentItem()) {
520 setItemY(adjustedPosition(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
521 } else if (baseline.item->parentItem() == item->parentItem()) {
522 setItemY(position(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
525 --updatingVerticalAnchor;
527 // ### Make this certain :)
528 qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on vertical anchor.");
532 inline QSGAnchorLine::AnchorLine reverseAnchorLine(QSGAnchorLine::AnchorLine anchorLine)
534 if (anchorLine == QSGAnchorLine::Left) {
535 return QSGAnchorLine::Right;
536 } else if (anchorLine == QSGAnchorLine::Right) {
537 return QSGAnchorLine::Left;
543 void QSGAnchorsPrivate::updateHorizontalAnchors()
546 if (fill || centerIn || !isItemComplete())
549 if (updatingHorizontalAnchor < 3) {
550 ++updatingHorizontalAnchor;
551 qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
552 QSGAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
553 QSGAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
555 effectiveLeftAnchor = QSGAnchors::RightAnchor;
556 effectiveRightAnchor = QSGAnchors::LeftAnchor;
557 effectiveLeft.item = right.item;
558 effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine);
559 effectiveRight.item = left.item;
560 effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine);
561 effectiveHorizontalCenter.item = hCenter.item;
562 effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine);
563 effectiveLeftMargin = rightMargin;
564 effectiveRightMargin = leftMargin;
565 effectiveHorizontalCenterOffset = -hCenterOffset;
567 effectiveLeftAnchor = QSGAnchors::LeftAnchor;
568 effectiveRightAnchor = QSGAnchors::RightAnchor;
569 effectiveLeft = left;
570 effectiveRight = right;
571 effectiveHorizontalCenter = hCenter;
572 effectiveLeftMargin = leftMargin;
573 effectiveRightMargin = rightMargin;
574 effectiveHorizontalCenterOffset = hCenterOffset;
577 if (usedAnchors & effectiveLeftAnchor) {
581 if (usedAnchors & effectiveRightAnchor) {
582 invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QSGAnchorLine::Left, width);
583 } else if (usedAnchors & QSGAnchors::HCenterAnchor) {
584 invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QSGAnchorLine::Left, width);
591 if (effectiveLeft.item == item->parentItem()) {
592 setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
593 } else if (effectiveLeft.item->parentItem() == item->parentItem()) {
594 setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
596 } else if (usedAnchors & effectiveRightAnchor) {
597 //Handle stretching (left + right case is handled in updateLeftAnchor)
598 if (usedAnchors & QSGAnchors::HCenterAnchor) {
600 bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin,
601 QSGAnchorLine::Left, width);
603 setItemWidth(width*2);
607 if (effectiveRight.item == item->parentItem()) {
608 setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
609 } else if (effectiveRight.item->parentItem() == item->parentItem()) {
610 setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
612 } else if (usedAnchors & QSGAnchors::HCenterAnchor) {
614 if (effectiveHorizontalCenter.item == item->parentItem()) {
615 setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
616 } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) {
617 setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
620 --updatingHorizontalAnchor;
622 // ### Make this certain :)
623 qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on horizontal anchor.");
627 QSGAnchorLine QSGAnchors::top() const
629 Q_D(const QSGAnchors);
633 void QSGAnchors::setTop(const QSGAnchorLine &edge)
636 if (!d->checkVAnchorValid(edge) || d->top == edge)
639 d->usedAnchors |= TopAnchor;
641 if (!d->checkVValid()) {
642 d->usedAnchors &= ~TopAnchor;
646 d->remDepend(d->top.item);
648 d->addDepend(d->top.item);
650 d->updateVerticalAnchors();
653 void QSGAnchors::resetTop()
656 d->usedAnchors &= ~TopAnchor;
657 d->remDepend(d->top.item);
658 d->top = QSGAnchorLine();
660 d->updateVerticalAnchors();
663 QSGAnchorLine QSGAnchors::bottom() const
665 Q_D(const QSGAnchors);
669 void QSGAnchors::setBottom(const QSGAnchorLine &edge)
672 if (!d->checkVAnchorValid(edge) || d->bottom == edge)
675 d->usedAnchors |= BottomAnchor;
677 if (!d->checkVValid()) {
678 d->usedAnchors &= ~BottomAnchor;
682 d->remDepend(d->bottom.item);
684 d->addDepend(d->bottom.item);
685 emit bottomChanged();
686 d->updateVerticalAnchors();
689 void QSGAnchors::resetBottom()
692 d->usedAnchors &= ~BottomAnchor;
693 d->remDepend(d->bottom.item);
694 d->bottom = QSGAnchorLine();
695 emit bottomChanged();
696 d->updateVerticalAnchors();
699 QSGAnchorLine QSGAnchors::verticalCenter() const
701 Q_D(const QSGAnchors);
705 void QSGAnchors::setVerticalCenter(const QSGAnchorLine &edge)
708 if (!d->checkVAnchorValid(edge) || d->vCenter == edge)
711 d->usedAnchors |= VCenterAnchor;
713 if (!d->checkVValid()) {
714 d->usedAnchors &= ~VCenterAnchor;
718 d->remDepend(d->vCenter.item);
720 d->addDepend(d->vCenter.item);
721 emit verticalCenterChanged();
722 d->updateVerticalAnchors();
725 void QSGAnchors::resetVerticalCenter()
728 d->usedAnchors &= ~VCenterAnchor;
729 d->remDepend(d->vCenter.item);
730 d->vCenter = QSGAnchorLine();
731 emit verticalCenterChanged();
732 d->updateVerticalAnchors();
735 QSGAnchorLine QSGAnchors::baseline() const
737 Q_D(const QSGAnchors);
741 void QSGAnchors::setBaseline(const QSGAnchorLine &edge)
744 if (!d->checkVAnchorValid(edge) || d->baseline == edge)
747 d->usedAnchors |= BaselineAnchor;
749 if (!d->checkVValid()) {
750 d->usedAnchors &= ~BaselineAnchor;
754 d->remDepend(d->baseline.item);
756 d->addDepend(d->baseline.item);
757 emit baselineChanged();
758 d->updateVerticalAnchors();
761 void QSGAnchors::resetBaseline()
764 d->usedAnchors &= ~BaselineAnchor;
765 d->remDepend(d->baseline.item);
766 d->baseline = QSGAnchorLine();
767 emit baselineChanged();
768 d->updateVerticalAnchors();
771 QSGAnchorLine QSGAnchors::left() const
773 Q_D(const QSGAnchors);
777 void QSGAnchors::setLeft(const QSGAnchorLine &edge)
780 if (!d->checkHAnchorValid(edge) || d->left == edge)
783 d->usedAnchors |= LeftAnchor;
785 if (!d->checkHValid()) {
786 d->usedAnchors &= ~LeftAnchor;
790 d->remDepend(d->left.item);
792 d->addDepend(d->left.item);
794 d->updateHorizontalAnchors();
797 void QSGAnchors::resetLeft()
800 d->usedAnchors &= ~LeftAnchor;
801 d->remDepend(d->left.item);
802 d->left = QSGAnchorLine();
804 d->updateHorizontalAnchors();
807 QSGAnchorLine QSGAnchors::right() const
809 Q_D(const QSGAnchors);
813 void QSGAnchors::setRight(const QSGAnchorLine &edge)
816 if (!d->checkHAnchorValid(edge) || d->right == edge)
819 d->usedAnchors |= RightAnchor;
821 if (!d->checkHValid()) {
822 d->usedAnchors &= ~RightAnchor;
826 d->remDepend(d->right.item);
828 d->addDepend(d->right.item);
830 d->updateHorizontalAnchors();
833 void QSGAnchors::resetRight()
836 d->usedAnchors &= ~RightAnchor;
837 d->remDepend(d->right.item);
838 d->right = QSGAnchorLine();
840 d->updateHorizontalAnchors();
843 QSGAnchorLine QSGAnchors::horizontalCenter() const
845 Q_D(const QSGAnchors);
849 void QSGAnchors::setHorizontalCenter(const QSGAnchorLine &edge)
852 if (!d->checkHAnchorValid(edge) || d->hCenter == edge)
855 d->usedAnchors |= HCenterAnchor;
857 if (!d->checkHValid()) {
858 d->usedAnchors &= ~HCenterAnchor;
862 d->remDepend(d->hCenter.item);
864 d->addDepend(d->hCenter.item);
865 emit horizontalCenterChanged();
866 d->updateHorizontalAnchors();
869 void QSGAnchors::resetHorizontalCenter()
872 d->usedAnchors &= ~HCenterAnchor;
873 d->remDepend(d->hCenter.item);
874 d->hCenter = QSGAnchorLine();
875 emit horizontalCenterChanged();
876 d->updateHorizontalAnchors();
879 qreal QSGAnchors::leftMargin() const
881 Q_D(const QSGAnchors);
882 return d->leftMargin;
885 void QSGAnchors::setLeftMargin(qreal offset)
888 if (d->leftMargin == offset)
890 d->leftMargin = offset;
894 d->updateHorizontalAnchors();
895 emit leftMarginChanged();
898 qreal QSGAnchors::rightMargin() const
900 Q_D(const QSGAnchors);
901 return d->rightMargin;
904 void QSGAnchors::setRightMargin(qreal offset)
907 if (d->rightMargin == offset)
909 d->rightMargin = offset;
913 d->updateHorizontalAnchors();
914 emit rightMarginChanged();
917 qreal QSGAnchors::margins() const
919 Q_D(const QSGAnchors);
923 void QSGAnchors::setMargins(qreal offset)
926 if (d->margins == offset)
928 //###Is it significantly faster to set them directly so we can call fillChanged only once?
929 if(!d->rightMargin || d->rightMargin == d->margins)
930 setRightMargin(offset);
931 if(!d->leftMargin || d->leftMargin == d->margins)
932 setLeftMargin(offset);
933 if(!d->topMargin || d->topMargin == d->margins)
934 setTopMargin(offset);
935 if(!d->bottomMargin || d->bottomMargin == d->margins)
936 setBottomMargin(offset);
938 emit marginsChanged();
942 qreal QSGAnchors::horizontalCenterOffset() const
944 Q_D(const QSGAnchors);
945 return d->hCenterOffset;
948 void QSGAnchors::setHorizontalCenterOffset(qreal offset)
951 if (d->hCenterOffset == offset)
953 d->hCenterOffset = offset;
955 d->centerInChanged();
957 d->updateHorizontalAnchors();
958 emit horizontalCenterOffsetChanged();
961 qreal QSGAnchors::topMargin() const
963 Q_D(const QSGAnchors);
967 void QSGAnchors::setTopMargin(qreal offset)
970 if (d->topMargin == offset)
972 d->topMargin = offset;
976 d->updateVerticalAnchors();
977 emit topMarginChanged();
980 qreal QSGAnchors::bottomMargin() const
982 Q_D(const QSGAnchors);
983 return d->bottomMargin;
986 void QSGAnchors::setBottomMargin(qreal offset)
989 if (d->bottomMargin == offset)
991 d->bottomMargin = offset;
995 d->updateVerticalAnchors();
996 emit bottomMarginChanged();
999 qreal QSGAnchors::verticalCenterOffset() const
1001 Q_D(const QSGAnchors);
1002 return d->vCenterOffset;
1005 void QSGAnchors::setVerticalCenterOffset(qreal offset)
1008 if (d->vCenterOffset == offset)
1010 d->vCenterOffset = offset;
1012 d->centerInChanged();
1014 d->updateVerticalAnchors();
1015 emit verticalCenterOffsetChanged();
1018 qreal QSGAnchors::baselineOffset() const
1020 Q_D(const QSGAnchors);
1021 return d->baselineOffset;
1024 void QSGAnchors::setBaselineOffset(qreal offset)
1027 if (d->baselineOffset == offset)
1029 d->baselineOffset = offset;
1030 d->updateVerticalAnchors();
1031 emit baselineOffsetChanged();
1034 QSGAnchors::Anchors QSGAnchors::usedAnchors() const
1036 Q_D(const QSGAnchors);
1037 return d->usedAnchors;
1040 bool QSGAnchorsPrivate::checkHValid() const
1042 if (usedAnchors & QSGAnchors::LeftAnchor &&
1043 usedAnchors & QSGAnchors::RightAnchor &&
1044 usedAnchors & QSGAnchors::HCenterAnchor) {
1045 qmlInfo(item) << QSGAnchors::tr("Cannot specify left, right, and hcenter anchors.");
1052 bool QSGAnchorsPrivate::checkHAnchorValid(QSGAnchorLine anchor) const
1055 qmlInfo(item) << QSGAnchors::tr("Cannot anchor to a null item.");
1057 } else if (anchor.anchorLine & QSGAnchorLine::Vertical_Mask) {
1058 qmlInfo(item) << QSGAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
1060 } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
1061 qmlInfo(item) << QSGAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1063 } else if (anchor.item == item) {
1064 qmlInfo(item) << QSGAnchors::tr("Cannot anchor item to self.");
1071 bool QSGAnchorsPrivate::checkVValid() const
1073 if (usedAnchors & QSGAnchors::TopAnchor &&
1074 usedAnchors & QSGAnchors::BottomAnchor &&
1075 usedAnchors & QSGAnchors::VCenterAnchor) {
1076 qmlInfo(item) << QSGAnchors::tr("Cannot specify top, bottom, and vcenter anchors.");
1078 } else if (usedAnchors & QSGAnchors::BaselineAnchor &&
1079 (usedAnchors & QSGAnchors::TopAnchor ||
1080 usedAnchors & QSGAnchors::BottomAnchor ||
1081 usedAnchors & QSGAnchors::VCenterAnchor)) {
1082 qmlInfo(item) << QSGAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.");
1089 bool QSGAnchorsPrivate::checkVAnchorValid(QSGAnchorLine anchor) const
1092 qmlInfo(item) << QSGAnchors::tr("Cannot anchor to a null item.");
1094 } else if (anchor.anchorLine & QSGAnchorLine::Horizontal_Mask) {
1095 qmlInfo(item) << QSGAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
1097 } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
1098 qmlInfo(item) << QSGAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1100 } else if (anchor.item == item){
1101 qmlInfo(item) << QSGAnchors::tr("Cannot anchor item to self.");
1110 #include <moc_qsganchors_p.cpp>