diff options
Diffstat (limited to 'src/declarative/items')
-rw-r--r-- | src/declarative/items/qsgitemsmodule.cpp | 1 | ||||
-rw-r--r-- | src/declarative/items/qsgpositioners.cpp | 122 | ||||
-rw-r--r-- | src/declarative/items/qsgpositioners_p.h | 39 |
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 |