summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoona Petrell <joona.t.petrell@nokia.com>2011-02-24 02:33:11 (GMT)
committerJoona Petrell <joona.t.petrell@nokia.com>2011-03-01 07:17:41 (GMT)
commit2c7cab4172f1acc86fd49345a2847417e162f2c3 (patch)
tree2df2e2bfccd17ed94980db0221ed3aec83afccb2 /src
parenta4b37abd96860a5bc46f88205bb11706cbaec228 (diff)
downloadQt-2c7cab4172f1acc86fd49345a2847417e162f2c3.zip
Qt-2c7cab4172f1acc86fd49345a2847417e162f2c3.tar.gz
Qt-2c7cab4172f1acc86fd49345a2847417e162f2c3.tar.bz2
Add LayoutMirroring attached property for mirroring QML layouts
Task-number: QTBUG-17280 Reviewed-by: Martin Jones Change-Id: I34a623b49ce0fd5c05ae7a7ea5d0437c107b8a9b
Diffstat (limited to 'src')
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanchors.cpp40
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanchors_p.h10
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanchors_p_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp69
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp154
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h53
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp90
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp114
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners_p.h15
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners_p_p.h30
13 files changed, 472 insertions, 122 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp
index a2d6261..5ff6d2c 100644
--- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp
@@ -175,13 +175,14 @@ QDeclarativeAnchors::~QDeclarativeAnchors()
void QDeclarativeAnchorsPrivate::fillChanged()
{
+ Q_Q(QDeclarativeAnchors);
if (!fill || !isItemComplete())
return;
if (updatingFill < 2) {
++updatingFill;
- qreal horizontalMargin = isMirrored() ? rightMargin : leftMargin;
+ qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
if (fill == item->parentItem()) { //child-parent
setItemPos(QPointF(horizontalMargin, topMargin));
@@ -201,13 +202,14 @@ void QDeclarativeAnchorsPrivate::fillChanged()
void QDeclarativeAnchorsPrivate::centerInChanged()
{
+ Q_Q(QDeclarativeAnchors);
if (!centerIn || fill || !isItemComplete())
return;
if (updatingCenterIn < 2) {
++updatingCenterIn;
- qreal effectiveHCenterOffset = isMirrored() ? -hCenterOffset : hCenterOffset;
+ qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
if (centerIn == item->parentItem()) {
QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset,
vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
@@ -315,6 +317,13 @@ void QDeclarativeAnchors::componentComplete()
d->componentComplete = true;
}
+bool QDeclarativeAnchors::mirrored()
+{
+ Q_D(QDeclarativeAnchors);
+ QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(d->item);
+ return itemPrivate->isDeclarativeItem ? static_cast<QDeclarativeItemPrivate *>(itemPrivate)->effectiveLayoutMirror : false;
+}
+
void QDeclarativeAnchorsPrivate::setItemHeight(qreal v)
{
updatingMe = true;
@@ -502,11 +511,6 @@ bool QDeclarativeAnchorsPrivate::calcStretch(const QDeclarativeAnchorLine &edge1
return invalid;
}
-bool QDeclarativeAnchorsPrivate::isMirrored() const
-{
- return layoutDirection == Qt::RightToLeft;
-}
-
void QDeclarativeAnchorsPrivate::updateVerticalAnchors()
{
if (fill || centerIn || !isItemComplete())
@@ -591,6 +595,7 @@ inline QDeclarativeAnchorLine::AnchorLine reverseAnchorLine(QDeclarativeAnchorLi
void QDeclarativeAnchorsPrivate::updateHorizontalAnchors()
{
+ Q_Q(QDeclarativeAnchors);
if (fill || centerIn || !isItemComplete())
return;
@@ -599,7 +604,7 @@ void QDeclarativeAnchorsPrivate::updateHorizontalAnchors()
qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
QDeclarativeAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
QDeclarativeAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
- if (isMirrored()) {
+ if (q->mirrored()) {
effectiveLeftAnchor = QDeclarativeAnchors::RightAnchor;
effectiveRightAnchor = QDeclarativeAnchors::LeftAnchor;
effectiveLeft.item = right.item;
@@ -1086,25 +1091,6 @@ QDeclarativeAnchors::Anchors QDeclarativeAnchors::usedAnchors() const
return d->usedAnchors;
}
-
-Qt::LayoutDirection QDeclarativeAnchors::layoutDirection() const
-{
- Q_D(const QDeclarativeAnchors);
- return d->layoutDirection;
-}
-
-void QDeclarativeAnchors::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
- Q_D(QDeclarativeAnchors);
- if (d->layoutDirection != layoutDirection) {
- d->layoutDirection = layoutDirection;
- d->fillChanged();
- d->centerInChanged();
- d->updateHorizontalAnchors();
- emit layoutDirectionChanged();
- }
-}
-
bool QDeclarativeAnchorsPrivate::checkHValid() const
{
if (usedAnchors & QDeclarativeAnchors::LeftAnchor &&
diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h
index 90a3508..388d6b9 100644
--- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h
@@ -79,7 +79,7 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeAnchors : public QObject
Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged)
Q_PROPERTY(QGraphicsObject *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged)
Q_PROPERTY(QGraphicsObject *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(bool mirrored READ mirrored NOTIFY mirroredChanged REVISION 1)
public:
QDeclarativeAnchors(QObject *parent=0);
@@ -161,12 +161,11 @@ public:
Anchors usedAnchors() const;
- Qt::LayoutDirection layoutDirection() const;
- void setLayoutDirection (Qt::LayoutDirection);
-
void classBegin();
void componentComplete();
+ bool mirrored();
+
Q_SIGNALS:
void leftChanged();
void rightChanged();
@@ -185,10 +184,11 @@ Q_SIGNALS:
void verticalCenterOffsetChanged();
void horizontalCenterOffsetChanged();
void baselineOffsetChanged();
- Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void mirroredChanged();
private:
friend class QDeclarativeItem;
+ friend class QDeclarativeItemPrivate;
friend class QDeclarativeGraphicsWidget;
Q_DISABLE_COPY(QDeclarativeAnchors)
Q_DECLARE_PRIVATE(QDeclarativeAnchors)
diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h
index ec96582..d8d2f15 100644
--- a/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h
@@ -94,7 +94,7 @@ public:
: componentComplete(true), updatingMe(false), updatingHorizontalAnchor(0),
updatingVerticalAnchor(0), updatingFill(0), updatingCenterIn(0), item(i), usedAnchors(0), fill(0),
centerIn(0), leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
- margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0), layoutDirection(Qt::LeftToRight)
+ margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)
{
}
@@ -161,8 +161,6 @@ public:
qreal vCenterOffset;
qreal hCenterOffset;
qreal baselineOffset;
-
- Qt::LayoutDirection layoutDirection;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 2eeadf4..f6810ed 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -73,7 +73,7 @@ public:
if (view->flow() == QDeclarativeGridView::LeftToRight) {
rowPos = item->y();
} else {
- if (view->layoutDirection() == Qt::RightToLeft)
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft)
rowPos = -view->cellWidth()-item->x();
else
rowPos = item->x();
@@ -83,7 +83,7 @@ public:
qreal colPos() const {
qreal colPos = 0;
if (view->flow() == QDeclarativeGridView::LeftToRight) {
- if (view->layoutDirection() == Qt::RightToLeft) {
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
int colSize = view->cellWidth();
int columns = view->width()/colSize;
colPos = colSize * (columns-1) - item->x();
@@ -101,14 +101,14 @@ public:
if (view->flow() == QDeclarativeGridView::LeftToRight) {
return item->y() + view->cellHeight() - 1;
} else {
- if (view->layoutDirection() == Qt::RightToLeft)
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft)
return -item->x() - 1;
else
return item->x() + view->cellWidth() - 1;
}
}
void setPosition(qreal col, qreal row) {
- if (view->layoutDirection() == Qt::RightToLeft) {
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
if (view->flow() == QDeclarativeGridView::LeftToRight) {
int columns = view->width()/view->cellWidth();
item->setPos(QPointF((view->cellWidth() * (columns-1) - col), row));
@@ -188,7 +188,24 @@ public:
}
bool isRightToLeftTopToBottom() const {
- return flow == QDeclarativeGridView::TopToBottom && layoutDirection == Qt::RightToLeft;
+ Q_Q(const QDeclarativeGridView);
+ return flow == QDeclarativeGridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft;
+ }
+
+ void regenerate() {
+ Q_Q(QDeclarativeGridView);
+ if (q->isComponentComplete()) {
+ clear();
+ updateGrid();
+ q->refill();
+ updateCurrent(currentIndex);
+ }
+ }
+
+ void mirrorChange() {
+ Q_Q(QDeclarativeGridView);
+ regenerate();
+ emit q->effectiveLayoutDirectionChanged();
}
qreal position() const {
@@ -201,7 +218,7 @@ public:
q->QDeclarativeFlickable::setContentY(pos);
q->QDeclarativeFlickable::setContentX(0);
} else {
- if (layoutDirection == Qt::LeftToRight)
+ if (q->effectiveLayoutDirection() == Qt::LeftToRight)
q->QDeclarativeFlickable::setContentX(pos);
else
q->QDeclarativeFlickable::setContentX(-pos-size());
@@ -918,7 +935,7 @@ void QDeclarativeGridViewPrivate::updateFooter()
rowOffset = footer->item->width()-cellWidth;
} else {
rowOffset = 0;
- if (layoutDirection == Qt::RightToLeft)
+ if (q->effectiveLayoutDirection() == Qt::RightToLeft)
colOffset = footer->item->width()-cellWidth;
}
if (visibleItems.count()) {
@@ -971,7 +988,7 @@ void QDeclarativeGridViewPrivate::updateHeader()
rowOffset = -cellWidth;
} else {
rowOffset = -headerSize();
- if (layoutDirection == Qt::RightToLeft)
+ if (q->effectiveLayoutDirection() == Qt::RightToLeft)
colOffset = header->item->width()-cellWidth;
}
if (visibleItems.count()) {
@@ -1761,7 +1778,6 @@ void QDeclarativeGridView::setHighlightRangeMode(HighlightRangeMode mode)
\bold Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if
GridView::layoutDirection is set to Qt.RightToLeft. The GridView.LeftToRight flow value simply
indicates that the flow is horizontal.
-
*/
Qt::LayoutDirection QDeclarativeGridView::layoutDirection() const
@@ -1775,15 +1791,33 @@ void QDeclarativeGridView::setLayoutDirection(Qt::LayoutDirection layoutDirectio
Q_D(QDeclarativeGridView);
if (d->layoutDirection != layoutDirection) {
d->layoutDirection = layoutDirection;
- d->clear();
- d->updateGrid();
- refill();
- d->updateCurrent(d->currentIndex);
+ d->regenerate();
emit layoutDirectionChanged();
+ emit effectiveLayoutDirectionChanged();
}
}
/*!
+ \qmlproperty enumeration GridView::effectiveLayoutDirection
+ This property holds the effective layout direction of the grid.
+
+ When using the attached property \l {LayoutMirroring::mirror}{LayoutMirroring::mirror} for locale layouts,
+ the visual layout direction of the grid will be mirrored. However, the
+ property \l {GridView::layoutDirection}{layoutDirection} will remain unchanged.
+
+ \sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QDeclarativeGridView::effectiveLayoutDirection() const
+{
+ Q_D(const QDeclarativeGridView);
+ if (d->effectiveLayoutMirror)
+ return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
+ else
+ return d->layoutDirection;
+}
+
+/*!
\qmlproperty enumeration GridView::flow
This property holds the flow of the grid.
@@ -1814,10 +1848,7 @@ void QDeclarativeGridView::setFlow(Flow flow)
}
setContentX(0);
setContentY(0);
- d->clear();
- d->updateGrid();
- refill();
- d->updateCurrent(d->currentIndex);
+ d->regenerate();
emit flowChanged();
}
}
@@ -2338,7 +2369,7 @@ void QDeclarativeGridView::moveCurrentIndexLeft()
if (!count)
return;
- if (d->layoutDirection == Qt::LeftToRight) {
+ if (effectiveLayoutDirection() == Qt::LeftToRight) {
if (d->flow == QDeclarativeGridView::LeftToRight) {
if (currentIndex() > 0 || d->wrap) {
int index = currentIndex() - 1;
@@ -2381,7 +2412,7 @@ void QDeclarativeGridView::moveCurrentIndexRight()
if (!count)
return;
- if (d->layoutDirection == Qt::LeftToRight) {
+ if (effectiveLayoutDirection() == Qt::LeftToRight) {
if (d->flow == QDeclarativeGridView::LeftToRight) {
if (currentIndex() < count - 1 || d->wrap) {
int index = currentIndex() + 1;
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index fc9e6b4..ad0c609 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -74,7 +74,8 @@ class Q_AUTOTEST_EXPORT QDeclarativeGridView : public QDeclarativeFlickable
Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) //Versioning support?
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged REVISION 1)
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
Q_PROPERTY(int cellWidth READ cellWidth WRITE setCellWidth NOTIFY cellWidthChanged)
@@ -132,6 +133,7 @@ public:
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection(Qt::LayoutDirection);
+ Qt::LayoutDirection effectiveLayoutDirection() const;
enum Flow { LeftToRight, TopToBottom };
Flow flow() const;
@@ -191,7 +193,8 @@ Q_SIGNALS:
void modelChanged();
void delegateChanged();
void flowChanged();
- void layoutDirectionChanged();
+ Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void effectiveLayoutDirectionChanged();
void keyNavigationWrapsChanged();
void cacheBufferChanged();
void snapModeChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index ac5d55c..d16025d 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -39,12 +39,12 @@
**
****************************************************************************/
-#include "private/qdeclarativeitem_p.h"
#include "qdeclarativeitem.h"
#include "private/qdeclarativeevents_p_p.h"
#include <private/qdeclarativeengine_p.h>
#include <private/qgraphicsitem_p.h>
+#include <QtDeclarative/private/qdeclarativeitem_p.h>
#include <qdeclarativeengine.h>
#include <qdeclarativeopenmetaobject_p.h>
@@ -731,6 +731,152 @@ void QDeclarativeKeyNavigationAttached::setFocusNavigation(QDeclarativeItem *cur
}
/*!
+ \qmlclass LayoutMirroring QDeclarativeLayoutMirroringAttached
+ \since QtQuick 1.1
+ \ingroup qml-utility-elements
+ \brief The LayoutMirroring is used for mirroring the Qt Quick application layouts.
+
+ LayoutMirroring \l enabled property can be used to horizontally mirror \l {anchor-layout}{Item anchors},
+ \l{Using QML Positioner and Repeater Items}{Positioner} elements and QML views like \l {GridView}{GridView}
+ and horizontal \l {ListView}{ListView}. Mirroring is a visual change, left anchors will become
+ right anchors and left-to-right positioner will instead position child items from right to left.
+ By default setting the \l enabled property to true only affects the item in question. You can set property
+ LayoutDirection \l childrenInherit to true if you want the item children also inherit the mirror setting.
+ If no attached property has been defined, mirroring is disabled.
+
+ The following example shows mirroring in action. When \l enabled is set to true, left anchor
+ becomes right, and \l {Row}{Row} starts positioning items in a reverse order:
+
+ \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
+
+ Layout mirroring is useful when you need to support both left-to-right and right-to-left
+ layout versions of your application that target different language areas. Inheritance saves
+ you from having to mirror the layouts manually for each layout item in your application. Keep
+ in mind however that the mirroring does not affect the positioning done by modifying Item's x
+ co-ordinate directly, so even with the mirroring enabled you will often need to do some layout
+ fixes to support the other reading direction. Also, there are cases where you need to disable
+ mirroring of individual child items, either because mirroring is not the wanted behavior or
+ because the item already implements mirroring in some custom way.
+*/
+
+/*!
+ \qmlproperty bool LayoutMirroring::enabled
+
+ Setting this property to true mirrors item's layout horizontally, whether the layout is done
+ using \l {anchor-layout}{anchors}, \l{Using QML Positioner and Repeater Items}{Positioners}
+ or as a QML view \l {GridView}{GridView} or \l {ListView}{ListView}.
+*/
+
+/*!
+ \qmlproperty bool LayoutMirroring::childrenInherit
+
+ This property can be set to true if you want the item children
+ to inherit the item's mirror setting.
+*/
+
+QDeclarativeLayoutMirroringAttached::QDeclarativeLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
+{
+ if (QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent)) {
+ itemPrivate = QDeclarativeItemPrivate::get(item);
+ itemPrivate->attachedLayoutDirection = this;
+ } else
+ qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
+}
+
+QDeclarativeLayoutMirroringAttached * QDeclarativeLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
+{
+ return new QDeclarativeLayoutMirroringAttached(object);
+}
+
+bool QDeclarativeLayoutMirroringAttached::enabled() const
+{
+ return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
+}
+
+void QDeclarativeLayoutMirroringAttached::setEnabled(bool enabled)
+{
+ if (!itemPrivate)
+ return;
+
+ itemPrivate->isMirrorImplicit = false;
+ if (enabled != itemPrivate->effectiveLayoutMirror) {
+ itemPrivate->setLayoutMirror(enabled);
+ if (itemPrivate->inheritMirrorFromItem)
+ itemPrivate->resolveLayoutMirror();
+ }
+}
+
+void QDeclarativeLayoutMirroringAttached::resetEnabled()
+{
+ if (itemPrivate && !itemPrivate->isMirrorImplicit) {
+ itemPrivate->isMirrorImplicit = true;
+ itemPrivate->resolveLayoutMirror();
+ }
+}
+
+bool QDeclarativeLayoutMirroringAttached::childrenInherit() const
+{
+ return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
+}
+
+void QDeclarativeLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
+ if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
+ itemPrivate->inheritMirrorFromItem = childrenInherit;
+ itemPrivate->resolveLayoutMirror();
+ childrenInheritChanged();
+ }
+}
+
+void QDeclarativeItemPrivate::resolveLayoutMirror()
+{
+ Q_Q(QDeclarativeItem);
+ if (QDeclarativeItem *parentItem = q->parentItem()) {
+ QDeclarativeItemPrivate *parentPrivate = QDeclarativeItemPrivate::get(parentItem);
+ setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
+ } else {
+ setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
+ }
+}
+
+void QDeclarativeItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
+{
+ inherit = inherit || inheritMirrorFromItem;
+ if (!isMirrorImplicit && inheritMirrorFromItem)
+ mirror = effectiveLayoutMirror;
+ if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
+ return;
+
+ inheritMirrorFromParent = inherit;
+ inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
+
+ if (isMirrorImplicit)
+ setLayoutMirror(inherit ? inheritedLayoutMirror : false);
+ for (int i = 0; i < children.count(); ++i) {
+ if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) {
+ QDeclarativeItemPrivate *childPrivate = QDeclarativeItemPrivate::get(child);
+ childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
+ }
+ }
+}
+
+void QDeclarativeItemPrivate::setLayoutMirror(bool mirror)
+{
+ if (mirror != effectiveLayoutMirror) {
+ effectiveLayoutMirror = mirror;
+ if (_anchors) {
+ _anchors->d_func()->fillChanged();
+ _anchors->d_func()->centerInChanged();
+ _anchors->d_func()->updateHorizontalAnchors();
+ emit _anchors->mirroredChanged();
+ }
+ mirrorChange();
+ if (attachedLayoutDirection) {
+ emit attachedLayoutDirection->enabledChanged();
+ }
+ }
+}
+
+/*!
\qmlclass Keys QDeclarativeKeysAttached
\ingroup qml-basic-interaction-elements
\since 4.7
@@ -1389,6 +1535,11 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec
\endqml
See the \l {Keys}{Keys} attached property for detailed documentation.
+
+ \section1 Layout Mirroring
+
+ Item layouts can be mirrored using \l {LayoutMirroring}{LayoutMirroring} attached property.
+
*/
/*!
@@ -2782,6 +2933,7 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
Q_D(QDeclarativeItem);
switch (change) {
case ItemParentHasChanged:
+ d->resolveLayoutMirror();
emit parentChanged(parentItem());
d->parentNotifier.notify();
break;
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index 4303c0a..b204d7f 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -77,6 +77,7 @@ QT_BEGIN_NAMESPACE
class QNetworkReply;
class QDeclarativeItemKeyFilter;
+class QDeclarativeLayoutMirroringAttached;
//### merge into private?
class QDeclarativeContents : public QObject, public QDeclarativeItemChangeListener
@@ -125,8 +126,10 @@ public:
_stateGroup(0), origin(QDeclarativeItem::Center),
widthValid(false), heightValid(false),
componentComplete(true), keepMouse(false),
- smooth(false), transformOriginDirty(true), doneEventPreHandler(false), keyHandler(0),
- mWidth(0), mHeight(0), mImplicitWidth(0), mImplicitHeight(0), hadSubFocusItem(false)
+ smooth(false), transformOriginDirty(true), doneEventPreHandler(false),
+ inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
+ inheritMirrorFromParent(false), inheritMirrorFromItem(false), keyHandler(0),
+ mWidth(0), mHeight(0), mImplicitWidth(0), mImplicitHeight(0), attachedLayoutDirection(0), hadSubFocusItem(false)
{
QGraphicsItemPrivate::acceptedMouseButtons = 0;
isDeclarativeItem = 1;
@@ -134,7 +137,6 @@ public:
QGraphicsItem::ItemHasNoContents
| QGraphicsItem::ItemIsFocusable
| QGraphicsItem::ItemNegativeZStacksBehindParent);
-
}
void init(QDeclarativeItem *parent)
@@ -146,6 +148,11 @@ public:
}
baselineOffset.invalidate();
mouseSetsFocus = false;
+ resolveLayoutMirror();
+ }
+
+ bool isMirrored() const {
+ return effectiveLayoutMirror;
}
// Private Properties
@@ -162,6 +169,10 @@ public:
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
+ void resolveLayoutMirror();
+ void setImplicitLayoutMirror(bool mirror, bool inherit);
+ void setLayoutMirror(bool mirror);
+
QDeclarativeListProperty<QObject> data();
QDeclarativeListProperty<QObject> resources();
@@ -272,6 +283,11 @@ public:
bool smooth:1;
bool transformOriginDirty : 1;
bool doneEventPreHandler : 1;
+ bool inheritedLayoutMirror:1;
+ bool effectiveLayoutMirror:1;
+ bool isMirrorImplicit:1;
+ bool inheritMirrorFromParent:1;
+ bool inheritMirrorFromItem:1;
QDeclarativeItemKeyFilter *keyHandler;
@@ -280,6 +296,8 @@ public:
qreal mImplicitWidth;
qreal mImplicitHeight;
+ QDeclarativeLayoutMirroringAttached* attachedLayoutDirection;
+
bool hadSubFocusItem;
QPointF computeTransformOrigin() const;
@@ -326,6 +344,8 @@ public:
virtual void focusChanged(bool);
+ virtual void mirrorChange() {};
+
static qint64 consistentTime;
static void setConsistentTime(qint64 t);
static void start(QElapsedTimer &);
@@ -423,6 +443,31 @@ private:
void setFocusNavigation(QDeclarativeItem *currentItem, const char *dir);
};
+class QDeclarativeLayoutMirroringAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
+
+public:
+ explicit QDeclarativeLayoutMirroringAttached(QObject *parent = 0);
+
+ bool enabled() const;
+ void setEnabled(bool);
+ void resetEnabled();
+
+ bool childrenInherit() const;
+ void setChildrenInherit(bool);
+
+ static QDeclarativeLayoutMirroringAttached *qmlAttachedProperties(QObject *);
+Q_SIGNALS:
+ void enabledChanged();
+ void childrenInheritChanged();
+private:
+ friend class QDeclarativeItemPrivate;
+ QDeclarativeItemPrivate *itemPrivate;
+};
+
class QDeclarativeKeysAttachedPrivate : public QObjectPrivate
{
public:
@@ -572,5 +617,7 @@ QML_DECLARE_TYPE(QDeclarativeKeysAttached)
QML_DECLARE_TYPEINFO(QDeclarativeKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QDeclarativeKeyNavigationAttached)
QML_DECLARE_TYPEINFO(QDeclarativeKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QDeclarativeLayoutMirroringAttached)
+QML_DECLARE_TYPEINFO(QDeclarativeLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QDECLARATIVEITEM_P_H
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 3c8f64e..c4a9030 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -198,6 +198,7 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterRevision<QDeclarativeImplicitSizeItem,1>("QtQuick",1,1);
qmlRegisterRevision<QDeclarativeImplicitSizePaintedItem,0>("QtQuick",1,0);
qmlRegisterRevision<QDeclarativeImplicitSizePaintedItem,1>("QtQuick",1,1);
+ qmlRegisterUncreatableType<QDeclarativeLayoutMirroringAttached>("QtQuick",1,1,"LayoutMirroring", QDeclarativeLayoutMirroringAttached::tr("LayoutMirroring is only available via attached properties"));
#ifndef QT_NO_IMPORT_QT47_QML
#ifdef QT_NO_MOVIE
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 486cec8..879b99b 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -104,16 +104,17 @@ public:
if (view->orientation() == QDeclarativeListView::Vertical)
return section->y();
else
- return (view->layoutDirection() == Qt::RightToLeft ? -section->width()-section->x() : section->x());
+ return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section->width()-section->x() : section->x());
} else {
return itemPosition();
}
}
+
qreal itemPosition() const {
if (view->orientation() == QDeclarativeListView::Vertical)
return item->y();
else
- return (view->layoutDirection() == Qt::RightToLeft ? -item->width()-item->x() : item->x());
+ return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-item->x() : item->x());
}
qreal size() const {
if (section)
@@ -133,7 +134,7 @@ public:
if (view->orientation() == QDeclarativeListView::Vertical) {
return item->y() + (item->height() >= 1.0 ? item->height() : 1) - 1;
} else {
- return (view->layoutDirection() == Qt::RightToLeft
+ return (view->effectiveLayoutDirection() == Qt::RightToLeft
? -item->width()-item->x() + (item->width() >= 1.0 ? item->width() : 1)
: item->x() + (item->width() >= 1.0 ? item->width() : 1)) - 1;
}
@@ -146,7 +147,7 @@ public:
}
item->setY(pos);
} else {
- if (view->layoutDirection() == Qt::RightToLeft) {
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
if (section) {
section->setX(-section->width()-pos);
pos += section->width();
@@ -248,8 +249,25 @@ public:
return 0;
}
+ void regenerate() {
+ Q_Q(QDeclarativeListView);
+ if (q->isComponentComplete()) {
+ clear();
+ setPosition(0);
+ q->refill();
+ updateCurrent(currentIndex);
+ }
+ }
+
+ void mirrorChange() {
+ Q_Q(QDeclarativeListView);
+ regenerate();
+ emit q->effectiveLayoutDirectionChanged();
+ }
+
bool isRightToLeft() const {
- return (layoutDirection == Qt::RightToLeft && orient == QDeclarativeListView::Horizontal);
+ Q_Q(const QDeclarativeListView);
+ return orient == QDeclarativeListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft;
}
qreal position() const {
@@ -262,7 +280,7 @@ public:
if (orient == QDeclarativeListView::Vertical) {
q->QDeclarativeFlickable::setContentY(pos);
} else {
- if (layoutDirection == Qt::RightToLeft)
+ if (isRightToLeft())
q->QDeclarativeFlickable::setContentX(-pos-size());
else
q->QDeclarativeFlickable::setContentX(pos);
@@ -2064,14 +2082,25 @@ void QDeclarativeListView::setOrientation(QDeclarativeListView::Orientation orie
setContentHeight(-1);
setFlickableDirection(HorizontalFlick);
}
- d->clear();
- d->setPosition(0);
- refill();
+ d->regenerate();
emit orientationChanged();
- d->updateCurrent(d->currentIndex);
}
}
+/*!
+ \qmlproperty enumeration ListView::layoutDirection
+ This property holds the layout direction of the horizontal list.
+
+ Possible values:
+
+ \list
+ \o Qt.LeftToRight (default) - Items will be laid out from left to right.
+ \o Qt.RightToLeft - Items will be laid out from right to let.
+ \endlist
+
+ \sa ListView::effectiveLayoutDirection
+*/
+
Qt::LayoutDirection QDeclarativeListView::layoutDirection() const
{
Q_D(const QDeclarativeListView);
@@ -2083,15 +2112,33 @@ void QDeclarativeListView::setLayoutDirection(Qt::LayoutDirection layoutDirectio
Q_D(QDeclarativeListView);
if (d->layoutDirection != layoutDirection) {
d->layoutDirection = layoutDirection;
- d->clear();
- d->setPosition(0);
- refill();
+ d->regenerate();
emit layoutDirectionChanged();
- d->updateCurrent(d->currentIndex);
+ emit effectiveLayoutDirectionChanged();
}
}
/*!
+ \qmlproperty enumeration ListView::effectiveLayoutDirection
+ This property holds the effective layout direction of the horizontal list.
+
+ When using the attached property \l {LayoutMirroring::mirror}{LayoutMirroring::mirror} for locale layouts,
+ the visual layout direction of the horizontal list will be mirrored. However, the
+ property \l {ListView::layoutDirection}{layoutDirection} will remain unchanged.
+
+ \sa ListView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QDeclarativeListView::effectiveLayoutDirection() const
+{
+ Q_D(const QDeclarativeListView);
+ if (d->effectiveLayoutMirror)
+ return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
+ else
+ return d->layoutDirection;
+}
+
+/*!
\qmlproperty bool ListView::keyNavigationWraps
This property holds whether the list wraps key navigation.
@@ -2671,8 +2718,8 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event)
return;
if (d->model && d->model->count() && d->interactive) {
- if ((d->orient == QDeclarativeListView::Horizontal && d->layoutDirection == Qt::LeftToRight && event->key() == Qt::Key_Left)
- || (d->orient == QDeclarativeListView::Horizontal && d->layoutDirection == Qt::RightToLeft && event->key() == Qt::Key_Right)
+ if ((!d->isRightToLeft() && event->key() == Qt::Key_Left)
+ || (d->orient == QDeclarativeListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right)
|| (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Up)) {
if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) {
decrementCurrentIndex();
@@ -2682,8 +2729,8 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event)
event->accept();
return;
}
- } else if ((d->orient == QDeclarativeListView::Horizontal && d->layoutDirection == Qt::LeftToRight && event->key() == Qt::Key_Right)
- || (d->orient == QDeclarativeListView::Horizontal && d->layoutDirection == Qt::RightToLeft && event->key() == Qt::Key_Left)
+ } else if ((!d->isRightToLeft() && event->key() == Qt::Key_Right)
+ || (d->orient == QDeclarativeListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left)
|| (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Down)) {
if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) {
incrementCurrentIndex();
@@ -2970,7 +3017,7 @@ void QDeclarativeListView::updateSections()
void QDeclarativeListView::refill()
{
Q_D(QDeclarativeListView);
- if (layoutDirection() == Qt::RightToLeft && orientation() == QDeclarativeListView::Horizontal)
+ if (d->isRightToLeft())
d->refill(-d->position()-d->size()+1, -d->position());
else
d->refill(d->position(), d->position()+d->size()-1);
@@ -3416,11 +3463,8 @@ void QDeclarativeListView::itemsChanged(int, int)
void QDeclarativeListView::modelReset()
{
Q_D(QDeclarativeListView);
- d->clear();
- d->setPosition(0);
- refill();
d->moveReason = QDeclarativeListViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
+ d->regenerate();
if (d->highlight && d->currentItem) {
if (d->autoHighlight)
d->highlight->setPosition(d->currentItem->position());
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 6b72240..30171f8 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -113,7 +113,8 @@ class Q_AUTOTEST_EXPORT QDeclarativeListView : public QDeclarativeFlickable
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged REVISION 1)
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
Q_PROPERTY(QDeclarativeViewSection *section READ sectionCriteria CONSTANT)
@@ -174,6 +175,7 @@ public:
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection(Qt::LayoutDirection);
+ Qt::LayoutDirection effectiveLayoutDirection() const;
bool isWrapEnabled() const;
void setWrapEnabled(bool);
@@ -226,7 +228,8 @@ Q_SIGNALS:
void countChanged();
void spacingChanged();
void orientationChanged();
- void layoutDirectionChanged();
+ Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void effectiveLayoutDirectionChanged();
void currentIndexChanged();
void currentSectionChanged();
void highlightMoveSpeedChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index 4560d32..f57f501 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -574,7 +574,7 @@ void QDeclarativeColumn::reportConflictingAnchors()
\sa Grid::spacing
*/
QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent)
-: QDeclarativeBasePositioner(Horizontal, parent), m_layoutDirection(Qt::LeftToRight)
+: QDeclarativeBasePositioner(Horizontal, parent)
{
}
@@ -595,20 +595,39 @@ QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent)
*/
Qt::LayoutDirection QDeclarativeRow::layoutDirection() const
{
- return m_layoutDirection;
+ return QDeclarativeBasePositionerPrivate::getLayoutDirection(this);
}
void QDeclarativeRow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
{
- if (m_layoutDirection != layoutDirection) {
- m_layoutDirection = layoutDirection;
+ QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate* >(QDeclarativeBasePositionerPrivate::get(this));
+ if (d->layoutDirection != layoutDirection) {
+ d->layoutDirection = layoutDirection;
prePositioning();
emit layoutDirectionChanged();
+ emit effectiveLayoutDirectionChanged();
}
}
+/*!
+ \qmlproperty enumeration Row::effectiveLayoutDirection
+ This property holds the effective layout direction of the row positioner.
+
+ When using the attached property {LayoutMirroring::mirror}{LayoutMirroring::mirror} for locale layouts,
+ the visual layout direction of the row positioner will be mirrored. However, the
+ property \l {Row::layoutDirection}{layoutDirection} will remain unchanged.
+
+ \sa Row::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QDeclarativeRow::effectiveLayoutDirection() const
+{
+ return QDeclarativeBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+
void QDeclarativeRow::doPositioning(QSizeF *contentSize)
{
+ QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
int hoffset = 0;
QList<int> hoffsets;
@@ -617,7 +636,7 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize)
if (!child.item || !child.isVisible)
continue;
- if(m_layoutDirection == Qt::LeftToRight){
+ if(d->isLeftToRight()){
if(child.item->x() != hoffset)
positionX(hoffset, child);
}else{
@@ -632,7 +651,7 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize)
contentSize->setWidth(hoffset - spacing());
- if(m_layoutDirection == Qt::LeftToRight)
+ if(d->isLeftToRight())
return;
//Right to Left layout
@@ -786,7 +805,7 @@ void QDeclarativeRow::reportConflictingAnchors()
\sa rows, columns
*/
QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) :
- QDeclarativeBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight), m_layoutDirection(Qt::LeftToRight)
+ QDeclarativeBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight)
{
}
@@ -860,11 +879,11 @@ void QDeclarativeGrid::setFlow(Flow flow)
Possible values are:
\list
- \o Qt.LeftToRight (default) - Items are positioned beginning
- from the top, left anchor. The flow direction is dependent
- on the \l Grid::flow property.
- \o Qt.RightToLeft - Items are positioned beginning from the
- top, right anchor. The flow direction is dependent on the
+ \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
+ and left to right. The flow direction is dependent on the
+ \l Grid::flow property.
+ \o Qt.RightToLeft - Items are positioned from the top to bottom,
+ and right to left. The flow direction is dependent on the
\l Grid::flow property.
\endlist
@@ -872,21 +891,39 @@ void QDeclarativeGrid::setFlow(Flow flow)
*/
Qt::LayoutDirection QDeclarativeGrid::layoutDirection() const
{
- return m_layoutDirection;
+ return QDeclarativeBasePositionerPrivate::getLayoutDirection(this);
}
void QDeclarativeGrid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
{
- if (m_layoutDirection != layoutDirection) {
- m_layoutDirection = layoutDirection;
+ QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
+ if (d->layoutDirection != layoutDirection) {
+ d->layoutDirection = layoutDirection;
prePositioning();
emit layoutDirectionChanged();
+ emit effectiveLayoutDirectionChanged();
}
}
-void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
+/*!
+ \qmlproperty enumeration Grid::effectiveLayoutDirection
+ This property holds the effective layout direction of the grid positioner.
+
+ When using the attached property {LayoutMirroring::mirror}{LayoutMirroring::mirror} for locale layouts,
+ the visual layout direction of the grid positioner will be mirrored. However, the
+ property \l {Grid::layoutDirection}{layoutDirection} will remain unchanged.
+
+ \sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QDeclarativeGrid::effectiveLayoutDirection() const
{
+ return QDeclarativeBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
+{
+ QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
int c = m_columns;
int r = m_rows;
//Is allocating the extra QPODVector too much overhead?
@@ -976,7 +1013,7 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
end = widthSum;
int xoffset=0;
- if(m_layoutDirection == Qt::RightToLeft)
+ if(!d->isLeftToRight())
xoffset=end;
int yoffset=0;
int curRow =0;
@@ -984,7 +1021,7 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
for (int i = 0; i < visibleItems.count(); ++i) {
const PositionedItem &child = visibleItems.at(i);
int childXOffset = xoffset;
- if(m_layoutDirection == Qt::RightToLeft)
+ if(!d->isLeftToRight())
childXOffset -= QGraphicsItemPrivate::get(child.item)->width();
if((child.item->x()!=childXOffset)||(child.item->y()!=yoffset)){
positionX(childXOffset, child);
@@ -992,7 +1029,7 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
}
if (m_flow == LeftToRight) {
- if(m_layoutDirection == Qt::LeftToRight)
+ if(d->isLeftToRight())
xoffset+=maxColWidth[curCol]+spacing();
else
xoffset-=maxColWidth[curCol]+spacing();
@@ -1000,7 +1037,7 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
curCol%=c;
if (!curCol){
yoffset+=maxRowHeight[curRow]+spacing();
- if(m_layoutDirection == Qt::LeftToRight)
+ if(d->isLeftToRight())
xoffset=0;
else
xoffset=end;
@@ -1013,7 +1050,7 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
curRow++;
curRow%=r;
if (!curRow){
- if(m_layoutDirection == Qt::LeftToRight)
+ if(d->isLeftToRight())
xoffset+=maxColWidth[curCol]+spacing();
else
xoffset-=maxColWidth[curCol]+spacing();
@@ -1148,12 +1185,10 @@ class QDeclarativeFlowPrivate : public QDeclarativeBasePositionerPrivate
public:
QDeclarativeFlowPrivate()
- : QDeclarativeBasePositionerPrivate(), flow(QDeclarativeFlow::LeftToRight),
- layoutDirection(Qt::LeftToRight)
+ : QDeclarativeBasePositionerPrivate(), flow(QDeclarativeFlow::LeftToRight)
{}
QDeclarativeFlow::Flow flow;
- Qt::LayoutDirection layoutDirection;
};
QDeclarativeFlow::QDeclarativeFlow(QDeclarativeItem *parent)
@@ -1202,11 +1237,11 @@ void QDeclarativeFlow::setFlow(Flow flow)
Possible values are:
\list
- \o Qt.LeftToRight (default) - Items are positioned beginning
- from the top, left anchor. The flow direction is dependent
- on the \l Flow::flow property.
- \o Qt.RightToLeft - Items are positioned beginning from the
- top, right anchor. The flow direction is dependent on the
+ \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
+ and left to right. The flow direction is dependent on the
+ \l Flow::flow property.
+ \o Qt.RightToLeft - Items are positioned from the top to bottom,
+ and right to left. The flow direction is dependent on the
\l Flow::flow property.
\endlist
@@ -1226,9 +1261,26 @@ void QDeclarativeFlow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
d->layoutDirection = layoutDirection;
prePositioning();
emit layoutDirectionChanged();
+ emit effectiveLayoutDirectionChanged();
}
}
+/*!
+ \qmlproperty enumeration Flow::effectiveLayoutDirection
+ This property holds the effective layout direction of the flow positioner.
+
+ When using the attached property {LayoutMirroring::mirror}{LayoutMirroring::mirror} for locale layouts,
+ the visual layout direction of the grid positioner will be mirrored. However, the
+ property \l {Flow::layoutDirection}{layoutDirection} will remain unchanged.
+
+ \sa Flow::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QDeclarativeFlow::effectiveLayoutDirection() const
+{
+ return QDeclarativeBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+
void QDeclarativeFlow::doPositioning(QSizeF *contentSize)
{
Q_D(QDeclarativeFlow);
@@ -1258,7 +1310,7 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize)
}
}
- if(d->layoutDirection == Qt::LeftToRight){
+ if(d->isLeftToRight()){
if(child.item->x() != hoffset)
positionX(hoffset, child);
}else{
@@ -1281,7 +1333,7 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize)
}
}
- if(d->layoutDirection == Qt::LeftToRight)
+ if(d->isLeftToRight())
return;
int end;
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners_p.h b/src/declarative/graphicsitems/qdeclarativepositioners_p.h
index 55d8fa1..214c04f 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepositioners_p.h
@@ -130,20 +130,22 @@ class Q_AUTOTEST_EXPORT QDeclarativeRow: public QDeclarativeBasePositioner
{
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged REVISION 1)
public:
QDeclarativeRow(QDeclarativeItem *parent=0);
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection (Qt::LayoutDirection);
+ Qt::LayoutDirection effectiveLayoutDirection() const;
Q_SIGNALS:
Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void effectiveLayoutDirectionChanged();
protected:
virtual void doPositioning(QSizeF *contentSize);
virtual void reportConflictingAnchors();
private:
- Qt::LayoutDirection m_layoutDirection;
Q_DISABLE_COPY(QDeclarativeRow)
};
@@ -154,7 +156,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeGrid : public QDeclarativeBasePositioner
Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
-
+ Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged REVISION 1)
public:
QDeclarativeGrid(QDeclarativeItem *parent=0);
@@ -171,12 +173,14 @@ public:
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection (Qt::LayoutDirection);
+ Qt::LayoutDirection effectiveLayoutDirection() const;
Q_SIGNALS:
void rowsChanged();
void columnsChanged();
void flowChanged();
Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void effectiveLayoutDirectionChanged();
protected:
virtual void doPositioning(QSizeF *contentSize);
@@ -186,7 +190,6 @@ private:
int m_rows;
int m_columns;
Flow m_flow;
- Qt::LayoutDirection m_layoutDirection;
Q_DISABLE_COPY(QDeclarativeGrid)
};
@@ -194,8 +197,9 @@ class QDeclarativeFlowPrivate;
class Q_AUTOTEST_EXPORT QDeclarativeFlow: public QDeclarativeBasePositioner
{
Q_OBJECT
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged REVISION 1)
public:
QDeclarativeFlow(QDeclarativeItem *parent=0);
@@ -206,10 +210,11 @@ public:
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection (Qt::LayoutDirection);
-
+ Qt::LayoutDirection effectiveLayoutDirection() const;
Q_SIGNALS:
void flowChanged();
Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1) void effectiveLayoutDirectionChanged();
protected:
virtual void doPositioning(QSizeF *contentSize);
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h
index df105c6..e80129d 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h
@@ -75,7 +75,7 @@ public:
QDeclarativeBasePositionerPrivate()
: spacing(0), type(QDeclarativeBasePositioner::None)
, moveTransition(0), addTransition(0), queuedPositioning(false)
- , doingPositioning(false), anchorConflict(false)
+ , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
{
}
@@ -100,6 +100,9 @@ public:
bool doingPositioning : 1;
bool anchorConflict : 1;
+ Qt::LayoutDirection layoutDirection;
+
+
void schedulePositioning()
{
Q_Q(QDeclarativeBasePositioner);
@@ -109,6 +112,18 @@ public:
}
}
+ void mirrorChange() {
+ Q_Q(QDeclarativeBasePositioner);
+ if (type != QDeclarativeBasePositioner::Vertical)
+ q->prePositioning();
+ }
+ bool isLeftToRight() const {
+ if (type == QDeclarativeBasePositioner::Vertical)
+ return true;
+ else
+ return effectiveLayoutMirror ? layoutDirection == Qt::RightToLeft : layoutDirection == Qt::LeftToRight;
+ }
+
virtual void itemSiblingOrderChanged(QDeclarativeItem* other)
{
Q_UNUSED(other);
@@ -139,6 +154,19 @@ public:
Q_Q(QDeclarativeBasePositioner);
q->positionedItems.removeOne(QDeclarativeBasePositioner::PositionedItem(item));
}
+
+ static Qt::LayoutDirection getLayoutDirection(const QDeclarativeBasePositioner *positioner)
+ {
+ return positioner->d_func()->layoutDirection;
+ }
+
+ static Qt::LayoutDirection getEffectiveLayoutDirection(const QDeclarativeBasePositioner *positioner)
+ {
+ if (positioner->d_func()->effectiveLayoutMirror)
+ return positioner->d_func()->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
+ else
+ return positioner->d_func()->layoutDirection;
+ }
};
QT_END_NAMESPACE