summaryrefslogtreecommitdiffstats
path: root/tests/manual/highdpi/screengadget/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/highdpi/screengadget/main.cpp')
-rw-r--r--tests/manual/highdpi/screengadget/main.cpp219
1 files changed, 219 insertions, 0 deletions
diff --git a/tests/manual/highdpi/screengadget/main.cpp b/tests/manual/highdpi/screengadget/main.cpp
new file mode 100644
index 0000000000..68343a31c5
--- /dev/null
+++ b/tests/manual/highdpi/screengadget/main.cpp
@@ -0,0 +1,219 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtGui>
+#include <QtWidgets>
+
+#include <QtGui/qpa/qplatformscreen.h>
+#include <QtGui/qpa/qplatformwindow.h>
+#include <QtGui/qpa/qplatformcursor.h>
+
+// This test app optionally doubles as a manual test for QScreen::mapToNative()
+// #define TEST_MAP_TO_NATIVE
+
+// ScreenDisplayer based on original impl from qtbase/tests/manual/highdpi
+class ScreenDisplayer : public QWidget
+{
+public:
+ ScreenDisplayer() = default;
+
+ void setTitle() {
+
+ QPoint deviceIndependentPos = pos();
+ QPlatformWindow *platformWindow = windowHandle()->handle();
+ QPoint nativePos = platformWindow->geometry().topLeft();
+
+ QString windowDebug = QString("pos ")
+ + QString("device independent %1 %2 ").arg(deviceIndependentPos.x()).arg(deviceIndependentPos.y())
+ + QString("native %1 %2 ").arg(nativePos.x()).arg(nativePos.y())
+ ;
+
+ setWindowTitle(windowDebug);
+ }
+
+ void updateMapToNative(QPointF pos)
+ {
+#ifdef TEST_MAP_TO_NATIVE
+ mappedToNative = QGuiApplication::mapToNative(QRectF(pos, QPointF(1,1))).topLeft(); // there
+ mappedFromNative = QGuiApplication::mapFromNative(QRectF(mappedToNative, QPointF(1,1))).topLeft(); // and back again
+#endif
+ }
+
+ void timerEvent(QTimerEvent *) override
+ {
+ update();
+ setTitle();
+ }
+
+ void mousePressEvent(QMouseEvent *) override
+ {
+ displayMappedToNativeCursor = true;
+ }
+
+ void mouseMoveEvent(QMouseEvent *e) override
+ {
+ setTitle();
+ updateMapToNative(e->globalPosition());
+ }
+
+ void mouseReleaseEvent(QMouseEvent *) override
+ {
+ }
+
+ void showEvent(QShowEvent *) override
+ {
+ refreshTimer.start(60, this);
+ }
+
+ void hideEvent(QHideEvent *) override
+ {
+ refreshTimer.stop();
+ }
+
+ void paintScreensInRect(QPainter &p, QRect rect, bool native) {
+ p.save();
+
+ QRectF total;
+ const auto screens = QGuiApplication::screens();
+ for (const QScreen *screen : screens)
+ total |= native ? screen->handle()->geometry() : screen->geometry();
+ if (total.isEmpty())
+ return;
+
+ qreal scaleMargin = 0.9;
+ scaleFactor = scaleMargin * qMin(rect.width()/total.width(), rect.height()/total.height());
+
+ // p.fillRect(rect, Qt::black);
+ int margin = 20;
+ p.translate(margin, margin + rect.y());
+ p.scale(scaleFactor, scaleFactor);
+ p.translate(-total.topLeft());
+ p.setPen(QPen(Qt::white, 10));
+ p.setBrush(Qt::gray);
+
+ for (const QScreen *screen : screens) {
+ QRect geometry = native ? screen->handle()->geometry() : screen->geometry();
+ p.drawRect(geometry);
+ QFont f("Courier New");
+ f.setPixelSize(geometry.height() / 16);
+ p.setFont(f);
+
+ if (displayInfo) {
+ QString text = "Name: " + screen->name() + "\n";
+ text += QString("\nGeometry: %1 %2 %3 %4 \n ").arg(geometry.x()).arg(geometry.y()).arg(geometry.width()).arg(geometry.height());
+ p.save();
+ p.translate(20, 0);
+ p.drawText(geometry, Qt::AlignLeft | Qt::AlignVCenter, text);
+ p.restore();
+ }
+ }
+ p.setBrush(QColor(200,220,255,127));
+
+ const auto topLevels = QApplication::topLevelWidgets();
+ for (QWidget *widget : topLevels) {
+ if (!widget->isHidden())
+ p.drawRect(native ? widget->windowHandle()->handle()->geometry() : widget->geometry());
+ }
+
+ QPolygon cursorShape;
+ cursorShape << QPoint(0,0) << QPoint(20, 60)
+ << QPoint(30, 50) << QPoint(60, 80)
+ << QPoint(80, 60) << QPoint(50, 30)
+ << QPoint(60, 20);
+
+ p.save();
+ p.translate(native ? qApp->primaryScreen()->handle()->cursor()->pos() : QCursor::pos());
+ p.drawPolygon(cursorShape);
+ p.restore();
+
+#ifdef TEST_MAP_TO_NATIVE
+ // Draw red "mapped to native" cursor. We expect this
+ // cursor to track the normal blue cursor if everything
+ // works out ok.
+ if (displayMappedToNativeCursor) {
+ p.save();
+ p.setBrush(QColor(230,120,155,127));
+ p.translate(native ? mappedToNative: mappedFromNative);
+ p.drawPolygon(cursorShape);
+ p.restore();
+ }
+#endif
+
+ p.restore();
+ }
+
+ void paintEvent(QPaintEvent *) override
+ {
+ QPainter p(this);
+
+ QRect g = geometry();
+ int halfHeight = g.height() / 2;
+ QRect topHalf = QRect(0, 0, g.width(), halfHeight);
+ QRect bottomHalf = QRect(0, halfHeight, g.width(), halfHeight);
+
+ if (displayDeviceIndependentGeometry)
+ paintScreensInRect(p, topHalf, false);
+ if (displayNativeGeometry)
+ paintScreensInRect(p, bottomHalf, true);
+ }
+
+ bool displayInfo = false;
+ bool displayDeviceIndependentGeometry = true;
+ bool displayNativeGeometry = false;
+private:
+ bool displayMappedToNativeCursor = false;
+ QPointF mappedToNative;
+ QPointF mappedFromNative;
+ qreal scaleFactor = 1;
+ QBasicTimer refreshTimer;
+};
+
+class Controller : public QWidget {
+public:
+ Controller(ScreenDisplayer *displayer) {
+ setWindowTitle("Controller");
+
+ QVBoxLayout *layout = new QVBoxLayout();
+ setLayout(layout);
+
+ layout->addWidget(new QLabel("Coordinate System:"));
+
+ QCheckBox *deviceIndpendentGeometry = new QCheckBox("Device Independent");
+ deviceIndpendentGeometry->setChecked(true);
+ connect(deviceIndpendentGeometry, &QCheckBox::stateChanged, [displayer](int checked){ displayer->displayDeviceIndependentGeometry = checked > 0; });
+ layout->addWidget(deviceIndpendentGeometry);
+
+ QCheckBox *nativeGeometry = new QCheckBox("Native");
+ nativeGeometry->setChecked(false);
+ connect(nativeGeometry, &QCheckBox::stateChanged, [displayer](int checked){ displayer->displayNativeGeometry = checked > 0; });
+ layout->addWidget(nativeGeometry);
+
+ layout->addSpacing(40);
+
+ QCheckBox *debug = new QCheckBox("Debug!");
+ debug->setChecked(false);
+ connect(debug, &QCheckBox::stateChanged, [displayer](int checked){ displayer->displayInfo = checked > 0; });
+ layout->addWidget(debug);
+
+ layout->addStretch();
+ }
+};
+
+int main(int argc, char **argv) {
+
+ QApplication app(argc, argv);
+
+ ScreenDisplayer displayer;
+ displayer.resize(300, 200);
+ displayer.show();
+
+ Controller controller(&displayer);
+ controller.resize(100, 200);
+
+ QTimer::singleShot(300, [&controller, &displayer](){
+ controller.move(displayer.pos() + QPoint(displayer.width(), 0) + QPoint(50, 0));
+ controller.show();
+ });
+
+ return app.exec();
+}