aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-03-13 15:06:40 +1000
committerMatthew Vogt <matthew.vogt@nokia.com>2012-03-13 15:22:14 +1000
commit784555f3032194a8923d804a8ce84957f113caf6 (patch)
tree6b538cea5bf82bd5288ac180125abd1bb312ddad /src/quick/items
parent1f52c5430144eb7ba6baa7e3954675ca0707b947 (diff)
parent648c80c4c0759efb6e35fac7acc8daad5aab13e2 (diff)
Merge branch 'master' of git://gitorious.org/qt/qtdeclarative into merge-master
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickcanvas.cpp24
-rw-r--r--src/quick/items/qquickflickable.cpp22
-rw-r--r--src/quick/items/qquickitem.cpp13
-rw-r--r--src/quick/items/qquickitemview.cpp5
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp86
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h8
-rw-r--r--src/quick/items/qquickpathview.cpp4
-rw-r--r--src/quick/items/qquickpathview_p_p.h3
-rw-r--r--src/quick/items/qquickrepeater.cpp10
-rw-r--r--src/quick/items/qquickrepeater_p_p.h2
10 files changed, 125 insertions, 52 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 60f1992b57..f14eccd9a9 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -376,10 +376,8 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
{
if (event->type() == QEvent::TouchCancel) {
touchMouseId = -1;
- if (!mouseGrabberItem)
- return;
- mouseGrabberItem->ungrabMouse();
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
return;
}
for (int i = 0; i < event->touchPoints().count(); ++i) {
@@ -447,7 +445,8 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
me.setTimestamp(event->timestamp());
me.setCapabilities(event->device()->capabilities());
deliverMouseEvent(&me);
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
}
break;
}
@@ -947,13 +946,13 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
QMouseEvent me(event->type(), p, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
me.accept();
- mouseGrabberItem = item;
+ item->grabMouse();
q->sendEvent(item, &me);
event->setAccepted(me.isAccepted());
if (me.isAccepted())
return true;
- mouseGrabberItem->ungrabMouse();
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
}
}
@@ -1023,7 +1022,8 @@ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event)
}
d->deliverMouseEvent(event);
- d->mouseGrabberItem = 0;
+ if (d->mouseGrabberItem)
+ d->mouseGrabberItem->ungrabMouse();
}
/*! \reimp */
@@ -1560,6 +1560,12 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e)
QQuickItemPrivate::get(item)->deliverMouseEvent(static_cast<QMouseEvent *>(e));
}
break;
+ case QEvent::UngrabMouse:
+ if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
+ e->accept();
+ item->mouseUngrabEvent();
+ }
+ break;
case QEvent::Wheel:
QQuickItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
break;
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index f75ca14989..82f674741f 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -107,7 +107,7 @@ static const int FlickThreshold = 20;
// RetainGrabVelocity is the maxmimum instantaneous velocity that
// will ensure the Flickable retains the grab on consecutive flicks.
-static const int RetainGrabVelocity = 15;
+static const int RetainGrabVelocity = 100;
QQuickFlickableVisibleArea::QQuickFlickableVisibleArea(QQuickFlickable *parent)
: QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
@@ -823,8 +823,8 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
Q_Q(QQuickFlickable);
QQuickItemPrivate::start(timer);
if (interactive && timeline.isActive()
- && (qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity
- || qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity)) {
+ && ((qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity && !hData.fixingUp && !hData.inOvershoot)
+ || (qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity && !vData.fixingUp && !vData.inOvershoot))) {
stealMouse = true; // If we've been flicked then steal the click.
int flickTime = timeline.time();
if (flickTime > 600) {
@@ -846,7 +846,10 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
}
q->setKeepMouseGrab(stealMouse);
pressed = true;
- timeline.clear();
+ if (!hData.fixingUp)
+ timeline.reset(hData.move);
+ if (!vData.fixingUp)
+ timeline.reset(vData.move);
hData.reset();
vData.reset();
hData.dragMinBound = q->minXExtent();
@@ -910,6 +913,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
}
}
if (!rejectY && stealMouse && dy != 0.0) {
+ timeline.clear();
vData.move.setValue(newY);
vMoved = true;
}
@@ -942,6 +946,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
}
}
if (!rejectX && stealMouse && dx != 0.0) {
+ timeline.clear();
hData.move.setValue(newX);
hMoved = true;
}
@@ -1753,6 +1758,7 @@ void QQuickFlickable::mouseUngrabEvent()
if (d->pressed) {
// if our mouse grab has been removed (probably by another Flickable),
// fix our state
+ d->clearDelayedPress();
d->pressed = false;
d->draggingEnding();
d->stealMouse = false;
@@ -1838,13 +1844,19 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
Q_D(QQuickFlickable);
- if (!isVisible() || !d->interactive || !isEnabled())
+ if (!isVisible() || !isEnabled())
return QQuickItem::childMouseEventFilter(i, e);
switch (e->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
return sendMouseEvent(static_cast<QMouseEvent *>(e));
+ case QEvent::UngrabMouse:
+ if (d->canvas && d->canvas->mouseGrabberItem() && d->canvas->mouseGrabberItem() != this) {
+ // The grab has been taken away from a child and given to some other item.
+ mouseUngrabEvent();
+ }
+ break;
default:
break;
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 1af4c31d75..8e351f1527 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3040,9 +3040,8 @@ void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
event->ignore();
}
-void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
{
- mousePressEvent(event);
}
void QQuickItem::mouseUngrabEvent()
@@ -4751,8 +4750,10 @@ void QQuickItem::grabMouse()
QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
canvasPriv->mouseGrabberItem = this;
- if (oldGrabber)
- oldGrabber->mouseUngrabEvent();
+ if (oldGrabber) {
+ QEvent ev(QEvent::UngrabMouse);
+ d->canvas->sendEvent(oldGrabber, &ev);
+ }
}
void QQuickItem::ungrabMouse()
@@ -4767,7 +4768,9 @@ void QQuickItem::ungrabMouse()
}
canvasPriv->mouseGrabberItem = 0;
- mouseUngrabEvent();
+
+ QEvent ev(QEvent::UngrabMouse);
+ d->canvas->sendEvent(this, &ev);
}
bool QQuickItem::keepMouseGrab() const
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index c6f45aaf0b..501b206ef6 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1658,10 +1658,11 @@ void QQuickItemViewPrivate::updateViewport()
{
Q_Q(QQuickItemView);
if (isValid()) {
+ qreal extra = headerSize() + footerSize();
if (layoutOrientation() == Qt::Vertical)
- q->setContentHeight(endPosition() - startPosition());
+ q->setContentHeight(endPosition() - startPosition() + extra);
else
- q->setContentWidth(endPosition() - startPosition());
+ q->setContentWidth(endPosition() - startPosition() + extra);
}
}
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index d9dce49349..823269bfc1 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -333,6 +333,8 @@ QQuickItemViewTransitionableItem::QQuickItemViewTransitionableItem(QQuickItem *i
, nextTransitionType(QQuickItemViewTransitioner::NoTransition)
, isTransitionTarget(false)
, nextTransitionToSet(false)
+ , nextTransitionFromSet(false)
+ , lastMovedToSet(false)
, prepared(false)
{
}
@@ -367,12 +369,17 @@ qreal QQuickItemViewTransitionableItem::itemY() const
void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos, bool immediate)
{
+ if (!nextTransitionFromSet && nextTransitionType != QQuickItemViewTransitioner::NoTransition) {
+ nextTransitionFrom = item->pos();
+ nextTransitionFromSet = true;
+ }
+
+ lastMovedTo = pos;
+ lastMovedToSet = true;
+
if (immediate || !transitionScheduledOrRunning()) {
- if (immediate) {
- if (transition)
- transition->cancel();
- resetTransitionData();
- }
+ if (immediate)
+ stopTransition();
item->setPos(pos);
} else {
nextTransitionTo = pos;
@@ -402,17 +409,27 @@ bool QQuickItemViewTransitionableItem::isPendingRemoval() const
bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds)
{
- bool doTransition = false;
+ if (nextTransitionType == QQuickItemViewTransitioner::NoTransition)
+ return false;
+
+ if (isTransitionTarget) {
+ // If item is not already moving somewhere, set it to not move anywhere.
+ // This ensures that removed targets don't transition to the default (0,0) and that
+ // items set for other transition types only transition if they actually move somewhere.
+ if (!nextTransitionToSet)
+ moveTo(item->pos());
+ } else {
+ // don't start displaced transitions that don't move anywhere
+ if (!nextTransitionToSet || (nextTransitionFromSet && nextTransitionFrom == nextTransitionTo)) {
+ clearCurrentScheduledTransition();
+ return false;
+ }
+ }
- // If item is not already moving somewhere, set it to not move anywhere.
- // This ensures that removed targets don't transition to the default (0,0) and that
- // items set for other transition types only transition if they actually move somewhere.
- if (nextTransitionType != QQuickItemViewTransitioner::NoTransition && !nextTransitionToSet)
- moveTo(item->pos());
+ bool doTransition = false;
// For move transitions (both target and displaced) and displaced transitions of other
// types, only run the transition if the item is actually moving to another position.
-
switch (nextTransitionType) {
case QQuickItemViewTransitioner::NoTransition:
{
@@ -465,10 +482,8 @@ bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitio
if (!doTransition) {
// if transition type is not valid, the previous transition still has to be
// canceled so that the item can move immediately to the right position
- if (transition)
- transition->cancel();
item->setPos(nextTransitionTo);
- resetTransitionData();
+ stopTransition();
}
prepared = true;
@@ -490,14 +505,8 @@ void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitione
transition = new QQuickItemViewTransitionJob;
}
- // if item is not already moving somewhere, set it to not move anywhere
- // so that removed items do not move to the default (0,0)
- if (!nextTransitionToSet)
- moveTo(item->pos());
-
transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget);
- nextTransitionType = QQuickItemViewTransitioner::NoTransition;
- prepared = false;
+ clearCurrentScheduledTransition();
}
void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem)
@@ -507,27 +516,50 @@ void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitio
// to calculate positions for transitions for other items in the view.
nextTransitionType = type;
isTransitionTarget = isTargetItem;
+
+ if (!nextTransitionFromSet && lastMovedToSet) {
+ nextTransitionFrom = lastMovedTo;
+ nextTransitionFromSet = true;
+ }
}
bool QQuickItemViewTransitionableItem::transitionWillChangePosition() const
{
if (transitionRunning() && transition->m_toPos != nextTransitionTo)
return true;
- return nextTransitionTo != item->pos();
+ if (!nextTransitionFromSet)
+ return false;
+ return nextTransitionTo != nextTransitionFrom;
}
-void QQuickItemViewTransitionableItem::finishedTransition()
+void QQuickItemViewTransitionableItem::resetNextTransitionPos()
{
nextTransitionToSet = false;
nextTransitionTo = QPointF();
}
-void QQuickItemViewTransitionableItem::resetTransitionData()
+void QQuickItemViewTransitionableItem::finishedTransition()
+{
+ resetNextTransitionPos();
+}
+
+void QQuickItemViewTransitionableItem::clearCurrentScheduledTransition()
{
+ // Just clear the current scheduled transition - don't touch the nextTransitionTo
+ // which may have already been set for a previously scheduled transition
+
nextTransitionType = QQuickItemViewTransitioner::NoTransition;
isTransitionTarget = false;
- nextTransitionTo = QPointF();
- nextTransitionToSet = false;
+ prepared = false;
+ nextTransitionFromSet = false;
+}
+
+void QQuickItemViewTransitionableItem::stopTransition()
+{
+ if (transition)
+ transition->cancel();
+ clearCurrentScheduledTransition();
+ resetNextTransitionPos();
}
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index a4babdca05..9e17385c46 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -142,11 +142,15 @@ public:
void startTransition(QQuickItemViewTransitioner *transitioner, int index);
QPointF nextTransitionTo;
+ QPointF lastMovedTo;
+ QPointF nextTransitionFrom;
QQuickItem *item;
QQuickItemViewTransitionJob *transition;
QQuickItemViewTransitioner::TransitionType nextTransitionType;
bool isTransitionTarget;
bool nextTransitionToSet;
+ bool nextTransitionFromSet;
+ bool lastMovedToSet;
bool prepared;
private:
@@ -155,7 +159,9 @@ private:
void setNextTransition(QQuickItemViewTransitioner::TransitionType, bool isTargetItem);
bool transitionWillChangePosition() const;
void finishedTransition();
- void resetTransitionData();
+ void resetNextTransitionPos();
+ void clearCurrentScheduledTransition();
+ void stopTransition();
};
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index f8098c8f65..0526187531 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1224,7 +1224,8 @@ void QQuickPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
return;
}
- if (tl.isActive() && flicking)
+
+ if (tl.isActive() && flicking && flickDuration && qreal(tl.time())/flickDuration < 0.8)
stealMouse = true; // If we've been flicked then steal the click.
else
stealMouse = false;
@@ -1335,6 +1336,7 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *)
} else {
dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0)));
}
+ flickDuration = static_cast<int>(1000 * qAbs(velocity) / accel);
offsetAdj = 0.0;
moveOffset.setValue(offset);
tl.accel(moveOffset, velocity, accel, dist);
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index a80c01f320..412caa6d2b 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -81,7 +81,7 @@ public:
, autoHighlight(true), highlightUp(false), layoutScheduled(false)
, moving(false), flicking(false), requestedOnPath(false), inRequest(false)
, dragMargin(0), deceleration(100)
- , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset)
+ , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
, firstIndex(-1), pathItems(-1), requestedIndex(-1), requestedZ(0)
, moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
, moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
@@ -171,6 +171,7 @@ public:
qreal deceleration;
QQuickTimeLine tl;
QQuickTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
+ int flickDuration;
int firstIndex;
int pathItems;
int requestedIndex;
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index d26ebed85e..1f7578c583 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
QQuickRepeaterPrivate::QQuickRepeaterPrivate()
- : model(0), ownModel(false), inRequest(false), itemCount(0), createFrom(-1)
+ : model(0), ownModel(false), inRequest(false), dataSourceIsObject(false), itemCount(0), createFrom(-1)
{
}
@@ -175,6 +175,12 @@ QQuickRepeater::~QQuickRepeater()
QVariant QQuickRepeater::model() const
{
Q_D(const QQuickRepeater);
+
+ if (d->dataSourceIsObject) {
+ QObject *o = d->dataSourceAsObject;
+ return QVariant::fromValue(o);
+ }
+
return d->dataSource;
}
@@ -194,6 +200,8 @@ void QQuickRepeater::setModel(const QVariant &model)
}
d->dataSource = model;
QObject *object = qvariant_cast<QObject*>(model);
+ d->dataSourceAsObject = object;
+ d->dataSourceIsObject = object != 0;
QQuickVisualModel *vim = 0;
if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
if (d->ownModel) {
diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h
index 88e0c94218..41d77ad977 100644
--- a/src/quick/items/qquickrepeater_p_p.h
+++ b/src/quick/items/qquickrepeater_p_p.h
@@ -75,8 +75,10 @@ private:
QQuickVisualModel *model;
QVariant dataSource;
+ QQmlGuard<QObject> dataSourceAsObject;
bool ownModel : 1;
bool inRequest : 1;
+ bool dataSourceIsObject : 1;
int itemCount;
int createFrom;