--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp Fri Sep 17 08:34:18 2010 +0300
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp Mon Oct 04 01:19:32 2010 +0300
@@ -61,16 +61,37 @@
| QDeclarativeItemPrivate::Opacity
| QDeclarativeItemPrivate::Destroyed;
-void QDeclarativeBasePositionerPrivate::watchChanges(QDeclarativeItem *other)
+void QDeclarativeBasePositionerPrivate::watchChanges(QGraphicsObject *other)
{
- QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
- otherPrivate->addItemChangeListener(this, watchedChanges);
+ if (QGraphicsItemPrivate::get(other)->isDeclarativeItem) {
+ QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
+ otherPrivate->addItemChangeListener(this, watchedChanges);
+ } else {
+ Q_Q(QDeclarativeBasePositioner);
+ QObject::connect(other, SIGNAL(widthChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::connect(other, SIGNAL(heightChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::connect(other, SIGNAL(opacityChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::connect(other, SIGNAL(visibleChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ }
}
-void QDeclarativeBasePositionerPrivate::unwatchChanges(QDeclarativeItem* other)
+void QDeclarativeBasePositionerPrivate::unwatchChanges(QGraphicsObject* other)
{
- QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
- otherPrivate->removeItemChangeListener(this, watchedChanges);
+ if (QGraphicsItemPrivate::get(other)->isDeclarativeItem) {
+ QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
+ otherPrivate->removeItemChangeListener(this, watchedChanges);
+ } else {
+ Q_Q(QDeclarativeBasePositioner);
+ QObject::disconnect(other, SIGNAL(widthChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::disconnect(other, SIGNAL(heightChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::disconnect(other, SIGNAL(opacityChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ QObject::disconnect(other, SIGNAL(visibleChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
+ }
+}
+
+void QDeclarativeBasePositioner::graphicsWidgetGeometryChanged()
+{
+ prePositioning();
}
/*!
@@ -87,8 +108,7 @@
You also need to set a PositionerType, to declare whether you are positioning the x, y or both
for the child items. Depending on the chosen type, only x or y changes will be applied.
- Note that the subclass is responsible for adding the
- spacing in between items.
+ Note that the subclass is responsible for adding the spacing in between items.
*/
QDeclarativeBasePositioner::QDeclarativeBasePositioner(PositionerType at, QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeBasePositionerPrivate), parent)
@@ -174,16 +194,16 @@
Q_D(QDeclarativeBasePositioner);
if (change == ItemChildAddedChange){
QGraphicsItem* item = value.value<QGraphicsItem*>();
- QDeclarativeItem* child = 0;
+ QGraphicsObject* child = 0;
if(item)
- child = qobject_cast<QDeclarativeItem*>(item->toGraphicsObject());
+ child = item->toGraphicsObject();
if (child)
prePositioning();
} else if (change == ItemChildRemovedChange) {
QGraphicsItem* item = value.value<QGraphicsItem*>();
- QDeclarativeItem* child = 0;
+ QGraphicsObject* child = 0;
if(item)
- child = qobject_cast<QDeclarativeItem*>(item->toGraphicsObject());
+ child = item->toGraphicsObject();
if (child) {
QDeclarativeBasePositioner::PositionedItem posItem(child);
int idx = positionedItems.find(posItem);
@@ -194,7 +214,6 @@
prePositioning();
}
}
-
return QDeclarativeItem::itemChange(change, value);
}
@@ -216,10 +235,10 @@
QPODVector<PositionedItem,8> oldItems;
positionedItems.copyAndClear(oldItems);
for (int ii = 0; ii < children.count(); ++ii) {
- QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii));
+ QGraphicsObject *child = children.at(ii)->toGraphicsObject();
if (!child)
continue;
- QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child));
+ QGraphicsItemPrivate *childPrivate = static_cast<QGraphicsItemPrivate*>(QGraphicsItemPrivate::get(child));
PositionedItem *item = 0;
PositionedItem posItem(child);
int wIdx = oldItems.find(posItem);
@@ -228,13 +247,13 @@
positionedItems.append(posItem);
item = &positionedItems[positionedItems.count()-1];
item->isNew = true;
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden)
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height())
item->isVisible = false;
} else {
item = &oldItems[wIdx];
// Items are only omitted from positioning if they are explicitly hidden
// i.e. their positioning is not affected if an ancestor is hidden.
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) {
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) {
item->isVisible = false;
} else if (!item->isVisible) {
item->isVisible = true;
@@ -302,14 +321,9 @@
d->moveActions.clear();
}
-static inline bool isInvisible(QDeclarativeItem *child)
-{
- QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child));
- return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !child->width() || !child->height();
-}
-
/*!
\qmlclass Column QDeclarativeColumn
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Column item arranges its children vertically.
\inherits Item
@@ -418,11 +432,6 @@
\image spacing_b.png
*/
-/*!
- \internal
- \class QDeclarativeColumn
- \brief The QDeclarativeColumn class lines up items vertically.
-*/
QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent)
: QDeclarativeBasePositioner(Vertical, parent)
{
@@ -434,15 +443,15 @@
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->y() != voffset)
positionY(voffset, child);
- contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
+ contentSize->setWidth(qMax(contentSize->width(), QGraphicsItemPrivate::get(child.item)->width()));
- voffset += child.item->height();
+ voffset += QGraphicsItemPrivate::get(child.item)->height();
voffset += spacing();
}
@@ -454,8 +463,8 @@
QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (child.item) {
- QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors;
+ if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
+ QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
if (anchors) {
QDeclarativeAnchors::Anchors usedAnchors = anchors->usedAnchors();
if (usedAnchors & QDeclarativeAnchors::TopAnchor ||
@@ -475,6 +484,7 @@
/*!
\qmlclass Row QDeclarativeRow
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Row item arranges its children horizontally.
\inherits Item
@@ -557,11 +567,6 @@
\image spacing_b.png
*/
-/*!
- \internal
- \class QDeclarativeRow
- \brief The QDeclarativeRow class lines up items horizontally.
-*/
QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent)
: QDeclarativeBasePositioner(Horizontal, parent)
{
@@ -573,15 +578,15 @@
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->x() != hoffset)
positionX(hoffset, child);
- contentSize->setHeight(qMax(contentSize->height(), child.item->height()));
+ contentSize->setHeight(qMax(contentSize->height(), QGraphicsItemPrivate::get(child.item)->height()));
- hoffset += child.item->width();
+ hoffset += QGraphicsItemPrivate::get(child.item)->width();
hoffset += spacing();
}
@@ -593,8 +598,8 @@
QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (child.item) {
- QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors;
+ if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
+ QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
if (anchors) {
QDeclarativeAnchors::Anchors usedAnchors = anchors->usedAnchors();
if (usedAnchors & QDeclarativeAnchors::LeftAnchor ||
@@ -613,6 +618,7 @@
/*!
\qmlclass Grid QDeclarativeGrid
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Grid item positions its children in a grid.
\inherits Item
@@ -713,11 +719,6 @@
\image spacing_b.png
*/
-/*!
- \internal
- \class QDeclarativeGrid
- \brief The QDeclarativeGrid class lays out items in a grid.
-*/
QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) :
QDeclarativeBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight)
{
@@ -786,9 +787,17 @@
void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
{
+
int c = m_columns;
int r = m_rows;
- int numVisible = positionedItems.count();
+ //Is allocating the extra QPODVector too much overhead?
+ QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
+ visibleItems.reserve(positionedItems.count());
+ for(int i=0; i<positionedItems.count(); i++)
+ if(positionedItems[i].item && positionedItems[i].isVisible)
+ visibleItems.append(positionedItems[i]);
+
+ int numVisible = visibleItems.count();
if (m_columns <= 0 && m_rows <= 0){
c = 4;
r = (numVisible+3)/4;
@@ -809,15 +818,15 @@
if (i==0)
maxColWidth << 0;
- if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
- if (child.item->width() > maxColWidth[j])
- maxColWidth[j] = child.item->width();
- if (child.item->height() > maxRowHeight[i])
- maxRowHeight[i] = child.item->height();
+ if (childIndex == visibleItems.count())
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
+ QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
+ if (childPrivate->width() > maxColWidth[j])
+ maxColWidth[j] = childPrivate->width();
+ if (childPrivate->height() > maxRowHeight[i])
+ maxRowHeight[i] = childPrivate->height();
}
}
} else {
@@ -829,14 +838,14 @@
maxColWidth << 0;
if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
- if (child.item->width() > maxColWidth[j])
- maxColWidth[j] = child.item->width();
- if (child.item->height() > maxRowHeight[i])
- maxRowHeight[i] = child.item->height();
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
+ QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
+ if (childPrivate->width() > maxColWidth[j])
+ maxColWidth[j] = childPrivate->width();
+ if (childPrivate->height() > maxRowHeight[i])
+ maxRowHeight[i] = childPrivate->height();
}
}
}
@@ -845,17 +854,15 @@
int yoffset=0;
int curRow =0;
int curCol =0;
- for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
- continue;
+ for (int i = 0; i < visibleItems.count(); ++i) {
+ const PositionedItem &child = visibleItems.at(i);
if((child.item->x()!=xoffset)||(child.item->y()!=yoffset)){
positionX(xoffset, child);
positionY(yoffset, child);
}
if (m_flow == LeftToRight) {
- contentSize->setWidth(qMax(contentSize->width(), xoffset + child.item->width()));
+ contentSize->setWidth(qMax(contentSize->width(), xoffset + QGraphicsItemPrivate::get(child.item)->width()));
contentSize->setHeight(yoffset + maxRowHeight[curRow]);
xoffset+=maxColWidth[curCol]+spacing();
@@ -869,7 +876,7 @@
break;
}
} else {
- contentSize->setHeight(qMax(contentSize->height(), yoffset + child.item->height()));
+ contentSize->setHeight(qMax(contentSize->height(), yoffset + QGraphicsItemPrivate::get(child.item)->height()));
contentSize->setWidth(xoffset + maxColWidth[curCol]);
yoffset+=maxRowHeight[curRow]+spacing();
@@ -891,8 +898,8 @@
QDeclarativeBasePositionerPrivate *d = static_cast<QDeclarativeBasePositionerPrivate*>(QDeclarativeBasePositionerPrivate::get(this));
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (child.item) {
- QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors;
+ if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
+ QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
d->anchorConflict = true;
break;
@@ -905,6 +912,7 @@
/*!
\qmlclass Flow QDeclarativeFlow
+ \ingroup qml-positioning-elements
\since 4.7
\brief The Flow item arranges its children side by side, wrapping as necessary.
\inherits Item
@@ -1023,17 +1031,18 @@
for (int i = 0; i < positionedItems.count(); ++i) {
const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
+ QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
if (d->flow == LeftToRight) {
- if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
+ if (widthValid() && hoffset && hoffset + childPrivate->width() > width()) {
hoffset = 0;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (heightValid() && voffset && voffset + child.item->height() > height()) {
+ if (heightValid() && voffset && voffset + childPrivate->height() > height()) {
voffset = 0;
hoffset += linemax + spacing();
linemax = 0;
@@ -1045,17 +1054,17 @@
positionY(voffset, child);
}
- contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
- contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
+ contentSize->setWidth(qMax(contentSize->width(), hoffset + childPrivate->width()));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + childPrivate->height()));
if (d->flow == LeftToRight) {
- hoffset += child.item->width();
+ hoffset += childPrivate->width();
hoffset += spacing();
- linemax = qMax(linemax, qCeil(child.item->height()));
+ linemax = qMax(linemax, qCeil(childPrivate->height()));
} else {
- voffset += child.item->height();
+ voffset += childPrivate->height();
voffset += spacing();
- linemax = qMax(linemax, qCeil(child.item->width()));
+ linemax = qMax(linemax, qCeil(childPrivate->width()));
}
}
}
@@ -1065,8 +1074,8 @@
Q_D(QDeclarativeFlow);
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (child.item) {
- QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(child.item)->_anchors;
+ if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
+ QDeclarativeAnchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
d->anchorConflict = true;
break;