aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/declarative/items/qsgitemsmodule.cpp1
-rw-r--r--src/declarative/items/qsgpositioners.cpp122
-rw-r--r--src/declarative/items/qsgpositioners_p.h39
3 files changed, 158 insertions, 4 deletions
diff --git a/src/declarative/items/qsgitemsmodule.cpp b/src/declarative/items/qsgitemsmodule.cpp
index 62a4bd06cb..9359906f25 100644
--- a/src/declarative/items/qsgitemsmodule.cpp
+++ b/src/declarative/items/qsgitemsmodule.cpp
@@ -126,6 +126,7 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QDeclarativePathPercent>(uri,major,minor,"PathPercent");
qmlRegisterType<QDeclarativePathQuad>(uri,major,minor,"PathQuad");
qmlRegisterType<QSGPathView>(uri,major,minor,"PathView");
+ qmlRegisterUncreatableType<QSGBasePositioner>(uri,major,minor,"Positioner","Positioner is an abstract type that is only available as an attached property.");
#ifndef QT_NO_VALIDATOR
qmlRegisterType<QIntValidator>(uri,major,minor,"IntValidator");
qmlRegisterType<QDoubleValidator>(uri,major,minor,"DoubleValidator");
diff --git a/src/declarative/items/qsgpositioners.cpp b/src/declarative/items/qsgpositioners.cpp
index d500afd81c..df3450e4d7 100644
--- a/src/declarative/items/qsgpositioners.cpp
+++ b/src/declarative/items/qsgpositioners.cpp
@@ -230,6 +230,7 @@ void QSGBasePositioner::prePositioning()
}
QSizeF contentSize(0,0);
doPositioning(&contentSize);
+ updateAttachedProperties();
if (!d->addActions.isEmpty() || !d->moveActions.isEmpty())
finishApplyTransitions();
d->doingPositioning = false;
@@ -285,6 +286,119 @@ void QSGBasePositioner::finishApplyTransitions()
d->moveActions.clear();
}
+QSGPositionerAttached *QSGBasePositioner::qmlAttachedProperties(QObject *obj)
+{
+ return new QSGPositionerAttached(obj);
+}
+
+void QSGBasePositioner::updateAttachedProperties(QSGPositionerAttached *specificProperty, QSGItem *specificPropertyOwner) const
+{
+ // If this function is deemed too expensive or shows up in profiles, it could
+ // be changed to run only when there are attached properties present. This
+ // could be a flag in the positioner that is set by the attached property
+ // constructor.
+ QSGPositionerAttached *prevLastProperty = 0;
+ QSGPositionerAttached *lastProperty = 0;
+
+ int visibleItemIndex = 0;
+ for (int ii = 0; ii < positionedItems.count(); ++ii) {
+ const PositionedItem &child = positionedItems.at(ii);
+ if (!child.item)
+ continue;
+
+ QSGPositionerAttached *property = 0;
+
+ if (specificProperty) {
+ if (specificPropertyOwner == child.item) {
+ property = specificProperty;
+ }
+ } else {
+ property = static_cast<QSGPositionerAttached *>(qmlAttachedPropertiesObject<QSGBasePositioner>(child.item, false));
+ }
+
+ if (child.isVisible) {
+ if (property) {
+ property->setIndex(visibleItemIndex);
+ property->setIsFirstItem(visibleItemIndex == 0);
+
+ if (property->isLastItem())
+ prevLastProperty = property;
+ }
+
+ lastProperty = property;
+ ++visibleItemIndex;
+ } else if (property) {
+ property->setIndex(-1);
+ property->setIsFirstItem(false);
+ property->setIsLastItem(false);
+ }
+ }
+
+ if (prevLastProperty && prevLastProperty != lastProperty)
+ prevLastProperty->setIsLastItem(false);
+ if (lastProperty)
+ lastProperty->setIsLastItem(true);
+}
+
+/*!
+ \qmlclass Positioner QSGPositionerAttached
+ \inqmlmodule QtQuick 2
+ \ingroup qml-positioning-elements
+ \brief The Positioner type provides attached properties that contain details on where an item exists in a positioner.
+
+ Positioner items (such as Column, Row, Flow and Grid) provide automatic layout
+ for child items. Attaching this property allows a child item to determine
+ where it exists within the positioner.
+*/
+
+QSGPositionerAttached::QSGPositionerAttached(QObject *parent) : QObject(parent), m_index(-1), m_isFirstItem(false), m_isLastItem(false)
+{
+ QSGItem *attachedItem = qobject_cast<QSGItem *>(parent);
+ if (attachedItem) {
+ QSGBasePositioner *positioner = qobject_cast<QSGBasePositioner *>(attachedItem->parent());
+ if (positioner) {
+ positioner->updateAttachedProperties(this, attachedItem);
+ }
+ }
+}
+
+/*!
+ \qmlattachedproperty Item QtQuick2::Positioner::index
+
+ This property allows the item to determine
+ its index within the positioner.
+*/
+void QSGPositionerAttached::setIndex(int index)
+{
+ if (m_index == index)
+ return;
+ m_index = index;
+ emit indexChanged();
+}
+
+/*!
+ \qmlattachedproperty Item QtQuick2::Positioner::isFirstItem
+ \qmlattachedproperty Item QtQuick2::Positioner::isLastItem
+
+ These properties allow the item to determine if it
+ is the first or last item in the positioner, respectively.
+*/
+void QSGPositionerAttached::setIsFirstItem(bool isFirstItem)
+{
+ if (m_isFirstItem == isFirstItem)
+ return;
+ m_isFirstItem = isFirstItem;
+ emit isFirstItemChanged();
+}
+
+void QSGPositionerAttached::setIsLastItem(bool isLastItem)
+{
+ if (m_isLastItem == isLastItem)
+ return;
+ m_isLastItem = isLastItem;
+ emit isLastItemChanged();
+}
+
/*!
\qmlclass Column QSGColumn
\inqmlmodule QtQuick 2
@@ -349,7 +463,7 @@ void QSGBasePositioner::finishApplyTransitions()
Items with a width or height of 0 will not be positioned.
- \sa Row, Grid, Flow, {declarative/positioners}{Positioners example}
+ \sa Row, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Column::add
@@ -492,7 +606,7 @@ void QSGColumn::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
- \sa Column, Grid, Flow, {declarative/positioners}{Positioners example}
+ \sa Column, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Row::add
@@ -722,7 +836,7 @@ void QSGRow::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
- \sa Flow, Row, Column, {declarative/positioners}{Positioners example}
+ \sa Flow, Row, Column, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Grid::add
@@ -1149,7 +1263,7 @@ void QSGGrid::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
- \sa Column, Row, Grid, {declarative/positioners}{Positioners example}
+ \sa Column, Row, Grid, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Flow::add
diff --git a/src/declarative/items/qsgpositioners_p.h b/src/declarative/items/qsgpositioners_p.h
index 8f9d3eb310..7200b6da8d 100644
--- a/src/declarative/items/qsgpositioners_p.h
+++ b/src/declarative/items/qsgpositioners_p.h
@@ -59,6 +59,37 @@ QT_MODULE(Declarative)
class QSGBasePositionerPrivate;
+class QSGPositionerAttached : public QObject
+{
+ Q_OBJECT
+
+public:
+ QSGPositionerAttached(QObject *parent);
+
+ Q_PROPERTY(int index READ index NOTIFY indexChanged)
+ Q_PROPERTY(bool isFirstItem READ isFirstItem NOTIFY isFirstItemChanged)
+ Q_PROPERTY(bool isLastItem READ isLastItem NOTIFY isLastItemChanged)
+
+ int index() const { return m_index; }
+ void setIndex(int index);
+
+ bool isFirstItem() const { return m_isFirstItem; }
+ void setIsFirstItem(bool isFirstItem);
+
+ bool isLastItem() const { return m_isLastItem; }
+ void setIsLastItem(bool isLastItem);
+
+Q_SIGNALS:
+ void indexChanged();
+ void isFirstItemChanged();
+ void isLastItemChanged();
+
+private:
+ int m_index;
+ bool m_isFirstItem;
+ bool m_isLastItem;
+};
+
class Q_DECLARATIVE_PRIVATE_EXPORT QSGBasePositioner : public QSGImplicitSizeItem
{
Q_OBJECT
@@ -80,6 +111,10 @@ public:
QDeclarativeTransition *add() const;
void setAdd(QDeclarativeTransition *);
+ static QSGPositionerAttached *qmlAttachedProperties(QObject *obj);
+
+ void updateAttachedProperties(QSGPositionerAttached *specificProperty = 0, QSGItem *specificPropertyOwner = 0) const;
+
protected:
QSGBasePositioner(QSGBasePositionerPrivate &dd, PositionerType at, QSGItem *parent);
virtual void componentComplete();
@@ -120,6 +155,7 @@ class Q_AUTOTEST_EXPORT QSGColumn : public QSGBasePositioner
Q_OBJECT
public:
QSGColumn(QSGItem *parent=0);
+
protected:
virtual void doPositioning(QSizeF *contentSize);
virtual void reportConflictingAnchors();
@@ -249,6 +285,9 @@ QML_DECLARE_TYPE(QSGRow)
QML_DECLARE_TYPE(QSGGrid)
QML_DECLARE_TYPE(QSGFlow)
+QML_DECLARE_TYPE(QSGBasePositioner)
+QML_DECLARE_TYPEINFO(QSGBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
+
QT_END_HEADER
#endif // QSGPOSITIONERS_P_H