An error occurred while loading the file. Please try again.
-
Gunnar Sletta authored
These include guards stem from the olden days before the QSG prefix and many of them are conflict prone, which can lead to pretty bisarrer errors for the user. Change-Id: I0e76c68a588404b6e82be9ecc2e7afa3b9a48e78 Reviewed-by:
Samuel Rødal <samuel.rodal@digia.com>
c324edd5
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $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();
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
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
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();
break;
default:
break;
}
return ret;
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
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()) {
QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
setItemPos(p);
}
--updatingCenterIn;
} else {
// ### Make this certain :)
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
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;
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;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
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();
}
}
bool QQuickAnchorsPrivate::isItemComplete() const
{
return componentComplete;
}
void QQuickAnchors::classBegin()
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
{
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->setPosition(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();
}
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;
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
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);
}
QQuickItem *QQuickAnchors::centerIn() const
{
Q_D(const QQuickAnchors);
return d->centerIn;
}
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
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())
return;
if (updatingVerticalAnchor < 2) {
++updatingVerticalAnchor;
if (usedAnchors & QQuickAnchors::TopAnchor) {
//Handle stretching
bool invalid = true;
qreal height = 0.0;
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
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;
} else {
return anchorLine;
}
}
void QQuickAnchorsPrivate::updateHorizontalAnchors()
{
Q_Q(QQuickAnchors);
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
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()) {
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);
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
} 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;
if (!d->checkVValid()) {
d->usedAnchors &= ~BottomAnchor;
return;
}
QQuickItem *oldBottom = d->bottom.item;
d->bottom = edge;
d->remDepend(oldBottom);
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
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)
return;
d->usedAnchors |= BaselineAnchor;
if (!d->checkVValid()) {
d->usedAnchors &= ~BaselineAnchor;
return;
}
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
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;
}
void QQuickAnchors::setRight(const QQuickAnchorLine &edge)
{
Q_D(QQuickAnchors);
if (!d->checkHAnchorValid(edge) || d->right == edge)
return;
d->usedAnchors |= RightAnchor;
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
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
{
Q_D(const QQuickAnchors);
return d->leftMargin;
}
void QQuickAnchors::setLeftMargin(qreal offset)
{
Q_D(QQuickAnchors);
d->leftMarginExplicit = true;
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
if (d->leftMargin == offset)
return;
d->leftMargin = offset;
if (d->fill)
d->fillChanged();
else
d->updateHorizontalAnchors();
emit leftMarginChanged();
}
void QQuickAnchors::resetLeftMargin()
{
Q_D(QQuickAnchors);
d->leftMarginExplicit = false;
if (d->leftMargin == d->margins)
return;
d->leftMargin = d->margins;
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);
d->rightMarginExplicit = true;
if (d->rightMargin == offset)
return;
d->rightMargin = offset;
if (d->fill)
d->fillChanged();
else
d->updateHorizontalAnchors();
emit rightMarginChanged();
}
void QQuickAnchors::resetRightMargin()
{
Q_D(QQuickAnchors);
d->rightMarginExplicit = false;
if (d->rightMargin == d->margins)
return;
d->rightMargin = d->margins;
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;
d->margins = offset;
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
bool updateHorizontal = false;
bool updateVertical = false;
if (!d->rightMarginExplicit && d->rightMargin != offset) {
d->rightMargin = offset;
updateHorizontal = true;
emit rightMarginChanged();
}
if (!d->leftMarginExplicit && d->leftMargin != offset) {
d->leftMargin = offset;
updateHorizontal = true;
emit leftMarginChanged();
}
if (!d->topMarginExplicit && d->topMargin != offset) {
d->topMargin = offset;
updateVertical = true;
emit topMarginChanged();
}
if (!d->bottomMarginExplicit && d->bottomMargin != offset) {
d->bottomMargin = offset;
updateVertical = true;
emit bottomMarginChanged();
}
if (d->fill) {
if (updateHorizontal || updateVertical)
d->fillChanged();
} else {
if (updateHorizontal)
d->updateHorizontalAnchors();
if (updateVertical)
d->updateVerticalAnchors();
}
emit marginsChanged();
}
qreal QQuickAnchors::horizontalCenterOffset() const
{
Q_D(const QQuickAnchors);
return d->hCenterOffset;
}
void QQuickAnchors::setHorizontalCenterOffset(qreal offset)
{
Q_D(QQuickAnchors);
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);
d->topMarginExplicit = true;
if (d->topMargin == offset)
return;
d->topMargin = offset;
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
if (d->fill)
d->fillChanged();
else
d->updateVerticalAnchors();
emit topMarginChanged();
}
void QQuickAnchors::resetTopMargin()
{
Q_D(QQuickAnchors);
d->topMarginExplicit = false;
if (d->topMargin == d->margins)
return;
d->topMargin = d->margins;
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);
d->bottomMarginExplicit = true;
if (d->bottomMargin == offset)
return;
d->bottomMargin = offset;
if (d->fill)
d->fillChanged();
else
d->updateVerticalAnchors();
emit bottomMarginChanged();
}
void QQuickAnchors::resetBottomMargin()
{
Q_D(QQuickAnchors);
d->bottomMarginExplicit = false;
if (d->bottomMargin == d->margins)
return;
d->bottomMargin = d->margins;
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
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
d->updateVerticalAnchors();
emit verticalCenterOffsetChanged();
}
qreal QQuickAnchors::baselineOffset() const
{
Q_D(const QQuickAnchors);
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 horizontalCenter anchors at the same time.");
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 verticalCenter anchors at the same time.");
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 verticalCenter anchors.");
return false;
12611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
}
return true;
}
bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
{
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>