From 89620720e9969360254f950fc63d131d82dd3471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 11 Sep 2009 12:34:08 +0200 Subject: API change. This will get rid of the ugly setAnchorSpacing() method. Say hello to QGraphicsAnchor, move the spacing (and removeAnchor) functionality over to that class. This also opens up for a cleaner API when we add support for size policies or min/pref/max sizes for anchors. Also remove - addLeftAndRightAnchors() - addTopAndBottomAnchors() - addAllAnchors() in favor of - addAnchors(itemA, itemB, Qt::Orientations) API change discussed with Caio and Andreas. Reviewed-by: Alexis --- examples/graphicsview/anchorlayout/main.cpp | 83 ++++----- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 185 ++++++++++---------- src/gui/graphicsview/qgraphicsanchorlayout.h | 73 ++++---- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 168 +++++++++++++------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 66 ++++++-- .../tst_qgraphicsanchorlayout.cpp | 186 ++++++++------------- .../tst_qgraphicsanchorlayout.cpp | 4 +- 7 files changed, 393 insertions(+), 372 deletions(-) diff --git a/examples/graphicsview/anchorlayout/main.cpp b/examples/graphicsview/anchorlayout/main.cpp index 4269eaa..a4bf1d0 100644 --- a/examples/graphicsview/anchorlayout/main.cpp +++ b/examples/graphicsview/anchorlayout/main.cpp @@ -79,66 +79,45 @@ int main(int argc, char **argv) QGraphicsProxyWidget *g = createItem(QSizeF(30, 50), QSizeF(30, 100), maxSize, "G"); QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setSpacing(0); QGraphicsWidget *w = new QGraphicsWidget(0, Qt::Window); w->setPos(20, 20); w->setLayout(l); // vertical - l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorTop, l, Qt::AnchorTop, 0); - l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorTop, l, Qt::AnchorTop, 0); - - l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, a, Qt::AnchorBottom, 0); - l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, b, Qt::AnchorBottom, 0); - l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); - l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, e, Qt::AnchorTop, 0); - - l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(d, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); - l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(e, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); - - l->addAnchor(c, Qt::AnchorTop, f, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorTop, f, Qt::AnchorTop, 0); - l->addAnchor(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom, 0); - l->addAnchor(f, Qt::AnchorBottom, g, Qt::AnchorTop); - l->setAnchorSpacing(f, Qt::AnchorBottom, g, Qt::AnchorTop, 0); - l->addAnchor(c, Qt::AnchorBottom, g, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorBottom, g, Qt::AnchorBottom, 0); + QGraphicsAnchor *anchor = l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop); + anchor = l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop); + + anchor = l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom); + anchor = l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom); + anchor = l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); + anchor = l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop); + + anchor = l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); + anchor = l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom); + + anchor = l->addAnchor(c, Qt::AnchorTop, f, Qt::AnchorTop); + anchor = l->addAnchor(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom); + anchor = l->addAnchor(f, Qt::AnchorBottom, g, Qt::AnchorTop); + anchor = l->addAnchor(c, Qt::AnchorBottom, g, Qt::AnchorBottom); // horizontal - l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); - l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, d, Qt::AnchorLeft, 0); - l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); - - l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); - l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(c, Qt::AnchorRight, e, Qt::AnchorLeft, 0); - - l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorRight, l, Qt::AnchorRight, 0); - l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(e, Qt::AnchorRight, l, Qt::AnchorRight, 0); - l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(d, Qt::AnchorRight, e, Qt::AnchorLeft, 0); - - l->addAnchor(l, Qt::AnchorLeft, f, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, f, Qt::AnchorLeft, 0); - l->addAnchor(l, Qt::AnchorLeft, g, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, g, Qt::AnchorLeft, 0); - l->addAnchor(f, Qt::AnchorRight, g, Qt::AnchorRight); - l->setAnchorSpacing(f, Qt::AnchorRight, g, Qt::AnchorRight, 0); + anchor = l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + anchor = l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft); + anchor = l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + + anchor = l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); + anchor = l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft); + + anchor = l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight); + anchor = l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight); + anchor = l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft); + + anchor = l->addAnchor(l, Qt::AnchorLeft, f, Qt::AnchorLeft); + anchor = l->addAnchor(l, Qt::AnchorLeft, g, Qt::AnchorLeft); + anchor = l->addAnchor(f, Qt::AnchorRight, g, Qt::AnchorRight); + scene.addItem(w); scene.setBackgroundBrush(Qt::darkGreen); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index c7033c6..f57f65f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -84,6 +84,55 @@ QT_BEGIN_NAMESPACE +QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout) + : QObject(*(new QGraphicsAnchorPrivate)) +{ + Q_D(QGraphicsAnchor); + Q_ASSERT(parentLayout); + d->layoutPrivate = parentLayout->d_func(); +} + +/*! + Removes the QGraphicsAnchor object from the layout and destroys it. +*/ +QGraphicsAnchor::~QGraphicsAnchor() +{ +} + +/*! + Set the spacing for the anchor to \a spacing. + + \sa spacing(), unsetSpacing() +*/ +void QGraphicsAnchor::setSpacing(qreal spacing) +{ + Q_D(QGraphicsAnchor); + d->setSpacing(spacing); +} + +/*! + Returns the spacing for the anchor + + \sa setSpacing() +*/ +qreal QGraphicsAnchor::spacing() const +{ + Q_D(const QGraphicsAnchor); + return d->spacing(); +} + +/*! + Resets the spacing of the anchor point to be the default spacing. Depending on the anchor type, + the default spacing is either 0 or a value returned from the style. + + \sa setSpacing(), spacing(), QGraphicsAnchorLayout::anchor() +*/ +void QGraphicsAnchor::unsetSpacing() +{ + Q_D(QGraphicsAnchor); + d->unsetSpacing(); +} + /*! Constructs a QGraphicsAnchorLayout instance. \a parent is passed to QGraphicsLayout's constructor. @@ -136,17 +185,30 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout() * the default vertical spacing). For all other anchor combinations, the spacing will be 0. * All anchoring functions will follow this rule. * - * The spacing can also be set manually by using setAnchorSpacing() method. + * The spacing can also be set manually by using QGraphicsAnchor::setSpacing() method. * - * \sa removeAnchor(), addCornerAnchors(), addLeftAndRightAnchors(), addTopAndBottomAnchors(), - * addAllAnchors() + * \sa addCornerAnchors(), addAnchors() */ -void QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) +QGraphicsAnchor * +QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { Q_D(QGraphicsAnchorLayout); - d->anchor(firstItem, firstEdge, secondItem, secondEdge); + QGraphicsAnchor *a = d->anchor(firstItem, firstEdge, secondItem, secondEdge); invalidate(); + return a; +} + +/*! + Returns the anchor between the anchor points defined by \a firstItem and \a firstEdge and + \a secondItem and \a secondEdge. If there is no such anchor, the function will return 0. +*/ +QGraphicsAnchor * +QGraphicsAnchorLayout::anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) +{ + Q_D(QGraphicsAnchorLayout); + return d->getAnchor(firstItem, firstEdge, secondItem, secondEdge); } /*! @@ -195,6 +257,37 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, } /*! + Anchors two or four edges of \a firstItem with the corresponding edges of \secondItem, + so that \a firstItem has the same size as \a secondItem in the dimensions specified by + \a orientation. + + Calling this convenience function with the following arguments + \code + l->addAnchors(firstItem, secondItem, Qt::Horizontal) + \endcode + + is the same as + + \code + l->addAnchor(firstItem, Qt::AnchorLeft, secondItem, Qt::AnchorLeft); + l->addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); + \endcode +*/ +void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem, + QGraphicsLayoutItem *secondItem, + Qt::Orientations orientations) +{ + if (orientations & Qt::Horizontal) { + addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft); + addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); + } + if (orientations & Qt::Vertical) { + addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop); + addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom); + } +} + +/*! \fn QGraphicsAnchorLayout::addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem) Anchors the left and right edges of \a firstItem to the same edges of @@ -234,86 +327,6 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, */ /*! - Set the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge to be \a spacing. -*/ -void QGraphicsAnchorLayout::setAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, - qreal spacing) -{ - Q_D(QGraphicsAnchorLayout); - - if (!d->setAnchorSize(firstItem, firstEdge, secondItem, secondEdge, &spacing)) { - qWarning("setAnchorSpacing: The anchor does not exist."); - return; - } - invalidate(); -} - -/*! - Returns the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge. The anchor must exist. -*/ -qreal QGraphicsAnchorLayout::anchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) const -{ - Q_D(const QGraphicsAnchorLayout); - qreal size = 0; - if (!d->anchorSize(firstItem, firstEdge, secondItem, secondEdge, 0, &size)) { - qWarning("anchorSpacing: The anchor does not exist."); - } - return size; -} - -/*! - Resets the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge to be the default spacing. Depending on the anchor type, the - default spacing is either 0 or a value returned from the style. - - \sa setAnchorSpacing(), anchorSpacing(), addAnchor() -*/ -void QGraphicsAnchorLayout::unsetAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) -{ - Q_D(QGraphicsAnchorLayout); - - if (!d->setAnchorSize(firstItem, firstEdge, secondItem, secondEdge, 0)) { - qWarning("unsetAnchorSpacing: The anchor does not exist."); - } - invalidate(); -} - -/*! - Removes the anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge - of item \a secondItem. If such an anchor does not exist, the layout will be left unchanged. -*/ -void QGraphicsAnchorLayout::removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) -{ - Q_D(QGraphicsAnchorLayout); - if ((firstItem == 0) || (secondItem == 0)) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor between NULL items"); - return; - } - - if (firstItem == secondItem) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor from the item to itself"); - return; - } - - if (d->edgeOrientation(secondEdge) != d->edgeOrientation(firstEdge)) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor from edges of different orientations"); - return; - } - - d->removeAnchor(firstItem, firstEdge, secondItem, secondEdge); - invalidate(); -} - -/*! Sets the default horizontal spacing for the anchor layout to \a spacing. \sa horizontalSpacing(), setVerticalSpacing(), setSpacing() diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h index 70b73ef..d9a87ba 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout.h @@ -54,41 +54,44 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +class QGraphicsAnchorPrivate; +class QGraphicsAnchorLayout; class QGraphicsAnchorLayoutPrivate; +class Q_GUI_EXPORT QGraphicsAnchor : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing) +public: + void setSpacing(qreal spacing); + void unsetSpacing(); + qreal spacing() const; + ~QGraphicsAnchor(); +private: + QGraphicsAnchor(QGraphicsAnchorLayout *parent); + + Q_DECLARE_PRIVATE(QGraphicsAnchor) + + friend class QGraphicsAnchorLayoutPrivate; +}; + class Q_GUI_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout { public: QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = 0); virtual ~QGraphicsAnchorLayout(); - void addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); void addCornerAnchors(QGraphicsLayoutItem *firstItem, Qt::Corner firstCorner, QGraphicsLayoutItem *secondItem, Qt::Corner secondCorner); - inline void addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - inline void addTopAndBottomAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - inline void addAllAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - void setAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, - qreal spacing); - - qreal anchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) const; - - void unsetAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); - - void removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + void addAnchors(QGraphicsLayoutItem *firstItem, + QGraphicsLayoutItem *secondItem, + Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical); void setHorizontalSpacing(qreal spacing); void setVerticalSpacing(qreal spacing); @@ -108,29 +111,9 @@ protected: private: Q_DISABLE_COPY(QGraphicsAnchorLayout) Q_DECLARE_PRIVATE(QGraphicsAnchorLayout) -}; - -void QGraphicsAnchorLayout::addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft); - addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); -} - -void QGraphicsAnchorLayout::addTopAndBottomAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop); - addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom); -} - -void QGraphicsAnchorLayout::addAllAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addLeftAndRightAnchors(firstItem, secondItem); - addTopAndBottomAnchors(firstItem, secondItem); -} + friend class QGraphicsAnchor; +}; #endif diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f81ede0..a37ec96 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -51,6 +51,47 @@ QT_BEGIN_NAMESPACE + +QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version) + : QObjectPrivate(version), layoutPrivate(0), data(0) +{ +} + +QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate() +{ + layoutPrivate->deleteAnchorData(data); +} + +void QGraphicsAnchorPrivate::setSpacing(qreal value) +{ + if (data) { + layoutPrivate->setAnchorSize(data, &value); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } +} + +void QGraphicsAnchorPrivate::unsetSpacing() +{ + if (data) { + layoutPrivate->setAnchorSize(data, 0); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } +} + +qreal QGraphicsAnchorPrivate::spacing() const +{ + qreal size = 0; + if (data) { + layoutPrivate->anchorSize(data, 0, &size, 0); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } + return size; +} + + void AnchorData::refreshSizeHints(qreal effectiveSpacing) { if (!isLayoutAnchor && from->m_item == to->m_item) { @@ -998,29 +1039,29 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem * * Helper function that is called from the anchor functions in the public API. * If \a spacing is 0, it will pick up the spacing defined by the style. */ -void QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - qreal *spacing) +QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge, + qreal *spacing) { Q_Q(QGraphicsAnchorLayout); if ((firstItem == 0) || (secondItem == 0)) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor NULL items"); - return; + return 0; } if (firstItem == secondItem) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor the item to itself"); - return; + return 0; } if (edgeOrientation(secondEdge) != edgeOrientation(firstEdge)) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor edges of different orientations"); - return; + return 0; } // Guarantee that the graph is no simplified when adding this anchor, @@ -1079,6 +1120,7 @@ void QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, data = new AnchorData(-*spacing); addAnchor(secondItem, secondEdge, firstItem, firstEdge, data); } + return acquireGraphicsAnchor(data); } void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, @@ -1117,77 +1159,97 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data); } +QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge) +{ + Orientation orient = edgeOrientation(firstEdge); + restoreSimplifiedGraph(orient); + + AnchorVertex *v1 = internalVertex(firstItem, firstEdge); + AnchorVertex *v2 = internalVertex(secondItem, secondEdge); + + QGraphicsAnchor *graphicsAnchor = 0; + + AnchorData *data = graph[orient].edgeData(v1, v2); + if (data) + graphicsAnchor = acquireGraphicsAnchor(data); + return graphicsAnchor; +} + void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { - // Guarantee that the graph is no simplified when adding this anchor, - // anchor manipulation always happen in the full graph - restoreSimplifiedGraph(edgeOrientation(firstEdge)); - - // Look for both vertices - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); + removeAnchor_helper(internalVertex(firstItem, firstEdge), + internalVertex(secondItem, secondEdge)); +} +void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2) +{ Q_ASSERT(v1 && v2); + // Guarantee that the graph is no simplified when removing this anchor, + // anchor manipulation always happen in the full graph + Orientation o = edgeOrientation(v1->m_edge); + restoreSimplifiedGraph(o); // Remove edge from graph - graph[edgeOrientation(firstEdge)].removeEdge(v1, v2); + graph[o].removeEdge(v1, v2); // Decrease vertices reference count (may trigger a deletion) - removeInternalVertex(firstItem, firstEdge); - removeInternalVertex(secondItem, secondEdge); + removeInternalVertex(v1->m_item, v1->m_edge); + removeInternalVertex(v2->m_item, v2->m_edge); } -bool QGraphicsAnchorLayoutPrivate::setAnchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - const qreal *anchorSize) +/*! + \internal + Only called from outside. (calls invalidate()) +*/ +void QGraphicsAnchorLayoutPrivate::deleteAnchorData(AnchorData *data) { + Q_Q(QGraphicsAnchorLayout); + removeAnchor_helper(data->from, data->to); + q->invalidate(); +} + +/*! + \internal + Only called from outside. (calls invalidate()) +*/ +void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *anchorSize) +{ + Q_Q(QGraphicsAnchorLayout); // ### we can avoid restoration if we really want to, but we would have to // search recursively through all composite anchors - restoreSimplifiedGraph(edgeOrientation(firstEdge)); - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); - - AnchorData *data = graph[edgeOrientation(firstEdge)].edgeData(v1, v2); - if (data) { - if (anchorSize) { - data->setFixedSize(*anchorSize); - } else { - data->unsetSize(); - } + Q_ASSERT(data); + restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + if (anchorSize) { + data->setFixedSize(*anchorSize); + } else { + data->unsetSize(); } - return data; + q->invalidate(); } -bool QGraphicsAnchorLayoutPrivate::anchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, +void QGraphicsAnchorLayoutPrivate::anchorSize(const AnchorData *data, qreal *minSize, qreal *prefSize, qreal *maxSize) const { Q_ASSERT(minSize || prefSize || maxSize); + Q_ASSERT(data); QGraphicsAnchorLayoutPrivate *that = const_cast(this); - that->restoreSimplifiedGraph(edgeOrientation(firstEdge)); - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); - - AnchorData *data = that->graph[edgeOrientation(firstEdge)].edgeData(v1, v2); - if (data) { - if (minSize) - *minSize = data->minSize; - if (prefSize) - *prefSize = data->prefSize; - if (maxSize) - *maxSize = data->maxSize; - } - return data; + that->restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + + if (minSize) + *minSize = data->minSize; + if (prefSize) + *prefSize = data->prefSize; + if (maxSize) + *maxSize = data->maxSize; } AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item, diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 31da1a1..f701c3f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -54,6 +54,7 @@ // #include +#include #include "qgraphicslayout_p.h" #include "qgraphicsanchorlayout.h" @@ -153,6 +154,7 @@ struct AnchorData : public QSimplexVariable { minSize(minimumSize), prefSize(preferredSize), maxSize(maximumSize), sizeAtMinimum(preferredSize), sizeAtPreferred(preferredSize), sizeAtMaximum(preferredSize), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -160,6 +162,7 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -167,6 +170,7 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(0), prefSize(0), maxSize(0), sizeAtMinimum(0), sizeAtPreferred(0), sizeAtMaximum(0), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(false), isLayoutAnchor(false) {} @@ -215,6 +219,7 @@ struct AnchorData : public QSimplexVariable { qreal sizeAtMinimum; qreal sizeAtPreferred; qreal sizeAtMaximum; + QGraphicsAnchor *graphicsAnchor; uint skipInPreferred : 1; uint type : 2; // either Normal, Sequential or Parallel @@ -226,6 +231,7 @@ protected: minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), + graphicsAnchor(0), skipInPreferred(0), type(type), hasSize(true), isLayoutAnchor(false) {} }; @@ -309,6 +315,28 @@ public: QSet negatives; }; +class QGraphicsAnchorLayoutPrivate; +/*! + \internal +*/ +class QGraphicsAnchorPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsAnchor) + +public: + explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion); + ~QGraphicsAnchorPrivate(); + + void setSpacing(qreal value); + void unsetSpacing(); + qreal spacing() const; + + QGraphicsAnchorLayoutPrivate *layoutPrivate; + AnchorData *data; +}; + + + /*! \internal @@ -365,12 +393,22 @@ public: void removeCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge, bool substitute = true); void removeCenterConstraints(QGraphicsLayoutItem *item, Orientation orientation); + QGraphicsAnchor *acquireGraphicsAnchor(AnchorData *data) + { + Q_Q(QGraphicsAnchorLayout); + if (!data->graphicsAnchor) { + data->graphicsAnchor = new QGraphicsAnchor(q); + data->graphicsAnchor->d_func()->data = data; + } + return data->graphicsAnchor; + } + // helper function used by the 4 API functions - void anchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - qreal *spacing = 0); + QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge, + qreal *spacing = 0); // Anchor Manipulation methods void addAnchor(QGraphicsLayoutItem *firstItem, @@ -379,21 +417,17 @@ public: Qt::AnchorPoint secondEdge, AnchorData *data); + QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + void removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); - - bool setAnchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - const qreal *anchorSize); - - bool anchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, + void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2); + void deleteAnchorData(AnchorData *data); + void setAnchorSize(AnchorData *data, const qreal *anchorSize); + void anchorSize(const AnchorData *data, qreal *minSize = 0, qreal *prefSize = 0, qreal *maxSize = 0) const; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 95476f0..059ad33 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -64,6 +64,7 @@ private slots: void example(); void setSpacing(); void hardComplexS60(); + void delete_anchor(); }; class RectWidget : public QGraphicsWidget @@ -101,8 +102,8 @@ static void setAnchor(QGraphicsAnchorLayout *l, Qt::AnchorPoint secondEdge, qreal spacing) { - l->addAnchor(firstItem, firstEdge, secondItem, secondEdge); - l->setAnchorSpacing(firstItem, firstEdge, secondItem, secondEdge, spacing); + QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge); + anchor->setSpacing(spacing); } static bool checkReverseDirection(QGraphicsWidget *w) @@ -293,47 +294,29 @@ void tst_QGraphicsAnchorLayout::diagonal() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); // vertical l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorTop, l, Qt::AnchorTop, 0); - l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorTop, l, Qt::AnchorTop, 0); - l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, a, Qt::AnchorBottom, 0); l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, b, Qt::AnchorBottom, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, e, Qt::AnchorTop, 0); - l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(d, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(e, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); // horizontal l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, d, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(c, Qt::AnchorRight, e, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(e, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(d, Qt::AnchorRight, e, Qt::AnchorLeft, 0); QCOMPARE(l->count(), 5); @@ -412,40 +395,25 @@ void tst_QGraphicsAnchorLayout::parallel() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(d, Qt::AnchorBottom, e, Qt::AnchorTop); - l->setAnchorSpacing(d, Qt::AnchorBottom, e, Qt::AnchorTop, 0); l->addAnchor(e, Qt::AnchorBottom, f, Qt::AnchorTop); - l->setAnchorSpacing(e, Qt::AnchorBottom, f, Qt::AnchorTop, 0); l->addAnchor(f, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(f, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, d, Qt::AnchorLeft); - l->setAnchorSpacing(b, Qt::AnchorRight, d, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(b, Qt::AnchorRight, e, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, f, Qt::AnchorLeft); - l->setAnchorSpacing(c, Qt::AnchorRight, f, Qt::AnchorLeft, 0); l->addAnchor(d, Qt::AnchorRight, f, Qt::AnchorLeft); - l->setAnchorSpacing(d, Qt::AnchorRight, f, Qt::AnchorLeft, 0); l->addAnchor(e, Qt::AnchorRight, f, Qt::AnchorLeft); - l->setAnchorSpacing(e, Qt::AnchorRight, f, Qt::AnchorLeft, 0); l->addAnchor(f, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(f, Qt::AnchorRight, l, Qt::AnchorRight, 0); QCOMPARE(l->count(), 6); @@ -503,19 +471,15 @@ void tst_QGraphicsAnchorLayout::parallel2() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(b, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); - l->addLeftAndRightAnchors(l, a); + l->addAnchors(l, a, Qt::Horizontal); l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, b, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorRight, a, Qt::AnchorRight, 0); QCOMPARE(l->count(), 2); @@ -556,24 +520,17 @@ void tst_QGraphicsAnchorLayout::snake() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorRight, 0); l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft); - l->setAnchorSpacing(b, Qt::AnchorLeft, c, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(c, Qt::AnchorRight, l, Qt::AnchorRight, 0); QCOMPARE(l->count(), 3); @@ -623,27 +580,20 @@ void tst_QGraphicsAnchorLayout::snakeOppositeDirections() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); // Both a and c are 'pointing' to b l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorRight, 0); l->addAnchor(c, Qt::AnchorLeft, b, Qt::AnchorLeft); - l->setAnchorSpacing(c, Qt::AnchorLeft, b, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(c, Qt::AnchorRight, l, Qt::AnchorRight, 0); QCOMPARE(l->count(), 3); @@ -700,30 +650,20 @@ void tst_QGraphicsAnchorLayout::fairDistribution() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(d, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(b, Qt::AnchorRight, c, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(c, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, d, Qt::AnchorLeft, 0); l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(d, Qt::AnchorRight, l, Qt::AnchorRight, 0); QCOMPARE(l->count(), 4); @@ -785,31 +725,21 @@ void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(d, Qt::AnchorBottom, e, Qt::AnchorTop); - l->setAnchorSpacing(d, Qt::AnchorBottom, e, Qt::AnchorTop, 0); l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(e, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(a, Qt::AnchorLeft, l, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorLeft, l, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorLeft, a, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorLeft, a, Qt::AnchorRight, 0); l->addAnchor(c, Qt::AnchorLeft, b, Qt::AnchorRight); - l->setAnchorSpacing(c, Qt::AnchorLeft, b, Qt::AnchorRight, 0); l->addAnchor(d, Qt::AnchorLeft, c, Qt::AnchorRight); - l->setAnchorSpacing(d, Qt::AnchorLeft, c, Qt::AnchorRight, 0); l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(d, Qt::AnchorRight, l, Qt::AnchorRight, 0); - l->addLeftAndRightAnchors(l, e); + l->addAnchors(l, e, Qt::Horizontal); QCOMPARE(l->count(), 5); @@ -857,32 +787,21 @@ void tst_QGraphicsAnchorLayout::proportionalPreferred() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); - l->setAnchorSpacing(l, Qt::AnchorTop, a, Qt::AnchorTop, 0); l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorBottom, b, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(d, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, b, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, d, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, d, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(c, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(d, Qt::AnchorRight, l, Qt::AnchorRight, 0); QCOMPARE(l->count(), 4); @@ -935,62 +854,40 @@ void tst_QGraphicsAnchorLayout::example() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); // vertical l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(a, Qt::AnchorTop, l, Qt::AnchorTop, 0); l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop); - l->setAnchorSpacing(b, Qt::AnchorTop, l, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, a, Qt::AnchorBottom, 0); l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorTop, b, Qt::AnchorBottom, 0); l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, d, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorBottom, e, Qt::AnchorTop, 0); l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(d, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->setAnchorSpacing(e, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); l->addAnchor(c, Qt::AnchorTop, f, Qt::AnchorTop); - l->setAnchorSpacing(c, Qt::AnchorTop, f, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom, 0); l->addAnchor(f, Qt::AnchorBottom, g, Qt::AnchorTop); - l->setAnchorSpacing(f, Qt::AnchorBottom, g, Qt::AnchorTop, 0); l->addAnchor(c, Qt::AnchorBottom, g, Qt::AnchorBottom); - l->setAnchorSpacing(c, Qt::AnchorBottom, g, Qt::AnchorBottom, 0); // horizontal l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, d, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); - l->setAnchorSpacing(a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(c, Qt::AnchorRight, e, Qt::AnchorLeft, 0); l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(b, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight); - l->setAnchorSpacing(e, Qt::AnchorRight, l, Qt::AnchorRight, 0); l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft); - l->setAnchorSpacing(d, Qt::AnchorRight, e, Qt::AnchorLeft, 0); l->addAnchor(l, Qt::AnchorLeft, f, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, f, Qt::AnchorLeft, 0); l->addAnchor(l, Qt::AnchorLeft, g, Qt::AnchorLeft); - l->setAnchorSpacing(l, Qt::AnchorLeft, g, Qt::AnchorLeft, 0); l->addAnchor(f, Qt::AnchorRight, g, Qt::AnchorRight); - l->setAnchorSpacing(f, Qt::AnchorRight, g, Qt::AnchorRight, 0); QCOMPARE(l->count(), 7); @@ -1039,7 +936,7 @@ void tst_QGraphicsAnchorLayout::setSpacing() l->addCornerAnchors(b, Qt::TopRightCorner, l, Qt::TopRightCorner); l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); - l->addLeftAndRightAnchors(l, c); + l->addAnchors(l, c, Qt::Horizontal); l->addAnchor(a, Qt::AnchorBottom, c, Qt::AnchorTop); l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom); @@ -1146,5 +1043,58 @@ void tst_QGraphicsAnchorLayout::hardComplexS60() } +void tst_QGraphicsAnchorLayout::delete_anchor() +{ + QGraphicsScene scene; + QSizeF minSize(0, 0); + QSizeF prefSize(50, 50); + QSizeF maxSize(100, 100); + QGraphicsWidget *w1 = createItem(minSize, prefSize, maxSize, "w1"); + QGraphicsWidget *w2 = createItem(minSize, prefSize, maxSize, "w2"); + QGraphicsWidget *w3 = createItem(minSize, prefSize, maxSize, "w3"); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setSpacing(0); + l->setContentsMargins(0, 0, 0, 0); + l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft); + l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft); + l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight); + l->addAnchor(w1, Qt::AnchorRight, w3, Qt::AnchorLeft); + l->addAnchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); + + QGraphicsAnchor *anchor = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); + anchor->setSpacing(10); + + QGraphicsWidget *p = new QGraphicsWidget; + p->setLayout(l); + + QCOMPARE(l->count(), 3); + + scene.addItem(p); + QGraphicsView *view = new QGraphicsView(&scene); + QApplication::processEvents(); + // Should now be simplified + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(110)); + QGraphicsAnchor *anchor1 = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); + QVERIFY(anchor1); + QGraphicsAnchor *anchor2 = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); + QVERIFY(anchor2); + + // should be the same object + QCOMPARE(anchor1, anchor2); + + // check if removal works + delete anchor1; + + QApplication::processEvents(); + + // it should also change the preferred size of the layout + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(100)); + + delete p; + delete view; + +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" diff --git a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 028b3a8..000ab6e 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -92,8 +92,8 @@ static void setAnchor(QGraphicsAnchorLayout *l, Qt::AnchorPoint secondEdge, qreal spacing) { - l->addAnchor(firstItem, firstEdge, secondItem, secondEdge); - l->setAnchorSpacing(firstItem, firstEdge, secondItem, secondEdge, spacing); + QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge); + anchor->setSpacing(spacing); } void tst_QGraphicsAnchorLayout::s60_hard_complex_data() -- cgit v0.12