summaryrefslogtreecommitdiffstats
path: root/tests/manual
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-11-19 15:20:05 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-11-25 20:50:30 +0000
commiteaf160c5861eed34410ea28b8725c4a0eb423cc1 (patch)
tree456de3003488b80f6b907cf4298da7d363bd32e0 /tests/manual
parent3c56e33a2793eecad5f98632c165fc2cc90f51e4 (diff)
Add a manual test for cursors in multi-screen/High DPI setups.
Change-Id: I4c0baeaf01f0b3d6162a16ef7fda822f5a4cb1db Task-number: QTBUG-49511 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'tests/manual')
-rw-r--r--tests/manual/qcursor/qcursor.pro2
-rw-r--r--tests/manual/qcursor/qcursorhighdpi/main.cpp321
-rw-r--r--tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro6
3 files changed, 328 insertions, 1 deletions
diff --git a/tests/manual/qcursor/qcursor.pro b/tests/manual/qcursor/qcursor.pro
index af082a4b82..0b5c2b1945 100644
--- a/tests/manual/qcursor/qcursor.pro
+++ b/tests/manual/qcursor/qcursor.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = allcursors grab_override
+SUBDIRS = allcursors grab_override qcursorhighdpi
diff --git a/tests/manual/qcursor/qcursorhighdpi/main.cpp b/tests/manual/qcursor/qcursorhighdpi/main.cpp
new file mode 100644
index 0000000000..fc45ae00d1
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/main.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QAction>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QSharedPointer>
+#include <QToolBar>
+
+#include <QBitmap>
+#include <QCursor>
+#include <QPainter>
+#include <QPixmap>
+
+#include <QDebug>
+#include <QStringList>
+#include <QTextStream>
+
+#if QT_VERSION > 0x050000
+# include <QScreen>
+# include <QWindow>
+# include <private/qhighdpiscaling_p.h>
+# include <qpa/qplatformwindow.h>
+#else
+# define Q_NULLPTR 0
+# define Q_DECL_OVERRIDE
+#endif
+
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+#endif
+
+#include <algorithm>
+#include <iterator>
+
+// High DPI cursor test for testing cursor sizes in multi-screen setups.
+// It creates one widget per screen with a grid of standard cursors,
+// pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2.
+// On the left, there is a ruler with 10 DIP marks.
+// The code is meant to compile with Qt 4 also.
+
+static QString screenInfo(const QWidget *w)
+{
+ QString result;
+ QTextStream str(&result);
+#if QT_VERSION > 0x050000
+ QScreen *screen = Q_NULLPTR;
+ if (const QWindow *window = w->windowHandle())
+ screen = window->screen();
+ if (screen) {
+ str << '"' << screen->name() << "\" " << screen->size().width() << 'x'
+ << screen->size().height() << ", DPR=" << screen->devicePixelRatio()
+ << ", " << screen->logicalDotsPerInchX() << "DPI ";
+ if (QHighDpiScaling::isActive())
+ str << ", factor=" << QHighDpiScaling::factor(screen);
+ else
+ str << ", no scaling";
+ } else {
+ str << "<null>";
+ }
+#else
+ QDesktopWidget *desktop = QApplication::desktop();
+ int screenNumber = desktop->screenNumber(w);
+ str << "Screen #" <<screenNumber << ' ' << desktop->screenGeometry(screenNumber).width()
+ << 'x' << desktop->screenGeometry(screenNumber).height() << " PD: " << w->logicalDpiX() << "DPI";
+#endif
+#ifdef Q_OS_WIN
+ str << ", SM_C_CURSOR: " << GetSystemMetrics(SM_CXCURSOR) << 'x' << GetSystemMetrics(SM_CYCURSOR);
+#endif
+ return result;
+}
+
+// Helpers for painting pixmaps and creating cursors
+static QPixmap paintPixmap(int size, QColor c)
+{
+ QPixmap result(size, size);
+ result.fill(c);
+ QPainter p(&result);
+ p.drawRect(QRect(QPoint(0, 0), result.size() - QSize(1, 1)));
+ p.drawLine(0, 0, size, size);
+ p.drawLine(0, size, size, 0);
+ return result;
+}
+
+static QCursor pixmapCursor(int size)
+{
+ QCursor result(paintPixmap(size, Qt::red), size / 2, size / 2);
+ return result;
+}
+
+static QPair<QBitmap, QBitmap> paintBitmaps(int size)
+{
+ QBitmap bitmap(size, size);
+ bitmap.fill(Qt::color1);
+ QBitmap mask(size, size);
+ mask.fill(Qt::color1);
+ {
+ QPainter mp(&mask);
+ mp.fillRect(QRect(0, 0, size / 2, size / 2), Qt::color0);
+ }
+ return QPair<QBitmap, QBitmap>(bitmap, mask);
+}
+
+static QCursor bitmapCursor(int size)
+{
+ QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(size);
+ return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+
+#if QT_VERSION > 0x050000
+static QCursor pixmapCursorDevicePixelRatio(int size, int dpr)
+{
+ QPixmap pixmap = paintPixmap(dpr * size, Qt::yellow);
+ pixmap.setDevicePixelRatio(dpr);
+ return QCursor(pixmap, size / 2, size / 2);
+}
+
+static QCursor bitmapCursorDevicePixelRatio(int size, int dpr)
+{
+ QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(dpr * size);
+ bitmaps.first.setDevicePixelRatio(dpr);
+ bitmaps.second.setDevicePixelRatio(dpr);
+ return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
+}
+#endif // Qt 5
+
+// Vertical ruler widget with 10 px marks
+class VerticalRuler : public QWidget {
+public:
+ VerticalRuler(QWidget *parent = Q_NULLPTR);
+
+protected:
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+};
+
+VerticalRuler::VerticalRuler(QWidget *parent) : QWidget(parent)
+{
+ const int screenWidth = QApplication::desktop()->screenGeometry(this).width();
+ setFixedWidth(screenWidth / 48); // 1920 pixel monitor ->40
+}
+
+void VerticalRuler::paintEvent(QPaintEvent *)
+{
+ const QSize sizeS(size());
+ const QPoint sizeP(sizeS.width(), sizeS.height());
+ const QPoint center = sizeP / 2;
+ QPainter painter(this);
+ painter.fillRect(QRect(QPoint(0, 0), sizeS), Qt::white);
+ painter.drawLine(center.x(), 0, center.x(), sizeP.y());
+ for (int y = 0; y < sizeP.y(); y += 10)
+ painter.drawLine(center.x() - 5, y, center.x() + 5, y);
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(QWidget *parent = Q_NULLPTR);
+ void updateScreenInfo() { m_screenInfoLabel->setText(screenInfo(this)); }
+
+public slots:
+ void screenChanged() { updateScreenInfo(); }
+
+private:
+ QLabel *m_screenInfoLabel;
+};
+
+static QLabel *createCursorLabel(const QCursor &cursor, const QString &additionalText = QString())
+{
+ QString labelText;
+ QDebug(&labelText).nospace() << cursor.shape();
+#if QT_VERSION > 0x050000
+ labelText.remove(0, labelText.indexOf('(') + 1);
+ labelText.chop(1);
+#endif // Qt 5
+ if (!additionalText.isEmpty())
+ labelText += ' ' + additionalText;
+ QLabel *result = new QLabel(labelText);
+ result->setFrameShape(QFrame::Box);
+ result->setCursor(cursor);
+ return result;
+}
+
+static void addToGrid(QWidget *w, QGridLayout *gridLayout, int columnCount, int &row, int &col)
+{
+ gridLayout->addWidget(w, row, col);
+ if (col >= columnCount) {
+ col = 0;
+ row++;
+ } else {
+ col++;
+ }
+}
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , m_screenInfoLabel(new QLabel)
+{
+ QString title = "Cursors ";
+#if QT_VERSION > 0x050000
+ title += '(' + QGuiApplication::platformName() + ") ";
+#endif
+ title += QT_VERSION_STR;
+ setWindowTitle(title);
+
+ QMenu *fileMenu = menuBar()->addMenu("File");
+ QAction *quitAction = fileMenu->addAction("Quit");
+ quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+ connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+ QToolBar *fileToolBar = addToolBar("File");
+ fileToolBar->addAction(quitAction);
+
+ QWidget *cw = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(cw);
+ hLayout->addWidget(new VerticalRuler(cw));
+ QGridLayout *gridLayout = new QGridLayout;
+ hLayout->addLayout(gridLayout);
+
+ const int columnCount = 5;
+ const int size = 32;
+
+ int row = 0;
+ int col = 0;
+ for (int i = 0; i < Qt::BitmapCursor; ++i)
+ addToGrid(createCursorLabel(QCursor(static_cast<Qt::CursorShape>(i))), gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(QCursor(pixmapCursor(size)),
+ QLatin1String("Plain PX ") + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(bitmapCursor(size),
+ QLatin1String("Plain BM ") + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+#if QT_VERSION > 0x050000
+ addToGrid(createCursorLabel(QCursor(pixmapCursorDevicePixelRatio(size, 2)),
+ "PX with DPR 2 " + QString::number(size)),
+ gridLayout, columnCount, row, col);
+
+ addToGrid(createCursorLabel(QCursor(bitmapCursorDevicePixelRatio(size, 2)),
+ "BM with DPR 2 " + QString::number(size)),
+ gridLayout, columnCount, row, col);
+#endif // Qt 5
+
+ gridLayout->addWidget(m_screenInfoLabel, row + 1, 0, 1, columnCount);
+
+ setCentralWidget(cw);
+}
+
+typedef QSharedPointer<MainWindow> MainWindowPtr;
+typedef QList<MainWindowPtr> MainWindowPtrList;
+
+int main(int argc, char *argv[])
+{
+ QStringList arguments;
+ std::copy(argv + 1, argv + argc, std::back_inserter(arguments));
+
+#if QT_VERSION > 0x050000
+ if (arguments.contains("-s"))
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ else if (arguments.contains("-n"))
+ QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+#endif // Qt 5
+
+ QApplication app(argc, argv);
+
+ MainWindowPtrList windows;
+
+ QDesktopWidget *desktopWidget = app.desktop();
+
+ for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) {
+ MainWindowPtr window(new MainWindow(desktopWidget->screen(s)));
+ const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100);
+ window->move(pos);
+ windows.append(window);
+ window->show();
+ window->updateScreenInfo();
+#if QT_VERSION > 0x050000
+ QObject::connect(window->windowHandle(), &QWindow::screenChanged,
+ window.data(), &MainWindow::updateScreenInfo);
+#endif
+ }
+ return app.exec();
+}
+#include "main.moc"
diff --git a/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
new file mode 100644
index 0000000000..3a8fc25b33
--- /dev/null
+++ b/tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+QT = core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += gui-private core-private widgets
+CONFIG -= app_bundle
+SOURCES += main.cpp
+win32: LIBS += -lUser32