From 17607be158a8d5605ea2426ec4aa9925bd628a2a Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 11 Sep 2009 17:59:46 -0300 Subject: QGraphicsAnchorLayout: Fix anchor creation heuristics Fixing the case where creating an anchor between the layout Left edge and an item Right edge (or vice-versa) would have different behaviors depending on the argument order. Now both calls below have the same meaning: addAnchor(layout, Qt::AnchorLeft, widget, Qt::AnchorRight) addAnchor(widget, Qt::AnchorRight, layout, Qt::AnchorLeft) Signed-off-by: Eduardo M. Fleury Reviewed-by: Jesus Sanchez-Palencia --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 36 +++++++++++------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index a37ec96..11e28ac 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1360,25 +1360,23 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi { Q_Q(QGraphicsAnchorLayout); - Qt::AnchorPoint effectiveFirst = firstEdge; - Qt::AnchorPoint effectiveSecond = secondEdge; - - if (firstItem == q) - effectiveFirst = QGraphicsAnchorLayoutPrivate::oppositeEdge(firstEdge); - if (secondItem == q) - effectiveSecond = QGraphicsAnchorLayoutPrivate::oppositeEdge(secondEdge); - - if (effectiveFirst < effectiveSecond) { - - // ### DEBUG - /* printf("Swapping Anchor from %s %d --to--> %s %d\n", - firstItem->isLayout() ? "" : - qPrintable(static_cast(firstItem)->data(0).toString()), - firstEdge, - secondItem->isLayout() ? "" : - qPrintable(static_cast(secondItem)->data(0).toString()), - secondEdge); - */ + if ((firstItem != q) && (secondItem != q)) { + // If connection is between widgets (not the layout itself) + // Ensure that "right-edges" sit to the left of "left-edges". + if (firstEdge < secondEdge) { + qSwap(firstItem, secondItem); + qSwap(firstEdge, secondEdge); + } + } else if (firstItem == q) { + // If connection involves the right or bottom of a layout, ensure + // the layout is the second item. + if ((firstEdge == Qt::AnchorRight) || (firstEdge == Qt::AnchorBottom)) { + qSwap(firstItem, secondItem); + qSwap(firstEdge, secondEdge); + } + } else if ((secondEdge != Qt::AnchorRight) && (secondEdge != Qt::AnchorBottom)) { + // If connection involves the left, center or top of layout, ensure + // the layout is the first item. qSwap(firstItem, secondItem); qSwap(firstEdge, secondEdge); } -- cgit v0.12 From 26d3ead5771a67a15a672441ce30359aa355b911 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 11 Sep 2009 18:21:08 -0300 Subject: QGraphicsAnchorLayout: Handle negative spacing in "setAnchorSpacing" The simplex solver cannot handle negative-sized anchors. Those should be handled by the layout itself. This is done by inverting such anchors and making their size positive again. Ie. A --> B with size -10 becomes B --> A with size 10 Signed-off-by: Eduardo M. Fleury Reviewed-by: Jesus Sanchez-Palencia --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 27 ++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 11e28ac..50d1a61 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1225,12 +1225,35 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal * // search recursively through all composite anchors Q_ASSERT(data); restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + + QGraphicsLayoutItem *firstItem = data->from->m_item; + QGraphicsLayoutItem *secondItem = data->to->m_item; + Qt::AnchorPoint firstEdge = data->from->m_edge; + Qt::AnchorPoint secondEdge = data->to->m_edge; + + // Use heuristics to find out what the user meant with this anchor. + correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge); + if (data->from->m_item != firstItem) + qSwap(data->from, data->to); + if (anchorSize) { - data->setFixedSize(*anchorSize); + // ### The current implementation makes "setAnchorSize" behavior + // dependent on the argument order for cases where we have + // no heuristic. Ie. two widgets, same anchor point. + + // We cannot have negative sizes inside the graph. This would cause + // the simplex solver to fail because all simplex variables are + // positive by definition. + // "negative spacing" is handled by inverting the standard item order. + if (*anchorSize >= 0) { + data->setFixedSize(*anchorSize); + } else { + data->setFixedSize(-*anchorSize); + qSwap(data->from, data->to); + } } else { data->unsetSize(); } - q->invalidate(); } -- cgit v0.12 From 312efdc70059562b1a782d5432ef06d08e002631 Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Tue, 15 Sep 2009 16:28:56 -0300 Subject: QGraphicsAnchorLayout: Removing methods names inconsistencies on private class QGraphicsAnchorLayoutPrivate now has addAnchor() replacing anchor() and addAnchor_helper() replacing addAnchor(). With this changes we are respecting the API behavior, where anchor() is a "getter" instead of a "setter". Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 6 +++--- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 24 ++++++++++++------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 8 ++++---- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 5897ae4..efad259 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -194,7 +194,7 @@ QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { Q_D(QGraphicsAnchorLayout); - QGraphicsAnchor *a = d->anchor(firstItem, firstEdge, secondItem, secondEdge); + QGraphicsAnchor *a = d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); invalidate(); return a; } @@ -246,12 +246,12 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, // Horizontal anchor Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft); Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft); - d->anchor(firstItem, firstEdge, secondItem, secondEdge); + d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); // Vertical anchor firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); - d->anchor(firstItem, firstEdge, secondItem, secondEdge); + d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); invalidate(); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 50d1a61..6c93a28 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -790,7 +790,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() // Horizontal AnchorData *data = new AnchorData(0, 0, QWIDGETSIZE_MAX); - addAnchor(layout, Qt::AnchorLeft, layout, + addAnchor_helper(layout, Qt::AnchorLeft, layout, Qt::AnchorRight, data); data->skipInPreferred = 1; @@ -800,7 +800,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() // Vertical data = new AnchorData(0, 0, QWIDGETSIZE_MAX); - addAnchor(layout, Qt::AnchorTop, layout, + addAnchor_helper(layout, Qt::AnchorTop, layout, Qt::AnchorBottom, data); data->skipInPreferred = 1; @@ -832,7 +832,7 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item) int maximumSize = item->maximumWidth(); AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize); - addAnchor(item, Qt::AnchorLeft, item, + addAnchor_helper(item, Qt::AnchorLeft, item, Qt::AnchorRight, data); // Vertical @@ -841,7 +841,7 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item) maximumSize = item->maximumHeight(); data = new AnchorData(minimumSize, preferredSize, maximumSize); - addAnchor(item, Qt::AnchorTop, item, + addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data); } @@ -904,11 +904,11 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors( QSimplexConstraint *c = new QSimplexConstraint; AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize); c->variables.insert(data, 1.0); - addAnchor(item, firstEdge, item, centerEdge, data); + addAnchor_helper(item, firstEdge, item, centerEdge, data); data = new AnchorData(minimumSize, preferredSize, maximumSize); c->variables.insert(data, -1.0); - addAnchor(item, centerEdge, item, lastEdge, data); + addAnchor_helper(item, centerEdge, item, lastEdge, data); itemCenterConstraints[orientation].append(c); @@ -976,7 +976,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors( int maximumSize = oldData->maxSize * 2; AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize); - addAnchor(item, firstEdge, item, lastEdge, data); + addAnchor_helper(item, firstEdge, item, lastEdge, data); // Remove old anchors removeAnchor(item, firstEdge, item, centerEdge); @@ -1039,7 +1039,7 @@ 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. */ -QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, +QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, @@ -1112,18 +1112,18 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *first } else { data = new AnchorData(0); // spacing should be 0 } - addAnchor(firstItem, firstEdge, secondItem, secondEdge, data); + addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); } else if (*spacing >= 0) { data = new AnchorData(*spacing); - addAnchor(firstItem, firstEdge, secondItem, secondEdge, data); + addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); } else { data = new AnchorData(-*spacing); - addAnchor(secondItem, secondEdge, firstItem, firstEdge, data); + addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data); } return acquireGraphicsAnchor(data); } -void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, +void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index f701c3f..9316847 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -403,15 +403,15 @@ public: return data->graphicsAnchor; } - // helper function used by the 4 API functions - QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, + // function used by the 4 API functions + QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, qreal *spacing = 0); - // Anchor Manipulation methods - void addAnchor(QGraphicsLayoutItem *firstItem, + // Helper for Anchor Manipulation methods + void addAnchor_helper(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, -- cgit v0.12 From 6cadb9004c10ca3b7b69311c1f885d60ed2afe8b Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Tue, 15 Sep 2009 16:59:20 -0300 Subject: QGraphicsAnchorLayoutPrivate: Removing method removeAnchor() All method calls were replaced by calling removeAnchor_helper(), with internalVertex() calls Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 30 ++++++++++-------------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 ---- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 6c93a28..f1b9fe5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -816,8 +816,10 @@ void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges() Q_ASSERT(internalVertex(q, Qt::AnchorHorizontalCenter) == NULL); Q_ASSERT(internalVertex(q, Qt::AnchorVerticalCenter) == NULL); - removeAnchor(q, Qt::AnchorLeft, q, Qt::AnchorRight); - removeAnchor(q, Qt::AnchorTop, q, Qt::AnchorBottom); + removeAnchor_helper(internalVertex(q, Qt::AnchorLeft), + internalVertex(q, Qt::AnchorRight)); + removeAnchor_helper(internalVertex(q, Qt::AnchorTop), + internalVertex(q, Qt::AnchorBottom)); } void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item) @@ -913,7 +915,7 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors( itemCenterConstraints[orientation].append(c); // Remove old one - removeAnchor(item, firstEdge, item, lastEdge); + removeAnchor_helper(first, last); } void QGraphicsAnchorLayoutPrivate::removeCenterAnchors( @@ -979,8 +981,8 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors( addAnchor_helper(item, firstEdge, item, lastEdge, data); // Remove old anchors - removeAnchor(item, firstEdge, item, centerEdge); - removeAnchor(item, centerEdge, item, lastEdge); + removeAnchor_helper(first, center); + removeAnchor_helper(center, internalVertex(item, lastEdge)); } else { // this is only called from removeAnchors() @@ -989,13 +991,13 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors( for (int i = 0; i < adjacents.count(); ++i) { AnchorVertex *v = adjacents.at(i); if (v->m_item != item) { - removeAnchor(item, centerEdge, v->m_item, v->m_edge); + removeAnchor_helper(center, internalVertex(v->m_item, v->m_edge)); } } // when all non-internal anchors is removed it will automatically merge the // center anchor into a left-right (or top-bottom) anchor. We must also delete that. // by this time, the center vertex is deleted and merged into a non-centered internal anchor - removeAnchor(item, firstEdge, item, lastEdge); + removeAnchor_helper(first, internalVertex(item, lastEdge)); } } @@ -1142,8 +1144,9 @@ void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstIt // Remove previous anchor // ### Could we update the existing edgeData rather than creating a new one? - if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) - removeAnchor(firstItem, firstEdge, secondItem, secondEdge); + if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) { + removeAnchor_helper(v1, v2); + } // Create a bi-directional edge in the sense it can be transversed both // from v1 or v2. "data" however is shared between the two references @@ -1178,15 +1181,6 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi return graphicsAnchor; } -void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge) -{ - removeAnchor_helper(internalVertex(firstItem, firstEdge), - internalVertex(secondItem, secondEdge)); -} - void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2) { Q_ASSERT(v1 && v2); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 9316847..89b49af 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -420,10 +420,6 @@ public: QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); - void removeAnchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge); void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2); void deleteAnchorData(AnchorData *data); void setAnchorSize(AnchorData *data, const qreal *anchorSize); -- cgit v0.12 From ecb7f47897049014d2956396d5634e3d418bdcb9 Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Tue, 15 Sep 2009 17:10:32 -0300 Subject: QGraphicsAnchorLayoutPrivate: Removing item from layout when there are no more anchors Now the removeAnchor() method has returned and it is ready for being use in the API for ensure that items are removed from the layout when they have no more external anchors. Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 76 ++++++++++++++++++++++++ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 1 + 2 files changed, 77 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f1b9fe5..f2eddde 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1181,6 +1181,82 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi return graphicsAnchor; } +/*! + * \internal + * + * Implements the high level "removeAnchor" feature. Called by + * the QAnchorData destructor. + */ +void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex, + AnchorVertex *secondVertex) +{ + Q_Q(QGraphicsAnchorLayout); + + // Actually delete the anchor + removeAnchor_helper(firstVertex, secondVertex); + + QGraphicsLayoutItem *firstItem = firstVertex->m_item; + QGraphicsLayoutItem *secondItem = secondVertex->m_item; + + // Checking if the item stays in the layout or not + bool keepFirstItem = false; + bool keepSecondItem = false; + + QPair v; + int refcount = -1; + + if (firstItem != q) { + for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) { + v = m_vertexList.value(qMakePair(firstItem, static_cast(i))); + if (v.first) { + if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter) + refcount = 2; + else + refcount = 1; + + if (v.second > refcount) { + keepFirstItem = true; + break; + } + } + } + } else + keepFirstItem = true; + + if (secondItem != q) { + for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) { + v = m_vertexList.value(qMakePair(secondItem, static_cast(i))); + if (v.first) { + if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter) + refcount = 2; + else + refcount = 1; + + if (v.second > refcount) { + keepSecondItem = true; + break; + } + } + } + } else + keepSecondItem = true; + + if (!keepFirstItem) + q->removeAt(items.indexOf(firstItem)); + + if (!keepSecondItem) + q->removeAt(items.indexOf(secondItem)); + + // Removing anchors invalidates the layout + q->invalidate(); +} + +/* + \internal + + Implements the low level "removeAnchor" feature. Called by + private methods. +*/ void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2) { Q_ASSERT(v1 && v2); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 89b49af..5a91baa 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -420,6 +420,7 @@ public: QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex); void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2); void deleteAnchorData(AnchorData *data); void setAnchorSize(AnchorData *data, const qreal *anchorSize); -- cgit v0.12 From eafa92ec86c61d6da6700f832de263829cb84dd3 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Tue, 15 Sep 2009 20:01:45 -0300 Subject: QGraphicsAnchorLayout: Remove QGALPrivate::deleteAnchorData() This method, formerly called by the QGraphicsAnchor destructor, to remove the anchor associated to it, is no longer needed. That destructor now calls QGALPrivate::removeAnchor(), a method analagous to addAnchor(), that provides the high level feature of "anchor removal". Signed-off-by: Eduardo M. Fleury Reviewed-by: Jesus Sanchez-Palencia --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 13 +------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f2eddde..b02adf4 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -59,7 +59,7 @@ QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version) QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate() { - layoutPrivate->deleteAnchorData(data); + layoutPrivate->removeAnchor(data->from, data->to); } void QGraphicsAnchorPrivate::setSpacing(qreal value) @@ -1277,17 +1277,6 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorV \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); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 5a91baa..4d746bf 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -422,7 +422,6 @@ public: void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex); 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, -- cgit v0.12 From 884a044f3d71616d317ea58a1ed364ee57220fe7 Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Wed, 16 Sep 2009 14:37:50 -0300 Subject: QGraphicsAnchorLayout: Added new autotests file Several autotests written by the Orbit team were added as a new QGraphicsAnchorLayout autotests file. Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Eduardo M. Fleury --- tests/auto/auto.pro | 1 + .../qgraphicsanchorlayout1.pro | 3 + .../tst_qgraphicsanchorlayout1.cpp | 3063 ++++++++++++++++++++ 3 files changed, 3067 insertions(+) create mode 100644 tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro create mode 100644 tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 6a5ac9e..e2a67af 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -143,6 +143,7 @@ SUBDIRS += \ qgraphicsitem \ qgraphicsitemanimation \ qgraphicsanchorlayout \ + qgraphicsanchorlayout1 \ qgraphicslayout \ qgraphicslayoutitem \ qgraphicslinearlayout \ diff --git a/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro new file mode 100644 index 0000000..27f48e0 --- /dev/null +++ b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +SOURCES += tst_qgraphicsanchorlayout1.cpp + diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp new file mode 100644 index 0000000..44c74d0 --- /dev/null +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -0,0 +1,3063 @@ +/**************************************************************************** + * ** + * ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * ** All rights reserved. + * ** Contact: Nokia Corporation (qt-info@nokia.com) + * ** + * ** This file is part of the test suite of the Qt Toolkit. + * ** + * ** $QT_BEGIN_LICENSE:LGPL$ + * ** No Commercial Usage + * ** This file contains pre-release code and may not be distributed. + * ** You may use this file in accordance with the terms and conditions + * ** contained in the Technology Preview License Agreement accompanying + * ** this package. + * ** + * ** 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 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. + * ** + * ** If you have questions regarding the use of this file, please contact + * ** Nokia at qt-info@nokia.com. + * ** + * ** + * ** + * ** + * ** + * ** + * ** + * ** + * ** $QT_END_LICENSE$ + * ** + * ****************************************************************************/ + +#include +#include +#include +#include +#include + +#define TEST_COMPLEX_CASES + + +//---------------------- AnchorLayout helper class ---------------------------- +class TheAnchorLayout : public QGraphicsAnchorLayout +{ +public: + TheAnchorLayout() : QGraphicsAnchorLayout() + { + setContentsMargins( 0,0,0,0 ); + setSpacing( 0 ); + } + + // ###: Remove me when isValid() is supported + bool isValid() + { + return true; + } + + void setAnchor( + QGraphicsLayoutItem *startItem, + Qt::AnchorPoint startEdge, + QGraphicsLayoutItem *endItem, + Qt::AnchorPoint endEdge, + qreal value) + { + QGraphicsAnchor *anchor = addAnchor( startItem, startEdge, endItem, endEdge); + if (anchor) + anchor->setSpacing(value); + } + + int indexOf(const QGraphicsLayoutItem* item) const + { + for ( int i=0; i< count(); i++) { + if ( itemAt(i) == item ) { + return i; + } + } + return -1; + } + + void removeItem(QGraphicsLayoutItem* item) + { + removeAt(indexOf(item)); + } + + void removeAnchor( + QGraphicsLayoutItem *startItem, + Qt::AnchorPoint startEdge, + QGraphicsLayoutItem *endItem, + Qt::AnchorPoint endEdge) + { + delete QGraphicsAnchorLayout::anchor(startItem, startEdge, endItem, endEdge); + } +}; +//----------------------------------------------------------------------------- + + +struct BasicLayoutTestData +{ + inline BasicLayoutTestData( + int index1, Qt::AnchorPoint edge1, + int index2, Qt::AnchorPoint edge2, + qreal distance) + : firstIndex(index1), firstEdge(edge1), + secondIndex(index2), secondEdge(edge2), + spacing(distance) + { + } + + int firstIndex; + Qt::AnchorPoint firstEdge; + int secondIndex; + Qt::AnchorPoint secondEdge; + qreal spacing; +}; + +struct AnchorItemSizeHint +{ + inline AnchorItemSizeHint( + qreal hmin, qreal hpref, qreal hmax, + qreal vmin, qreal vpref, qreal vmax ) + : hmin(hmin), hpref(hpref), hmax(hmax), vmin(vmin), vpref(vpref), vmax(vmax) + { + } + qreal hmin, hpref, hmax; + qreal vmin, vpref, vmax; +}; + +// some test results + +struct BasicLayoutTestResult +{ + inline BasicLayoutTestResult( + int resultIndex, const QRectF& resultRect ) + : index(resultIndex), rect(resultRect) + { + } + + int index; + QRectF rect; +}; + +typedef QList BasicLayoutTestDataList; +Q_DECLARE_METATYPE(BasicLayoutTestDataList) + +typedef QList BasicLayoutTestResultList; +Q_DECLARE_METATYPE(BasicLayoutTestResultList) + +typedef QList AnchorItemSizeHintList; +Q_DECLARE_METATYPE(AnchorItemSizeHintList) + + +//---------------------- Test Widget used on all tests ------------------------ +class TestWidget : public QGraphicsWidget +{ +public: + inline TestWidget(QGraphicsItem *parent = 0) + : QGraphicsWidget(parent) + { + setContentsMargins( 0,0,0,0 ); + } + ~TestWidget() + { + } + +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; +}; + +QSizeF TestWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED( constraint ); + if (which == Qt::MinimumSize) { + return QSizeF(5,5); + } + + if (which == Qt::PreferredSize) { + return QSizeF(50,50); + } + + return QSizeF(500,500); +} +//----------------------------------------------------------------------------- + + + +//----------------------------- Test class ------------------------------------ +class TestGraphicsAnchorLayout : public QObject +{ + Q_OBJECT + +private slots: + void testCount(); + + void testRemoveAt(); + void testRemoveItem(); + + void testItemAt(); + void testIndexOf(); + + void testAddAndRemoveAnchor(); + void testIsValid(); + void testSpecialCases(); + + void testBasicLayout_data(); + void testBasicLayout(); + + void testNegativeSpacing_data(); + void testNegativeSpacing(); + + void testMixedSpacing_data(); + void testMixedSpacing(); + + void testMulti_data(); + void testMulti(); + + void testCenterAnchors_data(); + void testCenterAnchors(); + + void testRemoveCenterAnchor_data(); + void testRemoveCenterAnchor(); + + void testSingleSizePolicy_data(); + void testSingleSizePolicy(); + + void testDoubleSizePolicy_data(); + void testDoubleSizePolicy(); + + void testSizeDistribution_data(); + void testSizeDistribution(); + + void testSizeHint(); + +#ifdef TEST_COMPLEX_CASES + void testComplexCases_data(); + void testComplexCases(); +#endif +}; + + +void TestGraphicsAnchorLayout::testCount() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + + TheAnchorLayout *layout = new TheAnchorLayout(); + QVERIFY( layout->count() == 0 ); + + TestWidget *widget1 = new TestWidget(); + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + QCOMPARE( layout->count(), 1 ); + + // adding one more anchor for already added widget should not increase the count + layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, 1); + QCOMPARE( layout->count(), 1 ); + + // create one more widget and attach with anchor layout + TestWidget *widget2 = new TestWidget(); + layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1); + QCOMPARE( layout->count(), 2 ); + + widget->setLayout(layout); + delete widget; +} + +void TestGraphicsAnchorLayout::testRemoveAt() +{ + TheAnchorLayout *layout = new TheAnchorLayout(); + QVERIFY( layout->count() == 0 ); + + TestWidget *widget1 = new TestWidget(); + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2); + QVERIFY( layout->count() == 1 ); + + TestWidget *widget2 = new TestWidget(); + layout->setAnchor(widget2, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1); + QVERIFY( layout->count() == 2 ); + + layout->removeAt(0); + QVERIFY( layout->count() == 1 ); + + layout->removeAt(-55); + layout->removeAt(55); + QVERIFY( layout->count() == 1 ); + + layout->removeAt(0); + QVERIFY( layout->count() == 0 ); + + delete layout; + delete widget1; + delete widget2; +} + +void TestGraphicsAnchorLayout::testRemoveItem() +{ + TheAnchorLayout *layout = new TheAnchorLayout(); + QCOMPARE( layout->count(), 0 ); + + TestWidget *widget1 = new TestWidget(); + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2); + QCOMPARE( layout->count(), 1 ); + + TestWidget *widget2 = new TestWidget(); + layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1); + QCOMPARE( layout->count(), 2 ); + + layout->removeItem(0); + QCOMPARE( layout->count(), 2 ); + + layout->removeItem(widget1); + QCOMPARE( layout->count(), 1 ); + QCOMPARE( layout->indexOf(widget1), -1 ); + QCOMPARE( layout->indexOf(widget2), 0 ); + + layout->removeItem(widget1); + QCOMPARE( layout->count(), 1 ); + + layout->removeItem(widget2); + QVERIFY( layout->count() == 0 ); + + delete layout; + delete widget1; + delete widget2; +} + +void TestGraphicsAnchorLayout::testItemAt() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + TestWidget *widget2 = new TestWidget(); + TestWidget *widget3 = new TestWidget(); + TestWidget *widget4 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1); + + QVERIFY( layout->itemAt(0) == widget1 ); + + layout->removeAt(0); + + QVERIFY( layout->itemAt(0) == widget2 ); + + widget->setLayout(layout); + delete widget; +} + +void TestGraphicsAnchorLayout::testIndexOf() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + TestWidget *widget2 = new TestWidget(); + TestWidget *widget3 = new TestWidget(); + TestWidget *widget4 = new TestWidget(); + + QCOMPARE( layout->indexOf(widget1), -1 ); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1); + + QCOMPARE( layout->indexOf(widget4), -1 ); + layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1); + + QCOMPARE( layout->count(), 4 ); + for (int i = 0; i < layout->count(); ++i) { + QCOMPARE(layout->indexOf(layout->itemAt(i)), i); + } + + QCOMPARE( layout->indexOf(0), -1 ); + widget->setLayout(layout); + delete widget; +} + +void TestGraphicsAnchorLayout::testAddAndRemoveAnchor() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + TestWidget *widget2 = new TestWidget(); + TestWidget *widget3 = new TestWidget(); + TestWidget *widget4 = new TestWidget(); + TestWidget *widget5 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.5); + layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 10); + layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1); + QCOMPARE( layout->count(), 4 ); + + // test setting invalid anchors + layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1); + QCOMPARE( layout->count(), 4 ); + + // test removing invalid anchors + layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight); + + // anchor one horizontal edge with vertical edge. it should not add this widget as a child + layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10); + QCOMPARE( layout->count(), 4 ); + + // ###: NOT SUPPORTED + // anchor two edges of a widget (to define width / height) + layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10); + // QCOMPARE( layout->count(), 5 ); + QCOMPARE( layout->count(), 4 ); + + // anchor yet new widget properly + layout->setAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight, 20 ); + QCOMPARE( layout->count(), 5 ); + + // remove anchor for widget1. widget1 should be removed from layout since the + // last anchor was removed. + layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft); + + QCOMPARE( layout->count(), 4 ); + QCOMPARE( (int)widget1->parentLayoutItem(), 0 ); + + // test that item is not removed from layout if other anchors remain set + layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10); + layout->removeAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft); + QCOMPARE( layout->count(), 4 ); + + // remove all the anchors + layout->removeAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight); + layout->removeAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft); + layout->removeAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft); + layout->removeAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight); + layout->removeAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight); + + QCOMPARE( layout->count(), 0 ); + + // set one anchor "another way round" to get full coverage for "removeAnchor" + layout->setAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1); + layout->removeAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft); + + QCOMPARE( layout->count(), 0 ); + + widget->setLayout(layout); + delete widget; +} + +void TestGraphicsAnchorLayout::testIsValid() +{ + // ###: REMOVE ME + return; + + // Empty, valid + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + widget->setLayout(layout); + widget->setGeometry(QRectF(0,0,100,100)); + + QCOMPARE(layout->isValid(), true); + delete widget; + } + + // One widget, valid + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1); + layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1); + layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1); + + widget->setLayout(layout); + + widget->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(layout->isValid(), true); + delete widget; + } + + // Overconstrained one widget, invalid + // ### Our understanding is that this case is valid. What happens though, + // is that the layout minimum and maximum vertical size hints become + // the same, 10.1. That means its height is fixed. + // What will "fail" then is the "setGeometry(0, 0, 100, 100)" call, + // after which the layout geometry will be (0, 0, 100, 10.1). + + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1); + layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1); + layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1); + + layout->setAnchor(widget1, Qt::AnchorTop, layout, Qt::AnchorBottom, 10); + + widget->setLayout(layout); + + widget->setGeometry(QRectF(0,0,100,100)); + // ###: this shall change once isValid() is ready + // QCOMPARE(layout->isValid(), false); + QCOMPARE(layout->isValid(), true); + delete widget; + } + + // Underconstrained two widgets, valid + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + TestWidget *widget2 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); + layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1); + + layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1); + layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1); + + widget->setLayout(layout); + + widget->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(layout->isValid(), true); + delete widget; + } +} + +void TestGraphicsAnchorLayout::testSpecialCases() +{ + // One widget, setLayout before defining layouts + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + widget->setLayout(layout); + + TestWidget *widget1 = new TestWidget(); + + layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 1); + layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 1); + layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + widget->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(widget1->geometry(), QRectF(1,1,98,98)); + delete widget1; + delete widget; + } + + // One widget, layout inside layout, layout inside layout inside layout + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + widget->setLayout(layout); + + TheAnchorLayout *layout1 = new TheAnchorLayout(); + TestWidget *widget1 = new TestWidget(); + layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1); + layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1); + layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1); + + TheAnchorLayout *layout2 = new TheAnchorLayout(); + TestWidget *widget2 = new TestWidget(); + layout2->setAnchor(layout2, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1); + layout2->setAnchor(layout2, Qt::AnchorTop, widget2, Qt::AnchorTop, 1); + layout2->setAnchor(widget2, Qt::AnchorRight, layout2, Qt::AnchorRight, 1); + layout2->setAnchor(widget2, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1); + + layout1->setAnchor(layout1, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 1); + layout1->setAnchor(layout1, Qt::AnchorTop, layout2, Qt::AnchorTop, 1); + layout1->setAnchor(layout2, Qt::AnchorRight, layout1, Qt::AnchorRight, 1); + layout1->setAnchor(layout2, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1); + + layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1); + layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1); + layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + // remove and add again to improve test coverage. + layout->removeItem(layout1); + + layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1); + layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1); + layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + widget->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(widget1->geometry(), QRectF(2,2,96,96)); + QCOMPARE(widget2->geometry(), QRectF(3,3,94,94)); + delete widget; + } + + // One widget, layout inside layout, setLayout after layout definition + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + + TheAnchorLayout *layout1 = new TheAnchorLayout(); + + TestWidget *widget1 = new TestWidget(); + layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1); + layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1); + layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1); + + layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1); + layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1); + layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + widget->setLayout(layout); + widget->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(widget1->geometry(), QRectF(2,2,96,96)); + delete widget; + } + + // One widget, layout inside layout, setLayout after layout definition, widget transferred from + // one layout to another + { + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout(); + widget->setLayout(layout); + + TheAnchorLayout *layout1 = new TheAnchorLayout(); + TestWidget *widget1 = new TestWidget(); + + // Additional layout + widget to improve coverage. + TheAnchorLayout *layout0 = new TheAnchorLayout(); + TestWidget *widget0 = new TestWidget(); + + // widget0 to layout0 + layout0->setAnchor(layout0, Qt::AnchorLeft, widget0, Qt::AnchorLeft, 1); + layout0->setAnchor(layout0, Qt::AnchorTop, widget0, Qt::AnchorTop, 1); + layout0->setAnchor(widget0, Qt::AnchorRight, layout0, Qt::AnchorRight, 1); + layout0->setAnchor(widget0, Qt::AnchorBottom, layout0, Qt::AnchorBottom, 1); + + // layout0 to layout + layout->setAnchor(layout, Qt::AnchorLeft, layout0, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, layout0, Qt::AnchorTop, 1); + layout->setAnchor(layout0, Qt::AnchorRight, layout, Qt::AnchorRight, 50); + layout->setAnchor(layout0, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + // widget1 to layout1 + layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1); + layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1); + layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1); + + // layout1 to layout + layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1); + layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1); + layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 50); + layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + TheAnchorLayout *layout2 = new TheAnchorLayout(); + + // layout2 to layout + layout->setAnchor(layout, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 50); + layout->setAnchor(layout, Qt::AnchorTop, layout2, Qt::AnchorTop, 1); + layout->setAnchor(layout2, Qt::AnchorRight, layout, Qt::AnchorRight, 1); + layout->setAnchor(layout2, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1); + + // transfer widget1 to layout2 + layout2->setAnchor(layout2, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + layout2->setAnchor(layout2, Qt::AnchorTop, widget1, Qt::AnchorTop, 1); + layout2->setAnchor(widget1, Qt::AnchorRight, layout2, Qt::AnchorRight, 1); + layout2->setAnchor(widget1, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1); + + // ###: uncomment when simplification bug is solved + //widget->setGeometry(QRectF(0,0,100,100)); + //QCOMPARE(widget1->geometry(), QRectF(51,2,47,96)); + delete widget; + } + + // One widget, set first to one layout then to another. Child reparented. + // In addition widget as a direct child of another widget. Child reparented. + { + QGraphicsWidget *widget1 = new QGraphicsWidget; + TheAnchorLayout *layout1 = new TheAnchorLayout(); + widget1->setLayout(layout1); + + TestWidget *childWidget = new TestWidget(); + + // childWidget to layout1 + layout1->setAnchor(layout1, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1); + layout1->setAnchor(layout1, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1); + layout1->setAnchor(childWidget, Qt::AnchorRight, layout1, Qt::AnchorRight, 1); + layout1->setAnchor(childWidget, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1); + + widget1->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98)); + QVERIFY(childWidget->parentLayoutItem() == layout1); + QGraphicsWidget *widget2 = new QGraphicsWidget; + TheAnchorLayout *layout2 = new TheAnchorLayout(); + widget2->setLayout(layout2); + + // childWidget to layout2 + layout2->setAnchor(layout2, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1); + layout2->setAnchor(layout2, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1); + layout2->setAnchor(childWidget, Qt::AnchorRight, layout2, Qt::AnchorRight, 1); + layout2->setAnchor(childWidget, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1); + + QGraphicsWidget *widget3 = new QGraphicsWidget; + QGraphicsWidget *widget4 = new QGraphicsWidget; + // widget4 is a direct child of widget3 (i.e. not in any layout) + widget4->setParentItem(widget3); + + // widget4 to layout2 + layout2->setAnchor(layout2, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 1); + layout2->setAnchor(layout2, Qt::AnchorTop, widget4, Qt::AnchorTop, 1); + layout2->setAnchor(widget4, Qt::AnchorRight, layout2, Qt::AnchorRight, 1); + layout2->setAnchor(widget4, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1); + + widget2->setGeometry(QRectF(0,0,100,100)); + QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98)); + QVERIFY(childWidget->parentLayoutItem() == layout2); + QCOMPARE(widget4->geometry(), QRectF(1,1,98,98)); + QVERIFY(widget4->parentLayoutItem() == layout2); + QVERIFY(widget4->parentItem() == widget2); + + delete widget4; + delete widget3; + delete widget1; + delete childWidget; + delete widget2; + } +} + +void TestGraphicsAnchorLayout::testBasicLayout_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // One widget, basic + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40) + ; + + theResult + << BasicResult(0, QRectF(20, 10, 150, 50) ) + ; + + QTest::newRow("One, simple") << QSizeF(200, 100) << theData << theResult; + } + + // One widget, duplicates + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40) + + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0) + ; + + theResult + << BasicResult(0, QRectF(0, 0, 200, 100) ) + ; + + QTest::newRow("One, duplicates") << QSizeF(200, 100) << theData << theResult; + } + + // One widget, mixed + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 80) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 150) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 150) + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 80) + ; + + theResult + << BasicResult(0, QRectF(50, 20, 100, 60) ) + ; + + QTest::newRow("One, mixed") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets (same layout), different ordering + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 180, 80) ) + << BasicResult(1, QRectF(10, 10, 180, 80) ) + ; + + QTest::newRow("Two, orderings") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, duplicate anchors + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 30) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20) + + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0) + ; + + theResult + << BasicResult(0, QRectF(30, 10, 160, 70) ) + << BasicResult(1, QRectF(10, 0, 190, 90) ) + ; + + QTest::newRow("Two, duplicates") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, mixed + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 90) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 190) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 190) + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 90) + + << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorBottom, 20) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10) + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 20) + ; + + // ### SIMPLIFICATION BUG FOR ITEM 1 + // ### remove this when bug is solved + + theResult + << BasicResult(0, QRectF(10, 10, 180, 80) ) + << BasicResult(1, QRectF(10, 80, 10, 10) ) + ; + + QTest::newRow("Two, mixed") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 1 horizontal connection, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(30, 10, 160, 70) ) + ; + + QTest::newRow("Two, 1h connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 2 horizontal connections, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + // ### QGAL is not sensible to the argument order in this case + // To achieve the desired result we must explicitly set a negative + // spacing. + // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100) + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100) + + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 30) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(50, 10, 60, 70) ) + ; + + QTest::newRow("Two, 2h connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 1 vertical connection, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(30, 20, 160, 60) ) + ; + + QTest::newRow("Two, 1v connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 2 vertical connections, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(30, 20, 160, 50) ) + ; + + QTest::newRow("Two, 2v connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 1 horizontal and 1 vertical connection, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(80, 10, 40, 70) ) + ; + + QTest::newRow("Two, 1h+1v connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 2 horizontal and 2 vertical connections, first completely defined + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180) + + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 10, 80) ) + << BasicResult(1, QRectF(90, 20, 30, 60) ) + ; + + QTest::newRow("Two, 2h+2v connected") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other. + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 150) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 10) + + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 90) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 30, 60) ) + << BasicResult(1, QRectF(100, 20, 90, 60) ) + ; + + QTest::newRow("Two, 2h+2v connected2") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, connected, overlapping + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, 30) + // ### QGAL has different semantics and assumes right edges are always + // to the left of left edges. Thus we need the minus sign here. + << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -30) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 40) + + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 40) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + ; + + theResult + << BasicResult(0, QRectF(10, 10, 60, 40) ) + << BasicResult(1, QRectF(40, 20, 150, 70) ) + ; + + QTest::newRow("Two, connected overlapping") << QSizeF(200, 100) << theData << theResult; + } +} + +void TestGraphicsAnchorLayout::testNegativeSpacing_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // One widget, negative spacing + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + /// ### QGAL assumes items are always inside the layout. + // In this case, the negative spacing would make the item + // grow beyond the layout edges, which is OK, but gives a + // different result. + // Changing the direction of anchors (-1 to 0 or vice-versa) + // has no effect in this case. + + theData + // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20) + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30) + // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40) + + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, -10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -20) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, -30) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, -40) + + ; + + theResult + // << BasicResult(0, QRectF(20, 10, 150, 50) ) + << BasicResult(0, QRectF(-20, -10, 250, 150) ) + ; + + QTest::newRow("One, simple (n)") << QSizeF(200, 100) << theData << theResult; + } + + // One widget, duplicates, negative spacing + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -20) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40) + + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -10) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10) + ; + + theResult + // ### Same as above... + // << BasicResult(0, QRectF(10, 10, 180, 80) ) + << BasicResult(0, QRectF(-10, -10, 220, 120) ) + ; + + QTest::newRow("One, duplicates (n)") << QSizeF(200, 100) << theData << theResult; + } + + // One widget, mixed, negative spacing + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // ### All anchors of negative spacing between the layout and an + // item are handled as to make sure the item is _outside_ the + // layout. + // To keep it inside, one _must_ use positive spacings. + // << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, -80) + // << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, -150) + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, -150) + // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, -80) + + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, 80) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, 150) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, 150) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, 80) + ; + + theResult + << BasicResult(0, QRectF(50, 20, 100, 60) ) + ; + + QTest::newRow("One, mixed (n)") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 1 horizontal connection, first completely defined, negative spacing + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10) + // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10) + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -180) + + // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10) + // << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10) + // << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + // << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20) + + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 180) + + << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10) + << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10) + << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20) + + ; + + theResult + // << BasicResult(0, QRectF(10, 10, 10, 80) ) + // << BasicResult(1, QRectF(30, 10, 160, 70) ) + + << BasicResult(0, QRectF(-10, -10, 30, 120) ) + << BasicResult(1, QRectF(10, -10, 200, 130) ) + ; + + QTest::newRow("Two, 1h connected (n)") << QSizeF(200, 100) << theData << theResult; + } + + // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other, negative spacing + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10) + << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, -150) + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10) + + << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -90) + << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10) + << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, -10) + << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20) + ; + + theResult + // << BasicResult(0, QRectF(10, 10, 30, 60) ) + // << BasicResult(1, QRectF(100, 20, 90, 60) ) + << BasicResult(0, QRectF(-10, -10, 70, 120) ) + << BasicResult(1, QRectF(80, 0, 130, 120) ) + ; + + QTest::newRow("Two, 2h+2v connected2 (n)") << QSizeF(200, 100) << theData << theResult; + } +} + +void TestGraphicsAnchorLayout::testMixedSpacing_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // Two widgets, partial overlapping + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -50) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 50) + << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, 15) + + // << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, 5) + << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, -5) + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, -10) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 20) + << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -5) + ; + + theResult + // << BasicResult(0, QRectF(50, 10, 45, 40) ) + // << BasicResult(1, QRectF(40, 45, 40, 50) ) + << BasicResult(0, QRectF(-50, 10, 145, 40) ) + << BasicResult(1, QRectF(-60, 45, 140, 60) ) + ; + + QTest::newRow("Two, partial overlap") << QSizeF(100, 100) << theData << theResult; + } + + // Two widgets, complete overlapping + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 25) + + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5) + << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorRight, 50) + << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10) + ; + + theResult + << BasicResult(0, QRectF(65, 5, 35, 35) ) + << BasicResult(1, QRectF(40, 5, 60, 35) ) + ; + + QTest::newRow("Two, complete overlap") << QSizeF(90, 45) << theData << theResult; + } + + // Five widgets, v shaped, edges shared + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // edges shared + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 0) + << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 0) + << BasicData(2, Qt::AnchorRight, 3, Qt::AnchorLeft, 0) + << BasicData(3, Qt::AnchorRight, 4, Qt::AnchorLeft, 0) + << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 0) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 0) + << BasicData(3, Qt::AnchorBottom, 2, Qt::AnchorTop, 0) + << BasicData(4, Qt::AnchorBottom, 3, Qt::AnchorTop, 0) + << BasicData(0, Qt::AnchorBottom, 4, Qt::AnchorBottom, 0) + << BasicData(1, Qt::AnchorBottom, 3, Qt::AnchorBottom, 0) + << BasicData(0, Qt::AnchorTop, 4, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorTop, 3, Qt::AnchorTop, 0) + + // margins + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 5) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5) + << BasicData(2, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5) + // << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, -5) + << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, 5) + + // additional details for exact size determination easily + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 25) + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 50) + // << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, -25) + // << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, -50) + << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, 25) + << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, 50) + << BasicData(-1, Qt::AnchorTop, 3, Qt::AnchorBottom, 50) + // << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, -50) + << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, 50) + + ; + + theResult + << BasicResult(0, QRectF(5,5,20,20)) + << BasicResult(1, QRectF(25,25,25,25)) + << BasicResult(2, QRectF(50,50,25,20)) + << BasicResult(3, QRectF(75,25,25,25)) + << BasicResult(4, QRectF(100,5,20,20)) + ; + + QTest::newRow("Five, V shape") << QSizeF(125, 75) << theData << theResult; + } + + // ### The behavior is different in QGraphicsAnchorLayout. What happens here is + // that when the above anchors are set, the layout size hints are changed. + // In the example, the minimum item width is 5, thus the minimum layout width + // becomes 105 (50 + 5 + 50). Once that size hint is set, trying to set + // the widget size to (10, 10) is not possible because + // QGraphicsWidget::setGeometry() will enforce the minimum is respected. + if (0) + // One widget, unsolvable + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50) + ; + theResult + << BasicResult(0, QRectF(0,0,0,0)) + ; + + QTest::newRow("One widget, unsolvable") << QSizeF(10, 10) << theData << theResult; + } + + // ### BUG. We are not handling "floating" elements properly. Ie. elements that + // have no anchors in a given orientation. + if (0) + // Two widgets, one has fixed size + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50) + // not supported, use sizePolicy instead + // << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 50) + + << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 50) + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 50) + ; + theResult + << BasicResult(0, QRectF(50,0,50,50)) + << BasicResult(1, QRectF(50,0,50,50)) + ; + + QTest::newRow("Two widgets, one has fixed size") << QSizeF(150, 150) << theData << theResult; + } +} + +void TestGraphicsAnchorLayout::testMulti_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // Multiple widgets, all overllapping + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + const int n = 30; + for ( int i = 0 ; i < n; i++ ) { + theData + << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, 20) + << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, 10) + // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -40) + // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -30); + << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, 40) + << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, 30); + + theResult + << BasicResult(i, QRectF(10, 20, 160, 40) ); + } + + + QTest::newRow("Overlapping multi") << QSizeF(200, 100) << theData << theResult; + } + + // Multiple widgets, linear order + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + const qreal height = 1000.f; + const qreal width = 2000.f; + + const int n = 30; + + const qreal verticalStep = height/qreal(n+2); + const qreal horizontalStep = width/qreal(n+2); + + for ( int i = 0 ; i < n; i++ ) { + + if ( i == 0 ) { + // First item + theData + << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + + } else if ( i == n-1 ) { + // Last item + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep) + << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep); + // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + + } else { + // items in the middle + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + // << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + // << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + + } + + theResult + << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) ); + } + + + QTest::newRow("Linear multi") << QSizeF(width, height) << theData << theResult; + } + + // Multiple widgets, V shape + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + const qreal height = 100.f; + const qreal width = 200.f; + + const int n = 31; // odd number please (3,5,7... ) + + const qreal verticalStep = height/(2.f+(n+1)/2.f); + const qreal horizontalStep = width/(n+2.f); + + for ( int i = 0 ; i < n; i++ ) { + + if ( i == 0 ) { + // First item + theData + << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep); + + } else if ( i == n-1 ) { + // Last item + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i, Qt::AnchorRight, -1, Qt::AnchorRight, horizontalStep); + } else if ( i == ((n-1)/2) ) { + // midway + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep) + << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep); + } else if ( i < ((n-1)/2) ) { + // before midway - going down + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep); + + } else { + // after midway - going up + theData + << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep) + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep); + + } + + if ( i <= ((n-1)/2) ) { + // until midway + theResult + << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) ); + } else { + // after midway + theResult + << BasicResult(i, QRectF((i+1)*horizontalStep, (n-i)*verticalStep, horizontalStep, verticalStep) ); + } + + } + QTest::newRow("V multi") << QSizeF(width, height) << theData << theResult; + } + + // Multiple widgets, grid + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + const qreal height = 100.f; + const qreal width = 200.f; + + const int d = 10; // items per dimension + const int n = d*d; + + const qreal verticalStep = height/(d+2.f); + const qreal horizontalStep = width/(d+2.f); + + for ( int i = 0 ; i < n; i++ ) { + if ( i%d == 0 ) { + // left side item + theData + << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + } else if ( (i+1)%d == 0 ) { + // rigth side item + theData + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep); + } else { + // horizontal middle + theData + << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep) + << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep); + } + + if ( i < d ) { + // top line + theData + << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep); + } else if ( i >= (d-1)*d ){ + // bottom line + theData + << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep) + << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep); + } else { + // vertical middle + theData + << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep) + << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep); + } + + theResult + << BasicResult(i, QRectF(((i%d)+1)*horizontalStep, ((i/d)+1)*verticalStep, horizontalStep, verticalStep) ); + } + + QTest::newRow("Grid multi") << QSizeF(200, 100) << theData << theResult; + } +} + +inline QGraphicsLayoutItem *getItem( + int index, + const QList& widgets, + QGraphicsLayoutItem *defaultItem) +{ + if (index < 0) { + return defaultItem; + } + + return widgets[index]; +} + +void TestGraphicsAnchorLayout::testBasicLayout() +{ + QFETCH(QSizeF, size); + QFETCH(BasicLayoutTestDataList, data); + QFETCH(BasicLayoutTestResultList, result); + + QGraphicsWidget *widget = new QGraphicsWidget; + + // Determine amount of widgets to add. + int widgetCount = -1; + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + widgetCount = qMax(widgetCount, item.firstIndex); + widgetCount = qMax(widgetCount, item.secondIndex); + } + ++widgetCount; // widgetCount is max of indices. + + // Create dummy widgets + QList widgets; + for (int i = 0; i < widgetCount; ++i) { + TestWidget *w = new TestWidget; + widgets << w; + } + + // Setup anchor layout + TheAnchorLayout *layout = new TheAnchorLayout; + + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + layout->setAnchor( + getItem(item.firstIndex, widgets, layout), + item.firstEdge, + getItem(item.secondIndex, widgets, layout), + item.secondEdge, + item.spacing ); + } + + widget->setLayout(layout); + widget->setContentsMargins(0,0,0,0); + + widget->setMinimumSize(size); + widget->setMaximumSize(size); + +// QTest::qWait(500); // layouting is asynchronous.. + + // Validate + for (int i = 0; i < result.count(); ++i) { + const BasicLayoutTestResult item = result[i]; + QCOMPARE(widgets[item.index]->geometry(), item.rect); + } + + // ###: not supported yet +/* + // Test mirrored mode + widget->setLayoutDirection(Qt::RightToLeft); + layout->activate(); + // Validate + for (int j = 0; j < result.count(); ++j) { + const BasicLayoutTestResult item = result[j]; + QRectF mirroredRect(item.rect); + // only valid cases are mirrored + if (mirroredRect.isValid()){ + mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left()); + } + QCOMPARE(widgets[item.index]->geometry(), mirroredRect); + delete widgets[item.index]; + } +*/ + delete widget; +} + +void TestGraphicsAnchorLayout::testNegativeSpacing() +{ + // use the same frame + testBasicLayout(); +} + +void TestGraphicsAnchorLayout::testMixedSpacing() +{ + // use the same frame + testBasicLayout(); +} + +void TestGraphicsAnchorLayout::testMulti() +{ + // use the same frame + testBasicLayout(); +} + +void TestGraphicsAnchorLayout::testCenterAnchors_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // Basic center case + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5); + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("center, basic") << QSizeF(20, 20) << theData << theResult; + } + + // Basic center case, with invalid (shouldn't affect on result) + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5) + + // bogus definitions + << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorBottom, 5) + << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorVerticalCenter, 5) + << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorRight, 5) + << BasicData(0, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 666) + << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 999) + << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorLeft, 333) + << BasicData(-1, Qt::AnchorRight, -1, Qt::AnchorRight, 222) + << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorTop, 111) + << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorBottom, 444); + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult; + } + + // Basic center case 2 + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0) + // Not supported << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5) + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5); + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("center, basic 2") << QSizeF(20, 20) << theData << theResult; + } + + // Basic center case, overrides + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 20) + << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 30) + << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 40) + // actual data: + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0) + // << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5) + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5); + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("center, overrides") << QSizeF(20, 20) << theData << theResult; + } + + // Two nested + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorLeft, 0) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0) + << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorTop, 0) + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 0); + + theResult + << BasicResult(0, QRectF(20, 0, 20, 40)) + << BasicResult(1, QRectF(20, 20, 20, 20)); + + QTest::newRow("center, two nested") << QSizeF(40, 40) << theData << theResult; + } + + // Two overlap + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + // theData + // // horizontal + // << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20) + // << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0) + // << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5) + // << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + // << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 10) + // // vertical is pretty much same as horizontal, just roles swapped + // << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20) + // << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0) + // << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, -5) + // << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10) + // << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, 10); + + theData + // horizontal + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20) + << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorHorizontalCenter, 5) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 20) + // vertical + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20) + << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorVerticalCenter, 5) + << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20); + + theResult + << BasicResult(0, QRectF(20, 30, 20, 30)) + << BasicResult(1, QRectF(30, 20, 30, 20)); + + QTest::newRow("center, two overlap") << QSizeF(70, 70) << theData << theResult; + } + + // Three + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0) + << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75) + << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10) + << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0) + << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + + << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35) + << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15) + << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0) + << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5) + << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20); + + theResult + << BasicResult(0, QRectF(0, 30, 10, 20)) + << BasicResult(1, QRectF(20, 0, 30, 10)) + << BasicResult(2, QRectF(60, 15, 40, 10)); + + QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult; + } + + // Two, parent center + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // vertical is pretty much same as horizontal, just roles swapped + << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, -15) + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 10) + << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0) + << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + // horizontal + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -15) + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0) + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0); + + theResult + << BasicResult(0, QRectF(20, 20, 30, 80)) + << BasicResult(1, QRectF(20, 20, 80, 30)); + + QTest::newRow("center, parent") << QSizeF(100, 100) << theData << theResult; + } + + // Two, parent center 2 + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, 15) + << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, -15) + << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 5) + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorRight, -5) + // vertical + << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 20) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 20) + << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 20) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10); + + theResult + << BasicResult(0, QRectF(30, 10, 15, 10)) + << BasicResult(1, QRectF(10, 30, 10, 10)); + + QTest::newRow("center, parent 2") << QSizeF(50, 50) << theData << theResult; + } + + // Two, parent center 3 + { + BasicLayoutTestDataList theData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5) + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 5) + // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100) + << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100) + << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, 0) + + // vertical + << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55) + << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0) + << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10) + // << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 45) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 45) + ; + + theResult + << BasicResult(0, QRectF(0, 0, 45, 45)) + << BasicResult(1, QRectF(55, 55, 45, 45)); + + QTest::newRow("center, parent 3") << QSizeF(100, 100) << theData << theResult; + } + +} + +void TestGraphicsAnchorLayout::testCenterAnchors() +{ + // use the same frame + testBasicLayout(); +} + +void TestGraphicsAnchorLayout::testRemoveCenterAnchor_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("removeData"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + { + BasicLayoutTestDataList theData; + BasicLayoutTestDataList theRemoveData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5) + + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66) + << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99) + << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33) + ; + + theRemoveData + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0) + << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 0) + << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0); + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("remove, center, basic") << QSizeF(20, 20) << theData + << theRemoveData << theResult; + } + + { + BasicLayoutTestDataList theData; + BasicLayoutTestDataList theRemoveData; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0) + << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75) + << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10) + << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0) + << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + + // extra: + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66) + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33) + << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55) + << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55) + + << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0) + << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35) + << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15) + << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0) + << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5) + << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20); + + theRemoveData + << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66) + << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33) + << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55) + << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55); + + theResult + << BasicResult(0, QRectF(0, 30, 10, 20)) + << BasicResult(1, QRectF(20, 0, 30, 10)) + << BasicResult(2, QRectF(60, 15, 40, 10)); + + QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult; + } + + // add edge (item0,edge0,item1,edge1), remove (item1,edge1,item0,edge0) + { + BasicLayoutTestDataList theData; + BasicLayoutTestDataList theRemoveData; + BasicLayoutTestResultList theResult; + + theData + // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10) + << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10) + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15) + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10) + << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5) + + << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66) + << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99) + << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33) + << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 22) + << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 11) + ; + + theRemoveData + << BasicData(1, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 0) + << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 0) + << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0) + << BasicData(0, Qt::AnchorRight, 0, Qt::AnchorLeft, 0) + << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorTop, 0) + ; + + theResult + << BasicResult(0, QRectF(5, 5, 10, 10) ); + + QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData + << theRemoveData << theResult; + } + +} + +void TestGraphicsAnchorLayout::testRemoveCenterAnchor() +{ + QFETCH(QSizeF, size); + QFETCH(BasicLayoutTestDataList, data); + QFETCH(BasicLayoutTestDataList, removeData); + QFETCH(BasicLayoutTestResultList, result); + + QGraphicsWidget *widget = new QGraphicsWidget; + + // Determine amount of widgets to add. + int widgetCount = -1; + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + widgetCount = qMax(widgetCount, item.firstIndex); + widgetCount = qMax(widgetCount, item.secondIndex); + } + ++widgetCount; // widgetCount is max of indices. + + // Create dummy widgets + QList widgets; + for (int i = 0; i < widgetCount; ++i) { + TestWidget *w = new TestWidget; + widgets << w; + } + + // Setup anchor layout + TheAnchorLayout *layout = new TheAnchorLayout; + + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + layout->setAnchor( + getItem(item.firstIndex, widgets, layout), + item.firstEdge, + getItem(item.secondIndex, widgets, layout), + item.secondEdge, + item.spacing ); + } + + for (int i = 0; i < removeData.count(); ++i) { + const BasicLayoutTestData item = removeData[i]; + layout->removeAnchor( + getItem(item.firstIndex, widgets, layout), + item.firstEdge, + getItem(item.secondIndex, widgets, layout), + item.secondEdge); + } + + widget->setLayout(layout); + widget->setContentsMargins(0,0,0,0); + + widget->setMinimumSize(size); + widget->setMaximumSize(size); + + // Validate + for (int i = 0; i < result.count(); ++i) { + const BasicLayoutTestResult item = result[i]; + + QCOMPARE(widgets[item.index]->geometry(), item.rect); + delete widgets[item.index]; + } + delete widget; +} + +void TestGraphicsAnchorLayout::testSingleSizePolicy_data() +{ + QTest::addColumn("size"); + QTest::addColumn("policy"); + QTest::addColumn("valid"); + +// FIXED + { + QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + QTest::newRow("single size policy: fixed ok") << QSizeF(70, 70) << sizePolicy << true; + } +/* + { + QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + QTest::newRow("single size policy: fixed too big") << QSizeF(100, 100) << sizePolicy << false; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + QTest::newRow("single size policy: fixed too small") << QSizeF(50, 50) << sizePolicy << false; + } +*/ +// MINIMUM + { + QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + QTest::newRow("single size policy: minimum bigger ok") << QSizeF(100, 100) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + QTest::newRow("single size policy: minimum limit ok") << QSizeF(70, 70) << sizePolicy << true; + } +/* + { + QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + QTest::newRow("single size policy: minimum too small") << QSizeF(50, 50) << sizePolicy << false; + } +*/ +// MAXIMUM + { + QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + QTest::newRow("single size policy: maximum small ok") << QSizeF(50, 50) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + QTest::newRow("single size policy: maximum limit ok") << QSizeF(70, 70) << sizePolicy << true; + } +/* + { + QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + QTest::newRow("single size policy: maximum bigger fail") << QSizeF(100, 100) << sizePolicy << false; + } +*/ +// PREFERRED + { + QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QTest::newRow("single size policy: preferred bigger ok") << QSizeF(100, 100) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QTest::newRow("single size policy: preferred smaller ok") << QSizeF(50, 50) << sizePolicy << true; + } +/* + { + QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QTest::newRow("single size policy: preferred too big") << QSizeF(700, 700) << sizePolicy << false; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QTest::newRow("single size policy: preferred too small") << QSizeF(21, 21) << sizePolicy << false; + } +*/ +// MINIMUMEXPANDING + + { + QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + QTest::newRow("single size policy: min.expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + QTest::newRow("single size policy: min.expanding limit ok") << QSizeF(70, 70) << sizePolicy << true; + } + + /*{ + QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + QTest::newRow("single size policy: min.expanding too small") << QSizeF(50, 50) << sizePolicy << false; + }*/ + +// EXPANDING + + { + QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + QTest::newRow("single size policy: expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + QTest::newRow("single size policy: expanding smaller ok") << QSizeF(50, 50) << sizePolicy << true; + } + + // IGNORED + + { + QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ); + QTest::newRow("single size policy: ignored bigger ok") << QSizeF(100, 100) << sizePolicy << true; + } + + { + QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ); + QTest::newRow("single size policy: ignored smaller ok") << QSizeF(50, 50) << sizePolicy << true; + } +} + +void TestGraphicsAnchorLayout::testSingleSizePolicy() +{ + QFETCH(QSizeF, size); + QFETCH(QSizePolicy, policy); + QFETCH(bool, valid); + + // create objects + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout; + TestWidget *childWidget = new TestWidget; + + // set anchors + layout->setAnchor( layout, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 10 ); + layout->setAnchor( childWidget, Qt::AnchorRight, layout, Qt::AnchorRight, 10 ); + layout->setAnchor( layout, Qt::AnchorTop, childWidget, Qt::AnchorTop, 10 ); + layout->setAnchor( childWidget, Qt::AnchorBottom, layout, Qt::AnchorBottom, 10 ); + + widget->setLayout( layout ); + + // set test case specific: policy and size + childWidget->setSizePolicy( policy ); + widget->setGeometry( QRectF( QPoint(0,0), size ) ); + + QCOMPARE( layout->isValid() , valid ); + + const QRectF childRect = childWidget->geometry(); + Q_UNUSED( childRect ); +} + +void TestGraphicsAnchorLayout::testDoubleSizePolicy_data() +{ + // tests only horizontal direction + QTest::addColumn("policy1"); + QTest::addColumn("policy2"); + QTest::addColumn("width1"); + QTest::addColumn("width2"); + + // layout size always 100x100 and size hints for items are 5<50<500 + // gabs: 10-item1-10-item2-10 + + { + QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 50; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: fixed-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 50; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: minimum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 35; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: maximum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 35; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: preferred-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 50; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: min.expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 35; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored ); + QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred ); + const qreal width1 = 35; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: ignored-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + /*{ + QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = -1; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: fixed-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2; + }*/ + + /*{ + QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = -1; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: minimum-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2; + }*/ + + { + QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = 20; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: maximum-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = 20; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: preferred-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + /*{ + QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = -1; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: min.expanding-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2; + }*/ + + { + QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = 20; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: expanding-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2; + } + + { + QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored ); + QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed ); + const qreal width1 = 20; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("double size policy: ignored-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2; + } +} + +void TestGraphicsAnchorLayout::testDoubleSizePolicy() +{ + // ### Size policy is not yet supported + return; + + QFETCH(QSizePolicy, policy1); + QFETCH(QSizePolicy, policy2); + QFETCH(qreal, width1); + QFETCH(qreal, width2); + + // create objects + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout; + TestWidget *childWidget1 = new TestWidget; + TestWidget *childWidget2 = new TestWidget; + + // set anchors + layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 ); + layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 ); + layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 ); + + widget->setLayout( layout ); + + // set test case specific: policy + childWidget1->setSizePolicy( policy1 ); + childWidget2->setSizePolicy( policy2 ); + + widget->setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); + + // check results: + if ( width1 == -1.0f ) { + // invalid + QCOMPARE( layout->isValid() , false ); + } else { + // valid + QCOMPARE( childWidget1->geometry().width(), width1 ); + QCOMPARE( childWidget2->geometry().width(), width2 ); + } +} + +typedef QMap SizeHintArray; +Q_DECLARE_METATYPE(SizeHintArray) + +void TestGraphicsAnchorLayout::testSizeDistribution_data() +{ + // tests only horizontal direction + QTest::addColumn("sizeHints1"); + QTest::addColumn("sizeHints2"); + QTest::addColumn("width1"); + QTest::addColumn("width2"); + + // layout size always 100x100 and size policy for items is preferred-preferred + // gabs: 10-item1-10-item2-10 + + { + SizeHintArray sizeHints1; + sizeHints1.insert( Qt::MinimumSize, 30 ); + sizeHints1.insert( Qt::PreferredSize, 35 ); + sizeHints1.insert( Qt::MaximumSize, 40 ); + Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + + SizeHintArray sizeHints2; + sizeHints2.insert( Qt::MinimumSize, 5 ); + sizeHints2.insert( Qt::PreferredSize, 35 ); + sizeHints2.insert( Qt::MaximumSize, 300 ); + Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + + const qreal width1 = 35; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("size distribution: preferred equal") << sizeHints1 << sizeHints2 << width1 << width2; + } + + { + SizeHintArray sizeHints1; + sizeHints1.insert( Qt::MinimumSize, 0 ); + sizeHints1.insert( Qt::PreferredSize, 20 ); + sizeHints1.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + + SizeHintArray sizeHints2; + sizeHints2.insert( Qt::MinimumSize, 0 ); + sizeHints2.insert( Qt::PreferredSize, 50 ); + sizeHints2.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + + const qreal width1 = 20; + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("size distribution: preferred non-equal") << sizeHints1 << sizeHints2 << width1 << width2; + } + + { + SizeHintArray sizeHints1; + sizeHints1.insert( Qt::MinimumSize, 0 ); + sizeHints1.insert( Qt::PreferredSize, 40 ); + sizeHints1.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + + SizeHintArray sizeHints2; + sizeHints2.insert( Qt::MinimumSize, 0 ); + sizeHints2.insert( Qt::PreferredSize, 60 ); + sizeHints2.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + + const qreal width1 = 28; // got from manual calculation + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("size distribution: below preferred") << sizeHints1 << sizeHints2 << width1 << width2; + } + + { + SizeHintArray sizeHints1; + sizeHints1.insert( Qt::MinimumSize, 0 ); + sizeHints1.insert( Qt::PreferredSize, 10 ); + sizeHints1.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + + SizeHintArray sizeHints2; + sizeHints2.insert( Qt::MinimumSize, 0 ); + sizeHints2.insert( Qt::PreferredSize, 40 ); + sizeHints2.insert( Qt::MaximumSize, 100 ); + Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + + const qreal width1 = 22; // got from manual calculation + const qreal width2 = 100-10-10-10-width1; + QTest::newRow("size distribution: above preferred") << sizeHints1 << sizeHints2 << width1 << width2; + } + +} + +void TestGraphicsAnchorLayout::testSizeDistribution() +{ + QFETCH(SizeHintArray, sizeHints1); + QFETCH(SizeHintArray, sizeHints2); + QFETCH(qreal, width1); + QFETCH(qreal, width2); + + // create objects + QGraphicsWidget *widget = new QGraphicsWidget; + TheAnchorLayout *layout = new TheAnchorLayout; + TestWidget *childWidget1 = new TestWidget; + TestWidget *childWidget2 = new TestWidget; + + // set anchors + layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 ); + layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 ); + layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 ); + + widget->setLayout( layout ); + + // set test case specific: size hints + childWidget1->setMinimumWidth( sizeHints1.value( Qt::MinimumSize ) ); + childWidget1->setPreferredWidth( sizeHints1.value( Qt::PreferredSize ) ); + childWidget1->setMaximumWidth( sizeHints1.value( Qt::MaximumSize ) ); + + childWidget2->setMinimumWidth( sizeHints2.value( Qt::MinimumSize ) ); + childWidget2->setPreferredWidth( sizeHints2.value( Qt::PreferredSize ) ); + childWidget2->setMaximumWidth( sizeHints2.value( Qt::MaximumSize ) ); + + widget->setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); + + // check results: + if ( width1 == -1.0f ) { + // invalid + QCOMPARE( layout->isValid() , false ); + } else { + // valid + QCOMPARE( float(childWidget1->geometry().width()), float(width1) ); + QCOMPARE( float(childWidget2->geometry().width()), float(width2) ); + } +} + +void TestGraphicsAnchorLayout::testSizeHint() +{ + QGraphicsWidget *widget[5]; + + for( int i = 0; i < 5; i++ ) { + widget[i] = new QGraphicsWidget; + widget[i]->setMinimumSize( 10, 10 ); + widget[i]->setPreferredSize( 20, 20 ); + widget[i]->setMaximumSize( 40, 40 ); + } + + // one, basic + { + TheAnchorLayout *layout = new TheAnchorLayout(); + + + layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 ); + layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 ); + + layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 ); + + QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() ); + QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() ); + QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() ); + + + delete layout; + } + + // one, basic again + { + TheAnchorLayout *layout = new TheAnchorLayout(); + + + layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 10 ); + // layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, -10 ); + layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 10 ); + + layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 10 ); + // layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, -10 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 10 ); + + QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( 20, 20 ) ); + QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( 20, 20 ) ); + QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( 20, 20 ) ); + + delete layout; + } + + // two, serial + { + TheAnchorLayout *layout = new TheAnchorLayout(); + + + layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 ); + layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 ); + + layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 ); + layout->setAnchor(widget[1], Qt::AnchorRight, layout, Qt::AnchorRight, 0 ); + + + QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( widget[1]->minimumWidth(), 0 ) ); + QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( widget[1]->preferredWidth(), 0 ) ); + QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( widget[1]->maximumWidth(), 0 ) ); + + delete layout; + } + + // two, parallel + { + TheAnchorLayout *layout = new TheAnchorLayout(); + + + layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 ); + layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 ); + layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 ); + + layout->setAnchor(layout, Qt::AnchorLeft, widget[1], Qt::AnchorLeft, 0 ); + layout->setAnchor(layout, Qt::AnchorTop, widget[1], Qt::AnchorTop, 0 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[1], Qt::AnchorBottom, 0 ); + layout->setAnchor(layout, Qt::AnchorRight, widget[1], Qt::AnchorRight, 0 ); + + QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() ); + QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() ); + QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() ); + + delete layout; + } + + // five, serial + { + TheAnchorLayout *layout = new TheAnchorLayout(); + + + layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 ); + layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 ); + layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 ); + + layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 ); + layout->setAnchor(widget[1], Qt::AnchorRight, widget[2], Qt::AnchorLeft, 0 ); + layout->setAnchor(widget[2], Qt::AnchorRight, widget[3], Qt::AnchorLeft, 0 ); + layout->setAnchor(widget[3], Qt::AnchorRight, widget[4], Qt::AnchorLeft, 0 ); + layout->setAnchor(widget[4], Qt::AnchorRight, layout, Qt::AnchorRight, 0 ); + + + QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + + QSizeF( widget[1]->minimumWidth() + + widget[2]->minimumWidth() + + widget[3]->minimumWidth() + + widget[4]->minimumWidth(), 0 ) ); + + QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + + QSizeF( widget[1]->preferredWidth() + + widget[2]->preferredWidth() + + widget[3]->preferredWidth() + + widget[4]->preferredWidth(), 0 ) ); + + QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + + QSizeF( widget[1]->maximumWidth() + + widget[2]->maximumWidth() + + widget[3]->maximumWidth() + + widget[4]->maximumWidth(), 0 ) ); + + delete layout; + } + + + for( int i = 0; i < 5; i++ ) { + delete widget[i]; + } +} + +#ifdef TEST_COMPLEX_CASES + +void TestGraphicsAnchorLayout::testComplexCases_data() +{ + QTest::addColumn("size"); + QTest::addColumn("data"); + QTest::addColumn("sizehint"); + QTest::addColumn("result"); + + typedef BasicLayoutTestData BasicData; + typedef BasicLayoutTestResult BasicResult; + + // Three widgets, the same sizehint + { + BasicLayoutTestDataList theData; + AnchorItemSizeHintList theSizeHint; + BasicLayoutTestResultList theResult1; + BasicLayoutTestResultList theResult2; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10) + + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0) + ; + + theSizeHint + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + ; + theResult1 + << BasicResult(0, QRectF(10, 0, 30, 50) ) + << BasicResult(1, QRectF(50, 0, 30, 50) ) + << BasicResult(2, QRectF(50, 0, 30, 50) ) + ; + + theResult2 + << BasicResult(0, QRectF(10, 0, 60, 50) ) + << BasicResult(1, QRectF(80, 0, 60, 50) ) + << BasicResult(2, QRectF(80, 0, 60, 50) ) + ; + + QTest::newRow("Three, the same sizehint(1)") << QSizeF(90, 50) << theData << theSizeHint << theResult1; + QTest::newRow("Three, the same sizehint(2)") << QSizeF(150, 50) << theData << theSizeHint << theResult2; + } + + // Three widgets, serial is bigger + { + BasicLayoutTestDataList theData; + AnchorItemSizeHintList theSizeHint; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10) + + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0) + ; + + theSizeHint + << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + ; + + theResult + << BasicResult(0, QRectF(10, 0, 70, 50) ) + << BasicResult(1, QRectF(90, 0, 35, 50) ) + << BasicResult(2, QRectF(90, 0, 35, 50) ); + + QTest::newRow("Three, serial is bigger") << QSizeF(135, 50) << theData << theSizeHint << theResult; + + // theResult + // << BasicResult(0, QRectF(10, 0, 80, 50) ) + // << BasicResult(1, QRectF(100, 0, 60, 50) ) + // << BasicResult(2, QRectF(100, 0, 60, 50) ) + // ; + + // QTest::newRow("Three, serial is bigger") << QSizeF(170, 50) << theData << theSizeHint << theResult; + } + + + // Three widgets, parallel is bigger + { + BasicLayoutTestDataList theData; + AnchorItemSizeHintList theSizeHint; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10) + + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0) + ; + + theSizeHint + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + ; + + // ### QGAL uses a different preferred size calculation algorithm. + // This algorithm was discussed with Jan-Arve and tries to grow + // items instead of shrinking them. + // In this case, the preferred size of each item becomes: + // Item 0: 50 + // Item 1: 100 (grows to avoid shrinking item 2) + // Item 2: 100 + // Therefore, the preferred size of the parent widget becomes + // 180 == (10 + 50 + 10 + 100 + 10) + // As we set its size to 150, each widget is shrinked in the same + // ratio, in order to achieve the width of 150 == (10 + 40 + 10 + 80 + 10) + + theResult + << BasicResult(0, QRectF(10, 0, 40, 50) ) + << BasicResult(1, QRectF(60, 0, 80, 50) ) + << BasicResult(2, QRectF(60, 0, 80, 50) ) + ; + + QTest::newRow("Three, parallel is bigger") << QSizeF(150, 50) << theData << theSizeHint << theResult; + + // #ifdef PREFERRED_IS_AVERAGE + // theResult + // << BasicResult(0, QRectF(10, 0, 50, 50) ) + // << BasicResult(1, QRectF(70, 0, 75, 50) ) + // << BasicResult(2, QRectF(70, 0, 75, 50) ) + // ; + + // QTest::newRow("Three, parallel is bigger") << QSizeF(155, 50) << theData << theSizeHint << theResult; + // #else + // theResult + // << BasicResult(0, QRectF(10, 0, 50, 50) ) + // << BasicResult(1, QRectF(70, 0, 66.66666666666666, 50) ) + // << BasicResult(2, QRectF(70, 0, 60.66666666666666, 50) ) + // ; + + // QTest::newRow("Three, parallel is bigger") << QSizeF(146.66666666666666, 50) << theData << theSizeHint << theResult; + // #endif + } + + // Three widgets, the same sizehint, one center anchor + { + BasicLayoutTestDataList theData; + AnchorItemSizeHintList theSizeHint; + BasicLayoutTestResultList theResult; + + theData + << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10) + << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorLeft, 10) + + << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10) + + << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0) + << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0) + ; + + theSizeHint + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 ) + ; + theResult + << BasicResult(0, QRectF(10, 0, 40, 50) ) + << BasicResult(1, QRectF(60, 0, 40, 50) ) + << BasicResult(2, QRectF(40, 0, 60, 50) ) + ; + + ; + + QTest::newRow("Three, the same sizehint, one center anchor") << QSizeF(110, 50) << theData << theSizeHint << theResult; + } +} + +void TestGraphicsAnchorLayout::testComplexCases() +{ + QFETCH(QSizeF, size); + QFETCH(BasicLayoutTestDataList, data); + QFETCH(AnchorItemSizeHintList, sizehint); + QFETCH(BasicLayoutTestResultList, result); + + QGraphicsWidget *widget = new QGraphicsWidget; + + // Determine amount of widgets to add. + int widgetCount = -1; + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + widgetCount = qMax(widgetCount, item.firstIndex); + widgetCount = qMax(widgetCount, item.secondIndex); + } + ++widgetCount; // widgetCount is max of indices. + + // Create dummy widgets + QList widgets; + for (int i = 0; i < widgetCount; ++i) { + TestWidget *w = new TestWidget; + + w->setMinimumWidth( sizehint[i].hmin ); + w->setPreferredWidth( sizehint[i].hpref ); + w->setMaximumWidth( sizehint[i].hmax ); + + w->setMinimumHeight( sizehint[i].vmin ); + w->setPreferredHeight( sizehint[i].vpref ); + w->setMaximumHeight( sizehint[i].vmax ); + + widgets << w; + } + + // Setup anchor layout + TheAnchorLayout *layout = new TheAnchorLayout; + + for (int i = 0; i < data.count(); ++i) { + const BasicLayoutTestData item = data[i]; + layout->setAnchor( + getItem(item.firstIndex, widgets, layout), + item.firstEdge, + getItem(item.secondIndex, widgets, layout), + item.secondEdge, + item.spacing ); + } + + widget->setLayout(layout); + widget->setContentsMargins(0,0,0,0); + + widget->setMinimumSize(size); + widget->setMaximumSize(size); + +// QTest::qWait(500); // layouting is asynchronous.. + + // Validate + for (int i = 0; i < result.count(); ++i) { + const BasicLayoutTestResult item = result[i]; + QCOMPARE(widgets[item.index]->geometry(), item.rect); + } + + // Test mirrored mode + widget->setLayoutDirection(Qt::RightToLeft); + layout->activate(); + // Validate + for (int j = 0; j < result.count(); ++j) { + const BasicLayoutTestResult item = result[j]; + QRectF mirroredRect(item.rect); + // only valid cases are mirrored + if (mirroredRect.isValid()){ + mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left()); + } + QCOMPARE(widgets[item.index]->geometry(), mirroredRect); + delete widgets[item.index]; + } + + delete widget; +} +#endif //TEST_COMPLEX_CASES + + +QTEST_MAIN(TestGraphicsAnchorLayout) +#include "tst_qgraphicsanchorlayout1.moc" +//----------------------------------------------------------------------------- + -- cgit v0.12 From a05d2ad1f34303b4ec9b982c75d3a046384364df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 17 Sep 2009 12:58:16 +0200 Subject: Add QTest::ignoreMessage() calls in order to reduce some console noise. --- .../tst_qgraphicsanchorlayout1.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 44c74d0..79d7beb 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -405,7 +405,9 @@ void TestGraphicsAnchorLayout::testAddAndRemoveAnchor() QCOMPARE( layout->count(), 4 ); // test setting invalid anchors + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items"); layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items"); layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1); QCOMPARE( layout->count(), 4 ); @@ -413,11 +415,13 @@ void TestGraphicsAnchorLayout::testAddAndRemoveAnchor() layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight); // anchor one horizontal edge with vertical edge. it should not add this widget as a child + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10); QCOMPARE( layout->count(), 4 ); // ###: NOT SUPPORTED // anchor two edges of a widget (to define width / height) + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10); // QCOMPARE( layout->count(), 5 ); QCOMPARE( layout->count(), 4 ); @@ -547,6 +551,9 @@ void TestGraphicsAnchorLayout::testSpecialCases() { // One widget, setLayout before defining layouts { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\"" + " in wrong parent; moved to correct parent"); + QGraphicsWidget *widget = new QGraphicsWidget; TheAnchorLayout *layout = new TheAnchorLayout(); widget->setLayout(layout); @@ -565,6 +572,8 @@ void TestGraphicsAnchorLayout::testSpecialCases() // One widget, layout inside layout, layout inside layout inside layout { + QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\"" + " in wrong parent; moved to correct parent"); QGraphicsWidget *widget = new QGraphicsWidget; TheAnchorLayout *layout = new TheAnchorLayout(); widget->setLayout(layout); @@ -1798,6 +1807,15 @@ void TestGraphicsAnchorLayout::testCenterAnchors_data() theResult << BasicResult(0, QRectF(5, 5, 10, 10) ); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult; } @@ -1929,6 +1947,9 @@ void TestGraphicsAnchorLayout::testCenterAnchors_data() << BasicResult(1, QRectF(20, 0, 30, 10)) << BasicResult(2, QRectF(60, 15, 40, 10)); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult; } @@ -2095,6 +2116,11 @@ void TestGraphicsAnchorLayout::testRemoveCenterAnchor_data() << BasicResult(1, QRectF(20, 0, 30, 10)) << BasicResult(2, QRectF(60, 15, 40, 10)); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult; } @@ -2129,6 +2155,8 @@ void TestGraphicsAnchorLayout::testRemoveCenterAnchor_data() theResult << BasicResult(0, QRectF(5, 5, 10, 10) ); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself"); QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData << theRemoveData << theResult; } -- cgit v0.12 From c2443b9d2cadb220012d37e4ed6a5973a6cc6abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 17 Sep 2009 13:40:15 +0200 Subject: Add QEXPECT_FAIL for the one test that fails. Note that t does not fail with simplification turned off (QT_ANCHORLAYOUT_NO_SIMPLIFICATION=1) --- tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 79d7beb..1216b76 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -1712,6 +1712,8 @@ void TestGraphicsAnchorLayout::testBasicLayout() // Validate for (int i = 0; i < result.count(); ++i) { + if (i == 1) + QEXPECT_FAIL("Two, mixed", "Works with simplification disabled.", Continue); const BasicLayoutTestResult item = result[i]; QCOMPARE(widgets[item.index]->geometry(), item.rect); } -- cgit v0.12