diff options
| author | Yoann Lopes <yoann.lopes@nokia.com> | 2011-01-06 14:42:19 +0100 |
|---|---|---|
| committer | Yoann Lopes <yoann.lopes@nokia.com> | 2011-01-06 14:42:19 +0100 |
| commit | e195a27a16ddb9f3486006a4e07fc441f57cf52f (patch) | |
| tree | a3cb46dac321e143b11fbb092806107fde605cf5 | |
| parent | 2486f22d386e619d9e780b8cebd77fb6931cdad8 (diff) | |
| parent | 27a2b8fd87f1a34711fab3adcdf1e16f61c4b0b7 (diff) | |
Merge branch 'master' of scm.dev.nokia.troll.no:research/qt-scene-graph
| -rw-r--r-- | src/canvas/qxgraphicsview.cpp | 4 | ||||
| -rw-r--r-- | src/graphicsitems/qxflickable.cpp | 207 | ||||
| -rw-r--r-- | src/graphicsitems/qxflipable.cpp | 4 | ||||
| -rw-r--r-- | src/graphicsitems/qxflipable_p.h | 6 | ||||
| -rw-r--r-- | src/graphicsitems/qxitem.cpp | 29 | ||||
| -rw-r--r-- | src/graphicsitems/qxlistview.cpp | 8 | ||||
| -rw-r--r-- | src/graphicsitems/qxpathview.cpp | 197 | ||||
| -rw-r--r-- | src/graphicsitems/qxpathview_p.h | 3 | ||||
| -rw-r--r-- | src/graphicsitems/qxpathview_p_p.h | 8 | ||||
| -rw-r--r-- | tests/ShaderEffect.qml | 16 | ||||
| -rw-r--r-- | tests/ShaderEffectTwiceOnSameSource.qml | 49 | ||||
| -rw-r--r-- | tests/ShaderEffectWith2Sources.qml | 52 | ||||
| -rw-r--r-- | tests/ShaderEffectWithSource.qml | 32 |
13 files changed, 441 insertions, 174 deletions
diff --git a/src/canvas/qxgraphicsview.cpp b/src/canvas/qxgraphicsview.cpp index af661b8..321f138 100644 --- a/src/canvas/qxgraphicsview.cpp +++ b/src/canvas/qxgraphicsview.cpp @@ -292,6 +292,7 @@ QGraphicsSceneMouseEvent *QxGraphicsViewPrivate::sceneMouseEvent(QMouseEvent *e, g->setButtons(e->buttons()); g->setButton(e->button()); g->setModifiers(e->modifiers()); + g->setAccepted(false); return g; } @@ -323,7 +324,8 @@ bool QxGraphicsViewPrivate::deliverInitialMouseEvent(QxItem *o, QMouseEvent *e) children = QxItemPrivate::get(children)->nextSibling; } - if (filter) mouseFilters.removeLast(); + if (filter && !mouseFilters.isEmpty()) + mouseFilters.removeLast(); if (op->acceptedButtons & e->button()) { bool ok = false; diff --git a/src/graphicsitems/qxflickable.cpp b/src/graphicsitems/qxflickable.cpp index 0287205..7055c2c 100644 --- a/src/graphicsitems/qxflickable.cpp +++ b/src/graphicsitems/qxflickable.cpp @@ -634,10 +634,12 @@ void QxFlickable::setFlickDirection(FlickableDirection direction) void QxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { + Q_Q(QxFlickable); if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10)) stealMouse = true; // If we've been flicked then steal the click. else stealMouse = false; + q->setKeepMouseGrab(stealMouse); pressed = true; timeline.clear(); hData.velocity = 0; @@ -662,6 +664,8 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) return; bool rejectY = false; bool rejectX = false; + bool stealY = stealMouse; + bool stealX = stealMouse; if (q->yflick()) { int dy = int(event->pos().y() - pressPos.y()); @@ -676,19 +680,22 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (newY < maxY && maxY - minY <= 0) newY = maxY + (newY - maxY) / 2; if (boundsBehavior == QxFlickable::StopAtBounds && (newY > minY || newY < maxY)) { - if (newY > minY) - newY = minY; - else if (newY < maxY) + rejectY = true; + if (newY < maxY) { newY = maxY; - else - rejectY = true; + rejectY = false; + } + if (newY > minY) { + newY = minY; + rejectY = false; + } } if (!rejectY && stealMouse) { vData.move.setValue(qRound(newY)); vMoved = true; } if (qAbs(dy) > QApplication::startDragDistance()) - stealMouse = true; + stealY = true; } } @@ -705,12 +712,15 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (newX < maxX && maxX - minX <= 0) newX = maxX + (newX - maxX) / 2; if (boundsBehavior == QxFlickable::StopAtBounds && (newX > minX || newX < maxX)) { - if (newX > minX) - newX = minX; - else if (newX < maxX) + rejectX = true; + if (newX < maxX) { newX = maxX; - else - rejectX = true; + rejectX = false; + } + if (newX > minX) { + newX = minX; + rejectX = false; + } } if (!rejectX && stealMouse) { hData.move.setValue(qRound(newX)); @@ -718,10 +728,15 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) } if (qAbs(dx) > QApplication::startDragDistance()) - stealMouse = true; + stealX = true; + } } + stealMouse = stealX || stealY; + if (stealMouse) + q->setKeepMouseGrab(true); + if (!lastPos.isNull()) { qreal elapsed = qreal(lastPosTime.restart()) / 1000.; if (elapsed <= 0) @@ -768,23 +783,15 @@ void QxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event } vTime = timeline.time(); - if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { - qreal velocity = vData.velocity; - if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. - velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; - flickY(velocity); - } else { + if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + flickY(vData.velocity); + else fixupY(); - } - if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { - qreal velocity = hData.velocity; - if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. - velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; - flickX(velocity); - } else { + if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + flickX(hData.velocity); + else fixupX(); - } lastPosTime.invalidate(); @@ -807,9 +814,8 @@ void QxFlickable::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxFlickable); if (d->interactive) { + d->clearDelayedPress(); d->handleMouseMoveEvent(event); - if (d->stealMouse) - setKeepMouseGrab(true); event->accept(); } else { QxItem::mouseMoveEvent(event); @@ -820,7 +826,15 @@ void QxFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxFlickable); if (d->interactive) { - d->clearDelayedPress(); + if (d->delayedPressEvent) { + d->stealMouse = false; + d->pressed = false; + setKeepMouseGrab(false); + QApplication::sendEvent(d->delayedPressTarget, d->delayedPressEvent); + QApplication::sendEvent(d->delayedPressTarget, event); + d->clearDelayedPress(); + return; + } d->handleMouseReleaseEvent(event); event->accept(); ungrabMouse(); @@ -913,19 +927,20 @@ void QxFlickablePrivate::setRoundedViewportY(qreal y) void QxFlickable::timerEvent(QTimerEvent *event) { Q_D(QxFlickable); + if (event->timerId() == d->delayedPressTimer.timerId()) { d->delayedPressTimer.stop(); if (d->delayedPressEvent) { - // XXX akennedy - /* - QxItem *grabber = qobject_cast<QxItem *>(mouseGrabberItem()); - if (!grabber || grabber != this) - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); - */ + d->stealMouse = false; + d->pressed = false; + setKeepMouseGrab(false); + d->delayedPressTarget->grabMouse(); + QApplication::sendEvent(d->delayedPressTarget, d->delayedPressEvent); delete d->delayedPressEvent; d->delayedPressEvent = 0; } } + } qreal QxFlickable::minYExtent() const @@ -1179,64 +1194,72 @@ bool QxFlickable::yflick() const bool QxFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxFlickable); - QGraphicsSceneMouseEvent mouseEvent(event->type()); - QRectF myRect = mapToScene(QRectF(0, 0, width(), height())); - - QxItem *grabber = qobject_cast<QxItem *>(mouseGrabberItem()); - bool stealThisEvent = d->stealMouse; - - if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { - mouseEvent.setAccepted(false); - for (int i = 0x1; i <= 0x10; i <<= 1) { - if (event->buttons() & i) { - Qt::MouseButton button = Qt::MouseButton(i); - mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); - } - } - mouseEvent.setScenePos(event->scenePos()); - mouseEvent.setLastScenePos(event->lastScenePos()); - mouseEvent.setPos(mapFromScene(event->scenePos())); - mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); - - switch(mouseEvent.type()) { - case QEvent::GraphicsSceneMouseMove: - d->handleMouseMoveEvent(&mouseEvent); - break; - case QEvent::GraphicsSceneMousePress: - if (d->delayedPressEvent) - return false; - - d->handleMousePressEvent(&mouseEvent); - d->captureDelayedPress(event); - break; - case QEvent::GraphicsSceneMouseRelease: - if (d->delayedPressEvent) { - // XXX akennedy - /* - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); - d->clearDelayedPress(); - */ - } - d->handleMouseReleaseEvent(&mouseEvent); - break; - default: - break; - } - grabber = qobject_cast<QxItem*>(mouseGrabberItem()); - if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { - d->clearDelayedPress(); - grabMouse(); - } - return stealThisEvent || d->delayedPressEvent; - } else if (d->lastPosTime.isValid()) { - d->lastPosTime.invalidate(); - } - if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { - d->clearDelayedPress(); - d->stealMouse = false; - } - return false; + QGraphicsSceneMouseEvent mouseEvent(event->type()); + QRectF myRect = mapToScene(QRectF(0, 0, width(), height())); + + QxItem *grabber = mouseGrabberItem(); + bool stealThisEvent = d->stealMouse; + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + mouseEvent.setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); + } + } + mouseEvent.setScenePos(event->scenePos()); + mouseEvent.setLastScenePos(event->lastScenePos()); + mouseEvent.setPos(mapFromScene(event->scenePos())); + mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); + + switch(mouseEvent.type()) { + case QEvent::GraphicsSceneMouseMove: + d->handleMouseMoveEvent(&mouseEvent); + break; + case QEvent::GraphicsSceneMousePress: + if (d->delayedPressEvent) + return false; + + d->handleMousePressEvent(&mouseEvent); + d->captureDelayedPress(event); + stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above + break; + case QEvent::GraphicsSceneMouseRelease: + if (d->delayedPressEvent) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(QApplication::focusWidget(), d->delayedPressEvent); + d->clearDelayedPress(); + // We send the release + QApplication::sendEvent(mouseGrabberItem(), event); + // And the event has been consumed + return true; + } + d->handleMouseReleaseEvent(&mouseEvent); + break; + default: + break; + } + grabber = qobject_cast<QxItem*>(mouseGrabberItem()); + if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { + d->clearDelayedPress(); + grabMouse(); + } + + return stealThisEvent || d->delayedPressEvent; + } else if (d->lastPosTime.isValid()) { + d->lastPosTime.invalidate(); + } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { + d->clearDelayedPress(); + d->stealMouse = false; + d->pressed = false; + } + return false; } bool QxFlickable::sceneEventFilter(QxItem *i, QEvent *e) diff --git a/src/graphicsitems/qxflipable.cpp b/src/graphicsitems/qxflipable.cpp index 892ac52..87d7b4e 100644 --- a/src/graphicsitems/qxflipable.cpp +++ b/src/graphicsitems/qxflipable.cpp @@ -90,6 +90,8 @@ void QxFlipable::setFront(QxItem *front) d->front->setParentItem(this); if (Back == d->current) d->front->setOpacity(0.); + + emit frontChanged(); } QxItem *QxFlipable::back() @@ -113,6 +115,8 @@ void QxFlipable::setBack(QxItem *back) this, SLOT(retransformBack())); connect(back, SIGNAL(heightChanged()), this, SLOT(retransformBack())); + + emit backChanged(); } void QxFlipable::retransformBack() diff --git a/src/graphicsitems/qxflipable_p.h b/src/graphicsitems/qxflipable_p.h index 0d548e2..506cd22 100644 --- a/src/graphicsitems/qxflipable_p.h +++ b/src/graphicsitems/qxflipable_p.h @@ -54,8 +54,8 @@ class QxFlipable : public QxItem Q_OBJECT Q_ENUMS(Side) - Q_PROPERTY(QxItem *front READ front WRITE setFront) - Q_PROPERTY(QxItem *back READ back WRITE setBack) + Q_PROPERTY(QxItem *front READ front WRITE setFront NOTIFY frontChanged) + Q_PROPERTY(QxItem *back READ back WRITE setBack NOTIFY backChanged) Q_PROPERTY(Side side READ side NOTIFY sideChanged) //### flipAxis //### flipRotation @@ -74,6 +74,8 @@ public: Q_SIGNALS: void sideChanged(); + void backChanged(); + void frontChanged(); protected: virtual void transformChanged(const QTransform &newTransform, const QTransform &oldTransform); diff --git a/src/graphicsitems/qxitem.cpp b/src/graphicsitems/qxitem.cpp index 4af41e7..5b135c4 100644 --- a/src/graphicsitems/qxitem.cpp +++ b/src/graphicsitems/qxitem.cpp @@ -67,6 +67,7 @@ #include <QGraphicsSceneMouseEvent> #include <QtCore/qnumeric.h> #include <QtScript/qscriptengine.h> +#include <QtGui/qapplication.h> #ifndef FLT_MAX #define FLT_MAX 1E+37 @@ -1328,10 +1329,13 @@ void QxItem::grabMouse() { Q_D(QxItem); - QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(d->view); + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); - if (mouseGrabberItem()) { - QxItem *grabber = v->mouseGrabber; + QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(view); + + if (QxItem *grabber = mouseGrabberItem()) { v->mouseFilters.clear(); QEvent e(QEvent::UngrabMouse); grabber->sceneEvent(&e); @@ -1345,7 +1349,10 @@ void QxItem::ungrabMouse() Q_D(QxItem); if (this == mouseGrabberItem()) { - QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(d->view); + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); + QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(view); QxItem *grabber = v->mouseGrabber; v->mouseFilters.clear(); QEvent e(QEvent::UngrabMouse); @@ -1357,7 +1364,10 @@ void QxItem::ungrabMouse() QxItem *QxItem::mouseGrabberItem() const { Q_D(const QxItem); - return d->view?QxGraphicsViewPrivate::get(d->view)->mouseGrabber:0; + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); + return view ? QxGraphicsViewPrivate::get(view)->mouseGrabber : 0; } static void children_append(QDeclarativeListProperty<QxItem> *p, QxItem *o) @@ -2591,6 +2601,15 @@ bool QxItem::event(QEvent *ev) case QEvent::FocusOut: d->focusChanged(hasFocus()); break; + case QEvent::GraphicsSceneMousePress: + mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(ev)); + break; + case QEvent::GraphicsSceneMouseRelease: + mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(ev)); + break; + case QEvent::GraphicsSceneMouseMove: + mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(ev)); + break; default: break; } diff --git a/src/graphicsitems/qxlistview.cpp b/src/graphicsitems/qxlistview.cpp index 6be8156..d3c6148 100644 --- a/src/graphicsitems/qxlistview.cpp +++ b/src/graphicsitems/qxlistview.cpp @@ -2731,9 +2731,11 @@ void QxListView::itemsRemoved(int modelIndex, int count) emit currentIndexChanged(); } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) { // current item has been removed. - d->currentItem->attached->setIsCurrentItem(false); - d->releaseItem(d->currentItem); - d->currentItem = 0; + if (d->currentItem) { + d->currentItem->attached->setIsCurrentItem(false); + d->releaseItem(d->currentItem); + d->currentItem = 0; + } d->currentIndex = -1; if (d->itemCount) d->updateCurrent(qMin(modelIndex, d->itemCount-1)); diff --git a/src/graphicsitems/qxpathview.cpp b/src/graphicsitems/qxpathview.cpp index 52060cb..b542d83 100644 --- a/src/graphicsitems/qxpathview.cpp +++ b/src/graphicsitems/qxpathview.cpp @@ -926,97 +926,138 @@ QPointF QxPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) c void QxPathView::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxPathView); - if (!d->interactive || !d->items.count()) + if (d->interactive) { + d->handleMousePressEvent(event); + event->accept(); + } else { + QxItem::mousePressEvent(event); + } +} + +void QxPathViewPrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QxPathView); + if (!interactive || !items.count()) return; - QPointF scenePoint = mapToScene(event->pos()); + QPointF scenePoint = q->mapToScene(event->pos()); int idx = 0; - for (; idx < d->items.count(); ++idx) { - QRectF rect = d->items.at(idx)->boundingRect(); - rect = d->items.at(idx)->mapToScene(rect); + for (; idx < items.count(); ++idx) { + QRectF rect = items.at(idx)->boundingRect(); + rect = items.at(idx)->mapToScene(rect); if (rect.contains(scenePoint)) break; } - if (idx == d->items.count() && d->dragMargin == 0.) // didn't click on an item + if (idx == items.count() && dragMargin == 0.) // didn't click on an item return; - d->startPoint = d->pointNear(event->pos(), &d->startPc); - if (idx == d->items.count()) { - qreal distance = qAbs(event->pos().x() - d->startPoint.x()) + qAbs(event->pos().y() - d->startPoint.y()); - if (distance > d->dragMargin) + startPoint = pointNear(event->pos(), &startPc); + if (idx == items.count()) { + qreal distance = qAbs(event->pos().x() - startPoint.x()) + qAbs(event->pos().y() - startPoint.y()); + if (distance > dragMargin) return; } - d->stealMouse = false; - d->lastElapsed = 0; - d->lastDist = 0; - QxItemPrivate::start(d->lastPosTime); - d->tl.clear(); + if (tl.isActive() && flicking) + stealMouse = true; // If we've been flicked then steal the click. + else + stealMouse = false; + + lastElapsed = 0; + lastDist = 0; + QxItemPrivate::start(lastPosTime); + tl.clear(); } + void QxPathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxPathView); - if (!d->interactive || !d->lastPosTime.isValid()) + if (d->interactive) { + d->handleMouseMoveEvent(event); + if (d->stealMouse) + setKeepMouseGrab(true); + event->accept(); + } else { + QxItem::mouseMoveEvent(event); + } +} + +void QxPathViewPrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QxPathView); + if (!interactive || !lastPosTime.isValid()) return; qreal newPc; - QPointF pathPoint = d->pointNear(event->pos(), &newPc); - if (!d->stealMouse) { - QPointF delta = pathPoint - d->startPoint; + QPointF pathPoint = pointNear(event->pos(), &newPc); + if (!stealMouse) { + QPointF delta = pathPoint - startPoint; if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance()) { - d->stealMouse = true; - d->startPc = newPc; + stealMouse = true; + startPc = newPc; } } - if (d->stealMouse) { - d->moveReason = QxPathViewPrivate::Mouse; - qreal diff = (newPc - d->startPc)*d->model->count()*d->mappedRange; + if (stealMouse) { + moveReason = QxPathViewPrivate::Mouse; + qreal diff = (newPc - startPc)*model->count()*mappedRange; if (diff) { - setOffset(d->offset + diff); + setOffset(offset + diff); - if (diff > d->model->count()/2) - diff -= d->model->count(); - else if (diff < -d->model->count()/2) - diff += d->model->count(); + if (diff > model->count()/2) + diff -= model->count(); + else if (diff < -model->count()/2) + diff += model->count(); - d->lastElapsed = QxItemPrivate::restart(d->lastPosTime); - d->lastDist = diff; - d->startPc = newPc; + lastElapsed = QxItemPrivate::restart(lastPosTime); + lastDist = diff; + startPc = newPc; } - if (!d->moving) { - d->moving = true; - emit movingChanged(); - emit movementStarted(); + if (!moving) { + moving = true; + emit q->movingChanged(); + emit q->movementStarted(); } } } -void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxPathView); - d->stealMouse = false; - setKeepMouseGrab(false); - if (!d->interactive || !d->lastPosTime.isValid()) + if (d->interactive) { + d->handleMouseReleaseEvent(event); + event->accept(); + ungrabMouse(); + } else { + QxItem::mouseReleaseEvent(event); + } +} + +void QxPathViewPrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + Q_Q(QxPathView); + stealMouse = false; + q->setKeepMouseGrab(false); + if (!interactive || !lastPosTime.isValid()) return; - qreal elapsed = qreal(d->lastElapsed + QxItemPrivate::elapsed(d->lastPosTime)) / 1000.; - qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0; - if (d->model && d->model->count() && qAbs(velocity) > 1.) { - qreal count = d->pathItems == -1 ? d->model->count() : d->pathItems; + qreal elapsed = qreal(lastElapsed + QxItemPrivate::elapsed(lastPosTime)) / 1000.; + qreal velocity = elapsed > 0. ? lastDist / elapsed : 0; + if (model && model->count() && qAbs(velocity) > 1.) { + qreal count = pathItems == -1 ? model->count() : pathItems; if (qAbs(velocity) > count * 2) // limit velocity velocity = (velocity > 0 ? count : -count) * 2; // Calculate the distance to be travelled qreal v2 = velocity*velocity; - qreal accel = d->deceleration/10; + qreal accel = deceleration/10; // + 0.25 to encourage moving at least one item in the flick direction - qreal dist = qMin(qreal(d->model->count()-1), qreal(v2 / (accel * 2.0) + 0.25)); - if (d->haveHighlightRange && d->highlightRangeMode == QxPathView::StrictlyEnforceRange) { + qreal dist = qMin(qreal(model->count()-1), qreal(v2 / (accel * 2.0) + 0.25)); + if (haveHighlightRange && highlightRangeMode == QxPathView::StrictlyEnforceRange) { // round to nearest item. if (velocity > 0.) - dist = qRound(dist + d->offset) - d->offset; + dist = qRound(dist + offset) - offset; else - dist = qRound(dist - d->offset) + d->offset; + dist = qRound(dist - offset) + offset; // Calculate accel required to stop on item boundary if (dist <= 0.) { dist = 0.; @@ -1025,15 +1066,36 @@ void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) accel = v2 / (2.0f * qAbs(dist)); } } - d->moveOffset.setValue(d->offset); - d->tl.accel(d->moveOffset, velocity, accel, dist); - d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d)); + moveOffset.setValue(offset); + tl.accel(moveOffset, velocity, accel, dist); + tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this)); + if (!flicking) { + flicking = true; + emit q->flickingChanged(); + emit q->flickStarted(); + } } else { - d->fixOffset(); + fixOffset(); } - d->lastPosTime.invalidate(); - ungrabMouse(); + lastPosTime.invalidate(); + if (!tl.isActive()) + movementEnding(); +} + +void QxPathViewPrivate::movementEnding() +{ + Q_Q(QxPathView); + if (flicking) { + flicking = false; + emit q->flickingChanged(); + emit q->flickEnded(); + } + if (moving && !stealMouse) { + moving = false; + emit q->movingChanged(); + emit q->movementEnded(); + } } bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event) @@ -1041,8 +1103,9 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event) Q_D(QxPathView); QGraphicsSceneMouseEvent mouseEvent(event->type()); QRectF myRect = mapToScene(QRectF(0, 0, width(), height())); - QxItem *grabber = d->view ? qobject_cast<QxItem*>(d->view->mouseGrabberItem()) : 0; - if ((d->stealMouse || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + QxItem *grabber = mouseGrabberItem(); + bool stealThisEvent = d->stealMouse; + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { mouseEvent.setAccepted(false); for (int i = 0x1; i <= 0x10; i <<= 1) { if (event->buttons() & i) { @@ -1061,6 +1124,7 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event) break; case QEvent::GraphicsSceneMousePress: mousePressEvent(&mouseEvent); + stealThisEvent = d->stealMouse; break; case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent(&mouseEvent); @@ -1068,14 +1132,16 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event) default: break; } - grabber = d->view ? qobject_cast<QxItem*>(d->view->mouseGrabberItem()) : 0; - if (grabber && d->stealMouse && !grabber->keepMouseGrab() && grabber != this) + grabber = mouseGrabberItem(); + if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) grabMouse(); return d->stealMouse; } else if (d->lastPosTime.isValid()) { d->lastPosTime.invalidate(); } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) + d->stealMouse = false; return false; } @@ -1090,12 +1156,7 @@ bool QxPathView::sceneEventFilter(QxItem *i, QEvent *e) case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseRelease: - { - bool ret = sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e)); - if (e->type() == QEvent::GraphicsSceneMouseRelease) - return ret; - break; - } + return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e)); default: break; } @@ -1364,11 +1425,7 @@ void QxPathView::ticked() void QxPathView::onTimeLineCompleted() { Q_D(QxPathView); - if (d->moving && !d->stealMouse) { - d->moving = false; - emit movingChanged(); - emit movementEnded(); - } + d->movementEnding(); } // find the item closest to the snap position diff --git a/src/graphicsitems/qxpathview_p.h b/src/graphicsitems/qxpathview_p.h index 9c8dee0..64bd2ae 100644 --- a/src/graphicsitems/qxpathview_p.h +++ b/src/graphicsitems/qxpathview_p.h @@ -142,6 +142,9 @@ Q_SIGNALS: void movingChanged(); void movementStarted(); void movementEnded(); + void flickingChanged(); + void flickStarted(); + void flickEnded(); void preferredHighlightBeginChanged(); void preferredHighlightEndChanged(); void highlightRangeModeChanged(); diff --git a/src/graphicsitems/qxpathview_p_p.h b/src/graphicsitems/qxpathview_p_p.h index 210cc7c..d2f0698 100644 --- a/src/graphicsitems/qxpathview_p_p.h +++ b/src/graphicsitems/qxpathview_p_p.h @@ -77,7 +77,7 @@ public: , lastElapsed(0), mappedRange(1.0) , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), layoutScheduled(false) - , moving(false) + , moving(false), flicking(false) , dragMargin(0), deceleration(100) , moveOffset(this, &QxPathViewPrivate::setOffset) , firstIndex(-1), pathItems(-1), requestedIndex(-1) @@ -116,6 +116,11 @@ public: } } + void movementEnding(); + void handleMousePressEvent(QGraphicsSceneMouseEvent *event); + void handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void handleMouseMoveEvent(QGraphicsSceneMouseEvent *event); + QxItem *getItem(int modelIndex); void releaseItem(QxItem *item); QxPathViewAttached *attached(QxItem *item); @@ -157,6 +162,7 @@ public: bool highlightUp : 1; bool layoutScheduled : 1; bool moving; + bool flicking; QElapsedTimer lastPosTime; QPointF lastPos; qreal dragMargin; diff --git a/tests/ShaderEffect.qml b/tests/ShaderEffect.qml new file mode 100644 index 0000000..0cb6a1d --- /dev/null +++ b/tests/ShaderEffect.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + width: 400 + height: 300 + + ShaderEffectItem { + anchors.fill: parent; + fragmentShader: " + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = vec4(qt_TexCoord0.x, qt_TexCoord0.y, 1, 1); + } + " + } +} diff --git a/tests/ShaderEffectTwiceOnSameSource.qml b/tests/ShaderEffectTwiceOnSameSource.qml new file mode 100644 index 0000000..2263dce --- /dev/null +++ b/tests/ShaderEffectTwiceOnSameSource.qml @@ -0,0 +1,49 @@ +import QtQuick 2.0 + +Item { + width: 400 + height: 300 + + Text { + id: text + anchors.centerIn: parent + font.pixelSize: 80 + text: "Shaderz!" + } + + ShaderEffectSource { + id: source + sourceItem: text + } + + ShaderEffectItem { + width: parent.width + height: parent.height / 2 + + property variant source: source + + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = vec4(0, qt_TexCoord0.y, 1, 1) * texture2D(source, qt_TexCoord0).a; + } + " + } + + ShaderEffectItem { + width: parent.width + y: parent.height / 2 + height: parent.height / 2 + + property variant source: source + + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = vec4(qt_TexCoord0.x, 1, 0, 1) * texture2D(source, qt_TexCoord0).a; + } + " + } +} diff --git a/tests/ShaderEffectWith2Sources.qml b/tests/ShaderEffectWith2Sources.qml new file mode 100644 index 0000000..35f9e24 --- /dev/null +++ b/tests/ShaderEffectWith2Sources.qml @@ -0,0 +1,52 @@ +import QtQuick 2.0 + +Item { + width: 400 + height: 300 + + Rectangle { + id: rect; + anchors.centerIn: parent + width: 1 + height: 10 + + gradient: Gradient { + GradientStop { position: 0; color: "#ff0000" } + GradientStop { position: 0.5; color: "#00ff00" } + GradientStop { position: 1; color: "#0000ff" } + } + } + + Text { + id: text + anchors.centerIn: parent + font.pixelSize: 80 + text: "Shaderz!" + } + + ShaderEffectSource { + id: maskSource + sourceItem: text + } + + ShaderEffectSource { + id: colorSource + sourceItem: rect; + } + + ShaderEffectItem { + anchors.fill: text; + + property variant colorSource: colorSource + property variant maskSource: maskSource; + + fragmentShader: " + uniform lowp sampler2D maskSource; + uniform lowp sampler2D colorSource; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(maskSource, qt_TexCoord0).a * texture2D(colorSource, qt_TexCoord0.yx); + } + " + } +} diff --git a/tests/ShaderEffectWithSource.qml b/tests/ShaderEffectWithSource.qml new file mode 100644 index 0000000..d99b4c6 --- /dev/null +++ b/tests/ShaderEffectWithSource.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Item { + width: 400 + height: 300 + + Text { + id: text + anchors.centerIn: parent + font.pixelSize: 80 + text: "Shaderz!" + } + + ShaderEffectSource { + id: source + sourceItem: text + } + + ShaderEffectItem { + anchors.fill: text; + + property variant source: source + + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = vec4(qt_TexCoord0.x, qt_TexCoord0.y, 1, 1) * texture2D(source, qt_TexCoord0).a; + } + " + } +} |
