Support pinch zoom gesture in the Mandelbrot example

Used QGesture for this as per the gesture example.
Moved the help and info text to separate lines.
Enabled word wrap to prevent text going off screen.

As a drive-by, the code to center the window at a size that's a fraction
of the screen is replaced with a simple sizeHint() override. The user
should have control over placement, particularly now that it should be
placed manually onto a touchscreen if the user has one.

Done-with: Shawn Rutledge
Fixes: QTBUG-96702
Pick-to: 6.4
Change-Id: I8dba8b09bed474f585341e9a7a8c71fb60293eee
Reviewed-by: Rami Potinkara <rami.potinkara@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Nicholas Bennett 2022-05-25 11:03:05 +03:00 committed by Rami Potinkara
parent eb9ace1cee
commit fc5482cac6
4 changed files with 59 additions and 15 deletions

View File

@ -303,6 +303,11 @@
\snippet threads/mandelbrot/mandelbrotwidget.cpp 13
Pinch to zoom has been implemented with QGesture as outlined in
\l{Gestures in Widgets and Graphics View}.
\snippet threads/mandelbrot/mandelbrotwidget.cpp gesture1
When the user presses the left mouse button, we store the mouse
pointer position in \c lastDragPos.

View File

@ -37,11 +37,7 @@ int main(int argc, char *argv[])
}
MandelbrotWidget widget;
const auto geometry = widget.screen()->availableGeometry();
widget.resize((2 * geometry.size()) / 3);
const auto pos = (geometry.size() - widget.size()) / 2;
widget.move(geometry.topLeft() + QPoint(pos.width(), pos.height()));
widget.grabGesture(Qt::PinchGesture);
widget.show();
return app.exec();
}

View File

@ -3,8 +3,9 @@
#include "mandelbrotwidget.h"
#include <QPainter>
#include <QGesture>
#include <QKeyEvent>
#include <QPainter>
#include <math.h>
@ -26,8 +27,7 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent) :
pixmapScale(DefaultScale),
curScale(DefaultScale)
{
help = tr("Use mouse wheel or the '+' and '-' keys to zoom. "
"Press and hold left mouse button to scroll.");
help = tr("Zoom with mouse wheel, +/- keys or pinch. Scroll with arrow keys or by dragging.");
connect(&thread, &RenderThread::renderedImage,
this, &MandelbrotWidget::updatePixmap);
@ -46,7 +46,7 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
if (pixmap.isNull()) {
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, tr("Rendering initial image, please wait..."));
painter.drawText(rect(), Qt::AlignCenter|Qt::TextWordWrap, tr("Rendering initial image, please wait..."));
//! [2] //! [3]
return;
//! [3] //! [4]
@ -80,17 +80,31 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
}
//! [8] //! [9]
QString text = help;
if (!info.isEmpty())
text += ' ' + info;
QFontMetrics metrics = painter.fontMetrics();
int textWidth = metrics.horizontalAdvance(text);
if (!info.isEmpty()){
int infoWidth = metrics.horizontalAdvance(info);
int infoHeight = metrics.height();
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 127));
infoHeight = (infoWidth/width()+1) * (infoHeight + 5);
painter.drawRect((width() - infoWidth) / 2 - 5, 0, infoWidth + 10, infoHeight);
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignHCenter|Qt::AlignTop|Qt::TextWordWrap, info);
}
int helpWidth = metrics.horizontalAdvance(help);
int helpHeight = metrics.height();
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 127));
painter.drawRect((width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5);
helpHeight = (helpWidth/width()+1) * (helpHeight + 5);
painter.drawRect((width() - helpWidth) / 2 - 5, height()-helpHeight, helpWidth + 10, helpHeight);
painter.setPen(Qt::white);
painter.drawText((width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text);
painter.drawText(rect(), Qt::AlignHCenter|Qt::AlignBottom|Qt::TextWordWrap, help);
}
//! [9]
@ -211,3 +225,24 @@ void MandelbrotWidget::scroll(int deltaX, int deltaY)
thread.render(centerX, centerY, curScale, size(), devicePixelRatio());
}
//! [18]
//! [gesture1]
#ifndef QT_NO_GESTURES
bool MandelbrotWidget::gestureEvent(QGestureEvent *event)
{
if (auto *pinch = static_cast<QPinchGesture *>(event->gesture(Qt::PinchGesture))) {
if (pinch->changeFlags().testFlag(QPinchGesture::ScaleFactorChanged))
zoom(1.0 / pinch->scaleFactor());
return true;
}
return false;
}
bool MandelbrotWidget::event(QEvent *event)
{
if (event->type() == QEvent::Gesture)
return gestureEvent(static_cast<QGestureEvent*>(event));
return QWidget::event(event);
}
#endif
//! [gesture1]

View File

@ -4,6 +4,7 @@
#ifndef MANDELBROTWIDGET_H
#define MANDELBROTWIDGET_H
#include <QGestureEvent>
#include <QPixmap>
#include <QWidget>
#include "renderthread.h"
@ -18,6 +19,7 @@ public:
MandelbrotWidget(QWidget *parent = nullptr);
protected:
QSize sizeHint() const override { return {1024, 768}; };
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
@ -27,6 +29,9 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
#ifndef QT_NO_GESTURES
bool event(QEvent *event) override;
#endif
private slots:
void updatePixmap(const QImage &image, double scaleFactor);
@ -34,6 +39,9 @@ private slots:
private:
void scroll(int deltaX, int deltaY);
#ifndef QT_NO_GESTURES
bool gestureEvent(QGestureEvent *event);
#endif
RenderThread thread;
QPixmap pixmap;