diff options
Diffstat (limited to 'examples/gestures/imageviewer/imagewidget.cpp')
-rw-r--r-- | examples/gestures/imageviewer/imagewidget.cpp | 267 |
1 files changed, 71 insertions, 196 deletions
diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 7d06303..495b73a 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -44,210 +44,97 @@ #include <QtGui> ImageWidget::ImageWidget(QWidget *parent) - : QWidget(parent) -{ - setAttribute(Qt::WA_AcceptTouchEvents); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_OpaquePaintEvent); - setAttribute(Qt::WA_NoSystemBackground); + : QWidget(parent), + position(0), + horizontalOffset(0), + verticalOffset(0), + rotationAngle(0), + scaleFactor(1) +{ setObjectName("ImageWidget"); - setMinimumSize(QSize(100,100)); - position = 0; - zoomed = rotated = false; - - zoomedIn = false; - horizontalOffset = 0; - verticalOffset = 0; + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_NoSystemBackground); - panGesture = new QPanGesture(this); - connect(panGesture, SIGNAL(started()), this, SLOT(gestureTriggered())); - connect(panGesture, SIGNAL(finished()), this, SLOT(gestureTriggered())); - connect(panGesture, SIGNAL(cancelled()), this, SLOT(gestureTriggered())); - connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); + QGesture *panGesture = new QPanGesture(this); + connect(panGesture, SIGNAL(started()), this, SLOT(panTriggered())); + connect(panGesture, SIGNAL(finished()), this, SLOT(panTriggered())); + connect(panGesture, SIGNAL(cancelled()), this, SLOT(panTriggered())); + connect(panGesture, SIGNAL(triggered()), this, SLOT(panTriggered())); -// tapAndHoldGesture = new TapAndHoldGesture(this); -// connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); -// connect(tapAndHoldGesture, SIGNAL(finished()), this, SLOT(gestureTriggered())); + QGesture *pinchGesture = new QPinchGesture(this); + connect(pinchGesture, SIGNAL(started()), this, SLOT(pinchTriggered())); + connect(pinchGesture, SIGNAL(finished()), this, SLOT(pinchTriggered())); + connect(pinchGesture, SIGNAL(cancelled()), this, SLOT(pinchTriggered())); + connect(pinchGesture, SIGNAL(triggered()), this, SLOT(pinchTriggered())); } void ImageWidget::paintEvent(QPaintEvent*) { QPainter p(this); - if (currentImage.isNull()) { - p.fillRect(geometry(), Qt::white); - return; - } - int hoffset = 0; - int voffset = 0; - const int w = pixmap.width(); - const int h = pixmap.height(); - p.save(); - if (zoomedIn) { - hoffset = horizontalOffset; - voffset = verticalOffset; - if (horizontalOffset > 0) - p.fillRect(0, 0, horizontalOffset, height(), Qt::white); - if (verticalOffset > 0) - p.fillRect(0, 0, width(), verticalOffset, Qt::white); - } - p.drawPixmap(hoffset, voffset, pixmap); - if (hoffset + w < width()) - p.fillRect(hoffset + w, 0, width() - w - hoffset, height(), Qt::white); - if (voffset + h < height()) - p.fillRect(0, voffset + h, width(), height() - h - voffset, Qt::white); - - // paint touch feedback - if (touchFeedback.tapped || touchFeedback.doubleTapped) { - p.setPen(QPen(Qt::gray, 2)); - p.drawEllipse(touchFeedback.position, 5, 5); - if (touchFeedback.doubleTapped) { - p.setPen(QPen(Qt::darkGray, 2, Qt::DotLine)); - p.drawEllipse(touchFeedback.position, 15, 15); - } else if (touchFeedback.tapAndHoldState != 0) { - QPoint pts[8] = { - touchFeedback.position + QPoint( 0, -15), - touchFeedback.position + QPoint( 10, -10), - touchFeedback.position + QPoint( 15, 0), - touchFeedback.position + QPoint( 10, 10), - touchFeedback.position + QPoint( 0, 15), - touchFeedback.position + QPoint(-10, 10), - touchFeedback.position + QPoint(-15, 0) - }; - for (int i = 0; i < touchFeedback.tapAndHoldState/5; ++i) - p.drawEllipse(pts[i], 3, 3); - } - } else if (touchFeedback.sliding) { - p.setPen(QPen(Qt::red, 3)); - QPoint endPos = QPoint(touchFeedback.position.x(), touchFeedback.slidingStartPosition.y()); - p.drawLine(touchFeedback.slidingStartPosition, endPos); - int dx = 10; - if (touchFeedback.slidingStartPosition.x() < endPos.x()) - dx = -1*dx; - p.drawLine(endPos, endPos + QPoint(dx, 5)); - p.drawLine(endPos, endPos + QPoint(dx, -5)); - } + p.fillRect(rect(), Qt::white); - for (int i = 0; i < TouchFeedback::MaximumNumberOfTouches; ++i) { - if (touchFeedback.touches[i].isNull()) - break; - p.drawEllipse(touchFeedback.touches[i], 10, 10); - } - p.restore(); -} + float iw = currentImage.width(); + float ih = currentImage.height(); + float wh = height(); + float ww = width(); -void ImageWidget::mousePressEvent(QMouseEvent *event) -{ - touchFeedback.tapped = true; - touchFeedback.position = event->pos(); + p.translate(ww/2, wh/2); + p.translate(horizontalOffset, verticalOffset); + p.rotate(rotationAngle); + p.scale(scaleFactor, scaleFactor); + p.translate(-iw/2, -ih/2); + p.drawImage(0, 0, currentImage); } -void ImageWidget::mouseDoubleClickEvent(QMouseEvent *event) +void ImageWidget::mouseDoubleClickEvent(QMouseEvent *) { - touchFeedback.doubleTapped = true; - const QPoint p = event->pos(); - touchFeedback.position = p; - horizontalOffset = p.x() - currentImage.width()*1.0*p.x()/width(); - verticalOffset = p.y() - currentImage.height()*1.0*p.y()/height(); - setZoomedIn(!zoomedIn); - zoomed = rotated = false; - updateImage(); - - feedbackFadeOutTimer.start(500, this); + rotationAngle = 0; + scaleFactor = 1; + verticalOffset = 0; + horizontalOffset = 0; + update(); } -void ImageWidget::gestureTriggered() +void ImageWidget::panTriggered() { - if (sender() == panGesture) { - touchFeedback.tapped = false; - touchFeedback.doubleTapped = false; - QPanGesture *pg = qobject_cast<QPanGesture*>(sender()); - if (zoomedIn) { + QPanGesture *pg = qobject_cast<QPanGesture*>(sender()); #ifndef QT_NO_CURSOR - switch (pg->state()) { - case Qt::GestureStarted: - case Qt::GestureUpdated: - setCursor(Qt::SizeAllCursor); - break; - default: - setCursor(Qt::ArrowCursor); - } -#endif - horizontalOffset += pg->lastOffset().width(); - verticalOffset += pg->lastOffset().height(); - } else { - // only slide gesture should be accepted - if (pg->state() == Qt::GestureFinished) { - touchFeedback.sliding = false; - zoomed = rotated = false; - if (pg->totalOffset().width() > 0) - goNextImage(); - else - goPrevImage(); - updateImage(); - } - } - update(); - feedbackFadeOutTimer.start(500, this); - } else if (sender() == tapAndHoldGesture) { - if (tapAndHoldGesture->state() == Qt::GestureFinished) { - qDebug() << "tap and hold detected"; - touchFeedback.reset(); - update(); - - QMenu menu; - menu.addAction("Action 1"); - menu.addAction("Action 2"); - menu.addAction("Action 3"); - menu.exec(mapToGlobal(tapAndHoldGesture->pos())); - } else { - ++touchFeedback.tapAndHoldState; - update(); - } - feedbackFadeOutTimer.start(500, this); + switch (pg->state()) { + case Qt::GestureStarted: + case Qt::GestureUpdated: + setCursor(Qt::SizeAllCursor); + break; + default: + setCursor(Qt::ArrowCursor); } +#endif + horizontalOffset += pg->lastOffset().width(); + verticalOffset += pg->lastOffset().height(); + update(); } -void ImageWidget::gestureFinished() +void ImageWidget::pinchTriggered() { - qDebug() << "gesture finished" << sender(); + QPinchGesture *pg = qobject_cast<QPinchGesture*>(sender()); + rotationAngle += pg->rotationAngle(); + scaleFactor += pg->scaleFactor(); + update(); } -void ImageWidget::gestureCancelled() +void ImageWidget::swipeTriggered() { - qDebug() << "gesture cancelled" << sender(); + qDebug() << "swipe!"; + goNextImage(); +// goPrevImage(); + update(); } void ImageWidget::resizeEvent(QResizeEvent*) { - updateImage(); -} - -void ImageWidget::updateImage() -{ - // should use qtconcurrent here? - transformation = QTransform(); - if (zoomedIn) { - } else { - if (currentImage.isNull()) - return; - if (zoomed) { - transformation = transformation.scale(zoom, zoom); - } else { - double xscale = (double)width()/currentImage.width(); - double yscale = (double)height()/currentImage.height(); - if (xscale < yscale) - yscale = xscale; - else - xscale = yscale; - transformation = transformation.scale(xscale, yscale); - } - if (rotated) - transformation = transformation.rotate(angle); - } - pixmap = QPixmap::fromImage(currentImage).transformed(transformation); update(); } @@ -261,7 +148,7 @@ void ImageWidget::openDirectory(const QString &path) position = 0; goToImage(0); - updateImage(); + update(); } QImage ImageWidget::loadImage(const QString &fileName) @@ -271,6 +158,7 @@ QImage ImageWidget::loadImage(const QString &fileName) qDebug() << fileName << ": can't load image"; return QImage(); } + QImage image; if (!reader.read(&image)) { qDebug() << fileName << ": corrupted image"; @@ -279,15 +167,11 @@ QImage ImageWidget::loadImage(const QString &fileName) return image; } -void ImageWidget::setZoomedIn(bool zoomed) -{ - zoomedIn = zoomed; -} - void ImageWidget::goNextImage() { if (files.isEmpty()) return; + if (position < files.size()-1) { ++position; prevImage = currentImage; @@ -297,14 +181,14 @@ void ImageWidget::goNextImage() else nextImage = QImage(); } - setZoomedIn(false); - updateImage(); + update(); } void ImageWidget::goPrevImage() { if (files.isEmpty()) return; + if (position > 0) { --position; nextImage = currentImage; @@ -314,28 +198,31 @@ void ImageWidget::goPrevImage() else prevImage = QImage(); } - setZoomedIn(false); - updateImage(); + update(); } void ImageWidget::goToImage(int index) { if (files.isEmpty()) return; + if (index < 0 || index >= files.size()) { qDebug() << "goToImage: invalid index: " << index; return; } + if (index == position+1) { goNextImage(); return; } + if (position > 0 && index == position-1) { goPrevImage(); return; } + position = index; - pixmap = QPixmap(); + if (index > 0) prevImage = loadImage(path+QLatin1String("/")+files.at(position-1)); else @@ -345,18 +232,6 @@ void ImageWidget::goToImage(int index) nextImage = loadImage(path+QLatin1String("/")+files.at(position+1)); else nextImage = QImage(); - setZoomedIn(false); - updateImage(); -} - -void ImageWidget::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == touchFeedback.tapTimer.timerId()) { - touchFeedback.tapTimer.stop(); - } else if (event->timerId() == feedbackFadeOutTimer.timerId()) { - feedbackFadeOutTimer.stop(); - touchFeedback.reset(); - } update(); } |