• Qt by Nokia's avatar
    Initial import from the monolithic Qt. · 50123887
    Qt by Nokia authored
    This is the beginning of revision history for this module. If you
    want to look at revision history older than this, please refer to the
    Qt Git wiki for how to use Git history grafting. At the time of
    writing, this wiki is located here:
    
    http://qt.gitorious.org/qt/pages/GitIntroductionWithQt
    
    If you have already performed the grafting and you don't see any
    history beyond this commit, try running "git log" with the "--follow"
    argument.
    
    Branched from the monolithic repo, Qt master branch, at commit
    896db169ea224deb96c59ce8af800d019de63f12
    50123887
qquickanchors.cpp 35.29 KiB
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
** $QT_END_LICENSE$
****************************************************************************/
#include "qquickanchors_p_p.h"
#include "qquickitem.h"
#include "qquickitem_p.h"
#include <qqmlinfo.h>
QT_BEGIN_NAMESPACE
//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
//TODO: support non-parent, non-sibling (need to find lowest common ancestor)
static inline qreal hcenter(QQuickItem *item)
    qreal width = item->width();
    if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
        if (!QQuickAnchorsPrivate::get(anchors)->centerAligned)
            return width / 2;
    int iw = width;
    if (iw % 2)
        return (width + 1) / 2;
    else
        return width / 2;
static inline qreal vcenter(QQuickItem *item)
    qreal height = item->height();
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) { if (!QQuickAnchorsPrivate::get(anchors)->centerAligned) return height / 2; } int ih = height; if (ih % 2) return (height + 1) / 2; else return height / 2; } //### const item? //local position static qreal position(QQuickItem *item, QQuickAnchorLine::AnchorLine anchorLine) { qreal ret = 0.0; switch (anchorLine) { case QQuickAnchorLine::Left: ret = item->x(); break; case QQuickAnchorLine::Right: ret = item->x() + item->width(); break; case QQuickAnchorLine::Top: ret = item->y(); break; case QQuickAnchorLine::Bottom: ret = item->y() + item->height(); break; case QQuickAnchorLine::HCenter: ret = item->x() + hcenter(item); break; case QQuickAnchorLine::VCenter: ret = item->y() + vcenter(item); break; case QQuickAnchorLine::Baseline: ret = item->y() + item->baselineOffset(); break; default: break; } return ret; } //position when origin is 0,0 static qreal adjustedPosition(QQuickItem *item, QQuickAnchorLine::AnchorLine anchorLine) { qreal ret = 0.0; switch (anchorLine) { case QQuickAnchorLine::Left: ret = 0.0; break; case QQuickAnchorLine::Right: ret = item->width(); break; case QQuickAnchorLine::Top: ret = 0.0; break; case QQuickAnchorLine::Bottom: ret = item->height(); break; case QQuickAnchorLine::HCenter: ret = hcenter(item); break; case QQuickAnchorLine::VCenter: ret = vcenter(item); break; case QQuickAnchorLine::Baseline: ret = item->baselineOffset();
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
break; default: break; } return ret; } QQuickAnchors::QQuickAnchors(QQuickItem *item, QObject *parent) : QObject(*new QQuickAnchorsPrivate(item), parent) { } QQuickAnchors::~QQuickAnchors() { Q_D(QQuickAnchors); d->inDestructor = true; d->remDepend(d->fill); d->remDepend(d->centerIn); d->remDepend(d->left.item); d->remDepend(d->right.item); d->remDepend(d->top.item); d->remDepend(d->bottom.item); d->remDepend(d->vCenter.item); d->remDepend(d->hCenter.item); d->remDepend(d->baseline.item); } void QQuickAnchorsPrivate::fillChanged() { Q_Q(QQuickAnchors); if (!fill || !isItemComplete()) return; if (updatingFill < 2) { ++updatingFill; qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin; if (fill == item->parentItem()) { //child-parent setItemPos(QPointF(horizontalMargin, topMargin)); } else if (fill->parentItem() == item->parentItem()) { //siblings setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin)); } setItemSize(QSizeF(fill->width()-leftMargin-rightMargin, fill->height()-topMargin-bottomMargin)); --updatingFill; } else { // ### Make this certain :) qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on fill."); } } void QQuickAnchorsPrivate::centerInChanged() { Q_Q(QQuickAnchors); if (!centerIn || fill || !isItemComplete()) return; if (updatingCenterIn < 2) { ++updatingCenterIn; qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset; if (centerIn == item->parentItem()) { QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset, vcenter(item->parentItem()) - vcenter(item) + vCenterOffset); setItemPos(p); } else if (centerIn->parentItem() == item->parentItem()) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset, centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset); setItemPos(p); } --updatingCenterIn; } else { // ### Make this certain :) qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn."); } } void QQuickAnchorsPrivate::clearItem(QQuickItem *item) { if (!item) return; if (fill == item) fill = 0; if (centerIn == item) centerIn = 0; if (left.item == item) { left.item = 0; usedAnchors &= ~QQuickAnchors::LeftAnchor; } if (right.item == item) { right.item = 0; usedAnchors &= ~QQuickAnchors::RightAnchor; } if (top.item == item) { top.item = 0; usedAnchors &= ~QQuickAnchors::TopAnchor; } if (bottom.item == item) { bottom.item = 0; usedAnchors &= ~QQuickAnchors::BottomAnchor; } if (vCenter.item == item) { vCenter.item = 0; usedAnchors &= ~QQuickAnchors::VCenterAnchor; } if (hCenter.item == item) { hCenter.item = 0; usedAnchors &= ~QQuickAnchors::HCenterAnchor; } if (baseline.item == item) { baseline.item = 0; usedAnchors &= ~QQuickAnchors::BaselineAnchor; } } int QQuickAnchorsPrivate::calculateDependency(QQuickItem *controlItem) { QQuickItemPrivate::GeometryChangeTypes dependency = QQuickItemPrivate::NoChange; if (!controlItem || inDestructor) return dependency; if (fill == controlItem) { if (controlItem == item->parentItem()) dependency |= QQuickItemPrivate::SizeChange; else //sibling dependency |= QQuickItemPrivate::GeometryChange; return dependency; //exit early } if (centerIn == controlItem) { if (controlItem == item->parentItem()) dependency |= QQuickItemPrivate::SizeChange; else //sibling dependency |= QQuickItemPrivate::GeometryChange;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
return dependency; //exit early } if ((usedAnchors & QQuickAnchors::LeftAnchor && left.item == controlItem) || (usedAnchors & QQuickAnchors::RightAnchor && right.item == controlItem) || (usedAnchors & QQuickAnchors::HCenterAnchor && hCenter.item == controlItem)) { if (controlItem == item->parentItem()) dependency |= QQuickItemPrivate::WidthChange; else //sibling dependency |= QFlags<QQuickItemPrivate::GeometryChangeType>(QQuickItemPrivate::XChange | QQuickItemPrivate::WidthChange); } if ((usedAnchors & QQuickAnchors::TopAnchor && top.item == controlItem) || (usedAnchors & QQuickAnchors::BottomAnchor && bottom.item == controlItem) || (usedAnchors & QQuickAnchors::VCenterAnchor && vCenter.item == controlItem) || (usedAnchors & QQuickAnchors::BaselineAnchor && baseline.item == controlItem)) { if (controlItem == item->parentItem()) dependency |= QQuickItemPrivate::HeightChange; else //sibling dependency |= QFlags<QQuickItemPrivate::GeometryChangeType>(QQuickItemPrivate::YChange | QQuickItemPrivate::HeightChange); } return dependency; } void QQuickAnchorsPrivate::addDepend(QQuickItem *item) { if (!item || !componentComplete) return; QQuickItemPrivate *p = QQuickItemPrivate::get(item); p->updateOrAddGeometryChangeListener(this, QFlags<QQuickItemPrivate::GeometryChangeType>(calculateDependency(item))); } void QQuickAnchorsPrivate::remDepend(QQuickItem *item) { if (!item || !componentComplete) return; QQuickItemPrivate *p = QQuickItemPrivate::get(item); p->updateOrRemoveGeometryChangeListener(this, QFlags<QQuickItemPrivate::GeometryChangeType>(calculateDependency(item))); } bool QQuickAnchors::mirrored() { Q_D(QQuickAnchors); return QQuickItemPrivate::get(d->item)->effectiveLayoutMirror; } bool QQuickAnchors::alignWhenCentered() const { Q_D(const QQuickAnchors); return d->centerAligned; } void QQuickAnchors::setAlignWhenCentered(bool aligned) { Q_D(QQuickAnchors); if (aligned == d->centerAligned) return; d->centerAligned = aligned; emit centerAlignedChanged(); if (d->centerIn) { d->centerInChanged(); } else { if (d->usedAnchors & QQuickAnchors::VCenterAnchor) d->updateVerticalAnchors(); else if (d->usedAnchors & QQuickAnchors::HCenterAnchor) d->updateHorizontalAnchors(); }
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
} bool QQuickAnchorsPrivate::isItemComplete() const { return componentComplete; } void QQuickAnchors::classBegin() { Q_D(QQuickAnchors); d->componentComplete = false; } void QQuickAnchors::componentComplete() { Q_D(QQuickAnchors); d->componentComplete = true; } void QQuickAnchorsPrivate::setItemHeight(qreal v) { updatingMe = true; item->setHeight(v); updatingMe = false; } void QQuickAnchorsPrivate::setItemWidth(qreal v) { updatingMe = true; item->setWidth(v); updatingMe = false; } void QQuickAnchorsPrivate::setItemX(qreal v) { updatingMe = true; item->setX(v); updatingMe = false; } void QQuickAnchorsPrivate::setItemY(qreal v) { updatingMe = true; item->setY(v); updatingMe = false; } void QQuickAnchorsPrivate::setItemPos(const QPointF &v) { updatingMe = true; item->setPos(v); updatingMe = false; } void QQuickAnchorsPrivate::setItemSize(const QSizeF &v) { updatingMe = true; item->setSize(v); updatingMe = false; } void QQuickAnchorsPrivate::updateMe() { if (updatingMe) { updatingMe = false; return; } update(); }
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
void QQuickAnchorsPrivate::updateOnComplete() { //optimization to only set initial dependencies once, at completion time QSet<QQuickItem *> dependencies; dependencies << fill << centerIn << left.item << right.item << hCenter.item << top.item << bottom.item << vCenter.item << baseline.item; foreach (QQuickItem *dependency, dependencies) addDepend(dependency); update(); } void QQuickAnchorsPrivate::update() { fillChanged(); centerInChanged(); if (usedAnchors & QQuickAnchorLine::Horizontal_Mask) updateHorizontalAnchors(); if (usedAnchors & QQuickAnchorLine::Vertical_Mask) updateVerticalAnchors(); } void QQuickAnchorsPrivate::itemGeometryChanged(QQuickItem *, const QRectF &newG, const QRectF &oldG) { fillChanged(); centerInChanged(); if ((usedAnchors & QQuickAnchorLine::Horizontal_Mask) && (newG.x() != oldG.x() || newG.width() != oldG.width())) updateHorizontalAnchors(); if ((usedAnchors & QQuickAnchorLine::Vertical_Mask) && (newG.y() != oldG.y() || newG.height() != oldG.height())) updateVerticalAnchors(); } QQuickItem *QQuickAnchors::fill() const { Q_D(const QQuickAnchors); return d->fill; } void QQuickAnchors::setFill(QQuickItem *f) { Q_D(QQuickAnchors); if (d->fill == f) return; if (!f) { QQuickItem *oldFill = d->fill; d->fill = f; d->remDepend(oldFill); emit fillChanged(); return; } if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){ qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling."); return; } QQuickItem *oldFill = d->fill; d->fill = f; d->remDepend(oldFill); d->addDepend(d->fill); emit fillChanged(); d->fillChanged(); } void QQuickAnchors::resetFill() { setFill(0);
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
} QQuickItem *QQuickAnchors::centerIn() const { Q_D(const QQuickAnchors); return d->centerIn; } void QQuickAnchors::setCenterIn(QQuickItem* c) { Q_D(QQuickAnchors); if (d->centerIn == c) return; if (!c) { QQuickItem *oldCI = d->centerIn; d->centerIn = c; d->remDepend(oldCI); emit centerInChanged(); return; } if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){ qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling."); return; } QQuickItem *oldCI = d->centerIn; d->centerIn = c; d->remDepend(oldCI); d->addDepend(d->centerIn); emit centerInChanged(); d->centerInChanged(); } void QQuickAnchors::resetCenterIn() { setCenterIn(0); } bool QQuickAnchorsPrivate::calcStretch(const QQuickAnchorLine &edge1, const QQuickAnchorLine &edge2, qreal offset1, qreal offset2, QQuickAnchorLine::AnchorLine line, qreal &stretch) { bool edge1IsParent = (edge1.item == item->parentItem()); bool edge2IsParent = (edge2.item == item->parentItem()); bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem()); bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem()); bool invalid = false; if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) { stretch = (position(edge2.item, edge2.anchorLine) + offset2) - (position(edge1.item, edge1.anchorLine) + offset1); } else if (edge2IsParent && edge1IsSibling) { stretch = (position(edge2.item, edge2.anchorLine) + offset2) - (position(item->parentItem(), line) + position(edge1.item, edge1.anchorLine) + offset1); } else if (edge2IsSibling && edge1IsParent) { stretch = (position(item->parentItem(), line) + position(edge2.item, edge2.anchorLine) + offset2) - (position(edge1.item, edge1.anchorLine) + offset1); } else invalid = true; return invalid; } void QQuickAnchorsPrivate::updateVerticalAnchors() { if (fill || centerIn || !isItemComplete())
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
return; if (updatingVerticalAnchor < 2) { ++updatingVerticalAnchor; if (usedAnchors & QQuickAnchors::TopAnchor) { //Handle stretching bool invalid = true; qreal height = 0.0; if (usedAnchors & QQuickAnchors::BottomAnchor) { invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QQuickAnchorLine::Top, height); } else if (usedAnchors & QQuickAnchors::VCenterAnchor) { invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QQuickAnchorLine::Top, height); height *= 2; } if (!invalid) setItemHeight(height); //Handle top if (top.item == item->parentItem()) { setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin); } else if (top.item->parentItem() == item->parentItem()) { setItemY(position(top.item, top.anchorLine) + topMargin); } } else if (usedAnchors & QQuickAnchors::BottomAnchor) { //Handle stretching (top + bottom case is handled above) if (usedAnchors & QQuickAnchors::VCenterAnchor) { qreal height = 0.0; bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin, QQuickAnchorLine::Top, height); if (!invalid) setItemHeight(height*2); } //Handle bottom if (bottom.item == item->parentItem()) { setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - item->height() - bottomMargin); } else if (bottom.item->parentItem() == item->parentItem()) { setItemY(position(bottom.item, bottom.anchorLine) - item->height() - bottomMargin); } } else if (usedAnchors & QQuickAnchors::VCenterAnchor) { //(stetching handled above) //Handle vCenter if (vCenter.item == item->parentItem()) { setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset); } else if (vCenter.item->parentItem() == item->parentItem()) { setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset); } } else if (usedAnchors & QQuickAnchors::BaselineAnchor) { //Handle baseline if (baseline.item == item->parentItem()) { setItemY(adjustedPosition(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset); } else if (baseline.item->parentItem() == item->parentItem()) { setItemY(position(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset); } } --updatingVerticalAnchor; } else { // ### Make this certain :) qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor."); } } inline QQuickAnchorLine::AnchorLine reverseAnchorLine(QQuickAnchorLine::AnchorLine anchorLine) { if (anchorLine == QQuickAnchorLine::Left) { return QQuickAnchorLine::Right; } else if (anchorLine == QQuickAnchorLine::Right) { return QQuickAnchorLine::Left;
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
} else { return anchorLine; } } void QQuickAnchorsPrivate::updateHorizontalAnchors() { Q_Q(QQuickAnchors); if (fill || centerIn || !isItemComplete()) return; if (updatingHorizontalAnchor < 3) { ++updatingHorizontalAnchor; qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset; QQuickAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter; QQuickAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor; if (q->mirrored()) { effectiveLeftAnchor = QQuickAnchors::RightAnchor; effectiveRightAnchor = QQuickAnchors::LeftAnchor; effectiveLeft.item = right.item; effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine); effectiveRight.item = left.item; effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine); effectiveHorizontalCenter.item = hCenter.item; effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine); effectiveLeftMargin = rightMargin; effectiveRightMargin = leftMargin; effectiveHorizontalCenterOffset = -hCenterOffset; } else { effectiveLeftAnchor = QQuickAnchors::LeftAnchor; effectiveRightAnchor = QQuickAnchors::RightAnchor; effectiveLeft = left; effectiveRight = right; effectiveHorizontalCenter = hCenter; effectiveLeftMargin = leftMargin; effectiveRightMargin = rightMargin; effectiveHorizontalCenterOffset = hCenterOffset; } if (usedAnchors & effectiveLeftAnchor) { //Handle stretching bool invalid = true; qreal width = 0.0; if (usedAnchors & effectiveRightAnchor) { invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QQuickAnchorLine::Left, width); } else if (usedAnchors & QQuickAnchors::HCenterAnchor) { invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QQuickAnchorLine::Left, width); width *= 2; } if (!invalid) setItemWidth(width); //Handle left if (effectiveLeft.item == item->parentItem()) { setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin); } else if (effectiveLeft.item->parentItem() == item->parentItem()) { setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin); } } else if (usedAnchors & effectiveRightAnchor) { //Handle stretching (left + right case is handled in updateLeftAnchor) if (usedAnchors & QQuickAnchors::HCenterAnchor) { qreal width = 0.0; bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin, QQuickAnchorLine::Left, width); if (!invalid) setItemWidth(width*2); } //Handle right if (effectiveRight.item == item->parentItem()) {
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin); } else if (effectiveRight.item->parentItem() == item->parentItem()) { setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin); } } else if (usedAnchors & QQuickAnchors::HCenterAnchor) { //Handle hCenter if (effectiveHorizontalCenter.item == item->parentItem()) { setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset); } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) { setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset); } } --updatingHorizontalAnchor; } else { // ### Make this certain :) qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor."); } } QQuickAnchorLine QQuickAnchors::top() const { Q_D(const QQuickAnchors); return d->top; } void QQuickAnchors::setTop(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkVAnchorValid(edge) || d->top == edge) return; d->usedAnchors |= TopAnchor; if (!d->checkVValid()) { d->usedAnchors &= ~TopAnchor; return; } QQuickItem *oldTop = d->top.item; d->top = edge; d->remDepend(oldTop); d->addDepend(d->top.item); emit topChanged(); d->updateVerticalAnchors(); } void QQuickAnchors::resetTop() { Q_D(QQuickAnchors); d->usedAnchors &= ~TopAnchor; d->remDepend(d->top.item); d->top = QQuickAnchorLine(); emit topChanged(); d->updateVerticalAnchors(); } QQuickAnchorLine QQuickAnchors::bottom() const { Q_D(const QQuickAnchors); return d->bottom; } void QQuickAnchors::setBottom(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkVAnchorValid(edge) || d->bottom == edge) return; d->usedAnchors |= BottomAnchor;
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
if (!d->checkVValid()) { d->usedAnchors &= ~BottomAnchor; return; } QQuickItem *oldBottom = d->bottom.item; d->bottom = edge; d->remDepend(oldBottom); d->addDepend(d->bottom.item); emit bottomChanged(); d->updateVerticalAnchors(); } void QQuickAnchors::resetBottom() { Q_D(QQuickAnchors); d->usedAnchors &= ~BottomAnchor; d->remDepend(d->bottom.item); d->bottom = QQuickAnchorLine(); emit bottomChanged(); d->updateVerticalAnchors(); } QQuickAnchorLine QQuickAnchors::verticalCenter() const { Q_D(const QQuickAnchors); return d->vCenter; } void QQuickAnchors::setVerticalCenter(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkVAnchorValid(edge) || d->vCenter == edge) return; d->usedAnchors |= VCenterAnchor; if (!d->checkVValid()) { d->usedAnchors &= ~VCenterAnchor; return; } QQuickItem *oldVCenter = d->vCenter.item; d->vCenter = edge; d->remDepend(oldVCenter); d->addDepend(d->vCenter.item); emit verticalCenterChanged(); d->updateVerticalAnchors(); } void QQuickAnchors::resetVerticalCenter() { Q_D(QQuickAnchors); d->usedAnchors &= ~VCenterAnchor; d->remDepend(d->vCenter.item); d->vCenter = QQuickAnchorLine(); emit verticalCenterChanged(); d->updateVerticalAnchors(); } QQuickAnchorLine QQuickAnchors::baseline() const { Q_D(const QQuickAnchors); return d->baseline; } void QQuickAnchors::setBaseline(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkVAnchorValid(edge) || d->baseline == edge)
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
return; d->usedAnchors |= BaselineAnchor; if (!d->checkVValid()) { d->usedAnchors &= ~BaselineAnchor; return; } QQuickItem *oldBaseline = d->baseline.item; d->baseline = edge; d->remDepend(oldBaseline); d->addDepend(d->baseline.item); emit baselineChanged(); d->updateVerticalAnchors(); } void QQuickAnchors::resetBaseline() { Q_D(QQuickAnchors); d->usedAnchors &= ~BaselineAnchor; d->remDepend(d->baseline.item); d->baseline = QQuickAnchorLine(); emit baselineChanged(); d->updateVerticalAnchors(); } QQuickAnchorLine QQuickAnchors::left() const { Q_D(const QQuickAnchors); return d->left; } void QQuickAnchors::setLeft(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkHAnchorValid(edge) || d->left == edge) return; d->usedAnchors |= LeftAnchor; if (!d->checkHValid()) { d->usedAnchors &= ~LeftAnchor; return; } QQuickItem *oldLeft = d->left.item; d->left = edge; d->remDepend(oldLeft); d->addDepend(d->left.item); emit leftChanged(); d->updateHorizontalAnchors(); } void QQuickAnchors::resetLeft() { Q_D(QQuickAnchors); d->usedAnchors &= ~LeftAnchor; d->remDepend(d->left.item); d->left = QQuickAnchorLine(); emit leftChanged(); d->updateHorizontalAnchors(); } QQuickAnchorLine QQuickAnchors::right() const { Q_D(const QQuickAnchors); return d->right; }
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
void QQuickAnchors::setRight(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkHAnchorValid(edge) || d->right == edge) return; d->usedAnchors |= RightAnchor; if (!d->checkHValid()) { d->usedAnchors &= ~RightAnchor; return; } QQuickItem *oldRight = d->right.item; d->right = edge; d->remDepend(oldRight); d->addDepend(d->right.item); emit rightChanged(); d->updateHorizontalAnchors(); } void QQuickAnchors::resetRight() { Q_D(QQuickAnchors); d->usedAnchors &= ~RightAnchor; d->remDepend(d->right.item); d->right = QQuickAnchorLine(); emit rightChanged(); d->updateHorizontalAnchors(); } QQuickAnchorLine QQuickAnchors::horizontalCenter() const { Q_D(const QQuickAnchors); return d->hCenter; } void QQuickAnchors::setHorizontalCenter(const QQuickAnchorLine &edge) { Q_D(QQuickAnchors); if (!d->checkHAnchorValid(edge) || d->hCenter == edge) return; d->usedAnchors |= HCenterAnchor; if (!d->checkHValid()) { d->usedAnchors &= ~HCenterAnchor; return; } QQuickItem *oldHCenter = d->hCenter.item; d->hCenter = edge; d->remDepend(oldHCenter); d->addDepend(d->hCenter.item); emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } void QQuickAnchors::resetHorizontalCenter() { Q_D(QQuickAnchors); d->usedAnchors &= ~HCenterAnchor; d->remDepend(d->hCenter.item); d->hCenter = QQuickAnchorLine(); emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } qreal QQuickAnchors::leftMargin() const {
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
Q_D(const QQuickAnchors); return d->leftMargin; } void QQuickAnchors::setLeftMargin(qreal offset) { Q_D(QQuickAnchors); if (d->leftMargin == offset) return; d->leftMargin = offset; if (d->fill) d->fillChanged(); else d->updateHorizontalAnchors(); emit leftMarginChanged(); } qreal QQuickAnchors::rightMargin() const { Q_D(const QQuickAnchors); return d->rightMargin; } void QQuickAnchors::setRightMargin(qreal offset) { Q_D(QQuickAnchors); if (d->rightMargin == offset) return; d->rightMargin = offset; if (d->fill) d->fillChanged(); else d->updateHorizontalAnchors(); emit rightMarginChanged(); } qreal QQuickAnchors::margins() const { Q_D(const QQuickAnchors); return d->margins; } void QQuickAnchors::setMargins(qreal offset) { Q_D(QQuickAnchors); if (d->margins == offset) return; //###Is it significantly faster to set them directly so we can call fillChanged only once? if (!d->rightMargin || d->rightMargin == d->margins) setRightMargin(offset); if (!d->leftMargin || d->leftMargin == d->margins) setLeftMargin(offset); if (!d->topMargin || d->topMargin == d->margins) setTopMargin(offset); if (!d->bottomMargin || d->bottomMargin == d->margins) setBottomMargin(offset); d->margins = offset; emit marginsChanged(); } qreal QQuickAnchors::horizontalCenterOffset() const { Q_D(const QQuickAnchors); return d->hCenterOffset; } void QQuickAnchors::setHorizontalCenterOffset(qreal offset) { Q_D(QQuickAnchors);
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
if (d->hCenterOffset == offset) return; d->hCenterOffset = offset; if (d->centerIn) d->centerInChanged(); else d->updateHorizontalAnchors(); emit horizontalCenterOffsetChanged(); } qreal QQuickAnchors::topMargin() const { Q_D(const QQuickAnchors); return d->topMargin; } void QQuickAnchors::setTopMargin(qreal offset) { Q_D(QQuickAnchors); if (d->topMargin == offset) return; d->topMargin = offset; if (d->fill) d->fillChanged(); else d->updateVerticalAnchors(); emit topMarginChanged(); } qreal QQuickAnchors::bottomMargin() const { Q_D(const QQuickAnchors); return d->bottomMargin; } void QQuickAnchors::setBottomMargin(qreal offset) { Q_D(QQuickAnchors); if (d->bottomMargin == offset) return; d->bottomMargin = offset; if (d->fill) d->fillChanged(); else d->updateVerticalAnchors(); emit bottomMarginChanged(); } qreal QQuickAnchors::verticalCenterOffset() const { Q_D(const QQuickAnchors); return d->vCenterOffset; } void QQuickAnchors::setVerticalCenterOffset(qreal offset) { Q_D(QQuickAnchors); if (d->vCenterOffset == offset) return; d->vCenterOffset = offset; if (d->centerIn) d->centerInChanged(); else d->updateVerticalAnchors(); emit verticalCenterOffsetChanged(); } qreal QQuickAnchors::baselineOffset() const { Q_D(const QQuickAnchors);
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
return d->baselineOffset; } void QQuickAnchors::setBaselineOffset(qreal offset) { Q_D(QQuickAnchors); if (d->baselineOffset == offset) return; d->baselineOffset = offset; d->updateVerticalAnchors(); emit baselineOffsetChanged(); } QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const { Q_D(const QQuickAnchors); return d->usedAnchors; } bool QQuickAnchorsPrivate::checkHValid() const { if (usedAnchors & QQuickAnchors::LeftAnchor && usedAnchors & QQuickAnchors::RightAnchor && usedAnchors & QQuickAnchors::HCenterAnchor) { qmlInfo(item) << QQuickAnchors::tr("Cannot specify left, right, and hcenter anchors."); return false; } return true; } bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const { if (!anchor.item) { qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item."); return false; } else if (anchor.anchorLine & QQuickAnchorLine::Vertical_Mask) { qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge."); return false; } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){ qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling."); return false; } else if (anchor.item == item) { qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self."); return false; } return true; } bool QQuickAnchorsPrivate::checkVValid() const { if (usedAnchors & QQuickAnchors::TopAnchor && usedAnchors & QQuickAnchors::BottomAnchor && usedAnchors & QQuickAnchors::VCenterAnchor) { qmlInfo(item) << QQuickAnchors::tr("Cannot specify top, bottom, and vcenter anchors."); return false; } else if (usedAnchors & QQuickAnchors::BaselineAnchor && (usedAnchors & QQuickAnchors::TopAnchor || usedAnchors & QQuickAnchors::BottomAnchor || usedAnchors & QQuickAnchors::VCenterAnchor)) { qmlInfo(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors."); return false; } return true; } bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const {
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
if (!anchor.item) { qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item."); return false; } else if (anchor.anchorLine & QQuickAnchorLine::Horizontal_Mask) { qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge."); return false; } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){ qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling."); return false; } else if (anchor.item == item){ qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self."); return false; } return true; } QT_END_NAMESPACE #include <moc_qquickanchors_p.cpp>