1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "QtQuick1/private/qdeclarativeanchors_p_p.h"
44 #include "QtQuick1/qdeclarativeitem.h"
45 #include "QtQuick1/private/qdeclarativeitem_p.h"
47 #include <QtDeclarative/qdeclarativeinfo.h>
55 //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
56 //TODO: support non-parent, non-sibling (need to find lowest common ancestor)
58 static qreal hcenter(QGraphicsItem *i)
60 QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);
62 qreal width = item->width();
65 return (width + 1) / 2;
70 static qreal vcenter(QGraphicsItem *i)
72 QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);
74 qreal height = item->height();
77 return (height + 1) / 2;
84 static qreal position(QGraphicsObject *item, QDeclarative1AnchorLine::AnchorLine anchorLine)
87 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
89 case QDeclarative1AnchorLine::Left:
92 case QDeclarative1AnchorLine::Right:
93 ret = item->x() + d->width();
95 case QDeclarative1AnchorLine::Top:
98 case QDeclarative1AnchorLine::Bottom:
99 ret = item->y() + d->height();
101 case QDeclarative1AnchorLine::HCenter:
102 ret = item->x() + hcenter(item);
104 case QDeclarative1AnchorLine::VCenter:
105 ret = item->y() + vcenter(item);
107 case QDeclarative1AnchorLine::Baseline:
108 if (d->isDeclarativeItem)
109 ret = item->y() + static_cast<QDeclarativeItem*>(item)->baselineOffset();
118 //position when origin is 0,0
119 static qreal adjustedPosition(QGraphicsObject *item, QDeclarative1AnchorLine::AnchorLine anchorLine)
122 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
124 case QDeclarative1AnchorLine::Left:
127 case QDeclarative1AnchorLine::Right:
130 case QDeclarative1AnchorLine::Top:
133 case QDeclarative1AnchorLine::Bottom:
136 case QDeclarative1AnchorLine::HCenter:
139 case QDeclarative1AnchorLine::VCenter:
142 case QDeclarative1AnchorLine::Baseline:
143 if (d->isDeclarativeItem)
144 ret = static_cast<QDeclarativeItem*>(item)->baselineOffset();
153 QDeclarative1Anchors::QDeclarative1Anchors(QObject *parent)
154 : QObject(*new QDeclarative1AnchorsPrivate(0), parent)
156 qFatal("QDeclarative1Anchors::QDeclarative1Anchors(QObject*) called");
159 QDeclarative1Anchors::QDeclarative1Anchors(QGraphicsObject *item, QObject *parent)
160 : QObject(*new QDeclarative1AnchorsPrivate(item), parent)
164 QDeclarative1Anchors::~QDeclarative1Anchors()
166 Q_D(QDeclarative1Anchors);
167 d->remDepend(d->fill);
168 d->remDepend(d->centerIn);
169 d->remDepend(d->left.item);
170 d->remDepend(d->right.item);
171 d->remDepend(d->top.item);
172 d->remDepend(d->bottom.item);
173 d->remDepend(d->vCenter.item);
174 d->remDepend(d->hCenter.item);
175 d->remDepend(d->baseline.item);
178 void QDeclarative1AnchorsPrivate::fillChanged()
180 Q_Q(QDeclarative1Anchors);
181 if (!fill || !isItemComplete())
184 if (updatingFill < 2) {
187 qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
189 if (fill == item->parentItem()) { //child-parent
190 setItemPos(QPointF(horizontalMargin, topMargin));
191 } else if (fill->parentItem() == item->parentItem()) { //siblings
192 setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin));
194 QGraphicsItemPrivate *fillPrivate = QGraphicsItemPrivate::get(fill);
195 setItemSize(QSizeF(fillPrivate->width()-leftMargin-rightMargin, fillPrivate->height()-topMargin-bottomMargin));
199 // ### Make this certain :)
200 qmlInfo(item) << QDeclarative1Anchors::tr("Possible anchor loop detected on fill.");
205 void QDeclarative1AnchorsPrivate::centerInChanged()
207 Q_Q(QDeclarative1Anchors);
208 if (!centerIn || fill || !isItemComplete())
211 if (updatingCenterIn < 2) {
214 qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
215 if (centerIn == item->parentItem()) {
216 QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset,
217 vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
220 } else if (centerIn->parentItem() == item->parentItem()) {
221 QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
222 centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
228 // ### Make this certain :)
229 qmlInfo(item) << QDeclarative1Anchors::tr("Possible anchor loop detected on centerIn.");
233 void QDeclarative1AnchorsPrivate::clearItem(QGraphicsObject *item)
239 if (centerIn == item)
241 if (left.item == item) {
243 usedAnchors &= ~QDeclarative1Anchors::LeftAnchor;
245 if (right.item == item) {
247 usedAnchors &= ~QDeclarative1Anchors::RightAnchor;
249 if (top.item == item) {
251 usedAnchors &= ~QDeclarative1Anchors::TopAnchor;
253 if (bottom.item == item) {
255 usedAnchors &= ~QDeclarative1Anchors::BottomAnchor;
257 if (vCenter.item == item) {
259 usedAnchors &= ~QDeclarative1Anchors::VCenterAnchor;
261 if (hCenter.item == item) {
263 usedAnchors &= ~QDeclarative1Anchors::HCenterAnchor;
265 if (baseline.item == item) {
267 usedAnchors &= ~QDeclarative1Anchors::BaselineAnchor;
271 void QDeclarative1AnchorsPrivate::addDepend(QGraphicsObject *item)
275 QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item);
276 if (itemPrivate->isDeclarativeItem) {
277 QDeclarativeItemPrivate *p =
278 static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item));
279 p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
280 } else if(itemPrivate->isWidget) {
281 Q_Q(QDeclarative1Anchors);
282 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
283 QObject::connect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*)));
284 QObject::connect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged()));
288 void QDeclarative1AnchorsPrivate::remDepend(QGraphicsObject *item)
292 QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item);
293 if (itemPrivate->isDeclarativeItem) {
294 QDeclarativeItemPrivate *p =
295 static_cast<QDeclarativeItemPrivate *>(itemPrivate);
296 p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
297 } else if(itemPrivate->isWidget) {
298 Q_Q(QDeclarative1Anchors);
299 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
300 QObject::disconnect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*)));
301 QObject::disconnect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged()));
305 bool QDeclarative1AnchorsPrivate::isItemComplete() const
307 return componentComplete;
310 void QDeclarative1Anchors::classBegin()
312 Q_D(QDeclarative1Anchors);
313 d->componentComplete = false;
316 void QDeclarative1Anchors::componentComplete()
318 Q_D(QDeclarative1Anchors);
319 d->componentComplete = true;
322 bool QDeclarative1Anchors::mirrored()
324 Q_D(QDeclarative1Anchors);
325 QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(d->item);
326 return itemPrivate->isDeclarativeItem ? static_cast<QDeclarativeItemPrivate *>(itemPrivate)->effectiveLayoutMirror : false;
329 void QDeclarative1AnchorsPrivate::setItemHeight(qreal v)
332 QGraphicsItemPrivate::get(item)->setHeight(v);
336 void QDeclarative1AnchorsPrivate::setItemWidth(qreal v)
339 QGraphicsItemPrivate::get(item)->setWidth(v);
343 void QDeclarative1AnchorsPrivate::setItemX(qreal v)
350 void QDeclarative1AnchorsPrivate::setItemY(qreal v)
357 void QDeclarative1AnchorsPrivate::setItemPos(const QPointF &v)
364 void QDeclarative1AnchorsPrivate::setItemSize(const QSizeF &v)
367 if(QGraphicsItemPrivate::get(item)->isWidget)
368 static_cast<QGraphicsWidget *>(item)->resize(v);
369 else if (QGraphicsItemPrivate::get(item)->isDeclarativeItem)
370 static_cast<QDeclarativeItem *>(item)->setSize(v);
374 void QDeclarative1AnchorsPrivate::updateMe()
383 updateHorizontalAnchors();
384 updateVerticalAnchors();
387 void QDeclarative1AnchorsPrivate::updateOnComplete()
391 updateHorizontalAnchors();
392 updateVerticalAnchors();
395 void QDeclarative1AnchorsPrivate::_q_widgetDestroyed(QObject *obj)
397 clearItem(qobject_cast<QGraphicsObject*>(obj));
400 void QDeclarative1AnchorsPrivate::_q_widgetGeometryChanged()
404 updateHorizontalAnchors();
405 updateVerticalAnchors();
408 void QDeclarative1AnchorsPrivate::itemGeometryChanged(QDeclarativeItem *, const QRectF &newG, const QRectF &oldG)
412 if (newG.x() != oldG.x() || newG.width() != oldG.width())
413 updateHorizontalAnchors();
414 if (newG.y() != oldG.y() || newG.height() != oldG.height())
415 updateVerticalAnchors();
418 QGraphicsObject *QDeclarative1Anchors::fill() const
420 Q_D(const QDeclarative1Anchors);
424 void QDeclarative1Anchors::setFill(QGraphicsObject *f)
426 Q_D(QDeclarative1Anchors);
431 d->remDepend(d->fill);
436 if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){
437 qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
440 d->remDepend(d->fill);
442 d->addDepend(d->fill);
447 void QDeclarative1Anchors::resetFill()
452 QGraphicsObject *QDeclarative1Anchors::centerIn() const
454 Q_D(const QDeclarative1Anchors);
458 void QDeclarative1Anchors::setCenterIn(QGraphicsObject* c)
460 Q_D(QDeclarative1Anchors);
461 if (d->centerIn == c)
465 d->remDepend(d->centerIn);
467 emit centerInChanged();
470 if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){
471 qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
475 d->remDepend(d->centerIn);
477 d->addDepend(d->centerIn);
478 emit centerInChanged();
479 d->centerInChanged();
482 void QDeclarative1Anchors::resetCenterIn()
487 bool QDeclarative1AnchorsPrivate::calcStretch(const QDeclarative1AnchorLine &edge1,
488 const QDeclarative1AnchorLine &edge2,
491 QDeclarative1AnchorLine::AnchorLine line,
494 bool edge1IsParent = (edge1.item == item->parentItem());
495 bool edge2IsParent = (edge2.item == item->parentItem());
496 bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem());
497 bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem());
499 bool invalid = false;
500 if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
501 stretch = (position(edge2.item, edge2.anchorLine) + offset2)
502 - (position(edge1.item, edge1.anchorLine) + offset1);
503 } else if (edge2IsParent && edge1IsSibling) {
504 stretch = (position(edge2.item, edge2.anchorLine) + offset2)
505 - (position(item->parentObject(), line)
506 + position(edge1.item, edge1.anchorLine) + offset1);
507 } else if (edge2IsSibling && edge1IsParent) {
508 stretch = (position(item->parentObject(), line) + position(edge2.item, edge2.anchorLine) + offset2)
509 - (position(edge1.item, edge1.anchorLine) + offset1);
516 void QDeclarative1AnchorsPrivate::updateVerticalAnchors()
518 if (fill || centerIn || !isItemComplete())
521 if (updatingVerticalAnchor < 2) {
522 ++updatingVerticalAnchor;
523 QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item);
524 if (usedAnchors & QDeclarative1Anchors::TopAnchor) {
528 if (usedAnchors & QDeclarative1Anchors::BottomAnchor) {
529 invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QDeclarative1AnchorLine::Top, height);
530 } else if (usedAnchors & QDeclarative1Anchors::VCenterAnchor) {
531 invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QDeclarative1AnchorLine::Top, height);
535 setItemHeight(height);
538 if (top.item == item->parentItem()) {
539 setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin);
540 } else if (top.item->parentItem() == item->parentItem()) {
541 setItemY(position(top.item, top.anchorLine) + topMargin);
543 } else if (usedAnchors & QDeclarative1Anchors::BottomAnchor) {
544 //Handle stretching (top + bottom case is handled above)
545 if (usedAnchors & QDeclarative1Anchors::VCenterAnchor) {
547 bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
548 QDeclarative1AnchorLine::Top, height);
550 setItemHeight(height*2);
554 if (bottom.item == item->parentItem()) {
555 setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin);
556 } else if (bottom.item->parentItem() == item->parentItem()) {
557 setItemY(position(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin);
559 } else if (usedAnchors & QDeclarative1Anchors::VCenterAnchor) {
560 //(stetching handled above)
563 if (vCenter.item == item->parentItem()) {
564 setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
565 - vcenter(item) + vCenterOffset);
566 } else if (vCenter.item->parentItem() == item->parentItem()) {
567 setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
569 } else if (usedAnchors & QDeclarative1Anchors::BaselineAnchor) {
571 if (baseline.item == item->parentItem()) {
572 if (itemPrivate->isDeclarativeItem)
573 setItemY(adjustedPosition(baseline.item, baseline.anchorLine)
574 - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset);
575 } else if (baseline.item->parentItem() == item->parentItem()) {
576 if (itemPrivate->isDeclarativeItem)
577 setItemY(position(baseline.item, baseline.anchorLine)
578 - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset);
581 --updatingVerticalAnchor;
583 // ### Make this certain :)
584 qmlInfo(item) << QDeclarative1Anchors::tr("Possible anchor loop detected on vertical anchor.");
588 inline QDeclarative1AnchorLine::AnchorLine reverseAnchorLine(QDeclarative1AnchorLine::AnchorLine anchorLine) {
589 if (anchorLine == QDeclarative1AnchorLine::Left) {
590 return QDeclarative1AnchorLine::Right;
591 } else if (anchorLine == QDeclarative1AnchorLine::Right) {
592 return QDeclarative1AnchorLine::Left;
598 void QDeclarative1AnchorsPrivate::updateHorizontalAnchors()
600 Q_Q(QDeclarative1Anchors);
601 if (fill || centerIn || !isItemComplete())
604 if (updatingHorizontalAnchor < 3) {
605 ++updatingHorizontalAnchor;
606 qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
607 QDeclarative1AnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
608 QDeclarative1Anchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
610 effectiveLeftAnchor = QDeclarative1Anchors::RightAnchor;
611 effectiveRightAnchor = QDeclarative1Anchors::LeftAnchor;
612 effectiveLeft.item = right.item;
613 effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine);
614 effectiveRight.item = left.item;
615 effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine);
616 effectiveHorizontalCenter.item = hCenter.item;
617 effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine);
618 effectiveLeftMargin = rightMargin;
619 effectiveRightMargin = leftMargin;
620 effectiveHorizontalCenterOffset = -hCenterOffset;
622 effectiveLeftAnchor = QDeclarative1Anchors::LeftAnchor;
623 effectiveRightAnchor = QDeclarative1Anchors::RightAnchor;
624 effectiveLeft = left;
625 effectiveRight = right;
626 effectiveHorizontalCenter = hCenter;
627 effectiveLeftMargin = leftMargin;
628 effectiveRightMargin = rightMargin;
629 effectiveHorizontalCenterOffset = hCenterOffset;
632 QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item);
633 if (usedAnchors & effectiveLeftAnchor) {
637 if (usedAnchors & effectiveRightAnchor) {
638 invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QDeclarative1AnchorLine::Left, width);
639 } else if (usedAnchors & QDeclarative1Anchors::HCenterAnchor) {
640 invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QDeclarative1AnchorLine::Left, width);
647 if (effectiveLeft.item == item->parentItem()) {
648 setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
649 } else if (effectiveLeft.item->parentItem() == item->parentItem()) {
650 setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
652 } else if (usedAnchors & effectiveRightAnchor) {
653 //Handle stretching (left + right case is handled in updateLeftAnchor)
654 if (usedAnchors & QDeclarative1Anchors::HCenterAnchor) {
656 bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin,
657 QDeclarative1AnchorLine::Left, width);
659 setItemWidth(width*2);
663 if (effectiveRight.item == item->parentItem()) {
664 setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin);
665 } else if (effectiveRight.item->parentItem() == item->parentItem()) {
666 setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin);
668 } else if (usedAnchors & QDeclarative1Anchors::HCenterAnchor) {
670 if (effectiveHorizontalCenter.item == item->parentItem()) {
671 setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
672 } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) {
673 setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
676 --updatingHorizontalAnchor;
678 // ### Make this certain :)
679 qmlInfo(item) << QDeclarative1Anchors::tr("Possible anchor loop detected on horizontal anchor.");
683 QDeclarative1AnchorLine QDeclarative1Anchors::top() const
685 Q_D(const QDeclarative1Anchors);
689 void QDeclarative1Anchors::setTop(const QDeclarative1AnchorLine &edge)
691 Q_D(QDeclarative1Anchors);
692 if (!d->checkVAnchorValid(edge) || d->top == edge)
695 d->usedAnchors |= TopAnchor;
697 if (!d->checkVValid()) {
698 d->usedAnchors &= ~TopAnchor;
702 d->remDepend(d->top.item);
704 d->addDepend(d->top.item);
706 d->updateVerticalAnchors();
709 void QDeclarative1Anchors::resetTop()
711 Q_D(QDeclarative1Anchors);
712 d->usedAnchors &= ~TopAnchor;
713 d->remDepend(d->top.item);
714 d->top = QDeclarative1AnchorLine();
716 d->updateVerticalAnchors();
719 QDeclarative1AnchorLine QDeclarative1Anchors::bottom() const
721 Q_D(const QDeclarative1Anchors);
725 void QDeclarative1Anchors::setBottom(const QDeclarative1AnchorLine &edge)
727 Q_D(QDeclarative1Anchors);
728 if (!d->checkVAnchorValid(edge) || d->bottom == edge)
731 d->usedAnchors |= BottomAnchor;
733 if (!d->checkVValid()) {
734 d->usedAnchors &= ~BottomAnchor;
738 d->remDepend(d->bottom.item);
740 d->addDepend(d->bottom.item);
741 emit bottomChanged();
742 d->updateVerticalAnchors();
745 void QDeclarative1Anchors::resetBottom()
747 Q_D(QDeclarative1Anchors);
748 d->usedAnchors &= ~BottomAnchor;
749 d->remDepend(d->bottom.item);
750 d->bottom = QDeclarative1AnchorLine();
751 emit bottomChanged();
752 d->updateVerticalAnchors();
755 QDeclarative1AnchorLine QDeclarative1Anchors::verticalCenter() const
757 Q_D(const QDeclarative1Anchors);
761 void QDeclarative1Anchors::setVerticalCenter(const QDeclarative1AnchorLine &edge)
763 Q_D(QDeclarative1Anchors);
764 if (!d->checkVAnchorValid(edge) || d->vCenter == edge)
767 d->usedAnchors |= VCenterAnchor;
769 if (!d->checkVValid()) {
770 d->usedAnchors &= ~VCenterAnchor;
774 d->remDepend(d->vCenter.item);
776 d->addDepend(d->vCenter.item);
777 emit verticalCenterChanged();
778 d->updateVerticalAnchors();
781 void QDeclarative1Anchors::resetVerticalCenter()
783 Q_D(QDeclarative1Anchors);
784 d->usedAnchors &= ~VCenterAnchor;
785 d->remDepend(d->vCenter.item);
786 d->vCenter = QDeclarative1AnchorLine();
787 emit verticalCenterChanged();
788 d->updateVerticalAnchors();
791 QDeclarative1AnchorLine QDeclarative1Anchors::baseline() const
793 Q_D(const QDeclarative1Anchors);
797 void QDeclarative1Anchors::setBaseline(const QDeclarative1AnchorLine &edge)
799 Q_D(QDeclarative1Anchors);
800 if (!d->checkVAnchorValid(edge) || d->baseline == edge)
803 d->usedAnchors |= BaselineAnchor;
805 if (!d->checkVValid()) {
806 d->usedAnchors &= ~BaselineAnchor;
810 d->remDepend(d->baseline.item);
812 d->addDepend(d->baseline.item);
813 emit baselineChanged();
814 d->updateVerticalAnchors();
817 void QDeclarative1Anchors::resetBaseline()
819 Q_D(QDeclarative1Anchors);
820 d->usedAnchors &= ~BaselineAnchor;
821 d->remDepend(d->baseline.item);
822 d->baseline = QDeclarative1AnchorLine();
823 emit baselineChanged();
824 d->updateVerticalAnchors();
827 QDeclarative1AnchorLine QDeclarative1Anchors::left() const
829 Q_D(const QDeclarative1Anchors);
833 void QDeclarative1Anchors::setLeft(const QDeclarative1AnchorLine &edge)
835 Q_D(QDeclarative1Anchors);
836 if (!d->checkHAnchorValid(edge) || d->left == edge)
839 d->usedAnchors |= LeftAnchor;
841 if (!d->checkHValid()) {
842 d->usedAnchors &= ~LeftAnchor;
846 d->remDepend(d->left.item);
848 d->addDepend(d->left.item);
850 d->updateHorizontalAnchors();
853 void QDeclarative1Anchors::resetLeft()
855 Q_D(QDeclarative1Anchors);
856 d->usedAnchors &= ~LeftAnchor;
857 d->remDepend(d->left.item);
858 d->left = QDeclarative1AnchorLine();
860 d->updateHorizontalAnchors();
863 QDeclarative1AnchorLine QDeclarative1Anchors::right() const
865 Q_D(const QDeclarative1Anchors);
869 void QDeclarative1Anchors::setRight(const QDeclarative1AnchorLine &edge)
871 Q_D(QDeclarative1Anchors);
872 if (!d->checkHAnchorValid(edge) || d->right == edge)
875 d->usedAnchors |= RightAnchor;
877 if (!d->checkHValid()) {
878 d->usedAnchors &= ~RightAnchor;
882 d->remDepend(d->right.item);
884 d->addDepend(d->right.item);
886 d->updateHorizontalAnchors();
889 void QDeclarative1Anchors::resetRight()
891 Q_D(QDeclarative1Anchors);
892 d->usedAnchors &= ~RightAnchor;
893 d->remDepend(d->right.item);
894 d->right = QDeclarative1AnchorLine();
896 d->updateHorizontalAnchors();
899 QDeclarative1AnchorLine QDeclarative1Anchors::horizontalCenter() const
901 Q_D(const QDeclarative1Anchors);
905 void QDeclarative1Anchors::setHorizontalCenter(const QDeclarative1AnchorLine &edge)
907 Q_D(QDeclarative1Anchors);
908 if (!d->checkHAnchorValid(edge) || d->hCenter == edge)
911 d->usedAnchors |= HCenterAnchor;
913 if (!d->checkHValid()) {
914 d->usedAnchors &= ~HCenterAnchor;
918 d->remDepend(d->hCenter.item);
920 d->addDepend(d->hCenter.item);
921 emit horizontalCenterChanged();
922 d->updateHorizontalAnchors();
925 void QDeclarative1Anchors::resetHorizontalCenter()
927 Q_D(QDeclarative1Anchors);
928 d->usedAnchors &= ~HCenterAnchor;
929 d->remDepend(d->hCenter.item);
930 d->hCenter = QDeclarative1AnchorLine();
931 emit horizontalCenterChanged();
932 d->updateHorizontalAnchors();
935 qreal QDeclarative1Anchors::leftMargin() const
937 Q_D(const QDeclarative1Anchors);
938 return d->leftMargin;
941 void QDeclarative1Anchors::setLeftMargin(qreal offset)
943 Q_D(QDeclarative1Anchors);
944 if (d->leftMargin == offset)
946 d->leftMargin = offset;
950 d->updateHorizontalAnchors();
951 emit leftMarginChanged();
954 qreal QDeclarative1Anchors::rightMargin() const
956 Q_D(const QDeclarative1Anchors);
957 return d->rightMargin;
960 void QDeclarative1Anchors::setRightMargin(qreal offset)
962 Q_D(QDeclarative1Anchors);
963 if (d->rightMargin == offset)
965 d->rightMargin = offset;
969 d->updateHorizontalAnchors();
970 emit rightMarginChanged();
973 qreal QDeclarative1Anchors::margins() const
975 Q_D(const QDeclarative1Anchors);
979 void QDeclarative1Anchors::setMargins(qreal offset)
981 Q_D(QDeclarative1Anchors);
982 if (d->margins == offset)
984 //###Is it significantly faster to set them directly so we can call fillChanged only once?
985 if(!d->rightMargin || d->rightMargin == d->margins)
986 setRightMargin(offset);
987 if(!d->leftMargin || d->leftMargin == d->margins)
988 setLeftMargin(offset);
989 if(!d->topMargin || d->topMargin == d->margins)
990 setTopMargin(offset);
991 if(!d->bottomMargin || d->bottomMargin == d->margins)
992 setBottomMargin(offset);
994 emit marginsChanged();
998 qreal QDeclarative1Anchors::horizontalCenterOffset() const
1000 Q_D(const QDeclarative1Anchors);
1001 return d->hCenterOffset;
1004 void QDeclarative1Anchors::setHorizontalCenterOffset(qreal offset)
1006 Q_D(QDeclarative1Anchors);
1007 if (d->hCenterOffset == offset)
1009 d->hCenterOffset = offset;
1011 d->centerInChanged();
1013 d->updateHorizontalAnchors();
1014 emit horizontalCenterOffsetChanged();
1017 qreal QDeclarative1Anchors::topMargin() const
1019 Q_D(const QDeclarative1Anchors);
1020 return d->topMargin;
1023 void QDeclarative1Anchors::setTopMargin(qreal offset)
1025 Q_D(QDeclarative1Anchors);
1026 if (d->topMargin == offset)
1028 d->topMargin = offset;
1032 d->updateVerticalAnchors();
1033 emit topMarginChanged();
1036 qreal QDeclarative1Anchors::bottomMargin() const
1038 Q_D(const QDeclarative1Anchors);
1039 return d->bottomMargin;
1042 void QDeclarative1Anchors::setBottomMargin(qreal offset)
1044 Q_D(QDeclarative1Anchors);
1045 if (d->bottomMargin == offset)
1047 d->bottomMargin = offset;
1051 d->updateVerticalAnchors();
1052 emit bottomMarginChanged();
1055 qreal QDeclarative1Anchors::verticalCenterOffset() const
1057 Q_D(const QDeclarative1Anchors);
1058 return d->vCenterOffset;
1061 void QDeclarative1Anchors::setVerticalCenterOffset(qreal offset)
1063 Q_D(QDeclarative1Anchors);
1064 if (d->vCenterOffset == offset)
1066 d->vCenterOffset = offset;
1068 d->centerInChanged();
1070 d->updateVerticalAnchors();
1071 emit verticalCenterOffsetChanged();
1074 qreal QDeclarative1Anchors::baselineOffset() const
1076 Q_D(const QDeclarative1Anchors);
1077 return d->baselineOffset;
1080 void QDeclarative1Anchors::setBaselineOffset(qreal offset)
1082 Q_D(QDeclarative1Anchors);
1083 if (d->baselineOffset == offset)
1085 d->baselineOffset = offset;
1086 d->updateVerticalAnchors();
1087 emit baselineOffsetChanged();
1090 QDeclarative1Anchors::Anchors QDeclarative1Anchors::usedAnchors() const
1092 Q_D(const QDeclarative1Anchors);
1093 return d->usedAnchors;
1096 bool QDeclarative1AnchorsPrivate::checkHValid() const
1098 if (usedAnchors & QDeclarative1Anchors::LeftAnchor &&
1099 usedAnchors & QDeclarative1Anchors::RightAnchor &&
1100 usedAnchors & QDeclarative1Anchors::HCenterAnchor) {
1101 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot specify left, right, and hcenter anchors.");
1108 bool QDeclarative1AnchorsPrivate::checkHAnchorValid(QDeclarative1AnchorLine anchor) const
1111 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor to a null item.");
1113 } else if (anchor.anchorLine & QDeclarative1AnchorLine::Vertical_Mask) {
1114 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
1116 } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
1117 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1119 } else if (anchor.item == item) {
1120 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor item to self.");
1127 bool QDeclarative1AnchorsPrivate::checkVValid() const
1129 if (usedAnchors & QDeclarative1Anchors::TopAnchor &&
1130 usedAnchors & QDeclarative1Anchors::BottomAnchor &&
1131 usedAnchors & QDeclarative1Anchors::VCenterAnchor) {
1132 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot specify top, bottom, and vcenter anchors.");
1134 } else if (usedAnchors & QDeclarative1Anchors::BaselineAnchor &&
1135 (usedAnchors & QDeclarative1Anchors::TopAnchor ||
1136 usedAnchors & QDeclarative1Anchors::BottomAnchor ||
1137 usedAnchors & QDeclarative1Anchors::VCenterAnchor)) {
1138 qmlInfo(item) << QDeclarative1Anchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.");
1145 bool QDeclarative1AnchorsPrivate::checkVAnchorValid(QDeclarative1AnchorLine anchor) const
1148 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor to a null item.");
1150 } else if (anchor.anchorLine & QDeclarative1AnchorLine::Horizontal_Mask) {
1151 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
1153 } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
1154 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
1156 } else if (anchor.item == item){
1157 qmlInfo(item) << QDeclarative1Anchors::tr("Cannot anchor item to self.");
1168 #include <moc_qdeclarativeanchors_p.cpp>