diff options
Diffstat (limited to 'tests/manual/examples/widgets/touch/pinchzoom')
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/CMakeLists.txt | 50 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png | bin | 0 -> 42493 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc | 14 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/graphicsview.cpp | 48 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/graphicsview.h | 18 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/images/cheese.jpg | bin | 0 -> 3029 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/main.cpp | 47 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/mice.qrc | 5 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/mouse.cpp | 158 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/mouse.h | 33 | ||||
-rw-r--r-- | tests/manual/examples/widgets/touch/pinchzoom/pinchzoom.pro | 16 |
11 files changed, 389 insertions, 0 deletions
diff --git a/tests/manual/examples/widgets/touch/pinchzoom/CMakeLists.txt b/tests/manual/examples/widgets/touch/pinchzoom/CMakeLists.txt new file mode 100644 index 0000000000..8820d8d44b --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(pinchzoom LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/touch/pinchzoom") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) + +qt_standard_project_setup() + +qt_add_executable(pinchzoom + graphicsview.cpp graphicsview.h + main.cpp + mouse.cpp mouse.h +) + +set_target_properties(pinchzoom PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(pinchzoom PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets +) + +# Resources: +set(mice_resource_files + "images/cheese.jpg" +) + +qt_add_resources(pinchzoom "mice" + PREFIX + "/" + FILES + ${mice_resource_files} +) + +install(TARGETS pinchzoom + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png b/tests/manual/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png Binary files differnew file mode 100644 index 0000000000..7db51fbf55 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png diff --git a/tests/manual/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc b/tests/manual/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc new file mode 100644 index 0000000000..aef5c59407 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc @@ -0,0 +1,14 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example touch/pinchzoom + \title Pinch Zoom Example + \ingroup touchinputexamples + \brief Shows how to recognize a gesture. + + The Pinch Zoom example shows how to use low-level touch information + to recognize a gesture. + + \image touch-pinchzoom-example.png +*/ diff --git a/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.cpp b/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.cpp new file mode 100644 index 0000000000..61042e7e02 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "graphicsview.h" + +#include <QScrollBar> +#include <QTouchEvent> + +GraphicsView::GraphicsView(QGraphicsScene *scene, QWidget *parent) + : QGraphicsView(scene, parent) +{ + viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + setDragMode(ScrollHandDrag); +} + +bool GraphicsView::viewportEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + { + QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); + const auto touchPoints = touchEvent->points(); + if (touchPoints.count() == 2) { + // determine scale factor + const QEventPoint &touchPoint0 = touchPoints.first(); + const QEventPoint &touchPoint1 = touchPoints.last(); + qreal currentScaleFactor = + QLineF(touchPoint0.position(), touchPoint1.position()).length() + / QLineF(touchPoint0.pressPosition(), touchPoint1.pressPosition()).length(); + if (touchEvent->touchPointStates() & QEventPoint::Released) { + // if one of the fingers is released, remember the current scale + // factor so that adding another finger later will continue zooming + // by adding new scale factor to the existing remembered value. + totalScaleFactor *= currentScaleFactor; + currentScaleFactor = 1; + } + setTransform(QTransform::fromScale(totalScaleFactor * currentScaleFactor, + totalScaleFactor * currentScaleFactor)); + } + return true; + } + default: + break; + } + return QGraphicsView::viewportEvent(event); +} diff --git a/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.h b/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.h new file mode 100644 index 0000000000..e6a300f418 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/graphicsview.h @@ -0,0 +1,18 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#pragma once +#include <QGraphicsView> + +class GraphicsView : public QGraphicsView +{ + Q_OBJECT + +public: + GraphicsView(QGraphicsScene *scene = nullptr, QWidget *parent = nullptr); + + bool viewportEvent(QEvent *event) override; + +private: + qreal totalScaleFactor = 1; +}; diff --git a/tests/manual/examples/widgets/touch/pinchzoom/images/cheese.jpg b/tests/manual/examples/widgets/touch/pinchzoom/images/cheese.jpg Binary files differnew file mode 100644 index 0000000000..dea5795fd0 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/images/cheese.jpg diff --git a/tests/manual/examples/widgets/touch/pinchzoom/main.cpp b/tests/manual/examples/widgets/touch/pinchzoom/main.cpp new file mode 100644 index 0000000000..85b5cad1f8 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/main.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "graphicsview.h" +#include "mouse.h" + +#include <QApplication> +#include <cmath> + +static constexpr int MouseCount = 7; + +//! [0] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); +//! [0] + +//! [1] + QGraphicsScene scene; + scene.setSceneRect(-300, -300, 600, 600); +//! [1] //! [2] + scene.setItemIndexMethod(QGraphicsScene::NoIndex); +//! [2] + +//! [3] + for (int i = 0; i < MouseCount; ++i) { + Mouse *mouse = new Mouse; + mouse->setPos(::sin((i * 6.28) / MouseCount) * 200, + ::cos((i * 6.28) / MouseCount) * 200); + scene.addItem(mouse); + } +//! [3] + +//! [4] + GraphicsView view(&scene); + view.setRenderHint(QPainter::Antialiasing); + view.setBackgroundBrush(QPixmap(":/images/cheese.jpg")); +//! [4] //! [5] + view.setCacheMode(QGraphicsView::CacheBackground); + view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); +//! [5] //! [6] + view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice")); + view.showMaximized(); + + return app.exec(); +} +//! [6] diff --git a/tests/manual/examples/widgets/touch/pinchzoom/mice.qrc b/tests/manual/examples/widgets/touch/pinchzoom/mice.qrc new file mode 100644 index 0000000000..accdb4d0a6 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/mice.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/" > + <file>images/cheese.jpg</file> + </qresource> +</RCC> diff --git a/tests/manual/examples/widgets/touch/pinchzoom/mouse.cpp b/tests/manual/examples/widgets/touch/pinchzoom/mouse.cpp new file mode 100644 index 0000000000..ae0d497833 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/mouse.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "mouse.h" + +#include <QGraphicsScene> +#include <QPainter> +#include <QRandomGenerator> +#include <QStyleOption> +#include <qmath.h> + +constexpr qreal Pi = M_PI; +constexpr qreal TwoPi = 2 * M_PI; + +static qreal normalizeAngle(qreal angle) +{ + while (angle < 0) + angle += TwoPi; + while (angle > TwoPi) + angle -= TwoPi; + return angle; +} + +//! [0] +Mouse::Mouse() : color(QRandomGenerator::global()->bounded(256), + QRandomGenerator::global()->bounded(256), + QRandomGenerator::global()->bounded(256)) +{ + setTransform(QTransform().rotate(QRandomGenerator::global()->bounded(360 * 16)), true); + startTimer(1000 / 33); +} +//! [0] + +//! [1] +QRectF Mouse::boundingRect() const +{ + qreal adjust = 0.5; + return QRectF(-18 - adjust, -22 - adjust, + 36 + adjust, 60 + adjust); +} +//! [1] + +//! [2] +QPainterPath Mouse::shape() const +{ + QPainterPath path; + path.addRect(-10, -20, 20, 40); + return path; +} +//! [2] + +//! [3] +void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + // Body + painter->setBrush(color); + painter->drawEllipse(-10, -20, 20, 40); + + // Eyes + painter->setBrush(Qt::white); + painter->drawEllipse(-10, -17, 8, 8); + painter->drawEllipse(2, -17, 8, 8); + + // Nose + painter->setBrush(Qt::black); + painter->drawEllipse(QRectF(-2, -22, 4, 4)); + + // Pupils + painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4)); + painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4)); + + // Ears + painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red); + painter->drawEllipse(-17, -12, 16, 16); + painter->drawEllipse(1, -12, 16, 16); + + // Tail + QPainterPath path(QPointF(0, 20)); + path.cubicTo(-5, 22, -5, 22, 0, 25); + path.cubicTo(5, 27, 5, 32, 0, 30); + path.cubicTo(-5, 32, -5, 42, 0, 35); + painter->setBrush(Qt::NoBrush); + painter->drawPath(path); +} +//! [3] + +//! [4] +void Mouse::timerEvent(QTimerEvent *) +{ +//! [4] + // Don't move too far away +//! [5] + QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0)); + if (lineToCenter.length() > 150) { + qreal angleToCenter = std::atan2(lineToCenter.dy(), lineToCenter.dx()); + angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2); + + if (angleToCenter < Pi && angleToCenter > Pi / 4) { + // Rotate left + angle += (angle < -Pi / 2) ? 0.25 : -0.25; + } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) { + // Rotate right + angle += (angle < Pi / 2) ? 0.25 : -0.25; + } + } else if (::sin(angle) < 0) { + angle += 0.25; + } else if (::sin(angle) > 0) { + angle -= 0.25; +//! [5] //! [6] + } +//! [6] + + // Try not to crash with any other mice +//! [7] + QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF() + << mapToScene(0, 0) + << mapToScene(-30, -50) + << mapToScene(30, -50)); + for (QGraphicsItem *item : dangerMice) { + if (item == this) + continue; + + QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0)); + qreal angleToMouse = std::atan2(lineToMouse.dy(), lineToMouse.dx()); + angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2); + + if (angleToMouse >= 0 && angleToMouse < Pi / 2) { + // Rotate right + angle += 0.5; + } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) { + // Rotate left + angle -= 0.5; +//! [7] //! [8] + } +//! [8] //! [9] + } +//! [9] + + // Add some random movement +//! [10] + if (dangerMice.size() > 1 && QRandomGenerator::global()->bounded(10) == 0) { + if (QRandomGenerator::global()->bounded(1)) + angle += QRandomGenerator::global()->bounded(1 / 500.0); + else + angle -= QRandomGenerator::global()->bounded(1 / 500.0); + } +//! [10] + +//! [11] + speed += (-50 + QRandomGenerator::global()->bounded(100)) / 100.0; + + qreal dx = ::sin(angle) * 10; + mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; + + setTransform(QTransform().rotate(dx), true); + setPos(mapToParent(0, -(3 + sin(speed) * 3))); +} +//! [11] diff --git a/tests/manual/examples/widgets/touch/pinchzoom/mouse.h b/tests/manual/examples/widgets/touch/pinchzoom/mouse.h new file mode 100644 index 0000000000..6b3ef98c22 --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/mouse.h @@ -0,0 +1,33 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef MOUSE_H +#define MOUSE_H + +#include <QGraphicsObject> + +//! [0] +class Mouse : public QGraphicsObject +{ + Q_OBJECT + +public: + Mouse(); + + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) override; + +protected: + void timerEvent(QTimerEvent *event) override; + +private: + qreal angle = 0; + qreal speed = 0; + qreal mouseEyeDirection = 0; + QColor color; +}; +//! [0] + +#endif diff --git a/tests/manual/examples/widgets/touch/pinchzoom/pinchzoom.pro b/tests/manual/examples/widgets/touch/pinchzoom/pinchzoom.pro new file mode 100644 index 0000000000..ebbc7ddf1f --- /dev/null +++ b/tests/manual/examples/widgets/touch/pinchzoom/pinchzoom.pro @@ -0,0 +1,16 @@ +QT += widgets + +HEADERS += \ + mouse.h \ + graphicsview.h +SOURCES += \ + main.cpp \ + mouse.cpp \ + graphicsview.cpp + +RESOURCES += \ + mice.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/pinchzoom +INSTALLS += target |