diff --git a/app/folderviewcontextmanageritem.cpp b/app/folderviewcontextmanageritem.cpp --- a/app/folderviewcontextmanageritem.cpp +++ b/app/folderviewcontextmanageritem.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // KDE #include @@ -209,6 +210,8 @@ mView->header()->setStretchLastSection(false); mView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + QScroller::grabGesture(mView->viewport(), QScroller::TouchGesture); + setWidget(mView); QObject::connect(mView, &QTreeView::activated, this, &FolderViewContextManagerItem::slotActivated); EventWatcher::install(mView, QEvent::Show, this, SLOT(expandToSelectedUrl())); diff --git a/app/startmainpage.cpp b/app/startmainpage.cpp --- a/app/startmainpage.cpp +++ b/app/startmainpage.cpp @@ -33,6 +33,7 @@ #include #include +#include // KDE #include @@ -167,6 +168,7 @@ d->mBookmarksView->setModel(d->mBookmarksModel); d->mBookmarksView->setAutoResizeItemsEnabled(false); + QScroller::grabGesture(d->mBookmarksView->viewport(), QScroller::TouchGesture); connect(d->mBookmarksView, &KFilePlacesView::urlChanged, this, &StartMainPage::urlSelected); diff --git a/lib/documentview/abstractdocumentviewadapter.h b/lib/documentview/abstractdocumentviewadapter.h --- a/lib/documentview/abstractdocumentviewadapter.h +++ b/lib/documentview/abstractdocumentviewadapter.h @@ -144,7 +144,7 @@ { mWidget = widget; } - + Q_SIGNALS: /** * @addgroup zooming functions diff --git a/lib/documentview/documentview.h b/lib/documentview/documentview.h --- a/lib/documentview/documentview.h +++ b/lib/documentview/documentview.h @@ -33,6 +33,7 @@ class QPropertyAnimation; class QUrl; +class QGestureEvent; namespace Gwenview { @@ -207,6 +208,8 @@ bool sceneEventFilter(QGraphicsItem*, QEvent*) Q_DECL_OVERRIDE; void dragEnterEvent(QGraphicsSceneDragDropEvent* event) override; void dropEvent(QGraphicsSceneDragDropEvent* event) override; + bool event(QEvent*) Q_DECL_OVERRIDE; + bool gestureEvent( QGestureEvent*); private Q_SLOTS: void finishOpenUrl(); diff --git a/lib/documentview/documentview.cpp b/lib/documentview/documentview.cpp --- a/lib/documentview/documentview.cpp +++ b/lib/documentview/documentview.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include // KDE #include @@ -67,6 +69,7 @@ #include #include #include +#include namespace Gwenview { @@ -113,7 +116,11 @@ QPointF mDragStartPosition; QPointer mDragThumbnailProvider; QPointer mDrag; - + qint64 timestamp; + qreal rotationsDelta = 25; + qreal lastRotation; + bool firstMoving; + void setCurrentAdapter(AbstractDocumentViewAdapter* adapter) { Q_ASSERT(adapter); @@ -433,6 +440,8 @@ d->controlWheelAccumulatedDelta = 0; d->mDragStartPosition = QPointF(0, 0); d->mDrag = nullptr; + grabGesture(Qt::PinchGesture); + setAcceptTouchEvents (true); // We use an opacity effect instead of using the opacity property directly, because the latter operates at // the painter level, which means if you draw multiple layers in paint(), all layers get the specified @@ -670,6 +679,94 @@ return d->mAdapter->zoom(); } +bool DocumentView::event(QEvent* event) +{ + + if (event->type() == QEvent::TouchBegin) { + QTouchEvent *touchEvent = static_cast(event); + event->accept(); + d->timestamp = touchEvent->timestamp(); + d->firstMoving = true; + return true; + } + if (event->type() == QEvent::TouchUpdate) { + QTouchEvent *touchEvent = static_cast(event); + if (touchEvent->touchPoints().size() == 1) { + qint64 now = touchEvent->timestamp(); + if (d->firstMoving && now - d->timestamp >= 400) { + d->startDragIfSensible(); + } + d->firstMoving = false; + } + return true; + } + if (event->type() == QEvent::TouchEnd) { + d->firstMoving = false; + QTouchEvent* touchEvent = static_cast(event); + const QPointF start = touchEvent->touchPoints().at(0).startPos(); + const QPointF end = touchEvent->touchPoints().at(0).pos(); + QPointF diff = start - end; + qint64 now = touchEvent->timestamp(); + qint64 time = now - d->timestamp; + if (touchEvent->touchPoints().size() == 1 && diff.manhattanLength() > 200 && time < 500) { + if (diff.x() < 0 && abs(diff.x()) >= abs(diff.y())) { + d->mAdapter->previousImageRequested(); + } + if (diff.x() > 0 && abs(diff.x()) >= abs(diff.y())) { + d->mAdapter->nextImageRequested(); + } + } + } + + if ( event->type() == QEvent::Gesture ) { + return gestureEvent(static_cast( event )); + } + return QGraphicsWidget::event( event ); +} + +bool DocumentView::gestureEvent( QGestureEvent* event ) +{ + QPinchGesture *pinch = static_cast(event->gesture(Qt::PinchGesture)); + + if (pinch) + { + event->accept(); + if (pinch->state() == Qt::GestureStarted) { + d->lastRotation = 0; + } + if (pinch->state() == Qt::GestureUpdated) { + if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged) { + if (d->mAdapter->canZoom()) { + qreal currentZoom = d->mAdapter->zoom(); + qreal zoom = currentZoom * pinch->scaleFactor(); + qreal diff = currentZoom > zoom ? currentZoom - zoom : zoom - currentZoom; + if (diff > 0.001) { + d->setZoom(zoom,mapToScene (pinch->lastCenterPoint())); + } + } + } + + if (pinch->changeFlags() & QPinchGesture::RotationAngleChanged) { + if (pinch->rotationAngle()-d->lastRotation > d->rotationsDelta) { + TransformImageOperation *op = new TransformImageOperation(ROT_90); + op->applyToDocument(d->mDocument); + d->lastRotation = pinch->rotationAngle(); + } + else if (-(pinch->rotationAngle()-d->lastRotation) > d->rotationsDelta) { + TransformImageOperation *op = new TransformImageOperation(ROT_270); + op->applyToDocument(d->mDocument); + d->lastRotation = pinch->rotationAngle(); + } + } + } + if (pinch->state() == Qt::GestureFinished) { + d->lastRotation = 0; + } + return true; + } + return false; +} + void DocumentView::resizeEvent(QGraphicsSceneResizeEvent *event) { d->resizeAdapterWidget(); @@ -891,7 +988,7 @@ const QGraphicsSceneMouseEvent* mouseEvent = static_cast(event); const qreal dragDistance = (mouseEvent->pos() - d->mDragStartPosition).manhattanLength(); const qreal minDistanceToStartDrag = QGuiApplication::styleHints()->startDragDistance(); - if (!d->canPan() && dragDistance >= minDistanceToStartDrag) { + if (!d->canPan() && dragDistance >= minDistanceToStartDrag && mouseEvent->source() == Qt::MouseEventNotSynthesized) { d->startDragIfSensible(); } } diff --git a/lib/thumbnailview/thumbnailview.cpp b/lib/thumbnailview/thumbnailview.cpp --- a/lib/thumbnailview/thumbnailview.cpp +++ b/lib/thumbnailview/thumbnailview.cpp @@ -36,6 +36,7 @@ #include #include #include +#include // KDE #include @@ -309,6 +310,8 @@ setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel); + QScroller::grabGesture(this->viewport(), QScroller::TouchGesture); + d->mScheduledThumbnailGenerationTimer.setSingleShot(true); d->mScheduledThumbnailGenerationTimer.setInterval(500); connect(&d->mScheduledThumbnailGenerationTimer, &QTimer::timeout, this, &ThumbnailView::generateThumbnailsForItems);