diff options
-rw-r--r-- | examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp | 4 | ||||
-rw-r--r-- | src/layout/duiflowlayoutpolicy.cpp | 52 | ||||
-rw-r--r-- | src/layout/duiflowlayoutpolicy.h | 20 | ||||
-rw-r--r-- | src/layout/duiflowlayoutpolicy_p.h | 3 | ||||
-rw-r--r-- | tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp | 47 | ||||
-rw-r--r-- | tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h | 1 |
6 files changed, 123 insertions, 4 deletions
diff --git a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp index 8be2e306..5b0b69ae 100644 --- a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp +++ b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp @@ -47,8 +47,12 @@ int main(int argc, char **argv) for (int i = 1; i <= 20; ++i) { DuiLabel *label = new DuiLabel(QString("Item %1").arg(i)); policy->addItem(label); + policy->setAlignment(label, Qt::AlignCenter); label->setObjectName("item"); //Set CSS name, for styling label->setAlignment(Qt::AlignCenter); + int random = i*10; + label->setMaximumHeight(random); + label->setMinimumHeight(random); } /* Attach the layout to the page */ diff --git a/src/layout/duiflowlayoutpolicy.cpp b/src/layout/duiflowlayoutpolicy.cpp index e0e2f025..b600dcae 100644 --- a/src/layout/duiflowlayoutpolicy.cpp +++ b/src/layout/duiflowlayoutpolicy.cpp @@ -31,11 +31,29 @@ DuiFlowLayoutPolicy::~DuiFlowLayoutPolicy() void DuiFlowLayoutPolicy::addItem(QGraphicsLayoutItem *item) { + Q_D(DuiFlowLayoutPolicy); DuiAbstractLayoutPolicy::addItem(item); + int index = indexOf(item); + if(index >= 0) + d->alignments.insert(index, Qt::AlignCenter); + + Q_ASSERT(count() == d->alignments.count()); } void DuiFlowLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item) { + Q_D(DuiFlowLayoutPolicy); DuiAbstractLayoutPolicy::insertItem(index, item); + index = indexOf(item); + if(index >= 0) + d->alignments.insert(index, Qt::AlignCenter); + Q_ASSERT(count() == d->alignments.count()); +} +void DuiFlowLayoutPolicy::removeAt(int index) +{ + Q_D(DuiFlowLayoutPolicy); + DuiAbstractLayoutPolicy::removeAt(index); + d->alignments.removeAt(index); + Q_ASSERT(count() == d->alignments.count()); } QSizeF DuiFlowLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { @@ -194,9 +212,11 @@ void DuiFlowLayoutPolicy::relayout() if (expandable) maxSize = item->effectiveSizeHint(Qt::MaximumSize); //let the items expand vertically if they want to - if (size.height() != current_rowheight && expandable.testFlag(Qt::Vertical)) { - //expand item to rowheight, making sure we don't exceed max size - size.setHeight(qMin(maxSize.height(), current_rowheight)); + if (size.height() != current_rowheight) { + if (expandable.testFlag(Qt::Vertical)) { + //expand item to rowheight, making sure we don't exceed max size + size.setHeight(qMin(maxSize.height(), current_rowheight)); + } } if (leftover_space > 0 && expandable.testFlag(Qt::Horizontal)) { @@ -212,6 +232,13 @@ void DuiFlowLayoutPolicy::relayout() } QRectF geometry = QRectF(origin, size); + + //Set vertical alignment as per flags + if(d->alignments[j] & Qt::AlignVCenter) + geometry.translate(0, (current_rowheight - size.height())/2); + else if(d->alignments[j] & Qt::AlignBottom) + geometry.translate(0, (current_rowheight - size.height())); + if (layout()->layoutDirection() == Qt::LeftToRight) geometry.translate(current_position); else @@ -243,4 +270,23 @@ int DuiFlowLayoutPolicy::rowLimit() const Q_D(const DuiFlowLayoutPolicy); return d->rowLimit; } +Qt::Alignment DuiFlowLayoutPolicy::alignment( QGraphicsLayoutItem * item ) const +{ + Q_D(const DuiFlowLayoutPolicy); + int index = indexOf(item); + if(index < 0) + return Qt::AlignCenter; + return d->alignments[index]; +} + +void DuiFlowLayoutPolicy::setAlignment( QGraphicsLayoutItem * item, Qt::Alignment alignment ) +{ + Q_D(DuiFlowLayoutPolicy); + int index = indexOf(item); + if(index < 0 || d->alignments[index] == alignment) + return; + + d->alignments[index] = alignment; + invalidatePolicyAndLayout(); +} diff --git a/src/layout/duiflowlayoutpolicy.h b/src/layout/duiflowlayoutpolicy.h index 04385897..5e59b4a6 100644 --- a/src/layout/duiflowlayoutpolicy.h +++ b/src/layout/duiflowlayoutpolicy.h @@ -98,11 +98,29 @@ public: * The default is -1, indicating no row limit */ int rowLimit() const; + /*! \brief Returns the alignment for @p item. + * + * The default alignment is Qt::AlignCenter. + * + * The alignment decides how the item is positioned within its assigned space in the + * case where there's more space available in the layout than the widgets can occupy. + * + * \see setAlignment() + */ + Qt::Alignment alignment( QGraphicsLayoutItem * item ) const; + + /*! \brief Sets the alignment of item to \p alignment. + * + * If item's alignment changes, the layout is automatically invalidated. + * \see alignment() + */ + void setAlignment( QGraphicsLayoutItem * item, Qt::Alignment alignment ); + /*! \reimp */ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; virtual void addItem(QGraphicsLayoutItem *item); virtual void insertItem(int index, QGraphicsLayoutItem *item); - + virtual void removeAt(int index); virtual void invalidate(); protected: virtual void relayout(); diff --git a/src/layout/duiflowlayoutpolicy_p.h b/src/layout/duiflowlayoutpolicy_p.h index 26b470b4..9f819679 100644 --- a/src/layout/duiflowlayoutpolicy_p.h +++ b/src/layout/duiflowlayoutpolicy_p.h @@ -52,6 +52,9 @@ public: /** Maximum number of rows of items to show. -1 if no limit */ int rowLimit; + + /** Alignment used for each row */ + QList<Qt::Alignment> alignments; }; #endif // Header Guard diff --git a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp index 2b4b401e..12cd869f 100644 --- a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp +++ b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp @@ -516,6 +516,7 @@ void Ut_DuiFlowLayoutPolicy::testHorizontalJustification() widget->setSizePolicy(horizontalPolicy, verticalPolicy); m_policy->addItem(widget); + m_policy->setAlignment(widget, Qt::AlignLeft | Qt::AlignTop); qApp->processEvents(); //for spacing change to trigger relayout } //test with all three items set to @@ -698,4 +699,50 @@ void Ut_DuiFlowLayoutPolicy::testAddingRemovingAdding() QCOMPARE(w3->isVisible(), true); QCOMPARE(w4->isVisible(), true); } +void Ut_DuiFlowLayoutPolicy::testAlignment() +{ + //Add two items + m_policy->addItem(m_mockItem100); + m_mockItem200->setPreferredSize(200, 200); + m_policy->addItem(m_mockItem200); + + m_form->setGeometry(QRectF(0, 0, 500, 500)); + + // Alignment is to center by default + QCOMPARE(m_policy->alignment(m_mockItem100), Qt::AlignCenter); + QCOMPARE(m_policy->alignment(m_mockItem200), Qt::AlignCenter); + qApp->processEvents(); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 50, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100, 0, 200, 200)); + + m_policy->setAlignment(m_mockItem200, Qt::AlignTop | Qt::AlignLeft); + QCOMPARE(m_policy->alignment(m_mockItem100), Qt::AlignCenter); + QCOMPARE(m_policy->alignment(m_mockItem200), Qt::AlignTop | Qt::AlignLeft); + qApp->processEvents(); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 50, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100, 0, 200, 200)); + + m_policy->setAlignment(m_mockItem200, Qt::AlignCenter); + QCOMPARE(m_policy->alignment(m_mockItem100), Qt::AlignCenter); + QCOMPARE(m_policy->alignment(m_mockItem200), Qt::AlignCenter); + qApp->processEvents(); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 50, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100, 0, 200, 200)); + + m_policy->setAlignment(m_mockItem100, Qt::AlignTop | Qt::AlignLeft); + QCOMPARE(m_policy->alignment(m_mockItem100), Qt::AlignTop | Qt::AlignLeft); + QCOMPARE(m_policy->alignment(m_mockItem200), Qt::AlignCenter); + qApp->processEvents(); + qDebug() << "alignment" << (m_policy->alignment(m_mockItem100) & Qt::AlignVCenter); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100, 0, 200, 200)); + + m_policy->setAlignment(m_mockItem100, Qt::AlignBottom | Qt::AlignLeft); + QCOMPARE(m_policy->alignment(m_mockItem100), Qt::AlignBottom | Qt::AlignLeft); + QCOMPARE(m_policy->alignment(m_mockItem200), Qt::AlignCenter); + qApp->processEvents(); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 100, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100, 0, 200, 200)); + +} QTEST_APPLESS_MAIN(Ut_DuiFlowLayoutPolicy) diff --git a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h index f9828fc2..bc8ceee1 100644 --- a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h +++ b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h @@ -59,6 +59,7 @@ private slots: void testBigItemInSmallLayout(); void testMarginsAndMinimumHeight(); void testAddingRemovingAdding(); + void testAlignment(); private: DuiLayout *m_mockLayout; |