From 5d0f90d480924c75fd4120b90efd5501307bee0b Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 7 Mar 2012 17:42:49 +1000 Subject: Fix selected text highlight in TextEdit. The call to QQuickTextNode::addTextDocument() omitted the anchor color argument meaning every subsquent argument was off by one and the selection end was always the default of -1. Change-Id: Iac3165e7aa95a3db935a19e54144d3967a3e6e38 Reviewed-by: Yann Bodson --- src/quick/items/qquicktextedit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index a9bff73bd9..3db5f5a7a3 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1626,7 +1626,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * QRectF bounds = boundingRect(); node->addTextDocument(bounds.topLeft(), d->document, d->color, QQuickText::Normal, QColor(), - d->selectionColor, d->selectedTextColor, selectionStart(), + QColor(), d->selectionColor, d->selectedTextColor, selectionStart(), selectionEnd() - 1); // selectionEnd() returns first char after // selection -- cgit v1.2.3 From 2ecf1f5d8ae37bdb4624bd1e3888a65ec357f7b3 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 8 Mar 2012 13:41:19 +1000 Subject: Handle QEvent::TouchCancel in QML_TRANSLATE_TOUCH_TO_MOUSE mode Just remove the mouse grab. The elements will react to this and correct their state. Change-Id: I8b91295606eaface54aa95b1500e7b138d9bc82e Reviewed-by: Michael Brasser --- src/quick/items/qquickcanvas.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 461236d183..d73701e2a1 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -374,6 +374,14 @@ static QQuickMouseEventEx touchToMouseEvent(QEvent::Type type, const QTouchEvent void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event) { + if (event->type() == QEvent::TouchCancel) { + touchMouseId = -1; + if (!mouseGrabberItem) + return; + mouseGrabberItem->ungrabMouse(); + mouseGrabberItem = 0; + return; + } for (int i = 0; i < event->touchPoints().count(); ++i) { QTouchEvent::TouchPoint p = event->touchPoints().at(i); if (touchMouseId == -1 && p.state() & Qt::TouchPointPressed) { -- cgit v1.2.3 From 4eab1984cebe9972283e88e7b91f763636e17c47 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 8 Mar 2012 17:05:07 +1000 Subject: Reset transitioner pointer when transition job finishes A transition job should only keep a reference to the transitioner for the lifetime of the transition. Change-Id: I22564d7b6587fed58ef53fd50ad4a700340dc7a4 Reviewed-by: Martin Jones Reviewed-by: Martin Jones --- src/quick/items/qquickitemviewtransition.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 5669ef927e..2134c8eca8 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -62,6 +62,7 @@ public: QPointF m_toPos; QQuickItemViewTransitioner::TransitionType m_type; bool m_isTarget; + bool *m_wasDeleted; protected: virtual void finished(); @@ -73,11 +74,14 @@ QQuickItemViewTransitionJob::QQuickItemViewTransitionJob() , m_item(0) , m_type(QQuickItemViewTransitioner::NoTransition) , m_isTarget(false) + , m_wasDeleted(0) { } QQuickItemViewTransitionJob::~QQuickItemViewTransitionJob() { + if (m_wasDeleted) + *m_wasDeleted = true; if (m_transitioner) m_transitioner->runningJobs.remove(this); } @@ -134,8 +138,16 @@ void QQuickItemViewTransitionJob::finished() { QQuickTransitionManager::finished(); - if (m_transitioner) + if (m_transitioner) { + bool deleted = false; + m_wasDeleted = &deleted; m_transitioner->finishedTransition(this, m_item); + if (deleted) + return; + m_wasDeleted = 0; + + m_transitioner = 0; + } m_item = 0; m_toPos.setX(0); -- cgit v1.2.3 From 78356f6038065227acb2dc898994765f49f07b42 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 7 Mar 2012 13:29:20 +1000 Subject: Avoid using QQuickViewItem as base class This patch renames it to QQuickItemViewTransitionableItem, and FxViewItem and PositionedItem now create instances of this instead of subclassing it, to reduce the memory used when transitions are not required. Change-Id: Ie050cda5a121bff9542c7ba7356f6eacf37d241a Reviewed-by: Alan Alpert --- src/quick/items/qquickgridview.cpp | 18 ++--- src/quick/items/qquickitemview.cpp | 105 ++++++++++++++++++++++----- src/quick/items/qquickitemview_p_p.h | 22 +++++- src/quick/items/qquickitemviewtransition.cpp | 52 ++++++------- src/quick/items/qquickitemviewtransition_p.h | 24 +++--- src/quick/items/qquicklistview.cpp | 15 ++-- src/quick/items/qquickpositioners.cpp | 64 ++++++++++++++-- src/quick/items/qquickpositioners_p.h | 17 ++++- 8 files changed, 225 insertions(+), 92 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index a78ab4c4e5..7c4f95faed 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2165,12 +2165,10 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & FxViewItem *item = visibleItems.at(i); if (item->index != -1 && item->index >= modelIndex) { item->index += count; - if (transitioner) { - if (change.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); - else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false); - } + if (change.isMove()) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); + else + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false); } } @@ -2201,8 +2199,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesBeforeVisiblePos += rowSize(); } @@ -2239,8 +2236,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesAfterVisiblePos += rowSize(); @@ -2291,7 +2287,7 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex qreal origColPos = gridItem->rowPos(); int indexDiff = gridItem->index - countItemsRemoved; gridItem->setPosition((indexDiff % columns) * colSize(), (indexDiff / columns) * rowSize()); - transitioner->transitionNextReposition(gridItem, QQuickItemViewTransitioner::RemoveTransition, false); + gridItem->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); gridItem->setPosition(origRowPos, origColPos); } } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index e368d1aaec..aafddb40c8 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -46,12 +46,16 @@ QT_BEGIN_NAMESPACE FxViewItem::FxViewItem(QQuickItem *i, bool own) - : QQuickViewItem(i), ownItem(own), releaseAfterTransition(false) + : item(i) + , transitionableItem(0) + , ownItem(own) + , releaseAfterTransition(false) { } FxViewItem::~FxViewItem() { + delete transitionableItem; if (ownItem && item) { item->setParentItem(0); item->deleteLater(); @@ -59,6 +63,71 @@ FxViewItem::~FxViewItem() } } +qreal FxViewItem::itemX() const +{ + return transitionableItem ? transitionableItem->itemX() : item->x(); +} + +qreal FxViewItem::itemY() const +{ + return transitionableItem ? transitionableItem->itemY() : item->y(); +} + +void FxViewItem::moveTo(const QPointF &pos) +{ + if (transitionableItem) + transitionableItem->moveTo(pos); + else + item->setPos(pos); +} + +void FxViewItem::setVisible(bool visible) +{ + if (!visible && transitionableItem && transitionableItem->transitionScheduledOrRunning()) + return; + item->setVisible(visible); +} + +QQuickItemViewTransitioner::TransitionType FxViewItem::scheduledTransitionType() const +{ + return transitionableItem ? transitionableItem->nextTransitionType : QQuickItemViewTransitioner::NoTransition; +} + +bool FxViewItem::transitionScheduledOrRunning() const +{ + return transitionableItem ? transitionableItem->transitionScheduledOrRunning() : false; +} + +bool FxViewItem::transitionRunning() const +{ + return transitionableItem ? transitionableItem->transitionRunning() : false; +} + +bool FxViewItem::isPendingRemoval() const +{ + return transitionableItem ? transitionableItem->isPendingRemoval() : false; +} + +void FxViewItem::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget) +{ + if (!transitioner) + return; + if (!transitionableItem) + transitionableItem = new QQuickItemViewTransitionableItem(item); + transitioner->transitionNextReposition(transitionableItem, type, asTarget); +} + +bool FxViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +{ + return transitionableItem ? transitionableItem->prepareTransition(transitioner, index, viewBounds) : false; +} + +void FxViewItem::startTransition(QQuickItemViewTransitioner *transitioner) +{ + if (transitionableItem) + transitionableItem->startTransition(transitioner, index); +} + QQuickItemViewChangeSet::QQuickItemViewChangeSet() : active(false) @@ -1615,7 +1684,7 @@ void QQuickItemViewPrivate::layout() // assume that any items moving now are moving due to the remove - if they schedule // a different transition, that will override this one anyway for (int i=0; itransitionNextReposition(visibleItems[i], QQuickItemViewTransitioner::RemoveTransition, false); + visibleItems[i]->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); } ChangeResult insertionPosChanges; @@ -1631,7 +1700,7 @@ void QQuickItemViewPrivate::layout() if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) { for (int i=0; itransitionNextReposition(visibleItems.at(i), QQuickItemViewTransitioner::PopulateTransition, true); + visibleItems.at(i)->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true); } layoutVisibleItems(); @@ -1791,7 +1860,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult repositionItemAt(movingIntoView[i].item, fromIndex, -totalInsertionResult->sizeChangesAfterVisiblePos); else repositionItemAt(movingIntoView[i].item, fromIndex, totalInsertionResult->sizeChangesAfterVisiblePos); - transitioner->transitionNextReposition(movingIntoView[i].item, QQuickItemViewTransitioner::MoveTransition, true); + movingIntoView[i].item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); } } } @@ -1855,12 +1924,10 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQuickChangeSet::Remove &re } else if (item->index >= removal.index + removal.count) { // after removed items item->index -= removal.count; - if (transitioner) { - if (removal.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); - else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, false); - } + if (removal.isMove()) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); + else + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); ++it; } else { // removed item @@ -1894,8 +1961,7 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQuickChangeSet:: } if (removal.isMove()) { currentChanges.removedItems.insert(removal.moveKey(item->index), item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); } else { // track item so it is released later currentChanges.removedItems.insertMulti(QQuickChangeSet::MoveKey(), item); @@ -1977,7 +2043,7 @@ void QQuickItemViewPrivate::prepareRemoveTransitions(QHashreleaseAfterTransition = true; releasePendingTransition.append(item); - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, true); it = removedItems->erase(it); } else { ++it; @@ -1996,7 +2062,7 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co if (!transitioner) return false; - if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) + if (item->scheduledTransitionType() == QQuickItemViewTransitioner::MoveTransition) repositionItemAt(item, item->index, 0); if (item->prepareTransition(transitioner, viewBounds)) { @@ -2006,12 +2072,13 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co return false; } -void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickViewItem *i) +void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) { - FxViewItem *item = static_cast(i); - if (item->releaseAfterTransition) { - releasePendingTransition.removeOne(item); - releaseItem(item); + for (int i=0; itransitionableItem == item) { + releaseItem(releasePendingTransition.takeAt(i)); + return; + } } } diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 80dacc0cb4..216f10aa23 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -57,12 +57,27 @@ QT_BEGIN_NAMESPACE QT_MODULE(Quick) -class FxViewItem : public QQuickViewItem +class FxViewItem { public: FxViewItem(QQuickItem *, bool own); virtual ~FxViewItem(); + qreal itemX() const; + qreal itemY() const; + + void moveTo(const QPointF &pos); + void setVisible(bool visible); + + QQuickItemViewTransitioner::TransitionType scheduledTransitionType() const; + bool transitionScheduledOrRunning() const; + bool transitionRunning() const; + bool isPendingRemoval() const; + + void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner); + // these are positions and sizes along the current direction of scrolling/flicking virtual qreal position() const = 0; virtual qreal endPosition() const = 0; @@ -71,7 +86,10 @@ public: virtual bool contains(qreal x, qreal y) const = 0; + QQuickItem *item; + QQuickItemViewTransitionableItem *transitionableItem; QQuickItemViewAttached *attached; + int index; bool ownItem; bool releaseAfterTransition; }; @@ -192,7 +210,7 @@ public: void prepareVisibleItemTransitions(); void prepareRemoveTransitions(QHash *removedItems); bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds); - virtual void viewItemTransitionFinished(QQuickViewItem *item); + virtual void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item); int findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector &changes) const; diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 2134c8eca8..7e804ae5bf 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -55,10 +55,10 @@ public: QQuickItemViewTransitionJob(); ~QQuickItemViewTransitionJob(); - void startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem); + void startTransition(QQuickItemViewTransitionableItem *item, int index, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem); QQuickItemViewTransitioner *m_transitioner; - QQuickViewItem *m_item; + QQuickItemViewTransitionableItem *m_item; QPointF m_toPos; QQuickItemViewTransitioner::TransitionType m_type; bool m_isTarget; @@ -86,7 +86,7 @@ QQuickItemViewTransitionJob::~QQuickItemViewTransitionJob() m_transitioner->runningJobs.remove(this); } -void QQuickItemViewTransitionJob::startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem) +void QQuickItemViewTransitionJob::startTransition(QQuickItemViewTransitionableItem *item, int index, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem) { if (type == QQuickItemViewTransitioner::NoTransition) return; @@ -114,7 +114,7 @@ void QQuickItemViewTransitionJob::startTransition(QQuickViewItem *item, QQuickIt QQuickViewTransitionAttached *attached = static_cast(qmlAttachedPropertiesObject(trans)); if (attached) { - attached->m_index = item->index; + attached->m_index = index; attached->m_item = item->item; attached->m_destination = to; attached->m_targetIndexes = m_transitioner->targetIndexes(type); @@ -209,12 +209,12 @@ bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::Trans return false; } -void QQuickItemViewTransitioner::transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget) +void QQuickItemViewTransitioner::transitionNextReposition(QQuickItemViewTransitionableItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget) { item->setNextTransition(type, isTarget); } -void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index) +void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickItemViewTransitionableItem *item, int index) { switch (type) { case NoTransition: @@ -314,7 +314,7 @@ const QList &QQuickItemViewTransitioner::targetItems(QQuickItemViewTr return qquickitemviewtransition_emptyTargets; } -void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item) +void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob *job, QQuickItemViewTransitionableItem *item) { if (!runningJobs.contains(job)) return; @@ -327,23 +327,22 @@ void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob } -QQuickViewItem::QQuickViewItem(QQuickItem *i) +QQuickItemViewTransitionableItem::QQuickItemViewTransitionableItem(QQuickItem *i) : item(i) , transition(0) , nextTransitionType(QQuickItemViewTransitioner::NoTransition) - , index(-1) , isTransitionTarget(false) , nextTransitionToSet(false) , prepared(false) { } -QQuickViewItem::~QQuickViewItem() +QQuickItemViewTransitionableItem::~QQuickItemViewTransitionableItem() { delete transition; } -qreal QQuickViewItem::itemX() const +qreal QQuickItemViewTransitionableItem::itemX() const { if (nextTransitionType != QQuickItemViewTransitioner::NoTransition) return nextTransitionToSet ? nextTransitionTo.x() : item->x(); @@ -353,7 +352,7 @@ qreal QQuickViewItem::itemX() const return item->x(); } -qreal QQuickViewItem::itemY() const +qreal QQuickItemViewTransitionableItem::itemY() const { // If item is transitioning to some pos, return that dest pos. // If item was redirected to some new pos before the current transition finished, @@ -366,7 +365,7 @@ qreal QQuickViewItem::itemY() const return item->y(); } -void QQuickViewItem::moveTo(const QPointF &pos) +void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos) { if (transitionScheduledOrRunning()) { nextTransitionTo = pos; @@ -376,25 +375,18 @@ void QQuickViewItem::moveTo(const QPointF &pos) } } -void QQuickViewItem::setVisible(bool visible) -{ - if (!visible && transitionScheduledOrRunning()) - return; - item->setVisible(visible); -} - -bool QQuickViewItem::transitionScheduledOrRunning() const +bool QQuickItemViewTransitionableItem::transitionScheduledOrRunning() const { return (transition && transition->isRunning()) || nextTransitionType != QQuickItemViewTransitioner::NoTransition; } -bool QQuickViewItem::transitionRunning() const +bool QQuickItemViewTransitionableItem::transitionRunning() const { return (transition && transition->isRunning()); } -bool QQuickViewItem::isPendingRemoval() const +bool QQuickItemViewTransitionableItem::isPendingRemoval() const { if (nextTransitionType == QQuickItemViewTransitioner::RemoveTransition) return isTransitionTarget; @@ -403,7 +395,7 @@ bool QQuickViewItem::isPendingRemoval() const return false; } -bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds) { bool doTransition = false; @@ -478,7 +470,7 @@ bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, return doTransition; } -void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) +void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitioner *transitioner, int index) { if (nextTransitionType == QQuickItemViewTransitioner::NoTransition) return; @@ -498,12 +490,12 @@ void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) if (!nextTransitionToSet) moveTo(item->pos()); - transition->startTransition(this, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget); + transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget); nextTransitionType = QQuickItemViewTransitioner::NoTransition; prepared = false; } -void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) +void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) { // Don't reset nextTransitionToSet - once it is set, it cannot be changed // until the animation finishes since the itemX() and itemY() may be used @@ -512,20 +504,20 @@ void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionTyp isTransitionTarget = isTargetItem; } -bool QQuickViewItem::transitionWillChangePosition() const +bool QQuickItemViewTransitionableItem::transitionWillChangePosition() const { if (transitionRunning() && transition->m_toPos != nextTransitionTo) return true; return nextTransitionTo != item->pos(); } -void QQuickViewItem::finishedTransition() +void QQuickItemViewTransitionableItem::finishedTransition() { nextTransitionToSet = false; nextTransitionTo = QPointF(); } -void QQuickViewItem::resetTransitionData() +void QQuickItemViewTransitionableItem::resetTransitionData() { nextTransitionType = QQuickItemViewTransitioner::NoTransition; isTransitionTarget = false; diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 73c238e929..d50b056593 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Quick) class QQuickItem; -class QQuickViewItem; +class QQuickItemViewTransitionableItem; class QQuickItemViewTransitionJob; @@ -61,7 +61,7 @@ public: QQuickItemViewTransitionChangeListener() {} virtual ~QQuickItemViewTransitionChangeListener() {} - virtual void viewItemTransitionFinished(QQuickViewItem *item) = 0; + virtual void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) = 0; }; @@ -80,9 +80,9 @@ public: virtual ~QQuickItemViewTransitioner(); bool canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const; - void transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget); + void transitionNextReposition(QQuickItemViewTransitionableItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget); - void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index); + void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickItemViewTransitionableItem *item, int index); void resetTargetLists(); QQuickTransition *transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget); @@ -116,37 +116,35 @@ private: QQuickItemViewTransitionChangeListener *changeListener; bool usePopulateTransition; - void finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item); + void finishedTransition(QQuickItemViewTransitionJob *job, QQuickItemViewTransitionableItem *item); }; /* - An item in a view, that can be transitioned using QQuickViewTransitionJob. + An item that can be transitioned using QQuickViewTransitionJob. */ -class QQuickViewItem +class QQuickItemViewTransitionableItem { public: - QQuickViewItem(QQuickItem *i); - virtual ~QQuickViewItem(); + QQuickItemViewTransitionableItem(QQuickItem *i); + virtual ~QQuickItemViewTransitionableItem(); qreal itemX() const; qreal itemY() const; void moveTo(const QPointF &pos); - void setVisible(bool visible); bool transitionScheduledOrRunning() const; bool transitionRunning() const; bool isPendingRemoval() const; - bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); - void startTransition(QQuickItemViewTransitioner *transitioner); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner, int index); QPointF nextTransitionTo; QQuickItem *item; QQuickItemViewTransitionJob *transition; QQuickItemViewTransitioner::TransitionType nextTransitionType; - int index; bool isTransitionTarget; bool nextTransitionToSet; bool prepared; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index a2f687c86b..0b9d1c2f7e 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -2786,8 +2786,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesBeforeVisiblePos += item->size() + spacing; pos -= item->size() + spacing; @@ -2817,8 +2816,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesAfterVisiblePos += item->size() + spacing; pos += item->size() + spacing; @@ -2828,13 +2826,12 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & for (; index < visibleItems.count(); ++index) { FxViewItem *item = visibleItems.at(index); - if (item->index != -1) + if (item->index != -1) { item->index += count; - if (transitioner) { if (change.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false); } } @@ -2869,7 +2866,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex if (!listItem->transitionScheduledOrRunning()) { qreal pos = listItem->position(); listItem->setPosition(pos - sizeRemoved); - transitioner->transitionNextReposition(listItem, QQuickItemViewTransitioner::RemoveTransition, false); + listItem->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); listItem->setPosition(pos); } } diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index e9a0c179e0..4a4e6fc6d9 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -72,6 +72,60 @@ void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other) otherPrivate->removeItemChangeListener(this, watchedChanges); } + +QQuickBasePositioner::PositionedItem::PositionedItem(QQuickItem *i) + : item(i) + , transitionableItem(0) + , index(-1) + , isNew(false) + , isVisible(true) +{ +} + +QQuickBasePositioner::PositionedItem::~PositionedItem() +{ + delete transitionableItem; +} + +qreal QQuickBasePositioner::PositionedItem::itemX() const +{ + return transitionableItem ? transitionableItem->itemX() : item->x(); +} + +qreal QQuickBasePositioner::PositionedItem::itemY() const +{ + return transitionableItem ? transitionableItem->itemY() : item->y(); +} + +void QQuickBasePositioner::PositionedItem::moveTo(const QPointF &pos) +{ + if (transitionableItem) + transitionableItem->moveTo(pos); + else + item->setPos(pos); +} + +void QQuickBasePositioner::PositionedItem::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget) +{ + if (!transitioner) + return; + if (!transitionableItem) + transitionableItem = new QQuickItemViewTransitionableItem(item); + transitioner->transitionNextReposition(transitionableItem, type, asTarget); +} + +bool QQuickBasePositioner::PositionedItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +{ + return transitionableItem ? transitionableItem->prepareTransition(transitioner, index, viewBounds) : false; +} + +void QQuickBasePositioner::PositionedItem::startTransition(QQuickItemViewTransitioner *transitioner) +{ + if (transitionableItem) + transitionableItem->startTransition(transitioner, index); +} + + QQuickBasePositioner::QQuickBasePositioner(PositionerType at, QQuickItem *parent) : QQuickImplicitSizeItem(*(new QQuickBasePositionerPrivate), parent) { @@ -246,8 +300,7 @@ void QQuickBasePositioner::prePositioning() if (addedIndex < 0) addedIndex = posItem.index; PositionedItem *theItem = &positionedItems[positionedItems.count()-1]; - d->transitioner->transitionNextReposition(theItem, - QQuickItemViewTransitioner::AddTransition, true); + theItem->transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, true); } } } else { @@ -268,8 +321,7 @@ void QQuickBasePositioner::prePositioning() if (d->transitioner) { if (addedIndex < 0) addedIndex = item->index; - d->transitioner->transitionNextReposition(&positionedItems[positionedItems.count()-1], - QQuickItemViewTransitioner::AddTransition, true); + positionedItems[positionedItems.count()-1].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, true); } } else { item->isNew = false; @@ -283,11 +335,11 @@ void QQuickBasePositioner::prePositioning() for (int i=0; i= 0) { - d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::AddTransition, false); + positionedItems[i].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, false); } else { // just queue the item for a move-type displace - if the item hasn't // moved anywhere, it won't be transitioned anyway - d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::MoveTransition, false); + positionedItems[i].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::MoveTransition, false); } } } diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index 8921bfa39b..1e456a9bb9 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -133,12 +133,25 @@ protected: virtual void doPositioning(QSizeF *contentSize)=0; virtual void reportConflictingAnchors()=0; - class PositionedItem : public QQuickViewItem + class PositionedItem { public : - PositionedItem(QQuickItem *i) : QQuickViewItem(i), isNew(false), isVisible(true) {} + PositionedItem(QQuickItem *i); + ~PositionedItem(); bool operator==(const PositionedItem &other) const { return other.item == item; } + qreal itemX() const; + qreal itemY() const; + + void moveTo(const QPointF &pos); + + void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner); + + QQuickItem *item; + QQuickItemViewTransitionableItem *transitionableItem; + int index; bool isNew; bool isVisible; }; -- cgit v1.2.3 From f2e1be963f885a6030136591414cdbda26d50695 Mon Sep 17 00:00:00 2001 From: Luis Gabriel Lima Date: Thu, 5 Jan 2012 15:19:26 -0300 Subject: Add mouse wheel events handler to MouseArea This patch was based on the attached patch in QTBUG-7369. It basically exposes the wheel events to MouseArea via the onWheel signal. The current API is based on the new QWheelEvent API introduced by this patch: http://codereview.qt-project.org/#change,12532 Task-number: QTBUG-7369 Change-Id: Id58513715c2d0ae81e3a69e9e1ed400bbae07507 Reviewed-by: Michael Brasser --- src/quick/items/qquickcanvas.cpp | 3 +- src/quick/items/qquickevents.cpp | 104 ++++++++++++++++++++++++++++++++++ src/quick/items/qquickevents_p_p.h | 38 +++++++++++++ src/quick/items/qquickitemsmodule.cpp | 1 + src/quick/items/qquickmousearea.cpp | 37 +++++++++++- src/quick/items/qquickmousearea_p.h | 3 + src/quick/items/qquickmousearea_p_p.h | 1 + 7 files changed, 185 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index d73701e2a1..643887360a 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -1185,7 +1185,8 @@ bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event QPointF p = item->mapFromScene(event->posF()); if (QRectF(0, 0, item->width(), item->height()).contains(p)) { - QWheelEvent wheel(p, event->delta(), event->buttons(), event->modifiers(), event->orientation()); + QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(), + event->orientation(), event->buttons(), event->modifiers()); wheel.accept(); q->sendEvent(item, &wheel); if (wheel.isAccepted()) { diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 597e64eb18..9222a7766d 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -236,4 +236,108 @@ Item { */ +/*! + \qmlclass WheelEvent QQuickWheelEvent + \inqmlmodule QtQuick 2 + \ingroup qml-event-elements + + \brief The WheelEvent object provides information about a mouse wheel event. + + The position of the mouse can be found via the \l x and \l y properties. + + \sa MouseArea +*/ + +/*! + \internal + \class QQuickWheelEvent +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::x + \qmlproperty int QtQuick2::WheelEvent::y + + These properties hold the coordinates of the position supplied by the wheel event. +*/ + +/*! + \qmlproperty bool QtQuick2::WheelEvent::accepted + + Setting \a accepted to true prevents the wheel event from being + propagated to items below this item. + + Generally, if the item acts on the wheel event then it should be accepted + so that items lower in the stacking order do not also respond to the same event. +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::buttons + + This property holds the mouse buttons pressed when the wheel event was generated. + + It contains a bitwise combination of: + \list + \o Qt.LeftButton + \o Qt.RightButton + \o Qt.MiddleButton + \endlist +*/ + +/*! + \qmlproperty point QtQuick2::WheelEvent::angleDelta + + This property holds the distance that the wheel is rotated in wheel degrees. + The x and y cordinate of this property holds the delta in horizontal and + vertical orientation. + + A positive value indicates that the wheel was rotated up/right; + a negative value indicates that the wheel was rotated down/left. + + Most mouse types work in steps of 15 degrees, in which case the delta value is a + multiple of 120; i.e., 120 units * 1/8 = 15 degrees. +*/ + +/*! + \qmlproperty point QtQuick2::WheelEvent::pixelDelta + + This property holds the delta in screen pixels and is available in plataforms that + have high-resolution trackpads, such as Mac OS X. + The x and y cordinate of this property holds the delta in horizontal and + vertical orientation. The value should be used directly to scroll content on screen. + + For platforms without high-resolution trackpad support, pixelDelta will always be (0,0), + and angleDelta should be used instead. +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::modifiers + + This property holds the keyboard modifier flags that existed immediately + before the event occurred. + + It contains a bitwise combination of: + \list + \o Qt.NoModifier - No modifier key is pressed. + \o Qt.ShiftModifier - A Shift key on the keyboard is pressed. + \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed. + \o Qt.AltModifier - An Alt key on the keyboard is pressed. + \o Qt.MetaModifier - A Meta key on the keyboard is pressed. + \o Qt.KeypadModifier - A keypad button is pressed. + \endlist + + For example, to react to a Control key pressed during the wheel event: + \qml + MouseArea { + onWheel: { + if (wheel.modifiers & Qt.ControlModifier) { + if (wheel.angleDelta.y > 0) + zoomIn(); + else + zoomOut(); + } + } + } + \endqml +*/ + QT_END_NAMESPACE diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 6300b0f2a7..004daafb04 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -201,9 +201,47 @@ private: }; +class QQuickWheelEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x) + Q_PROPERTY(qreal y READ y) + Q_PROPERTY(QPoint angleDelta READ angleDelta) + Q_PROPERTY(QPoint pixelDelta READ pixelDelta) + Q_PROPERTY(int buttons READ buttons) + Q_PROPERTY(int modifiers READ modifiers) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + +public: + QQuickWheelEvent(qreal x, qreal y, const QPoint& angleDelta, const QPoint& pixelDelta, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) + : _x(x), _y(y), _angleDelta(angleDelta), _pixelDelta(pixelDelta), _buttons(buttons), + _modifiers(modifiers), _accepted(true) {} + + qreal x() const { return _x; } + qreal y() const { return _y; } + QPoint angleDelta() const { return _angleDelta; } + QPoint pixelDelta() const { return _pixelDelta; } + int buttons() const { return _buttons; } + int modifiers() const { return _modifiers; } + + bool isAccepted() { return _accepted; } + void setAccepted(bool accepted) { _accepted = accepted; } + +private: + qreal _x; + qreal _y; + QPoint _angleDelta; + QPoint _pixelDelta; + Qt::MouseButtons _buttons; + Qt::KeyboardModifiers _modifiers; + bool _accepted; +}; + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickKeyEvent) QML_DECLARE_TYPE(QQuickMouseEvent) +QML_DECLARE_TYPE(QQuickWheelEvent) #endif // QQUICKEVENTS_P_P_H diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 3d23f7b03a..421a4cd0b1 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -169,6 +169,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); + qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index ef57242319..efb804bd18 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -236,6 +236,13 @@ bool QQuickMouseAreaPrivate::isClickConnected() return QObjectPrivate::get(q)->isSignalConnected(idx); } +bool QQuickMouseAreaPrivate::isWheelConnected() +{ + Q_Q(QQuickMouseArea); + static int idx = QObjectPrivate::get(q)->signalIndex("wheel(QQuickWheelEvent*)"); + return QObjectPrivate::get(q)->isSignalConnected(idx); +} + void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t) { Q_Q(QQuickMouseArea); @@ -331,7 +338,8 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i Information about the mouse position and button clicks are provided via signals for which event handler properties are defined. The most commonly used involved handling mouse presses and clicks: onClicked, onDoubleClicked, - onPressed, onReleased and onPressAndHold. + onPressed, onReleased and onPressAndHold. It's also possible to handle mouse + wheel events via the onWheel signal. By default, MouseArea items only report mouse clicks and not changes to the position of the mouse cursor. Setting the hoverEnabled property ensures that @@ -513,6 +521,17 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i the logic when the MouseArea has lost the mouse handling to the \l Flickable, \c onCanceled should be used in addition to onReleased. */ + +/*! + \qmlsignal QtQuick2::MouseArea::onWheel(WheelEvent mouse) + + This handler is called in response to both mouse wheel and trackpad scroll gestures. + + The \l {WheelEvent}{wheel} parameter provides information about the event, including the x and y + position, any buttons currently pressed, and information about the wheel movement, including + angleDelta and pixelDelta. +*/ + QQuickMouseArea::QQuickMouseArea(QQuickItem *parent) : QQuickItem(*(new QQuickMouseAreaPrivate), parent) { @@ -860,6 +879,22 @@ void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) setHovered(false); } +void QQuickMouseArea::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickMouseArea); + if (!d->absorb) { + QQuickItem::wheelEvent(event); + return; + } + + QQuickWheelEvent we(event->posF().x(), event->posF().y(), event->angleDelta(), + event->pixelDelta(), event->buttons(), event->modifiers()); + we.setAccepted(d->isWheelConnected()); + emit wheel(&we); + if (!we.isAccepted()) + QQuickItem::wheelEvent(event); +} + void QQuickMouseArea::ungrabMouse() { Q_D(QQuickMouseArea); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index 93a0635eb5..7eb9e5da05 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -119,6 +119,7 @@ private: }; class QQuickMouseAreaPrivate; +class QQuickWheelEvent; // used in QtLocation class Q_QUICK_EXPORT QQuickMouseArea : public QQuickItem { @@ -182,6 +183,7 @@ Q_SIGNALS: void released(QQuickMouseEvent *mouse); void clicked(QQuickMouseEvent *mouse); void doubleClicked(QQuickMouseEvent *mouse); + void wheel(QQuickWheelEvent *wheel); void entered(); void exited(); void canceled(); @@ -199,6 +201,7 @@ protected: virtual void hoverEnterEvent(QHoverEvent *event); virtual void hoverMoveEvent(QHoverEvent *event); virtual void hoverLeaveEvent(QHoverEvent *event); + virtual void wheelEvent(QWheelEvent *event); virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e); virtual void timerEvent(QTimerEvent *event); virtual void windowDeactivateEvent(); diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h index bcdf033cba..f5521d9228 100644 --- a/src/quick/items/qquickmousearea_p_p.h +++ b/src/quick/items/qquickmousearea_p_p.h @@ -83,6 +83,7 @@ public: bool isPressAndHoldConnected(); bool isDoubleClickConnected(); bool isClickConnected(); + bool isWheelConnected(); bool absorb : 1; bool hovered : 1; -- cgit v1.2.3 From fc741d3ac3f3b4da330100da10ce1a800cdb467b Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 7 Mar 2012 18:20:06 +1000 Subject: Clean up transition objects for positioners These must be cleaned up whenever items are removed from the internal PositionedItem lists. Change-Id: I56f64a29bd98c603b00faaead514fd43780c18de Reviewed-by: Alan Alpert --- src/quick/items/qquickpositioners.cpp | 25 ++++++++++++++++++++++--- src/quick/items/qquickpositioners_p.h | 4 ++++ src/quick/items/qquickpositioners_p_p.h | 4 +++- 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index 4a4e6fc6d9..7c4cd18346 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -168,7 +168,8 @@ QQuickBasePositioner::~QQuickBasePositioner() d->unwatchChanges(positionedItems.at(i).item); for (int i = 0; i < unpositionedItems.count(); ++i) d->unwatchChanges(unpositionedItems.at(i).item); - positionedItems.clear(); + clearPositionedItems(&positionedItems); + clearPositionedItems(&unpositionedItems); } void QQuickBasePositioner::updatePolish() @@ -248,10 +249,10 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v int idx = positionedItems.find(posItem); if (idx >= 0) { d->unwatchChanges(child); - positionedItems.remove(idx); + removePositionedItem(&positionedItems, idx); } else if ((idx = unpositionedItems.find(posItem)) >= 0) { d->unwatchChanges(child); - unpositionedItems.remove(idx); + removePositionedItem(&unpositionedItems, idx); } d->setPositioningDirty(); } @@ -394,6 +395,24 @@ void QQuickBasePositioner::positionItemY(qreal y, PositionedItem *target) } } +/* + Since PositionedItem values are stored by value, their internal transitionableItem pointers + must be cleaned up when a PositionedItem is removed from a QPODVector, otherwise the pointer + is never deleted since QPODVector doesn't invoke the destructor. + */ +void QQuickBasePositioner::removePositionedItem(QPODVector *items, int index) +{ + Q_ASSERT(index >= 0 && index < items->count()); + delete items->at(index).transitionableItem; + items->remove(index); +} +void QQuickBasePositioner::clearPositionedItems(QPODVector *items) +{ + for (int i=0; icount(); i++) + delete items->at(i).transitionableItem; + items->clear(); +} + QQuickPositionerAttached *QQuickBasePositioner::qmlAttachedProperties(QObject *obj) { return new QQuickPositionerAttached(obj); diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index 1e456a9bb9..c13d9975af 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -158,10 +158,14 @@ protected: QPODVector positionedItems; QPODVector unpositionedItems;//Still 'in' the positioner, just not positioned + void positionItem(qreal x, qreal y, PositionedItem *target); void positionItemX(qreal, PositionedItem *target); void positionItemY(qreal, PositionedItem *target); + void removePositionedItem(QPODVector *items, int index); + void clearPositionedItems(QPODVector *items); + private: Q_DISABLE_COPY(QQuickBasePositioner) Q_DECLARE_PRIVATE(QQuickBasePositioner) diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h index 21fa67574b..8c6bf7f101 100644 --- a/src/quick/items/qquickpositioners_p_p.h +++ b/src/quick/items/qquickpositioners_p_p.h @@ -139,7 +139,9 @@ public: void itemDestroyed(QQuickItem *item) { Q_Q(QQuickBasePositioner); - q->positionedItems.removeOne(QQuickBasePositioner::PositionedItem(item)); + int index = q->positionedItems.find(QQuickBasePositioner::PositionedItem(item)); + if (index >= 0) + q->removePositionedItem(&q->positionedItems, index); } static Qt::LayoutDirection getLayoutDirection(const QQuickBasePositioner *positioner) -- cgit v1.2.3 From ed74ec4c40f1476c545bcaacb12fe3a607172035 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 5 Mar 2012 18:05:40 +1000 Subject: refilled items should be moved immediately refill() functionality should reposition items immediately, else removeNonVisibleItems() sees different positions from those added in addVisibleItems() if an item is animating. Change-Id: Ib9904e08bf92b18fd4b712270c0ab69e9a113e04 Reviewed-by: Martin Jones --- src/quick/items/qquickgridview.cpp | 8 ++++---- src/quick/items/qquickitemview.cpp | 4 ++-- src/quick/items/qquickitemview_p_p.h | 2 +- src/quick/items/qquickitemviewtransition.cpp | 13 +++++++++---- src/quick/items/qquickitemviewtransition_p.h | 2 +- src/quick/items/qquicklistview.cpp | 8 ++++---- 6 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 7c4f95faed..78899b27e5 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -120,8 +120,8 @@ public: return itemX() + view->cellWidth(); } } - void setPosition(qreal col, qreal row) { - moveTo(pointForPosition(col, row)); + void setPosition(qreal col, qreal row, bool immediate = false) { + moveTo(pointForPosition(col, row), immediate); } bool contains(qreal x, qreal y) const { return (x >= itemX() && x < itemX() + view->cellWidth() && @@ -483,7 +483,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d if (!(item = static_cast(createItem(modelIndex, doBuffer)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(colPos, rowPos); + item->setPosition(colPos, rowPos, true); item->item->setVisible(!doBuffer); visibleItems.append(item); if (++colNum >= columns) { @@ -521,7 +521,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d break; --visibleIndex; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(colPos, rowPos); + item->setPosition(colPos, rowPos, true); item->item->setVisible(!doBuffer); visibleItems.prepend(item); if (--colNum < 0) { diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index aafddb40c8..c6f45aaf0b 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -73,10 +73,10 @@ qreal FxViewItem::itemY() const return transitionableItem ? transitionableItem->itemY() : item->y(); } -void FxViewItem::moveTo(const QPointF &pos) +void FxViewItem::moveTo(const QPointF &pos, bool immediate) { if (transitionableItem) - transitionableItem->moveTo(pos); + transitionableItem->moveTo(pos, immediate); else item->setPos(pos); } diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 216f10aa23..dfc0a8bc7e 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -66,7 +66,7 @@ public: qreal itemX() const; qreal itemY() const; - void moveTo(const QPointF &pos); + void moveTo(const QPointF &pos, bool immediate); void setVisible(bool visible); QQuickItemViewTransitioner::TransitionType scheduledTransitionType() const; diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 7e804ae5bf..d9dce49349 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -365,13 +365,18 @@ qreal QQuickItemViewTransitionableItem::itemY() const return item->y(); } -void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos) +void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos, bool immediate) { - if (transitionScheduledOrRunning()) { + if (immediate || !transitionScheduledOrRunning()) { + if (immediate) { + if (transition) + transition->cancel(); + resetTransitionData(); + } + item->setPos(pos); + } else { nextTransitionTo = pos; nextTransitionToSet = true; - } else { - item->setPos(pos); } } diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index d50b056593..a4babdca05 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -132,7 +132,7 @@ public: qreal itemX() const; qreal itemY() const; - void moveTo(const QPointF &pos); + void moveTo(const QPointF &pos, bool immediate = false); bool transitionScheduledOrRunning() const; bool transitionRunning() const; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 0b9d1c2f7e..9db2060d89 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -292,7 +292,7 @@ public: : itemX() + item->width()); } } - void setPosition(qreal pos) { + void setPosition(qreal pos, bool immediate = false) { // position the section immediately even if there is a transition if (section()) { if (view->orientation() == QQuickListView::Vertical) { @@ -304,7 +304,7 @@ public: section()->setX(pos); } } - moveTo(pointForPosition(pos)); + moveTo(pointForPosition(pos), immediate); } void setSize(qreal size) { if (view->orientation() == QQuickListView::Vertical) @@ -638,7 +638,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d if (!(item = static_cast(createItem(modelIndex, doBuffer)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(pos); + item->setPosition(pos, true); item->item->setVisible(!doBuffer); pos += item->size() + spacing; visibleItems.append(item); @@ -658,7 +658,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d --visibleIndex; visiblePos -= item->size() + spacing; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(visiblePos); + item->setPosition(visiblePos, true); item->item->setVisible(!doBuffer); visibleItems.prepend(item); changed = true; -- cgit v1.2.3