From 33d1c616d8d4085ba6fa848bafaec66576eba224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 9 Sep 2009 15:54:40 +0200 Subject: Respect the layoutDirection property of the parent widget. Add a layoutDirection autotest, and sprinkle some of the tests with checkReverseDirection() Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 2 +- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 45 ++++++++----- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- .../tst_qgraphicsanchorlayout.cpp | 78 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 3bb8c29..c7033c6 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -383,7 +383,7 @@ void QGraphicsAnchorLayout::setGeometry(const QRectF &geom) QGraphicsLayout::setGeometry(geom); d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Horizontal); d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Vertical); - d->setItemsGeometries(); + d->setItemsGeometries(geom); } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 787060f..f81ede0 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1772,20 +1772,42 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) Use the current vertices distance to calculate and set the geometry of each item. */ -void QGraphicsAnchorLayoutPrivate::setItemsGeometries() +void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom) { + Q_Q(QGraphicsAnchorLayout); AnchorVertex *firstH, *secondH, *firstV, *secondV; + qreal top; + qreal left; + qreal right; + + q->getContentsMargins(&left, &top, &right, 0); + const Qt::LayoutDirection visualDir = visualDirection(); + if (visualDir == Qt::RightToLeft) + qSwap(left, right); + + left += geom.left(); + top += geom.top(); + right = geom.right() - right; + foreach (QGraphicsLayoutItem *item, items) { firstH = internalVertex(item, Qt::AnchorLeft); secondH = internalVertex(item, Qt::AnchorRight); firstV = internalVertex(item, Qt::AnchorTop); secondV = internalVertex(item, Qt::AnchorBottom); - QPointF topLeft(firstH->distance, firstV->distance); - QPointF bottomRight(secondH->distance, secondV->distance); + QRectF newGeom; + newGeom.setTop(top + firstV->distance); + newGeom.setBottom(top + secondV->distance); - item->setGeometry(QRectF(topLeft, bottomRight)); + if (visualDir == Qt::LeftToRight) { + newGeom.setLeft(left + firstH->distance); + newGeom.setRight(left + secondH->distance); + } else { + newGeom.setLeft(right - secondH->distance); + newGeom.setRight(right - firstH->distance); + } + item->setGeometry(newGeom); } } @@ -1798,26 +1820,13 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries() void QGraphicsAnchorLayoutPrivate::calculateVertexPositions( QGraphicsAnchorLayoutPrivate::Orientation orientation) { - Q_Q(QGraphicsAnchorLayout); QQueue > queue; QSet visited; // Get root vertex AnchorVertex *root = graph[orientation].rootVertex(); - qreal widgetMargin; - qreal layoutMargin; - - // Initialize the first vertex - if (orientation == Horizontal) { - widgetMargin = q->geometry().x(); - q->getContentsMargins(&layoutMargin, 0, 0, 0); - } else { - // Root position is equal to the top margin - widgetMargin = q->geometry().y(); - q->getContentsMargins(0, &layoutMargin, 0, 0); - } - root->distance = widgetMargin + layoutMargin; + root->distance = 0; visited.insert(root); // Add initial edges to the queue diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 1470fb3..31da1a1 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -437,7 +437,7 @@ public: void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge); // Geometry interpolation methods - void setItemsGeometries(); + void setItemsGeometries(const QRectF &geom); void calculateVertexPositions(Orientation orientation); void setupEdgesInterpolation(Orientation orientation); diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 0d311fe..95476f0 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -52,6 +52,7 @@ private slots: void simple(); void simple_center(); void simple_semifloat(); + void layoutDirection(); void diagonal(); void parallel(); void parallel2(); @@ -104,6 +105,39 @@ static void setAnchor(QGraphicsAnchorLayout *l, l->setAnchorSpacing(firstItem, firstEdge, secondItem, secondEdge, spacing); } +static bool checkReverseDirection(QGraphicsWidget *w) +{ + QGraphicsLayout *l = w->layout(); + Q_ASSERT(l); + qreal left, top, right, bottom; + l->getContentsMargins(&left, &top, &right, &bottom); + w->setLayoutDirection(Qt::LeftToRight); + QApplication::processEvents(); + const QRectF lg = l->geometry(); + QMap geometries; + for (int i = 0; i < l->count(); ++i) { + QGraphicsLayoutItem *w = l->itemAt(i); + geometries.insert(w, w->geometry()); + } + w->setLayoutDirection(Qt::RightToLeft); + QApplication::processEvents(); + lg.adjusted(+right, +top, -left, -bottom); + for (int i = 0; i < l->count(); ++i) { + QGraphicsLayoutItem *w = l->itemAt(i); + const QRectF rtlGeom = w->geometry(); + const QRectF ltrGeom = geometries.value(w); + QRectF expectedGeom = ltrGeom; + expectedGeom.moveRight(lg.right() - (0 + ltrGeom.left())); + if (expectedGeom != rtlGeom) { + qDebug() << "layout->geometry():" << lg + << "expected:" << expectedGeom + << "actual:" << rtlGeom; + return false; + } + } + return true; +} + void tst_QGraphicsAnchorLayout::simple() { QGraphicsWidget *w1 = createItem(); @@ -204,6 +238,46 @@ void tst_QGraphicsAnchorLayout::simple_semifloat() QCOMPARE(layoutMaximumSize, QSizeF(200, 20)); } +void tst_QGraphicsAnchorLayout::layoutDirection() +{ + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(100, 10); + + QGraphicsWidget *a = createItem(min, pref, max, "a"); + QGraphicsWidget *b = createItem(min, pref, max, "b"); + QGraphicsWidget *c = createItem(min, pref, QSizeF(100, 20), "c"); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 5, 10, 15); + // horizontal + setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); + setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); + setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight, 0); + setAnchor(l, a, Qt::AnchorHorizontalCenter, c, Qt::AnchorLeft, 0); + setAnchor(l, c, Qt::AnchorRight, b, Qt::AnchorHorizontalCenter, 0); + + // vertical + setAnchor(l, l, Qt::AnchorTop, a, Qt::AnchorTop, 0); + setAnchor(l, l, Qt::AnchorTop, b, Qt::AnchorTop, 0); + setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorTop, 0); + setAnchor(l, b, Qt::AnchorBottom, c, Qt::AnchorTop, 0); + setAnchor(l, c, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); + + QCOMPARE(l->count(), 3); + + QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window); + p->setLayoutDirection(Qt::LeftToRight); + p->setLayout(l); + + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + scene.addItem(p); + p->show(); + view->show(); + + QCOMPARE(checkReverseDirection(p), true); +} void tst_QGraphicsAnchorLayout::diagonal() { @@ -306,6 +380,8 @@ void tst_QGraphicsAnchorLayout::diagonal() QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0)); QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0)); QCOMPARE(p.size(), testA); + + QCOMPARE(checkReverseDirection(&p), true); } void tst_QGraphicsAnchorLayout::parallel() @@ -599,6 +675,8 @@ void tst_QGraphicsAnchorLayout::snakeOppositeDirections() QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0)); QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + + QCOMPARE(checkReverseDirection(&p), true); } void tst_QGraphicsAnchorLayout::fairDistribution() -- cgit v0.12