From b6170b833f424e641446d5cec40d2021dcfa2a0a Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 8 Dec 2009 17:11:02 +1000 Subject: Stagger creation and release of items in GridView. Avoid creating a full row in one frame. --- .../graphicsitems/qmlgraphicsgridview.cpp | 179 +++++++++++++++------ .../tst_qmlgraphicsgridview.cpp | 11 +- 2 files changed, 137 insertions(+), 53 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp index 7279ea6..fb40b35 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp @@ -157,7 +157,7 @@ public: , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , ownModel(false), wrap(false), autoHighlight(true) - , fixCurrentVisibility(false) {} + , fixCurrentVisibility(false), lazyRelease(false) {} void init(); void clear(); @@ -264,6 +264,16 @@ public: return 0; } + FxGridItem *firstVisibleItem() const { + const qreal pos = position(); + for (int i = 0; i < visibleItems.count(); ++i) { + FxGridItem *item = visibleItems.at(i); + if (item->index != -1 && item->endRowPos() > pos) + return item; + } + return visibleItems.count() ? visibleItems.first() : 0; + } + // Map a model index to visibleItems list index. // These may differ if removed items are still present in the visible list, // e.g. doing a removal animation @@ -321,6 +331,7 @@ public: bool wrap : 1; bool autoHighlight : 1; bool fixCurrentVisibility : 1; + bool lazyRelease : 1; }; void QmlGraphicsGridViewPrivate::init() @@ -406,17 +417,24 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to) --i; modelIndex = visibleItems.at(i)->index + 1; } + int colNum = colPos / colSize(); FxGridItem *item = 0; - while (modelIndex < model->count() && rowPos <= to) { + + // Item creation and release is staggered in order to avoid + // creating/releasing multiple items in one frame + // while flicking (as much as possible). + while (modelIndex < model->count() && rowPos <= to + rowSize()*(columns - colNum)/(columns+1)) { //qDebug() << "refill: append item" << modelIndex; if (!(item = createItem(modelIndex))) break; item->setPosition(colPos, rowPos); visibleItems.append(item); colPos += colSize(); + colNum++; if (colPos > colSize() * (columns-1)) { colPos = 0; + colNum = 0; rowPos += rowSize(); } ++modelIndex; @@ -431,7 +449,8 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to) rowPos -= rowSize(); } } - while (visibleIndex > 0 && rowPos + rowSize() - 1 >= from){ + colNum = colPos / colSize(); + while (visibleIndex > 0 && rowPos + rowSize() - 1 >= from - rowSize()*(colNum+1)/(columns+1)){ //qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; if (!(item = createItem(visibleIndex-1))) break; @@ -439,30 +458,38 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to) item->setPosition(colPos, rowPos); visibleItems.prepend(item); colPos -= colSize(); + colNum--; if (colPos < 0) { colPos = colSize() * (columns - 1); + colNum = columns-1; rowPos -= rowSize(); } changed = true; } - while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endRowPos() < from) { - if (item->attached->delayRemove()) - break; - //qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); - if (item->index != -1) - visibleIndex++; - visibleItems.removeFirst(); - releaseItem(item); - changed = true; - } - while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->rowPos() > to) { - if (item->attached->delayRemove()) - break; - //qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; - visibleItems.removeLast(); - releaseItem(item); - changed = true; + if (!lazyRelease || !changed) { // avoid destroying items in the same frame that we create + while (visibleItems.count() > 1 + && (item = visibleItems.first()) + && item->endRowPos() < from - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) { + if (item->attached->delayRemove()) + break; + //qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); + if (item->index != -1) + visibleIndex++; + visibleItems.removeFirst(); + releaseItem(item); + changed = true; + } + while (visibleItems.count() > 1 + && (item = visibleItems.last()) + && item->rowPos() > to + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) { + if (item->attached->delayRemove()) + break; + //qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; + visibleItems.removeLast(); + releaseItem(item); + changed = true; + } } if (changed) { if (flow == QmlGraphicsGridView::LeftToRight) @@ -470,6 +497,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to) else q->setViewportWidth(endPosition() - startPosition()); } + lazyRelease = false; } void QmlGraphicsGridViewPrivate::updateGrid() @@ -1127,7 +1155,9 @@ void QmlGraphicsGridView::sizeChange() void QmlGraphicsGridView::viewportMoved() { + Q_D(QmlGraphicsGridView); QmlGraphicsFlickable::viewportMoved(); + d->lazyRelease = true; refill(); } @@ -1177,7 +1207,6 @@ void QmlGraphicsGridView::keyPressEvent(QKeyEvent *event) QmlGraphicsFlickable::keyPressEvent(event); if (event->isAccepted()) return; - if (d->model && d->model->count() && d->interactive) { d->moveReason = QmlGraphicsGridViewPrivate::SetIndex; int oldCurrent = currentIndex(); @@ -1430,21 +1459,71 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) } QList added; - int i = 0; - for (; i < insertCount && rowPos + d->rowSize() - 1 <= to; ++i) { - int mod = (modelIndex+i) % d->columns; - while (mod++ < d->columns && modelIndex + i < d->model->count() && i < insertCount) { - FxGridItem *item = d->createItem(modelIndex + i); - d->visibleItems.insert(index, item); - item->setPosition(colPos, rowPos); - added.append(item); - colPos += d->colSize(); - if (colPos > d->colSize() * (d->columns-1)) { - colPos = 0; - rowPos += d->rowSize(); + FxGridItem *firstItem = d->firstVisibleItem(); + if (firstItem && rowPos < firstItem->rowPos()) { + int from = d->position() - d->buffer; + int i = 0; + int insertionIdx = index; + for (i = insertCount-1; i >= 0 && rowPos > from; --i) { + int mod = (modelIndex+i) % d->columns; + while (mod++ < d->columns && modelIndex + i < d->model->count() && i < insertCount) { + FxGridItem *item = d->createItem(modelIndex + i); + d->visibleItems.insert(insertionIdx, item); + item->setPosition(colPos, rowPos); + added.append(item); + colPos -= d->colSize(); + if (colPos < 0) { + colPos = d->colSize() * (d->columns-1); + rowPos -= d->rowSize(); + } + ++index; + ++i; + } + } + if (i >= 0) { + // If we didn't insert all our new items - anything + // before the current index is not visible - remove it. + while (insertionIdx--) { + FxGridItem *item = d->visibleItems.takeFirst(); + if (item->index != -1) + d->visibleIndex++; + d->releaseItem(item); + } + } else { + // adjust pos of items before inserted items. + for (int i = insertionIdx-1; i >= 0; i--) { + FxGridItem *gridItem = d->visibleItems.at(i); + gridItem->setPosition(colPos, rowPos); + colPos -= d->colSize(); + if (colPos < 0) { + colPos = d->colSize() * (d->columns-1); + rowPos -= d->rowSize(); + } + } + } + } else { + int i = 0; + for (i = 0; i < insertCount && rowPos + d->rowSize() - 1 <= to; ++i) { + int mod = (modelIndex+i) % d->columns; + while (mod++ < d->columns && modelIndex + i < d->model->count() && i < insertCount) { + FxGridItem *item = d->createItem(modelIndex + i); + d->visibleItems.insert(index, item); + item->setPosition(colPos, rowPos); + added.append(item); + colPos += d->colSize(); + if (colPos > d->colSize() * (d->columns-1)) { + colPos = 0; + rowPos += d->rowSize(); + } + ++index; + ++i; } - ++index; - ++i; + } + if (i < insertCount) { + // We didn't insert all our new items, which means anything + // beyond the current index is not visible - remove it. + while (d->visibleItems.count() > index) + d->releaseItem(d->visibleItems.takeLast()); } } @@ -1456,19 +1535,13 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); } } - if (i < insertCount) { - // We didn't insert all our new items, which means anything - // beyond the current index is not visible - remove it. - while (d->visibleItems.count() > index) - d->releaseItem(d->visibleItems.takeLast()); - } else { - // Update the indexes of the following visible items. - for (; index < d->visibleItems.count(); ++index) { - FxGridItem *listItem = d->visibleItems.at(index); - if (listItem->index != -1) - listItem->index += count; - } + // Update the indexes of the following visible items. + for (; index < d->visibleItems.count(); ++index) { + FxGridItem *listItem = d->visibleItems.at(index); + if (listItem->index != -1) + listItem->index += count; } + // everything is in order now - emit add() signal for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); @@ -1587,6 +1660,12 @@ void QmlGraphicsGridView::itemsMoved(int from, int to, int count) Q_D(QmlGraphicsGridView); QHash moved; + bool removedBeforeVisible = false; + FxGridItem *firstItem = d->firstVisibleItem(); + + if (from < to && from < d->visibleIndex && to > d->visibleIndex) + removedBeforeVisible = true; + QList::Iterator it = d->visibleItems.begin(); while (it != d->visibleItems.end()) { FxGridItem *item = *it; @@ -1595,12 +1674,16 @@ void QmlGraphicsGridView::itemsMoved(int from, int to, int count) item->index += (to-from); moved.insert(item->index, item); it = d->visibleItems.erase(it); + if (item->rowPos() < firstItem->rowPos()) + removedBeforeVisible = true; } else { if (item->index > from && item->index != -1) { // move everything after the moved items. item->index -= count; if (item->index < d->visibleIndex) d->visibleIndex = item->index; + } else if (item->index != -1) { + removedBeforeVisible = true; } ++it; } @@ -1642,7 +1725,7 @@ void QmlGraphicsGridView::itemsMoved(int from, int to, int count) while (moved.count()) d->releaseItem(moved.take(moved.begin().key())); - d->layout(); + d->layout(removedBeforeVisible); } void QmlGraphicsGridView::createdItem(int index, QmlGraphicsItem *item) diff --git a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp index 96a164b..b28d805 100644 --- a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp +++ b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp @@ -525,13 +525,13 @@ void tst_QmlGraphicsGridView::moved() QTest::qWait(300); // Confirm items positioned correctly and indexes correct - itemCount = findItems(viewport, "wrapper").count(); - for (int i = 3; i < model.count() && i < itemCount; ++i) { + itemCount = findItems(viewport, "wrapper").count()-1; + for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) { QmlGraphicsItem *item = findItem(viewport, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QVERIFY(item); QCOMPARE(item->x(), qreal((i%3)*80)); - QCOMPARE(item->y(), qreal((i/3)*60 + 60)); + QCOMPARE(item->y(), qreal((i/3)*60)); name = findItem(viewport, "textName", i); QVERIFY(name != 0); QCOMPARE(name->text(), model.name(i)); @@ -547,12 +547,12 @@ void tst_QmlGraphicsGridView::moved() QTest::qWait(300); // Confirm items positioned correctly and indexes correct - for (int i = 3; i < model.count() && i < itemCount; ++i) { + for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) { QmlGraphicsItem *item = findItem(viewport, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QVERIFY(item); QVERIFY(item->x() == (i%3)*80); - QVERIFY(item->y() == (i/3)*60 + 60); + QVERIFY(item->y() == (i/3)*60); name = findItem(viewport, "textName", i); QVERIFY(name != 0); QCOMPARE(name->text(), model.name(i)); @@ -648,6 +648,7 @@ void tst_QmlGraphicsGridView::currentIndex() // Test keys canvas->show(); + canvas->setFocus(); qApp->processEvents(); QEvent wa(QEvent::WindowActivate); -- cgit v0.12 From 0828d52eafa2cc0e588af05ff9dbb8865af9de27 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 8 Dec 2009 17:28:03 +1000 Subject: Link to Data Models doc --- src/declarative/util/qmllistmodel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 995a7a4..f4317af 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -199,6 +199,8 @@ static void dump(ModelNode *node, int ind); When creating content dynamically, note that the set of available properties cannot be changed except by first clearing the model - whatever properties are first added are then the only permitted properties in the model. + + \sa {qmlmodels}{Data Models} */ class ModelObject : public QObject -- cgit v0.12 From c115ca5a025cedcbb5a34863918b22aac860f66a Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 8 Dec 2009 17:36:43 +1000 Subject: It *did* make it into 4.6.0. See commit fab1ce65da8bacfce92b1df7656780e729d31b74. --- src/declarative/graphicsitems/qmlgraphicstextedit.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index 0b8bc83..747e2fb 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -871,10 +871,7 @@ void QmlGraphicsTextEditPrivate::init() q->setFlag(QGraphicsItem::ItemAcceptsInputMethod); control = new QTextControl(q); - -#if QT_VERSION >= 0x040601 // XXX see bug QT-2236 control->setIgnoreUnusedNavigationEvents(true); -#endif QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateImgCache(QRectF))); -- cgit v0.12 From fd4813062ce0851ddad4fe19358e4086e42efaa5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 8 Dec 2009 12:57:57 +0100 Subject: small improvements --- src/declarative/util/qnumberformat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qnumberformat.cpp b/src/declarative/util/qnumberformat.cpp index c6a03e9..fd44db1 100644 --- a/src/declarative/util/qnumberformat.cpp +++ b/src/declarative/util/qnumberformat.cpp @@ -75,7 +75,7 @@ void QNumberFormat::handleFormat() { // ### is extremely messy if (_format.isEmpty()) { - _text = QString(QLatin1String("%1")).arg(_number, -1, 'f', -1); + _text = QString::number(_number, 'f', -1); return; } @@ -115,7 +115,7 @@ void QNumberFormat::handleFormat() } // round given the decimal length/precision - inputString = QString(QLatin1String("%1")).arg(_number, -1, 'f', decimalLength); + inputString = QString::number(_number, 'f', decimalLength); QStringList parts = inputString.split(QLatin1Char('.')); QStringList formatParts = _format.split(QLatin1Char('.')); -- cgit v0.12 From 3ed9d026dd6ca23802f59bfc22333a8e753fa1dc Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 09:37:11 +1000 Subject: Fix crash. --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index dd76f1c..9e6fcc0 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1328,6 +1328,7 @@ QGraphicsItem::~QGraphicsItem() d_ptr->removeExtraItemCache(); clearFocus(); + d_ptr->subFocusItem = 0; // Update focus scope item ptr. QGraphicsItem *p = d_ptr->parent; -- cgit v0.12 From 1616c62ceaded1a77cf49c6d05aa51814ac855bd Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 9 Dec 2009 09:48:51 +1000 Subject: Fix flick correction with variable height items. --- .../graphicsitems/qmlgraphicslistview.cpp | 80 ++++++++++++---------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index 135262c..2084d94 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -1076,14 +1076,11 @@ void QmlGraphicsListViewPrivate::flickX(qreal velocity) accel = v2 / (2.0f * qAbs(dist)); overshootDist = 0.0; } else { - if (velocity > 0) - flickTargetX = minX; - else - flickTargetX = maxX; + flickTargetX = velocity > 0 ? minX : maxX; overshootDist = overShoot ? 30 : 0; } timeline.reset(_moveX); - timeline.accel(_moveX, v, accel, maxDistance); + timeline.accel(_moveX, v, accel, maxDistance + overshootDist); timeline.execute(fixupXEvent); flicked = true; emit q->flickingChanged(); @@ -1091,14 +1088,15 @@ void QmlGraphicsListViewPrivate::flickX(qreal velocity) correctFlick = true; } else { // reevaluate the target boundary. - qreal newtarget = -snapPosAt(-(flickTargetX - highlightRangeStart)) + highlightRangeStart; - if (newtarget < maxX) { + qreal newtarget = flickTargetX; + if (snapMode != QmlGraphicsListView::NoSnap || highlightRange == QmlGraphicsListView::StrictlyEnforceRange) + newtarget = -snapPosAt(-(flickTargetX - highlightRangeStart)) + highlightRangeStart; + if (velocity < 0 && newtarget < maxX) newtarget = maxX; - } - if (newtarget == flickTargetX) { - // boundary unchanged - nothing to do + else if (velocity > 0 && newtarget > minX) + newtarget = minX; + if (newtarget == flickTargetX) // boundary unchanged - nothing to do return; - } flickTargetX = newtarget; qreal dist = -newtarget + _moveX.value(); if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) { @@ -1175,14 +1173,11 @@ void QmlGraphicsListViewPrivate::flickY(qreal velocity) accel = v2 / (2.0f * qAbs(dist)); overshootDist = 0.0; } else { - if (velocity > 0) - flickTargetY = minY; - else - flickTargetY = maxY; + flickTargetY = velocity > 0 ? minY : maxY; overshootDist = overShoot ? 30 : 0; } timeline.reset(_moveY); - timeline.accel(_moveY, v, accel, maxDistance); + timeline.accel(_moveY, v, accel, maxDistance + overshootDist); timeline.execute(fixupYEvent); flicked = true; emit q->flickingChanged(); @@ -1190,14 +1185,15 @@ void QmlGraphicsListViewPrivate::flickY(qreal velocity) correctFlick = true; } else { // reevaluate the target boundary. - qreal newtarget = -snapPosAt(-(flickTargetY - highlightRangeStart)) + highlightRangeStart; - if (newtarget < maxY) { + qreal newtarget = flickTargetY; + if (snapMode != QmlGraphicsListView::NoSnap || highlightRange == QmlGraphicsListView::StrictlyEnforceRange) + newtarget = -snapPosAt(-(flickTargetY - highlightRangeStart)) + highlightRangeStart; + if (velocity < 0 && newtarget < maxY) newtarget = maxY; - } - if (newtarget == flickTargetY) { - // boundary unchanged - nothing to do + else if (velocity > 0 && newtarget > minY) + newtarget = minY; + if (newtarget == flickTargetY) // boundary unchanged - nothing to do return; - } flickTargetY = newtarget; qreal dist = -newtarget + _moveY.value(); if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) { @@ -1922,20 +1918,32 @@ void QmlGraphicsListView::viewportMoved() if (d->flicked && d->correctFlick) { // Near an end and it seems that the extent has changed? // Recalculate the flick so that we don't end up in an odd position. - if (d->velocityY > 0) { - if (d->flickTargetY - d->_moveY.value() < height()/2 && minYExtent() != d->flickTargetY) - d->flickY(-d->verticalVelocity.value()); - } else if (d->velocityY < 0) { - if (d->_moveY.value() - d->flickTargetY < height()/2 && maxYExtent() != d->flickTargetY) - d->flickY(-d->verticalVelocity.value()); - } - - if (d->velocityX > 0) { - if (d->flickTargetX - d->_moveX.value() < height()/2 && minXExtent() != d->flickTargetX) - d->flickX(-d->verticalVelocity.value()); - } else if (d->velocityX < 0) { - if (d->_moveX.value() - d->flickTargetX < height()/2 && maxXExtent() != d->flickTargetX) - d->flickX(-d->verticalVelocity.value()); + if (yflick()) { + if (d->velocityY > 0) { + const qreal minY = minYExtent(); + if ((minY - d->_moveY.value() < height()/2 || d->flickTargetY - d->_moveY.value() < height()/2) + && minY != d->flickTargetY) + d->flickY(-d->verticalVelocity.value()); + } else if (d->velocityY < 0) { + const qreal maxY = maxYExtent(); + if ((d->_moveY.value() - maxY < height()/2 || d->_moveY.value() - d->flickTargetY < height()/2) + && maxY != d->flickTargetY) + d->flickY(-d->verticalVelocity.value()); + } + } + + if (xflick()) { + if (d->velocityX > 0) { + const qreal minX = minXExtent(); + if ((minX - d->_moveX.value() < height()/2 || d->flickTargetX - d->_moveX.value() < height()/2) + && minX != d->flickTargetX) + d->flickX(-d->verticalVelocity.value()); + } else if (d->velocityX < 0) { + const qreal maxX = maxXExtent(); + if ((d->_moveX.value() - maxX < height()/2 || d->_moveX.value() - d->flickTargetX < height()/2) + && maxX != d->flickTargetX) + d->flickX(-d->verticalVelocity.value()); + } } } } -- cgit v0.12 From 5d5cdf9d3c96481295626f327f383557b967c04f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 9 Dec 2009 09:59:04 +1000 Subject: Add a Flow positioner. --- examples/declarative/layouts/positioners.qml | 62 ++++++-- .../graphicsitems/qmlgraphicspositioners.cpp | 173 +++++++++++++++++++++ .../graphicsitems/qmlgraphicspositioners_p.h | 30 +++- 3 files changed, 254 insertions(+), 11 deletions(-) diff --git a/examples/declarative/layouts/positioners.qml b/examples/declarative/layouts/positioners.qml index e912632..4c26bea 100644 --- a/examples/declarative/layouts/positioners.qml +++ b/examples/declarative/layouts/positioners.qml @@ -78,6 +78,9 @@ Rectangle { blueG1.opacity = 0 blueG2.opacity = 0 blueG3.opacity = 0 + blueF1.opacity = 0 + blueF2.opacity = 0 + blueF3.opacity = 0 } } @@ -95,6 +98,9 @@ Rectangle { blueG1.opacity = 1 blueG2.opacity = 1 blueG3.opacity = 1 + blueF1.opacity = 1 + blueF2.opacity = 1 + blueF3.opacity = 1 } } @@ -121,20 +127,58 @@ Rectangle { } } - Rectangle { color: "red"; width: 50; height: 100; border.color: "black"; radius: 15 } - Rectangle { id: blueG1; color: "lightsteelblue"; width: 50; height: 100; border.color: "black"; radius: 15 + Rectangle { color: "red"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueG1; color: "lightsteelblue"; width: 50; height: 50; border.color: "black"; radius: 15 opacity: Behavior{NumberAnimation{}} } - Rectangle { color: "green"; width: 50; height: 100; border.color: "black"; radius: 15 } - Rectangle { id: blueG2; color: "lightsteelblue"; width: 50; height: 100; border.color: "black"; radius: 15 + Rectangle { color: "green"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueG2; color: "lightsteelblue"; width: 50; height: 50; border.color: "black"; radius: 15 opacity: Behavior{NumberAnimation{}} } - Rectangle { color: "orange"; width: 50; height: 100; border.color: "black"; radius: 15 } - Rectangle { id: blueG3; color: "lightsteelblue"; width: 50; height: 100; border.color: "black"; radius: 15 + Rectangle { color: "orange"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueG3; color: "lightsteelblue"; width: 50; height: 50; border.color: "black"; radius: 15 opacity: Behavior{NumberAnimation{}} } - Rectangle { color: "red"; width: 50; height: 100; border.color: "black"; radius: 15 } - Rectangle { color: "green"; width: 50; height: 100; border.color: "black"; radius: 15 } - Rectangle { color: "orange"; width: 50; height: 100; border.color: "black"; radius: 15 } + Rectangle { color: "red"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { color: "green"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { color: "orange"; width: 50; height: 50; border.color: "black"; radius: 15 } } + + Flow { + id: layout4 + x: 260 + y: 250 + width: 150 + remove: Transition { + NumberAnimation { + matchProperties: "x,y"; easing: "easeOutBounce" + } + } + + move: Transition { + NumberAnimation { + matchProperties: "x,y"; easing: "easeOutBounce" + } + } + + add: Transition { + NumberAnimation { + matchProperties: "x,y"; easing: "easeOutBounce" + } + } + Rectangle { color: "red"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueF1; color: "lightsteelblue"; width: 60; height: 50; border.color: "black"; radius: 15 + opacity: Behavior{NumberAnimation{}} + } + Rectangle { color: "green"; width: 30; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueF2; color: "lightsteelblue"; width: 60; height: 50; border.color: "black"; radius: 15 + opacity: Behavior{NumberAnimation{}} + } + Rectangle { color: "orange"; width: 50; height: 50; border.color: "black"; radius: 15 } + Rectangle { id: blueF3; color: "lightsteelblue"; width: 40; height: 50; border.color: "black"; radius: 15 + opacity: Behavior{NumberAnimation{}} + } + Rectangle { color: "red"; width: 80; height: 50; border.color: "black"; radius: 15 } + } + } diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp index db0cc7c..b1ec5a7 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -889,4 +890,176 @@ void QmlGraphicsGrid::doPositioning() } } + +QML_DEFINE_TYPE(Qt,4,6,Flow,QmlGraphicsFlow) +/*! + \qmlclass Flow QmlGraphicsFlow + \brief The Flow item lines up its children side by side, wrapping as necessary. + \inherits Item + + +*/ +/*! + \qmlproperty Transition Flow::remove + This property holds the transition to apply when removing an item from the positioner. + The transition will only be applied to the removed item(s). + Positioner transitions will only affect the position (x,y) of items. + + Removed can mean that either the object has been deleted or reparented, and thus is now longer a child of the positioner, or that the object has had its opacity set to zero, and thus is no longer visible. + + Note that if the item counts as removed because its opacity is zero it will not be visible during the transition unless you set the opacity in the transition, like in the below example. + + +*/ +/*! + \qmlproperty Transition Flow::add + This property holds the transition to apply when adding an item to the positioner. + The transition will only be applied to the added item(s). + Positioner transitions will only affect the position (x,y) of items. + + Added can mean that either the object has been created or reparented, and thus is now a child or the positioner, or that the object has had its opacity increased from zero, and thus is now visible. + + +*/ +/*! + \qmlproperty Transition Flow::move + This property holds the transition to apply when moving an item within the positioner. + Positioner transitions will only affect the position (x,y) of items. + + This can happen when other items are added or removed from the positioner, or when items resize themselves. + + \qml +Flow { + id: positioner + move: Transition { + NumberAnimation { + matchProperties: "x,y" + ease: "easeOutBounce" + } + } +} + \endqml + +*/ +/*! + \qmlproperty int Flow::spacing + + spacing is the amount in pixels left empty between each adjacent + item, and defaults to 0. + +*/ + +class QmlGraphicsFlowPrivate : public QmlGraphicsBasePositionerPrivate +{ + Q_DECLARE_PUBLIC(QmlGraphicsFlow) + +public: + QmlGraphicsFlowPrivate() + : QmlGraphicsBasePositionerPrivate(), flow(QmlGraphicsFlow::LeftToRight) + {} + + QmlGraphicsFlow::Flow flow; +}; + +QmlGraphicsFlow::QmlGraphicsFlow(QmlGraphicsItem *parent) +: QmlGraphicsBasePositioner(*(new QmlGraphicsFlowPrivate), Both, parent) +{ +} + +/*! + \qmlproperty enumeration Flow::flow + This property holds the flow of the layout. + + Possible values are \c LeftToRight (default) and \c TopToBottom. + + If \a flow is \c LeftToRight, the items are positioned next to + to each other from left to right until the width of the Flow + is exceeded, then wrapped to the next line. + If \a flow is \c TopToBottom, the items are positioned next to each + other from top to bottom until the height of the Flow is exceeded, + then wrapped to the next column. +*/ +QmlGraphicsFlow::Flow QmlGraphicsFlow::flow() const +{ + Q_D(const QmlGraphicsFlow); + return d->flow; +} + +void QmlGraphicsFlow::setFlow(Flow flow) +{ + Q_D(QmlGraphicsFlow); + if (d->flow != flow) { + d->flow = flow; + prePositioning(); + emit flowChanged(); + } +} + +void QmlGraphicsFlow::doPositioning() +{ + Q_D(QmlGraphicsFlow); + foreach(QmlGraphicsItem* item, *leavingItems()){ + if (remove()){ + QList > changes; + applyRemove(changes, item); + } + } + + int hoffset = 0; + int voffset = 0; + int linemax = 0; + + QList children = positionedItems; + for (int ii = 0; ii < children.count(); ++ii) { + QmlGraphicsItem *child = children.at(ii); + if (!child || isInvisible(child)) + continue; + + if (d->flow == LeftToRight) { + if (hoffset && hoffset + child->width() > width()) { + hoffset = 0; + voffset += linemax + spacing(); + linemax = 0; + } + } else { + if (voffset && voffset + child->height() > height()) { + voffset = 0; + hoffset += linemax + spacing(); + linemax = 0; + } + } + + bool needMove = (child->x() != hoffset || child->y() != voffset); + + if (newItems()->contains(child) && add()) { + QList > changes; + changes << qMakePair(QString(QLatin1String("x")),QVariant(hoffset)); + changes << qMakePair(QString(QLatin1String("y")),QVariant(voffset)); + applyAdd(changes,child); + } else if (needMove) { + if (move()){ + QList > changes; + changes << qMakePair(QString(QLatin1String("x")),QVariant(hoffset)); + changes << qMakePair(QString(QLatin1String("y")),QVariant(voffset)); + applyMove(changes,child); + } else { + setMovingItem(child); + child->setPos(QPointF(hoffset, voffset)); + setMovingItem(0); + } + } + + if (d->flow == LeftToRight) { + hoffset += child->width(); + hoffset += spacing(); + linemax = qMax(linemax, qCeil(child->height())); + } else { + voffset += child->height(); + voffset += spacing(); + linemax = qMax(linemax, qCeil(child->width())); + } + } +} + + QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h index 03e0f41..a4ef32d 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h @@ -98,8 +98,6 @@ Q_SIGNALS: protected Q_SLOTS: virtual void doPositioning()=0; - -private Q_SLOTS: void prePositioning(); protected: @@ -158,11 +156,39 @@ private: Q_DISABLE_COPY(QmlGraphicsGrid) }; +class QmlGraphicsFlowPrivate; +class Q_DECLARATIVE_EXPORT QmlGraphicsFlow: public QmlGraphicsBasePositioner +{ + Q_OBJECT + Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) +public: + QmlGraphicsFlow(QmlGraphicsItem *parent=0); + + Q_ENUMS(Flow) + enum Flow { LeftToRight, TopToBottom }; + Flow flow() const; + void setFlow(Flow); + +Q_SIGNALS: + void flowChanged(); + +protected Q_SLOTS: + virtual void doPositioning(); + +protected: + QmlGraphicsFlow(QmlGraphicsFlowPrivate &dd, QmlGraphicsItem *parent); +private: + Q_DISABLE_COPY(QmlGraphicsFlow) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QmlGraphicsFlow) +}; + + QT_END_NAMESPACE QML_DECLARE_TYPE(QmlGraphicsColumn) QML_DECLARE_TYPE(QmlGraphicsRow) QML_DECLARE_TYPE(QmlGraphicsGrid) +QML_DECLARE_TYPE(QmlGraphicsFlow) QT_END_HEADER -- cgit v0.12 From 6bb5a7154afe7db75fbc5828a99dad44f2bd3874 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 9 Dec 2009 10:07:30 +1000 Subject: Link to QML Debugging from index page --- doc/src/declarative/declarativeui.qdoc | 1 + doc/src/declarative/qmldebugging.qdoc | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 637e5f1..81968d4 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -102,5 +102,6 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \o \l {Extending QML} \o \l {QML Internationalization} \o \l {QtDeclarative Module} +\o \l {Debugging QML} \endlist */ diff --git a/doc/src/declarative/qmldebugging.qdoc b/doc/src/declarative/qmldebugging.qdoc index 13ad5f7..a6def19 100644 --- a/doc/src/declarative/qmldebugging.qdoc +++ b/doc/src/declarative/qmldebugging.qdoc @@ -45,7 +45,7 @@ \section1 Logging -console.log can be used to print debugging information to the console. For example: +\c console.log can be used to print debugging information to the console. For example: \qml Rectangle { @@ -57,6 +57,13 @@ Rectangle { } \endqml +\section1 Debugging Transitions + +When a transition doesn't look quite right, it can be helpful to view it in slow +motion to see what is happening more clearly. \l {qmlviewer} provides a +"Slow Down Animations" menu option to facilitate this. + + \section1 The QML Inspector The \c qmldebugger tool provides an experimental inspector to aid with debugging. @@ -110,11 +117,4 @@ to an available port number and run the \c qmlviewer. For example: Then in another process, start the \c qmldebugger tool, enter the port number into the corresponding spinbox in the top right hand corner, and press the "Connect" button. - -\section1 Debugging Transitions - -When a transition doesn't look quite right, it can be helpful to view it in slow -motion to see more clearly what is happening. \l {qmlviewer} provides a menu option -"Slow Down Animations" to facilitate this. - */ -- cgit v0.12 From 77c8e7886a7de0deb55066c25817d0c2c9f8e306 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 9 Dec 2009 10:32:25 +1000 Subject: Increase prominence of "QML", since many people know the technology by that name. --- doc/src/declarative/declarativeui.qdoc | 2 +- doc/src/index.qdoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 637e5f1..8516c98 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -40,7 +40,7 @@ ****************************************************************************/ /*! -\title Declarative UI +\title Declarative UI (QML) \page declarativeui.html \brief The Qt Declarative module provides a declarative framework for building diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 762a900..c3c1701 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -103,7 +103,7 @@
  • Painting and Printing
  • Canvas UI with Graphics View
  • Integrating Web Content
  • -
  • Declarative UI
  • +
  • Declarative UI (QML)
  • -- cgit v0.12 From 06745eba2d7716b03a12b2614a8da74b8a3af858 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 10:42:05 +1000 Subject: Quick fix for translation. --- src/script/api/qscriptengine.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index b6aa872..1879367 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -33,6 +33,7 @@ #include "qscriptvalue_p.h" #include "qscriptvalueiterator.h" #include "qscriptclass.h" +#include "qscriptcontextinfo.h" #include "qscriptprogram.h" #include "qscriptprogram_p.h" #include "qdebug.h" @@ -698,9 +699,9 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number"); #ifndef QT_NO_QOBJECT QString context; -// ### implement context resolution -// if (ctx->parentContext()) -// context = QFileInfo(ctx->parentContext()->fileName()).baseName(); + QScriptContext *ctx = QScriptEnginePrivate::contextForFrame(exec); + if (ctx && ctx->parentContext()) + context = QFileInfo(QScriptContextInfo(ctx->parentContext()).fileName()).baseName(); #endif QString text(args.at(0).toString(exec)); #ifndef QT_NO_QOBJECT -- cgit v0.12 From 81e855944cecbd0a37bd04c899d71add97a15a65 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 11:24:08 +1000 Subject: Add simple translation example to docs. --- doc/src/declarative/qmli18n.qdoc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/src/declarative/qmli18n.qdoc b/doc/src/declarative/qmli18n.qdoc index 4b62fcb..0c8b1d1 100644 --- a/doc/src/declarative/qmli18n.qdoc +++ b/doc/src/declarative/qmli18n.qdoc @@ -43,6 +43,8 @@ \page qmli18n.html \title QML Internationalization +\section1 Overview + Strings in QML can be marked for translation using the qsTr(), qsTranslate(), QT_TR_NOOP(), and QT_TRANSLATE_NOOP() functions. @@ -63,4 +65,31 @@ capabilities are described more fully in: You can test a translation in \l {qmlviewer} using the -translation option. +\section1 Example + +First we create a simple QML file with text to be translated. The string +that needs to be translated is enclosed in a call to \c qsTr(). + +hello.qml: +\qml +import Qt 4.6 + +Rectangle { + width: 200; height: 200 + Text { text: qsTr("Hello"); anchors.centerIn: parent } +} +\endqml + +Next we create a translation source file using lupdate: +\code +lupdate hello.qml -ts hello.ts +\endcode + +Then we open \c hello.ts in \l {Linguist}, provide a translation +and create the release file \c hello.qm. + +Finally, we can test the translation in qmlviewer: +\code +qmlviewer -translation hello.qm hello.qml +\endcode */ -- cgit v0.12 From 31156004ac128a3d35870e3cc8b198515fa7b4d9 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 9 Dec 2009 11:30:16 +1000 Subject: Allow tests that use private headers to compile. (while not using private/*_p.h, since that makes module require private/ copies) --- src/declarative/graphicsitems/qmlgraphicsitem_p.h | 4 ++-- src/declarative/graphicsitems/qmlgraphicspositioners_p.h | 2 +- src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h | 2 +- src/declarative/qml/qmlenginedebug_p.h | 2 +- src/declarative/util/qmllistmodel_p.h | 2 +- src/declarative/util/qmlstateoperations_p.h | 2 +- src/declarative/util/qmlxmllistmodel_p.h | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsitem_p.h b/src/declarative/graphicsitems/qmlgraphicsitem_p.h index a8d77ea..304e36c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem_p.h @@ -58,8 +58,8 @@ #include "qmlgraphicsanchors_p.h" #include "qmlgraphicsanchors_p_p.h" -#include -#include +#include "../util/qmlstate_p.h" +#include "../util/qmlnullablevalue_p_p.h" #include #include diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h index a4ef32d..4148ff6 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h @@ -44,7 +44,7 @@ #include "qmlgraphicsitem.h" -#include +#include "../util/qmlstate_p.h" #include #include diff --git a/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h b/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h index c7d067d..88938a7 100644 --- a/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h @@ -44,7 +44,7 @@ #include "qmlgraphicsborderimage_p.h" -#include +#include "../util/qmlpixmapcache_p.h" #include #include diff --git a/src/declarative/qml/qmlenginedebug_p.h b/src/declarative/qml/qmlenginedebug_p.h index c173fdc..7c48b8b 100644 --- a/src/declarative/qml/qmlenginedebug_p.h +++ b/src/declarative/qml/qmlenginedebug_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include +#include "../debugger/qmldebugservice_p.h" #include #include diff --git a/src/declarative/util/qmllistmodel_p.h b/src/declarative/util/qmllistmodel_p.h index 734d44c..2a1a57d 100644 --- a/src/declarative/util/qmllistmodel_p.h +++ b/src/declarative/util/qmllistmodel_p.h @@ -49,7 +49,7 @@ #include #include #include -#include +#include "../3rdparty/qlistmodelinterface_p.h" #include QT_BEGIN_HEADER diff --git a/src/declarative/util/qmlstateoperations_p.h b/src/declarative/util/qmlstateoperations_p.h index b03af48..87af7bb 100644 --- a/src/declarative/util/qmlstateoperations_p.h +++ b/src/declarative/util/qmlstateoperations_p.h @@ -45,7 +45,7 @@ #include "qmlstate_p.h" #include -#include +#include "../graphicsitems/qmlgraphicsanchors_p.h" #include QT_BEGIN_HEADER diff --git a/src/declarative/util/qmlxmllistmodel_p.h b/src/declarative/util/qmlxmllistmodel_p.h index e645740..67fc751 100644 --- a/src/declarative/util/qmlxmllistmodel_p.h +++ b/src/declarative/util/qmlxmllistmodel_p.h @@ -45,7 +45,7 @@ #include #include -#include +#include "../3rdparty/qlistmodelinterface_p.h" QT_BEGIN_HEADER -- cgit v0.12 From d019f392273d4c0904abce72bcce95fc75575ec0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 9 Dec 2009 11:32:38 +1000 Subject: Fix flicking to item boundary (snap). --- src/declarative/graphicsitems/qmlgraphicslistview.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index 2084d94..a4fa07a 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -182,7 +182,7 @@ public: , snapMode(QmlGraphicsListView::NoSnap), overshootDist(0.0) , footerComponent(0), footer(0), headerComponent(0), header(0) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) - , correctFlick(true), lazyRelease(false) + , correctFlick(true), inFlickCorrection(false), lazyRelease(false) {} void init(); @@ -322,8 +322,7 @@ public: if (item->index == -1) continue; qreal itemTop = item->position(); - if ((item->index == model->count()-1 || itemTop >= pos-item->size()/2) - && (item->index == 0 || itemTop <= pos+item->size()/2)) + if (item->index == model->count()-1 || (itemTop+item->size()/2 >= pos)) return item->position(); } if (visibleItems.count()) { @@ -343,8 +342,7 @@ public: if (item->index == -1) continue; qreal itemTop = item->position(); - if ((item->index == model->count()-1 || itemTop >= pos-item->size()/2) - && (item->index == 0 || itemTop <= pos+item->size()/2)) + if (item->index == model->count()-1 || (itemTop+item->size()/2 >= pos)) return item; } if (visibleItems.count() && visibleItems.first()->position() <= pos) @@ -483,6 +481,7 @@ public: bool autoHighlight : 1; bool haveHighlightRange : 1; bool correctFlick : 1; + bool inFlickCorrection : 1; bool lazyRelease : 1; static int itemResizedIdx; @@ -1915,7 +1914,8 @@ void QmlGraphicsListView::viewportMoved() } } - if (d->flicked && d->correctFlick) { + if (d->flicked && d->correctFlick && !d->inFlickCorrection) { + d->inFlickCorrection = true; // Near an end and it seems that the extent has changed? // Recalculate the flick so that we don't end up in an odd position. if (yflick()) { @@ -1945,6 +1945,7 @@ void QmlGraphicsListView::viewportMoved() d->flickX(-d->verticalVelocity.value()); } } + d->inFlickCorrection = false; } } -- cgit v0.12 From 0150b8ffd4e12ca0f3c5197ce225d81b0f9d1537 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 13:03:32 +1000 Subject: Item creation benchmarks. --- .../declarative/creation/tst_creation.cpp | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index 99411d4..a73de41 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include class tst_creation : public QObject @@ -65,6 +66,12 @@ private slots: void qgraphicsitem(); void qgraphicsitem_tree(); + void itemtree_notree_cpp(); + void itemtree_objtree_cpp(); + void itemtree_cpp(); + void itemtree_data_cpp(); + void itemtree_qml(); + private: QmlEngine engine; }; @@ -241,6 +248,82 @@ void tst_creation::qgraphicsitem_tree() } } +struct QmlGraphics_DerivedObject : public QObject +{ + void setParent_noEvent(QObject *parent) { + bool sce = d_ptr->sendChildEvents; + d_ptr->sendChildEvents = false; + setParent(parent); + d_ptr->sendChildEvents = sce; + } +}; + +inline void QmlGraphics_setParent_noEvent(QObject *object, QObject *parent) +{ + static_cast(object)->setParent_noEvent(parent); +} + +void tst_creation::itemtree_notree_cpp() +{ + QBENCHMARK { + QmlGraphicsItem *item = new QmlGraphicsItem; + for (int i = 0; i < 30; ++i) { + QmlGraphicsItem *child = new QmlGraphicsItem; + } + delete item; + } +} + +void tst_creation::itemtree_objtree_cpp() +{ + QBENCHMARK { + QmlGraphicsItem *item = new QmlGraphicsItem; + for (int i = 0; i < 30; ++i) { + QmlGraphicsItem *child = new QmlGraphicsItem; + QmlGraphics_setParent_noEvent(child,item); + } + delete item; + } +} + +void tst_creation::itemtree_cpp() +{ + QBENCHMARK { + QmlGraphicsItem *item = new QmlGraphicsItem; + for (int i = 0; i < 30; ++i) { + QmlGraphicsItem *child = new QmlGraphicsItem; + QmlGraphics_setParent_noEvent(child,item); + child->setParentItem(item); + } + delete item; + } +} + +void tst_creation::itemtree_data_cpp() +{ + QBENCHMARK { + QmlGraphicsItem *item = new QmlGraphicsItem; + for (int i = 0; i < 30; ++i) { + QmlGraphicsItem *child = new QmlGraphicsItem; + QmlGraphics_setParent_noEvent(child,item); + item->data()->append(child); + } + delete item; + } +} + +void tst_creation::itemtree_qml() +{ + QmlComponent component(&engine, TEST_FILE("item.qml")); + QObject *obj = component.create(); + delete obj; + + QBENCHMARK { + QObject *obj = component.create(); + delete obj; + } +} + QTEST_MAIN(tst_creation) -- cgit v0.12 From e569fac3b23885aec1295cb1845a96ca6fca26e2 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 9 Dec 2009 13:09:39 +1000 Subject: Inline QML still needs a URL so that subtypes are relative to that URL. Fixes tst_qmlecmascript::dynamicCreation --- src/declarative/qml/qmlengine.cpp | 2 ++ tests/auto/declarative/qmlqt/tst_qmlqt.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 63d5b70..ad68c8f 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -680,6 +680,8 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi QUrl url; if(ctxt->argumentCount() > 2) url = QUrl(ctxt->argument(2).toString()); + else + url = QUrl("inline"); if (url.isValid() && url.isRelative()) url = context->resolvedUrl(url); diff --git a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp index 21c5478..f184af0 100644 --- a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp +++ b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp @@ -327,7 +327,7 @@ void tst_qmlqt::createQmlObject() QString warning2 = " " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name"; QString warning3 = "QmlEngine::createQmlObject(): Component is not ready"; QString warning4 = "QmlEngine::createQmlObject():"; - QString warning5 = " :3: Cannot assign object type QObject with no default method"; + QString warning5 = " " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); -- cgit v0.12 From 8c7e8e7306ad23986b55deaba3ed2c284053b6dd Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 13:31:23 +1000 Subject: Let anchors.centerIn honor horizontalCenterOffset and verticalCenterOffset. --- src/declarative/graphicsitems/qmlgraphicsanchors.cpp | 8 ++++---- tests/auto/declarative/anchors/data/centerin.qml | 12 ++++++++++++ tests/auto/declarative/anchors/tst_anchors.cpp | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 tests/auto/declarative/anchors/data/centerin.qml diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index c838d7d..153149e4 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -183,14 +183,14 @@ void QmlGraphicsAnchorsPrivate::centerInChanged() ++updatingCenterIn; if (centerIn == item->parentItem()) { - QPointF p((item->parentItem()->width() - item->width()) / 2., - (item->parentItem()->height() - item->height()) / 2.); + QPointF p((item->parentItem()->width() - item->width()) / 2. + hCenterOffset, + (item->parentItem()->height() - item->height()) / 2. + vCenterOffset); setItemPos(p); } else if (centerIn->parentItem() == item->parentItem()) { - QPointF p(centerIn->x() + (centerIn->width() - item->width()) / 2., - centerIn->y() + (centerIn->height() - item->height()) / 2.); + QPointF p(centerIn->x() + (centerIn->width() - item->width()) / 2. + hCenterOffset, + centerIn->y() + (centerIn->height() - item->height()) / 2. + vCenterOffset); setItemPos(p); } diff --git a/tests/auto/declarative/anchors/data/centerin.qml b/tests/auto/declarative/anchors/data/centerin.qml new file mode 100644 index 0000000..09b97f6 --- /dev/null +++ b/tests/auto/declarative/anchors/data/centerin.qml @@ -0,0 +1,12 @@ +import Qt 4.6 + +Rectangle { + width: 200; height: 200 + Rectangle { + objectName: "centered" + width: 50; height: 50; color: "blue" + anchors.centerIn: parent; + anchors.verticalCenterOffset: 30 + anchors.horizontalCenterOffset: 10 + } +} diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index 7378d95..bbe5ef1 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -71,6 +71,7 @@ private slots: void nullItem(); void nullItem_data(); void crash1(); + void centerIn(); }; /* @@ -378,6 +379,21 @@ void tst_anchors::crash1() delete view; } +void tst_anchors::centerIn() +{ + QmlView *view = new QmlView; + + view->setUrl(QUrl("file://" SRCDIR "/data/centerin.qml")); + + view->execute(); + qApp->processEvents(); + + QCOMPARE(findItem(view->root(), QLatin1String("centered"))->x(), 85.0); + QCOMPARE(findItem(view->root(), QLatin1String("centered"))->y(), 105.0); + + delete view; +} + QTEST_MAIN(tst_anchors) #include "tst_anchors.moc" -- cgit v0.12 From 2b1aea7db5c6b8e5c31740add1dfb8dd1c9acb87 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 13:33:36 +1000 Subject: Fix leak. --- src/declarative/qml/qmlxmlhttprequest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp index 5f0fe9ce..9629d7b 100644 --- a/src/declarative/qml/qmlxmlhttprequest.cpp +++ b/src/declarative/qml/qmlxmlhttprequest.cpp @@ -1006,6 +1006,7 @@ QmlXMLHttpRequest::QmlXMLHttpRequest() QmlXMLHttpRequest::~QmlXMLHttpRequest() { destroyNetwork(); + delete m_nam; } QScriptValue QmlXMLHttpRequest::callback() const -- cgit v0.12 From 366abae3466f4a8d91f88caafb87f10f3031c355 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 13:43:38 +1000 Subject: Add missing file. --- .../benchmarks/declarative/creation/data/item.qml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/benchmarks/declarative/creation/data/item.qml diff --git a/tests/benchmarks/declarative/creation/data/item.qml b/tests/benchmarks/declarative/creation/data/item.qml new file mode 100644 index 0000000..74d2f27 --- /dev/null +++ b/tests/benchmarks/declarative/creation/data/item.qml @@ -0,0 +1,34 @@ +import Qt 4.6 + +Item { + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} +} -- cgit v0.12 From 0a1a4915307b023ce0eb7c34ba8960a1260f7798 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 9 Dec 2009 14:09:17 +1000 Subject: Remove ASSERT-failing tests QmlListModel is not directly accessible from QML and so it requires that the caller has checked the index validity. --- tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp index 14de1df..ddf9a07 100644 --- a/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp +++ b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp @@ -69,8 +69,6 @@ void tst_QmlListAccessor::invalid() QCOMPARE(accessor.type(), QmlListAccessor::Invalid); QCOMPARE(accessor.count(), 0); - QCOMPARE(accessor.at(0), QVariant()); - QCOMPARE(accessor.at(4), QVariant()); QVERIFY(!accessor.append(QVariant(10))); QVERIFY(!accessor.insert(0, QVariant(10))); QVERIFY(!accessor.removeAt(0)); @@ -83,8 +81,6 @@ void tst_QmlListAccessor::invalid() QCOMPARE(accessor.type(), QmlListAccessor::Invalid); QCOMPARE(accessor.count(), 0); - QCOMPARE(accessor.at(0), QVariant()); - QCOMPARE(accessor.at(4), QVariant()); QVERIFY(!accessor.append(QVariant(10))); QVERIFY(!accessor.insert(0, QVariant(10))); QVERIFY(!accessor.removeAt(0)); -- cgit v0.12 From 611bd1247ff8254c567dc2c50573e84093dd8c5a Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 9 Dec 2009 14:25:05 +1000 Subject: print error message --- tests/auto/declarative/valuetypes/tst_valuetypes.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/auto/declarative/valuetypes/tst_valuetypes.cpp b/tests/auto/declarative/valuetypes/tst_valuetypes.cpp index d42bfc5..1a5d7b6 100644 --- a/tests/auto/declarative/valuetypes/tst_valuetypes.cpp +++ b/tests/auto/declarative/valuetypes/tst_valuetypes.cpp @@ -474,11 +474,23 @@ void tst_valuetypes::valueSources() delete object; } +static void checkNoErrors(QmlComponent& component) +{ + QList errors = component.errors(); + if (errors.isEmpty()) + return; + for (int ii = 0; ii < errors.count(); ++ii) { + const QmlError &error = errors.at(ii); + qWarning("%d:%d:%s",error.line(),error.column(),error.description().toUtf8().constData()); + } +} + // Test that property value interceptors can be applied to value types void tst_valuetypes::valueInterceptors() { QmlComponent component(&engine, TEST_FILE("valueInterceptors.qml")); MyTypeObject *object = qobject_cast(component.create()); + checkNoErrors(component); QVERIFY(object != 0); QCOMPARE(object->rect().x(), 26); -- cgit v0.12 From 4bad9d6661f6b63c6ce9b9a29e9f5cf7aa032e37 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 9 Dec 2009 14:58:11 +1000 Subject: Another creation benchmark. --- .../benchmarks/declarative/creation/tst_creation.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index a73de41..61033e2 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,7 @@ private slots: void itemtree_cpp(); void itemtree_data_cpp(); void itemtree_qml(); + void itemtree_scene_cpp(); private: QmlEngine engine; @@ -324,6 +326,24 @@ void tst_creation::itemtree_qml() } } +void tst_creation::itemtree_scene_cpp() +{ + QGraphicsScene scene; + QmlGraphicsItem *root = new QmlGraphicsItem; + scene.addItem(root); + QBENCHMARK { + QmlGraphicsItem *item = new QmlGraphicsItem; + for (int i = 0; i < 30; ++i) { + QmlGraphicsItem *child = new QmlGraphicsItem; + QmlGraphics_setParent_noEvent(child,item); + child->setParentItem(item); + } + item->setParentItem(root); + delete item; + } + delete root; +} + QTEST_MAIN(tst_creation) -- cgit v0.12