summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-01-06 14:42:19 +0100
committerYoann Lopes <yoann.lopes@nokia.com>2011-01-06 14:42:19 +0100
commite195a27a16ddb9f3486006a4e07fc441f57cf52f (patch)
treea3cb46dac321e143b11fbb092806107fde605cf5
parent2486f22d386e619d9e780b8cebd77fb6931cdad8 (diff)
parent27a2b8fd87f1a34711fab3adcdf1e16f61c4b0b7 (diff)
Merge branch 'master' of scm.dev.nokia.troll.no:research/qt-scene-graph
-rw-r--r--src/canvas/qxgraphicsview.cpp4
-rw-r--r--src/graphicsitems/qxflickable.cpp207
-rw-r--r--src/graphicsitems/qxflipable.cpp4
-rw-r--r--src/graphicsitems/qxflipable_p.h6
-rw-r--r--src/graphicsitems/qxitem.cpp29
-rw-r--r--src/graphicsitems/qxlistview.cpp8
-rw-r--r--src/graphicsitems/qxpathview.cpp197
-rw-r--r--src/graphicsitems/qxpathview_p.h3
-rw-r--r--src/graphicsitems/qxpathview_p_p.h8
-rw-r--r--tests/ShaderEffect.qml16
-rw-r--r--tests/ShaderEffectTwiceOnSameSource.qml49
-rw-r--r--tests/ShaderEffectWith2Sources.qml52
-rw-r--r--tests/ShaderEffectWithSource.qml32
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;
+ }
+ "
+ }
+}