Allow aligning items in a grid

This change introduces two new properties, horizontalItemAlignment and verticalItemAlignment to a
Grid element. This gives the user the possibility to align the items.

Change-Id: I7322a689f1bbc1da342bd618f6c30dd8c139ee29
Reviewed-by: Alan Alpert <aalpert@rim.com>
This commit is contained in:
Fabian Bumberger 2013-01-14 15:00:41 +01:00 committed by The Qt Project
parent 8b62bb86cd
commit 233e83b205
8 changed files with 266 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

View File

@ -222,6 +222,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#ifndef QT_NO_ACCESSIBILITY
qmlRegisterUncreatableType<QQuickAccessibleAttached>("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties"));
#endif
qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid");
}
void QQuickItemsModule::defineModule()

View File

@ -1102,6 +1102,8 @@ QQuickGrid::QQuickGrid(QQuickItem *parent)
, m_useRowSpacing(false)
, m_useColumnSpacing(false)
, m_flow(LeftToRight)
, m_hItemAlign(AlignLeft)
, m_vItemAlign(AlignTop)
{
}
@ -1248,6 +1250,7 @@ void QQuickGrid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
prePositioning();
emit layoutDirectionChanged();
emit effectiveLayoutDirectionChanged();
emit effectiveHorizontalAlignmentChanged(effectiveHAlign());
}
}
@ -1266,6 +1269,97 @@ Qt::LayoutDirection QQuickGrid::effectiveLayoutDirection() const
return QQuickBasePositionerPrivate::getEffectiveLayoutDirection(this);
}
/*!
\qmlproperty enumeration QtQuick2::Grid::horizontalItmeAlignment
\qmlproperty enumeration QtQuick2::Grid::verticalItemAlignment
\qmlproperty enumeration QtQuick2::Grid::effectiveHorizontalItemAlignment
Sets the horizontal and vertical alignment of items in the Grid. By default,
the items are vertically aligned to the top. Horizontal
alignment follows the layoutDirection of the Grid, for example when having a layoutDirection
from LeftToRight, the items will be aligned on the left.
The valid values for \c horizontalItemAlignment are, \c Grid.AlignLeft, \c Grid.AlignRight and
\c Grid.AlignHCenter.
The valid values for \c verticalItemAlignment are \c Grid.AlignTop, \c Grid.AlignBottom
and \c Grid.AlignVCenter.
The below images show three examples of how to align items.
\table
\row
\li
\li \inlineimage gridLayout_aligntopleft.png
\li \inlineimage gridLayout_aligntop.png
\li \inlineimage gridLayout_aligncenter.png
\row
\li Horizontal alignment
\li AlignLeft
\li AlignHCenter
\li AlignHCenter
\row
\li Vertical alignment
\li AlignTop
\li AlignTop
\li AlignVCenter
\endtable
When mirroring the layout using either the attached property LayoutMirroring::enabled or
by setting the layoutDirection, the horizontal alignment of items will be mirrored as well.
However, the property \c horizontalItemAlignment will remain unchanged.
To query the effective horizontal alignment of items, use the read-only property
\c effectiveHorizontalItemAlignment.
\sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
*/
QQuickGrid::HAlignment QQuickGrid::hItemAlign() const
{
return m_hItemAlign;
}
void QQuickGrid::setHItemAlign(HAlignment align)
{
if (m_hItemAlign != align) {
m_hItemAlign = align;
prePositioning();
emit horizontalAlignmentChanged(align);
emit effectiveHorizontalAlignmentChanged(effectiveHAlign());
}
}
QQuickGrid::HAlignment QQuickGrid::effectiveHAlign() const
{
HAlignment effectiveAlignment = m_hItemAlign;
if (effectiveLayoutDirection() == Qt::RightToLeft) {
switch (hItemAlign()) {
case AlignLeft:
effectiveAlignment = AlignRight;
break;
case AlignRight:
effectiveAlignment = AlignLeft;
break;
default:
break;
}
}
return effectiveAlignment;
}
QQuickGrid::VAlignment QQuickGrid::vItemAlign() const
{
return m_vItemAlign;
}
void QQuickGrid::setVItemAlign(VAlignment align)
{
if (m_vItemAlign != align) {
m_vItemAlign = align;
prePositioning();
emit verticalAlignmentChanged(align);
}
}
void QQuickGrid::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
@ -1362,9 +1456,22 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
qreal childXOffset = xoffset;
if (effectiveHAlign() == AlignRight)
childXOffset += maxColWidth[curCol] - child.item->width();
else if (hItemAlign() == AlignHCenter)
childXOffset += (maxColWidth[curCol] - child.item->width())/2.0;
if (!d->isLeftToRight())
childXOffset -= child.item->width();
positionItem(childXOffset, yoffset, &child);
childXOffset -= maxColWidth[curCol];
qreal alignYOffset = yoffset;
if (m_vItemAlign == AlignVCenter)
alignYOffset += (maxRowHeight[curRow] - child.item->height())/2.0;
else if (m_vItemAlign == AlignBottom)
alignYOffset += maxRowHeight[curRow] - child.item->height();
positionItem(childXOffset, alignYOffset, &child);
if (m_flow == LeftToRight) {
if (d->isLeftToRight())

View File

@ -220,6 +220,9 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1)
Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1)
Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1)
public:
QQuickGrid(QQuickItem *parent=0);
@ -247,6 +250,22 @@ public:
void setLayoutDirection (Qt::LayoutDirection);
Qt::LayoutDirection effectiveLayoutDirection() const;
Q_ENUMS(HAlignment)
Q_ENUMS(VAlignment)
enum HAlignment { AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
AlignHCenter = Qt::AlignHCenter};
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
HAlignment hItemAlign() const;
void setHItemAlign(HAlignment align);
HAlignment effectiveHAlign() const;
VAlignment vItemAlign() const;
void setVItemAlign(VAlignment align);
Q_SIGNALS:
void rowsChanged();
void columnsChanged();
@ -255,6 +274,9 @@ Q_SIGNALS:
void effectiveLayoutDirectionChanged();
void rowSpacingChanged();
void columnSpacingChanged();
Q_REVISION(1) void horizontalAlignmentChanged(HAlignment alignment);
Q_REVISION(1) void effectiveHorizontalAlignmentChanged(HAlignment alignment);
Q_REVISION(1) void verticalAlignmentChanged(VAlignment alignment);
protected:
virtual void doPositioning(QSizeF *contentSize);
@ -268,6 +290,8 @@ private:
bool m_useRowSpacing;
bool m_useColumnSpacing;
Flow m_flow;
HAlignment m_hItemAlign;
VAlignment m_vItemAlign;
Q_DISABLE_COPY(QQuickGrid)
};

View File

@ -1,11 +1,15 @@
import QtQuick 2.0
import QtQuick 2.1
Item {
width: 640
height: 480
property bool testRightToLeft: false
property int testHAlignment: Grid.AlignLeft;
property int testVAlignment: Grid.AlignTop;
Grid {
layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight
horizontalItemAlignment: testHAlignment
verticalItemAlignment: testVAlignment
objectName: "grid"
columns: 3
Rectangle {

View File

@ -78,6 +78,8 @@ private slots:
void test_grid_animated();
void test_grid_animated_rightToLeft();
void test_grid_zero_columns();
void test_grid_H_alignment();
void test_grid_V_alignment();
void test_propertychanges();
void test_repeater();
void test_flow();
@ -1418,6 +1420,130 @@ void tst_qquickpositioners::test_grid_zero_columns()
delete window;
}
void tst_qquickpositioners::test_grid_H_alignment()
{
QQuickView *window = createView(testFile("gridtest.qml"));
window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignHCenter);
QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one");
QVERIFY(one != 0);
QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two");
QVERIFY(two != 0);
QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three");
QVERIFY(three != 0);
QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four");
QVERIFY(four != 0);
QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five");
QVERIFY(five != 0);
QCOMPARE(one->x(), 0.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 50.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 70.0);
QCOMPARE(three->y(), 0.0);
QCOMPARE(four->x(), 0.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 55.0);
QCOMPARE(five->y(), 50.0);
QQuickItem *grid = window->rootObject()->findChild<QQuickItem*>("grid");
QCOMPARE(grid->width(), 100.0);
QCOMPARE(grid->height(), 100.0);
window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignRight);
QCOMPARE(one->x(), 0.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 50.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 70.0);
QCOMPARE(three->y(), 0.0);
QCOMPARE(four->x(), 0.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 60.0);
QCOMPARE(five->y(), 50.0);
QCOMPARE(grid->width(), 100.0);
QCOMPARE(grid->height(), 100.0);
window->rootObject()->setProperty("testRightToLeft", true);
QCOMPARE(one->x(), 50.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 30.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 0.0);
QCOMPARE(three->y(), 0.0);
QCOMPARE(four->x(), 50.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 30.0);
QCOMPARE(five->y(), 50.0);
QCOMPARE(grid->width(), 100.0);
QCOMPARE(grid->height(), 100.0);
window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignHCenter);
QCOMPARE(one->x(), 50.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 30.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 0.0);
QCOMPARE(three->y(), 0.0);
QCOMPARE(four->x(), 50.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 35.0);
QCOMPARE(five->y(), 50.0);
QCOMPARE(grid->width(), 100.0);
QCOMPARE(grid->height(), 100.0);
delete window;
}
void tst_qquickpositioners::test_grid_V_alignment()
{
QQuickView *window = createView(testFile("gridtest.qml"));
window->rootObject()->setProperty("testVAlignment", QQuickGrid::AlignVCenter);
QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one");
QVERIFY(one != 0);
QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two");
QVERIFY(two != 0);
QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three");
QVERIFY(three != 0);
QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four");
QVERIFY(four != 0);
QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five");
QVERIFY(five != 0);
QCOMPARE(one->x(), 0.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 50.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 70.0);
QCOMPARE(three->y(), 15.0);
QCOMPARE(four->x(), 0.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 50.0);
QCOMPARE(five->y(), 70.0);
window->rootObject()->setProperty("testVAlignment", QQuickGrid::AlignBottom);
QCOMPARE(one->x(), 0.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 50.0);
QCOMPARE(two->y(), 0.0);
QCOMPARE(three->x(), 70.0);
QCOMPARE(three->y(), 30.0);
QCOMPARE(four->x(), 0.0);
QCOMPARE(four->y(), 50.0);
QCOMPARE(five->x(), 50.0);
QCOMPARE(five->y(), 90.0);
delete window;
}
void tst_qquickpositioners::test_propertychanges()
{
QQuickView *window = createView(testFile("propertychangestest.qml"));