diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2010-02-04 03:39:58 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2010-02-04 03:39:58 (GMT) |
commit | 4c8b9316de5728276d24f2d72599cf9c6534fced (patch) | |
tree | b726d4826db4d98fd355f0c2c8a69229cf790b6a /src/declarative/graphicsitems | |
parent | 0b8ef5c78b724901cfae343920b3e9e8f4a78fda (diff) | |
parent | e1c72879ed2c25819537bc5bbb12569b705ba79f (diff) | |
download | Qt-4c8b9316de5728276d24f2d72599cf9c6534fced.zip Qt-4c8b9316de5728276d24f2d72599cf9c6534fced.tar.gz Qt-4c8b9316de5728276d24f2d72599cf9c6534fced.tar.bz2 |
Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative/graphicsitems')
15 files changed, 239 insertions, 154 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp index da031f1..c4edb28 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp @@ -819,6 +819,32 @@ void QmlGraphicsFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } } +void QmlGraphicsFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + Q_D(QmlGraphicsFlickable); + if (!d->interactive) { + QmlGraphicsItem::wheelEvent(event); + } else if (yflick()) { + if (event->delta() > 0) + d->velocityY = qMax(event->delta() - d->verticalVelocity.value(), qreal(250.0)); + else + d->velocityY = qMin(event->delta() - d->verticalVelocity.value(), qreal(-250.0)); + d->flicked = false; + d->flickY(d->velocityY); + event->accept(); + } else if (xflick()) { + if (event->delta() > 0) + d->velocityX = qMax(event->delta() - d->horizontalVelocity.value(), qreal(250.0)); + else + d->velocityX = qMin(event->delta() - d->horizontalVelocity.value(), qreal(-250.0)); + d->flicked = false; + d->flickX(d->velocityX); + event->accept(); + } else { + QmlGraphicsItem::wheelEvent(event); + } +} + void QmlGraphicsFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) { Q_Q(QmlGraphicsFlickable); diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h index df6f6b1..ea07da4 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h @@ -166,6 +166,7 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); void timerEvent(QTimerEvent *event); QmlGraphicsFlickableVisibleArea *visibleArea(); diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp index 2fad3bb..afc2e15 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp @@ -151,14 +151,14 @@ class QmlGraphicsGridViewPrivate : public QmlGraphicsFlickablePrivate public: QmlGraphicsGridViewPrivate() - : model(0), currentItem(0), flow(QmlGraphicsGridView::LeftToRight) + : currentItem(0), flow(QmlGraphicsGridView::LeftToRight) , visiblePos(0), visibleIndex(0) , currentIndex(-1) , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1) , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , bufferMode(NoBuffer) , ownModel(false), wrap(false), autoHighlight(true) - , fixCurrentVisibility(false), lazyRelease(false) {} + , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) {} void init(); void clear(); @@ -167,6 +167,7 @@ public: void refill(qreal from, qreal to, bool doBuffer=false); void updateGrid(); + void scheduleLayout(); void layout(bool removed=false); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); @@ -306,7 +307,7 @@ public: } } - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; QList<FxGridItem*> visibleItems; QHash<QmlGraphicsItem*,int> unrequestedItems; @@ -335,6 +336,7 @@ public: bool autoHighlight : 1; bool fixCurrentVisibility : 1; bool lazyRelease : 1; + bool layoutScheduled : 1; }; void QmlGraphicsGridViewPrivate::init() @@ -372,6 +374,7 @@ FxGridItem *QmlGraphicsGridViewPrivate::createItem(int modelIndex) model->completeItem(); listItem->item->setZValue(1); listItem->item->setParent(q->viewport()); + unrequestedItems.remove(listItem->item); } requestedIndex = 0; return listItem; @@ -381,7 +384,7 @@ FxGridItem *QmlGraphicsGridViewPrivate::createItem(int modelIndex) void QmlGraphicsGridViewPrivate::releaseItem(FxGridItem *item) { Q_Q(QmlGraphicsGridView); - if (!item) + if (!item || !model) return; if (trackedItem == item) { QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); @@ -435,7 +438,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) // creating/releasing multiple items in one frame // while flicking (as much as possible). while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { - //qDebug() << "refill: append item" << modelIndex; +// qDebug() << "refill: append item" << modelIndex; if (!(item = createItem(modelIndex))) break; item->setPosition(colPos, rowPos); @@ -463,7 +466,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) } colNum = colPos / colSize(); while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){ - //qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; +// qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; if (!(item = createItem(visibleIndex-1))) break; --visibleIndex; @@ -487,7 +490,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) && item->endRowPos() < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); +// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); if (item->index != -1) visibleIndex++; visibleItems.removeFirst(); @@ -499,7 +502,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; +// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; visibleItems.removeLast(); releaseItem(item); changed = true; @@ -528,19 +531,27 @@ void QmlGraphicsGridViewPrivate::updateGrid() } } +void QmlGraphicsGridViewPrivate::scheduleLayout() +{ + Q_Q(QmlGraphicsGridView); + if (!layoutScheduled) { + layoutScheduled = true; + QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection); + } +} + void QmlGraphicsGridViewPrivate::layout(bool removed) { Q_Q(QmlGraphicsGridView); + layoutScheduled = false; if (visibleItems.count()) { qreal rowPos = visibleItems.first()->rowPos(); qreal colPos = visibleItems.first()->colPos(); - if (visibleIndex % columns != 0) { + int col = visibleIndex % columns; + if (colPos != col * colSize()) { if (removed) rowPos -= rowSize(); - colPos = (visibleIndex % columns) * colSize(); - visibleItems.first()->setPosition(colPos, rowPos); - } else if (colPos != 0) { - colPos = 0; + colPos = col * colSize(); visibleItems.first()->setPosition(colPos, rowPos); } for (int i = 1; i < visibleItems.count(); ++i) { @@ -555,6 +566,7 @@ void QmlGraphicsGridViewPrivate::layout(bool removed) } q->refill(); updateHighlight(); + moveReason = Other; if (flow == QmlGraphicsGridView::LeftToRight) { q->setViewportHeight(endPosition() - startPosition()); fixupY(); @@ -1126,7 +1138,7 @@ void QmlGraphicsGridView::setCacheBuffer(int buffer) These properties holds the width and height of each cell in the grid - The default sell size is 100x100. + The default cell size is 100x100. */ int QmlGraphicsGridView::cellWidth() const { @@ -1406,7 +1418,7 @@ void QmlGraphicsGridView::trackedPositionChanged() Q_D(QmlGraphicsGridView); if (!d->trackedItem) return; - if (!isFlicking() && !d->moving && d->moveReason != QmlGraphicsGridViewPrivate::Mouse) { + if (!isFlicking() && !d->moving && d->moveReason == QmlGraphicsGridViewPrivate::SetIndex) { const qreal viewPos = d->position(); if (d->trackedItem->rowPos() < viewPos && d->currentItem->rowPos() < viewPos) { d->setPosition(d->currentItem->rowPos() < d->trackedItem->rowPos() ? d->trackedItem->rowPos() : d->currentItem->rowPos()); @@ -1446,12 +1458,12 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) // Special case of appending an item to the model. index = d->visibleIndex + d->visibleItems.count(); } else { - if (modelIndex + count - 1 < d->visibleIndex) { + if (modelIndex <= d->visibleIndex) { // Insert before visible items d->visibleIndex += count; for (int i = 0; i < d->visibleItems.count(); ++i) { FxGridItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) + if (listItem->index != -1 && listItem->index >= modelIndex) listItem->index += count; } } @@ -1492,71 +1504,25 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) } QList<FxGridItem*> added; - 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; - } + int i = 0; + while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) { + 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(); } - 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()); + ++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()); } } @@ -1586,32 +1552,7 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) { Q_D(QmlGraphicsGridView); bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; - int index = d->mapFromModel(modelIndex); - if (index == -1) { - if (modelIndex + count - 1 < d->visibleIndex) { - // Items removed before our visible items. - d->visibleIndex -= count; - for (int i = 0; i < d->visibleItems.count(); ++i) { - FxGridItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) - listItem->index -= count; - } - } - if (d->currentIndex >= modelIndex + count) { - d->currentIndex -= count; - if (d->currentItem) - d->currentItem->index -= count; - } else if (currentRemoved) { - // current item has been removed. - d->releaseItem(d->currentItem); - d->currentItem = 0; - d->currentIndex = -1; - d->updateCurrent(qMin(modelIndex, d->model->count()-1)); - } - d->layout(true); - emit countChanged(); - return; - } + bool removedVisible = false; // Remove the items from the visible list, skipping anything already marked for removal QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); @@ -1619,6 +1560,8 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) FxGridItem *item = *it; if (item->index == -1 || item->index < modelIndex) { // already removed, or before removed items + if (item->index < modelIndex) + removedVisible = true; ++it; } else if (item->index >= modelIndex + count) { // after removed items @@ -1626,6 +1569,7 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item + removedVisible = true; item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -1659,17 +1603,27 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) } } - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->setPosition(0); - refill(); - } else { - // Correct the positioning of the items - d->layout(); + if (removedVisible) { + if (d->visibleItems.isEmpty()) { + d->visibleIndex = 0; + d->setPosition(0); + refill(); + } else { + // Correct the positioning of the items + d->scheduleLayout(); + } } + emit countChanged(); } +void QmlGraphicsGridView::layout() +{ + Q_D(QmlGraphicsGridView); + if (d->layoutScheduled) + d->layout(); +} + void QmlGraphicsGridView::destroyRemoved() { Q_D(QmlGraphicsGridView); diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h index 1615469..d2ef70e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h @@ -148,6 +148,7 @@ private Q_SLOTS: void createdItem(int index, QmlGraphicsItem *item); void destroyingItem(QmlGraphicsItem *item); void sizeChange(); + void layout(); private: void refill(); diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index ad43027..a1e8c17 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -128,6 +128,7 @@ QML_DEFINE_TYPE(Qt,4,6,Image,QmlGraphicsImage) QmlGraphicsImage::QmlGraphicsImage(QmlGraphicsItem *parent) : QmlGraphicsImageBase(*(new QmlGraphicsImagePrivate), parent) { + connect(this, SIGNAL(sourceChanged(QUrl)), this, SLOT(updatePaintedGeometry())); } QmlGraphicsImage::QmlGraphicsImage(QmlGraphicsImagePrivate &dd, QmlGraphicsItem *parent) @@ -270,6 +271,8 @@ void QmlGraphicsImage::updatePaintedGeometry() if (d->fillMode == PreserveAspectFit) { qreal widthScale = width() / qreal(d->pix.width()); qreal heightScale = height() / qreal(d->pix.height()); + if (!d->pix.width() || !d->pix.height()) + return; if (widthScale <= heightScale) { d->paintedWidth = width(); d->paintedHeight = widthScale * qreal(d->pix.height()); diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p.h index 36066e1..dde5d79 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p.h @@ -86,6 +86,8 @@ Q_SIGNALS: protected: QmlGraphicsImage(QmlGraphicsImagePrivate &dd, QmlGraphicsItem *parent); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + +protected Q_SLOTS: void updatePaintedGeometry(); private: diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index bd3c1ea..b03f359 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -57,6 +57,7 @@ #include <QFile> #include <QEvent> #include <QGraphicsSceneMouseEvent> +#include <QtCore/qnumeric.h> #include <QtScript/qscriptengine.h> #include <QtGui/qgraphicstransform.h> #include <QtGui/qgraphicseffect.h> @@ -2160,6 +2161,7 @@ QmlGraphicsAnchorLine QmlGraphicsItem::baseline() const \qmlproperty Item Item::anchors.fill \qmlproperty Item Item::anchors.centerIn + \qmlproperty real Item::anchors.margins \qmlproperty real Item::anchors.topMargin \qmlproperty real Item::anchors.bottomMargin \qmlproperty real Item::anchors.leftMargin @@ -2172,6 +2174,7 @@ QmlGraphicsAnchorLine QmlGraphicsItem::baseline() const relationship with other items. Margins apply to top, bottom, left, right, and fill anchors. + The margins property can be used to set all of the various margins at once, to the same value. Offsets apply for horizontal center, vertical center, and baseline anchors. @@ -2790,6 +2793,7 @@ void QmlGraphicsItem::setTransformOrigin(TransformOrigin origin) if (origin != d->origin) { d->origin = origin; QGraphicsItem::setTransformOriginPoint(d->computeTransformOrigin()); + emit transformOriginChanged(d->origin); } } @@ -2842,6 +2846,9 @@ qreal QmlGraphicsItem::width() const void QmlGraphicsItem::setWidth(qreal w) { Q_D(QmlGraphicsItem); + if (qIsNaN(w)) + return; + d->widthValid = true; if (d->width == w) return; @@ -2911,6 +2918,9 @@ qreal QmlGraphicsItem::height() const void QmlGraphicsItem::setHeight(qreal h) { Q_D(QmlGraphicsItem); + if (qIsNaN(h)) + return; + d->heightValid = true; if (d->height == h) return; diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.h b/src/declarative/graphicsitems/qmlgraphicsitem.h index df8c634..8ae2d5c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem.h @@ -91,7 +91,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsItem : public QGraphicsObject, public QmlP Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) Q_PROPERTY(bool wantsFocus READ wantsFocus NOTIFY wantsFocusChanged) Q_PROPERTY(QmlList<QGraphicsTransform *>* transform READ transform DESIGNABLE false FINAL) - Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin) + Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin NOTIFY transformOriginChanged) Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect) Q_ENUMS(TransformOrigin) @@ -176,6 +176,7 @@ Q_SIGNALS: void focusChanged(); void wantsFocusChanged(); void parentChanged(); + void transformOriginChanged(TransformOrigin); protected: bool isComponentComplete() const; diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index f75833a..8fb7c84 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -210,7 +210,7 @@ class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate, private Q public: QmlGraphicsListViewPrivate() - : model(0), currentItem(0), orient(QmlGraphicsListView::Vertical) + : currentItem(0), orient(QmlGraphicsListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0) @@ -495,7 +495,7 @@ public: virtual void flickX(qreal velocity); virtual void flickY(qreal velocity); - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; QList<FxListItem*> visibleItems; QHash<QmlGraphicsItem*,int> unrequestedItems; @@ -605,6 +605,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) if (listItem->attached->m_prevSection != listItem->attached->m_section) createSection(listItem); } + unrequestedItems.remove(listItem->item); } requestedIndex = -1; @@ -614,7 +615,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) void QmlGraphicsListViewPrivate::releaseItem(FxListItem *item) { Q_Q(QmlGraphicsListView); - if (!item) + if (!item || !model) return; if (trackedItem == item) { const char *notifier1 = orient == QmlGraphicsListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); @@ -731,6 +732,7 @@ void QmlGraphicsListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (footer) updateFooter(); updateViewport(); + updateUnrequestedPositions(); } else if (!doBuffer && buffer && bufferMode != NoBuffer) { refill(from, to, true); } @@ -765,7 +767,6 @@ void QmlGraphicsListViewPrivate::layout() updateHeader(); if (footer) updateFooter(); - updateUnrequestedPositions(); updateViewport(); } @@ -779,14 +780,20 @@ void QmlGraphicsListViewPrivate::updateUnrequestedIndexes() void QmlGraphicsListViewPrivate::updateUnrequestedPositions() { - QHash<QmlGraphicsItem*,int>::const_iterator it; - for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) { - if (visibleItem(*it)) - continue; - if (orient == QmlGraphicsListView::Vertical) - it.key()->setY(positionAt(*it)); - else - it.key()->setX(positionAt(*it)); + Q_Q(QmlGraphicsListView); + if (unrequestedItems.count()) { + qreal pos = position(); + QHash<QmlGraphicsItem*,int>::const_iterator it; + for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) { + QmlGraphicsItem *item = it.key(); + if (orient == QmlGraphicsListView::Vertical) { + if (item->y() + item->height() > pos && item->y() < pos + q->height()) + item->setY(positionAt(*it)); + } else { + if (item->x() + item->width() > pos && item->x() < pos + q->width()) + item->setX(positionAt(*it)); + } + } } } @@ -2114,12 +2121,14 @@ void QmlGraphicsListView::viewportMoved() 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()); + d->flickX(-d->horizontalVelocity.value()); + d->bufferMode = QmlGraphicsListViewPrivate::BufferBefore; } 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()); + d->flickX(-d->horizontalVelocity.value()); + d->bufferMode = QmlGraphicsListViewPrivate::BufferAfter; } } d->inFlickCorrection = false; @@ -2399,12 +2408,12 @@ void QmlGraphicsListView::itemsInserted(int modelIndex, int count) // Special case of appending an item to the model. modelIndex = d->visibleIndex + d->visibleItems.count(); } else { - if (modelIndex + count - 1 < d->visibleIndex) { + if (modelIndex < d->visibleIndex) { // Insert before visible items d->visibleIndex += count; for (int i = 0; i < d->visibleItems.count(); ++i) { FxListItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) + if (listItem->index != -1 && listItem->index >= modelIndex) listItem->index += count; } } @@ -2609,6 +2618,7 @@ void QmlGraphicsListView::destroyRemoved() void QmlGraphicsListView::itemsMoved(int from, int to, int count) { Q_D(QmlGraphicsListView); + d->updateUnrequestedIndexes(); if (d->visibleItems.isEmpty()) { refill(); diff --git a/src/declarative/graphicsitems/qmlgraphicsloader.cpp b/src/declarative/graphicsitems/qmlgraphicsloader.cpp index bb1020c..7cd4d1a 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsloader.cpp @@ -64,8 +64,14 @@ void QmlGraphicsLoaderPrivate::clear() } source = QUrl(); - delete item; - item = 0; + if (item) { + // We can't delete immediately because our item may have triggered + // the Loader to load a different item. + item->setVisible(false); + static_cast<QGraphicsItem*>(item)->setParentItem(0); + item->deleteLater(); + item = 0; + } } void QmlGraphicsLoaderPrivate::initResize() diff --git a/src/declarative/graphicsitems/qmlgraphicspathview.cpp b/src/declarative/graphicsitems/qmlgraphicspathview.cpp index 112eda2..85e87eb 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspathview.cpp @@ -71,9 +71,11 @@ inline qreal qmlMod(qreal x, qreal y) class QmlGraphicsPathViewAttached : public QObject { Q_OBJECT + + Q_PROPERTY(bool onPath READ isOnPath NOTIFY onPathChanged) public: QmlGraphicsPathViewAttached(QObject *parent) - : QObject(parent), mo(new QmlOpenMetaObject(this)) + : QObject(parent), mo(new QmlOpenMetaObject(this)), onPath(false) { } @@ -91,10 +93,49 @@ public: mo->setValue(name, val); } + bool isOnPath() const { return onPath; } + void setOnPath(bool on) { + if (on != onPath) { + onPath = on; + emit onPathChanged(); + } + } + +Q_SIGNALS: + void onPathChanged(); + private: QmlOpenMetaObject *mo; + bool onPath; }; + +QmlGraphicsItem *QmlGraphicsPathViewPrivate::getItem(int modelIndex) +{ + Q_Q(QmlGraphicsPathView); + requestedIndex = modelIndex; + QmlGraphicsItem *item = model->item(modelIndex); + if (item) { + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(true); + item->setParentItem(q); + } + requestedIndex = -1; + return item; +} + +void QmlGraphicsPathViewPrivate::releaseItem(QmlGraphicsItem *item) +{ + if (!item || !model) + return; + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(false); + if (model->release(item) == 0) { + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(false); + } +} + /*! \qmlclass PathView QmlGraphicsPathView \brief The PathView element lays out model-provided items on a path. @@ -126,6 +167,26 @@ QmlGraphicsPathView::~QmlGraphicsPathView() } /*! + \qmlattachedproperty bool PathView::onPath + This attached property holds whether the item is currently on the path. + + If a pathItemCount has been set, it is possible that some items may + be instantiated, but not considered to be currently on the path. + Usually, these items would be set invisible, for example: + + \code + Component { + Rectangle { + visible: PathView.onPath + ... + } + } + \endcode + + It is attached to each instance of the delegate. +*/ + +/*! \qmlproperty model PathView::model This property holds the model providing data for the view. diff --git a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h index 7ffe6ac..18cb205 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h @@ -79,7 +79,7 @@ public: : path(0), currentIndex(0), startPc(0), lastDist(0) , lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0) , snapPos(0), dragMargin(0), moveOffset(this, &QmlGraphicsPathViewPrivate::setOffset) - , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1), model(0) + , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1) , moveReason(Other) { fixupOffsetEvent = QmlTimeLineEvent::timeLineEvent<QmlGraphicsPathViewPrivate, &QmlGraphicsPathViewPrivate::fixOffset>(&moveOffset, this); @@ -95,18 +95,8 @@ public: q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } - QmlGraphicsItem *getItem(int modelIndex) { - Q_Q(QmlGraphicsPathView); - requestedIndex = modelIndex; - QmlGraphicsItem *item = model->item(modelIndex); - if (item) - item->setParentItem(q); - requestedIndex = -1; - return item; - } - void releaseItem(QmlGraphicsItem *item) { - model->release(item); - } + QmlGraphicsItem *getItem(int modelIndex); + void releaseItem(QmlGraphicsItem *item); bool isValid() const { return model && model->count() > 0 && model->isValid() && path; @@ -143,7 +133,7 @@ public: int pathOffset; int requestedIndex; QList<QmlGraphicsItem *> items; - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; enum MovementReason { Other, Key, Mouse }; MovementReason moveReason; diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index 6e14d3a..c3495b3 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -784,8 +784,17 @@ Handles the given mouse \a event. void QmlGraphicsTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QmlGraphicsTextEdit); - if (d->focusOnPress) + if (d->focusOnPress){ + QGraphicsItem *p = parentItem();//###Is there a better way to find my focus scope? + while(p) { + if(p->flags() & QGraphicsItem::ItemIsFocusScope){ + p->setFocus(); + break; + } + p = p->parentItem(); + } setFocus(true); + } d->control->processEvent(event, QPointF(0, 0)); if (!event->isAccepted()) QmlGraphicsPaintedItem::mousePressEvent(event); diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp index 6068e93..cfb93f6 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp @@ -647,9 +647,15 @@ void QmlGraphicsTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QmlGraphicsTextInput); if(d->focusOnPress){ + QGraphicsItem *p = parentItem();//###Is there a better way to find my focus scope? + while(p) { + if(p->flags() & QGraphicsItem::ItemIsFocusScope){ + p->setFocus(); + break; + } + p = p->parentItem(); + } setFocus(true); - setCursorVisible(true); - d->focused = true; } d->control->processEvent(event); } diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index 70e3a43..2fc143d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -462,7 +462,8 @@ int QmlGraphicsVisualDataModelDataMetaObject::createProperty(const char *name, c QmlGraphicsVisualDataModelPrivate *model = QmlGraphicsVisualDataModelPrivate::get(data->m_model); if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { - if (model->m_listAccessor->type() == QmlListAccessor::QmlList) { + if (model->m_listAccessor->type() == QmlListAccessor::QmlList + || model->m_listAccessor->type() == QmlListAccessor::QListPtr) { model->ensureRoles(); QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); if (object && object->property(name).isValid()) @@ -724,7 +725,7 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model) } d->m_listAccessor = new QmlListAccessor; d->m_listAccessor->setList(model, d->m_context?d->m_context->engine():qmlEngine(this)); - if (d->m_listAccessor->type() != QmlListAccessor::QmlList) + if (d->m_listAccessor->type() != QmlListAccessor::QmlList && d->m_listAccessor->type() != QmlListAccessor::QListPtr) d->m_metaDataCacheable = true; if (d->m_delegate && d->modelCount()) { emit itemsInserted(0, d->modelCount()); @@ -805,8 +806,12 @@ QmlGraphicsVisualDataModel::ReleaseFlags QmlGraphicsVisualDataModel::release(Qml } if (d->m_cache.releaseItem(obj)) { - if (inPackage) + if (inPackage) { emit destroyingPackage(qobject_cast<QmlPackage*>(obj)); + } else { + item->setVisible(false); + static_cast<QGraphicsItem*>(item)->setParentItem(0); + } stat |= Destroyed; obj->deleteLater(); } else if (!inPackage) { |