From c0701f3789acf3234e9f6431b4e8c7dc3ccefabb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 27 Mar 2014 09:57:59 +0100 Subject: Polish the image gestures example. - Add a command line parser to properly evaluate help option and directory argument, add options to disable gestures. - Add logging category so that the user can actually see what is happening. - Scale large images. - Use qreal instead of float. - Minor polishing: set window title, position file dialog at pictures location. Task-number: QTBUG-37759 Task-number: QTBUG-37203 Change-Id: Ibaf54a13034b150386a8aee476f83a9eba298298 Reviewed-by: Indrajit Tapadar Reviewed-by: Shawn Rutledge --- .../widgets/gestures/imagegestures/imagewidget.cpp | 56 +++++++++------ .../widgets/gestures/imagegestures/imagewidget.h | 15 ++-- examples/widgets/gestures/imagegestures/main.cpp | 79 ++++++++++++++++++++-- .../widgets/gestures/imagegestures/mainwidget.cpp | 19 +++++- .../widgets/gestures/imagegestures/mainwidget.h | 3 +- 5 files changed, 138 insertions(+), 34 deletions(-) (limited to 'examples/widgets/gestures') diff --git a/examples/widgets/gestures/imagegestures/imagewidget.cpp b/examples/widgets/gestures/imagegestures/imagewidget.cpp index aad40afc26..57c2af4502 100644 --- a/examples/widgets/gestures/imagegestures/imagewidget.cpp +++ b/examples/widgets/gestures/imagegestures/imagewidget.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -43,6 +43,8 @@ #include +Q_LOGGING_CATEGORY(lcExample, "qt.examples.imagegestures") + //! [constructor] ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent), @@ -55,15 +57,17 @@ ImageWidget::ImageWidget(QWidget *parent) { setMinimumSize(QSize(100,100)); - -//! [enable gestures] - grabGesture(Qt::PanGesture); - grabGesture(Qt::PinchGesture); - grabGesture(Qt::SwipeGesture); -//! [enable gestures] } //! [constructor] +void ImageWidget::grabGestures(const QList &gestures) +{ + //! [enable gestures] + foreach (Qt::GestureType gesture, gestures) + grabGesture(gesture); + //! [enable gestures] +} + //! [event handler] bool ImageWidget::event(QEvent *event) { @@ -77,10 +81,10 @@ void ImageWidget::paintEvent(QPaintEvent*) { QPainter p(this); - float iw = currentImage.width(); - float ih = currentImage.height(); - float wh = height(); - float ww = width(); + const qreal iw = currentImage.width(); + const qreal ih = currentImage.height(); + const qreal wh = height(); + const qreal ww = width(); p.translate(ww/2, wh/2); p.translate(horizontalOffset, verticalOffset); @@ -98,11 +102,13 @@ void ImageWidget::mouseDoubleClickEvent(QMouseEvent *) verticalOffset = 0; horizontalOffset = 0; update(); + qCDebug(lcExample) << "reset on mouse double click"; } //! [gesture event handler] bool ImageWidget::gestureEvent(QGestureEvent *event) { + qCDebug(lcExample) << "gestureEvent():" << event->gestures().size(); if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) swipeTriggered(static_cast(swipe)); else if (QGesture *pan = event->gesture(Qt::PanGesture)) @@ -126,6 +132,7 @@ void ImageWidget::panTriggered(QPanGesture *gesture) } #endif QPointF delta = gesture->delta(); + qCDebug(lcExample) << "panTriggered():" << delta; horizontalOffset += delta.x(); verticalOffset += delta.y(); update(); @@ -135,13 +142,16 @@ void ImageWidget::pinchTriggered(QPinchGesture *gesture) { QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); if (changeFlags & QPinchGesture::RotationAngleChanged) { - qreal value = gesture->property("rotationAngle").toReal(); - qreal lastValue = gesture->property("lastRotationAngle").toReal(); - rotationAngle += value - lastValue; + const qreal value = gesture->property("rotationAngle").toReal(); + const qreal lastValue = gesture->property("lastRotationAngle").toReal(); + const qreal rotationAngleDelta = value - lastValue; + rotationAngle += rotationAngleDelta; + qCDebug(lcExample) << "pinchTriggered(): rotation by" << rotationAngleDelta << rotationAngle; } if (changeFlags & QPinchGesture::ScaleFactorChanged) { qreal value = gesture->property("scaleFactor").toReal(); currentStepScaleFactor = value; + qCDebug(lcExample) << "pinchTriggered(): " << currentStepScaleFactor; } if (gesture->state() == Qt::GestureFinished) { scaleFactor *= currentStepScaleFactor; @@ -155,10 +165,13 @@ void ImageWidget::swipeTriggered(QSwipeGesture *gesture) { if (gesture->state() == Qt::GestureFinished) { if (gesture->horizontalDirection() == QSwipeGesture::Left - || gesture->verticalDirection() == QSwipeGesture::Up) + || gesture->verticalDirection() == QSwipeGesture::Up) { + qCDebug(lcExample) << "swipeTriggered(): swipe to previous"; goPrevImage(); - else + } else { + qCDebug(lcExample) << "swipeTriggered(): swipe to next"; goNextImage(); + } update(); } } @@ -184,17 +197,22 @@ void ImageWidget::openDirectory(const QString &path) QImage ImageWidget::loadImage(const QString &fileName) { + qDebug() << position << files << fileName; QImageReader reader(fileName); + qCDebug(lcExample) << "loading" << QDir::toNativeSeparators(fileName) << position << '/' << files.size(); if (!reader.canRead()) { - qDebug() << fileName << ": can't load image"; + qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": can't load image"; return QImage(); } QImage image; if (!reader.read(&image)) { - qDebug() << fileName << ": corrupted image"; + qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": corrupted image: " << reader.errorString(); return QImage(); } + const QSize maximumSize(2000, 2000); // Reduce in case someone has large photo images. + if (image.size().width() > maximumSize.width() || image.height() > maximumSize.height()) + image = image.scaled(maximumSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); return image; } @@ -238,7 +256,7 @@ void ImageWidget::goToImage(int index) return; if (index < 0 || index >= files.size()) { - qDebug() << "goToImage: invalid index: " << index; + qCWarning(lcExample) << "goToImage: invalid index: " << index; return; } diff --git a/examples/widgets/gestures/imagegestures/imagewidget.h b/examples/widgets/gestures/imagegestures/imagewidget.h index 7aaf554117..d061935fe0 100644 --- a/examples/widgets/gestures/imagegestures/imagewidget.h +++ b/examples/widgets/gestures/imagegestures/imagewidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -52,6 +52,8 @@ class QPinchGesture; class QSwipeGesture; QT_END_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcExample) + //! [class definition begin] class ImageWidget : public QWidget { @@ -60,6 +62,7 @@ class ImageWidget : public QWidget public: ImageWidget(QWidget *parent = 0); void openDirectory(const QString &path); + void grabGestures(const QList &gestures); protected: bool event(QEvent *event); @@ -88,11 +91,11 @@ private: QImage prevImage, nextImage; QImage currentImage; - float horizontalOffset; - float verticalOffset; - float rotationAngle; - float scaleFactor; - float currentStepScaleFactor; + qreal horizontalOffset; + qreal verticalOffset; + qreal rotationAngle; + qreal scaleFactor; + qreal currentStepScaleFactor; //! [class definition end] }; //! [class definition end] diff --git a/examples/widgets/gestures/imagegestures/main.cpp b/examples/widgets/gestures/imagegestures/main.cpp index aec32149f0..80f275bd5f 100644 --- a/examples/widgets/gestures/imagegestures/main.cpp +++ b/examples/widgets/gestures/imagegestures/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -42,17 +42,86 @@ #include "mainwidget.h" +static void showHelp(QCommandLineParser &parser, const QString errorMessage = QString()) +{ + QString text; + QTextStream str(&text); + str << ""; + if (!errorMessage.isEmpty()) + str << "

" << errorMessage << "

"; + str << "
" << parser.helpText() << "
"; + QMessageBox box(errorMessage.isEmpty() ? QMessageBox::Information : QMessageBox::Warning, + QGuiApplication::applicationDisplayName(), text, + QMessageBox::Ok); + box.setTextInteractionFlags(Qt::TextBrowserInteraction); + box.exec(); +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCoreApplication::setApplicationName(QStringLiteral("imagegestures")); + QGuiApplication::setApplicationDisplayName(QStringLiteral("Image Gestures Example")); + + QCommandLineParser commandLineParser; + const QCommandLineOption disablePanOption("no-pan", "Disable pan gesture"); + commandLineParser.addOption(disablePanOption); + const QCommandLineOption disablePinchOption("no-pinch", "Disable pinch gesture"); + commandLineParser.addOption(disablePinchOption); + const QCommandLineOption disableSwipeOption("no-swipe", "Disable swipe gesture"); + commandLineParser.addOption(disableSwipeOption); + const QCommandLineOption helpOption = commandLineParser.addHelpOption(); + commandLineParser.addPositionalArgument(QStringLiteral("Directory"), + QStringLiteral("Directory to display")); + + const QString description = QGuiApplication::applicationDisplayName() + + QLatin1String("\n\nEnable \"debug\" on the logging category \"qt.examples.imagegestures\" in order to\n" + "in order to obtain verbose information about Qt's gesture event processing,\n" + "for example by setting the environment variables QT_LOGGING_RULES to\n" + "qt.examples.imagegestures.debug=true\n"); + commandLineParser.setApplicationDescription(description); + + if (!commandLineParser.parse(QCoreApplication::arguments())) { + showHelp(commandLineParser, commandLineParser.errorText()); + return -1; + } + if (commandLineParser.isSet(helpOption)) { + showHelp(commandLineParser); + return 0; + } + + QStringList arguments = commandLineParser.positionalArguments(); + if (!arguments.isEmpty() && !QFileInfo(arguments.front()).isDir()) { + showHelp(commandLineParser, + QLatin1Char('"') + QDir::toNativeSeparators(arguments.front()) + + QStringLiteral("\" is not a directory.")); + return -1; + } + + QList gestures; + if (!commandLineParser.isSet(disablePanOption)) + gestures << Qt::PanGesture; + if (!commandLineParser.isSet(disablePinchOption)) + gestures << Qt::PinchGesture; + if (!commandLineParser.isSet(disableSwipeOption)) + gestures << Qt::SwipeGesture; MainWidget w; + w.grabGestures(gestures); w.show(); - if (QApplication::arguments().size() > 1) - w.openDirectory(QApplication::arguments().at(1)); - else - w.openDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); + if (arguments.isEmpty()) { + const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); + const QString directory = + QFileDialog::getExistingDirectory(&w, "Select image folder", + picturesLocations.isEmpty() ? QString() : picturesLocations.front()); + if (directory.isEmpty()) + return 0; + arguments.append(directory); + } + + w.openDirectory(arguments.front()); return app.exec(); } diff --git a/examples/widgets/gestures/imagegestures/mainwidget.cpp b/examples/widgets/gestures/imagegestures/mainwidget.cpp index 105cdf184e..74c2cc5bb1 100644 --- a/examples/widgets/gestures/imagegestures/mainwidget.cpp +++ b/examples/widgets/gestures/imagegestures/mainwidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -41,15 +41,28 @@ #include "imagewidget.h" #include "mainwidget.h" +#include +#include +#include + MainWidget::MainWidget(QWidget *parent) : QMainWindow(parent) + , imageWidget(new ImageWidget(this)) { - resize(400, 300); - imageWidget = new ImageWidget(this); setCentralWidget(imageWidget); + const QRect screenGeometry = QGuiApplication::primaryScreen()->availableGeometry(); + QRect geometry(QPoint(0, 0), QSize(screenGeometry.width() * 3 / 4, screenGeometry.height() * 3 / 4)); + geometry.moveCenter(screenGeometry.center()); + setGeometry(geometry); } void MainWidget::openDirectory(const QString &path) { + setWindowTitle(QDir::toNativeSeparators(path)); imageWidget->openDirectory(path); } + +void MainWidget::grabGestures(const QList &gestures) +{ + imageWidget->grabGestures(gestures); +} diff --git a/examples/widgets/gestures/imagegestures/mainwidget.h b/examples/widgets/gestures/imagegestures/mainwidget.h index 5135466fde..79ed3a087a 100644 --- a/examples/widgets/gestures/imagegestures/mainwidget.h +++ b/examples/widgets/gestures/imagegestures/mainwidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -51,6 +51,7 @@ class MainWidget : public QMainWindow public: MainWidget(QWidget *parent = 0); + void grabGestures(const QList &gestures); public slots: void openDirectory(const QString &path); -- cgit v1.2.3