summaryrefslogtreecommitdiffstats
path: root/tests/manual
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual')
-rw-r--r--tests/manual/cocoa/qt_on_cocoa/main.mm168
-rw-r--r--tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro10
-rw-r--r--tests/manual/cocoa/qt_on_cocoa/rasterwindow.cpp (renamed from tests/manual/cocoa/qt_on_cocoa/window.cpp)37
-rw-r--r--tests/manual/cocoa/qt_on_cocoa/rasterwindow.h (renamed from tests/manual/cocoa/qt_on_cocoa/window.h)7
-rw-r--r--tests/manual/diaglib/eventfilter.cpp9
-rw-r--r--tests/manual/diaglib/textdump.cpp12
-rw-r--r--tests/manual/highdpi/dragwidget.cpp223
-rw-r--r--tests/manual/highdpi/dragwidget.h68
-rw-r--r--tests/manual/highdpi/highdpi.pro13
-rw-r--r--tests/manual/highdpi/highdpi.qrc1
-rw-r--r--tests/manual/highdpi/main.cpp725
-rw-r--r--tests/manual/highdpi/qticon16@3x.pngbin0 -> 5307 bytes
-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
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp7
-rw-r--r--tests/manual/qopenglwidget/openglwidget/main.cpp175
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.cpp23
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.h5
-rw-r--r--tests/manual/qscreen/main.cpp148
-rw-r--r--tests/manual/qscreen/propertywatcher.cpp81
-rw-r--r--tests/manual/qscreen/propertywatcher.h14
-rw-r--r--tests/manual/qscreen/qscreen.pro1
-rw-r--r--tests/manual/qsysinfo/main.cpp1
-rw-r--r--tests/manual/qtabletevent/device_information/tabletwidget.cpp3
-rw-r--r--tests/manual/qtabletevent/device_information/tabletwidget.h1
-rw-r--r--tests/manual/qtabletevent/regular_widgets/main.cpp34
-rw-r--r--tests/manual/touch/main.cpp433
28 files changed, 2182 insertions, 346 deletions
diff --git a/tests/manual/cocoa/qt_on_cocoa/main.mm b/tests/manual/cocoa/qt_on_cocoa/main.mm
index 5dd546479e..23370b0305 100644
--- a/tests/manual/cocoa/qt_on_cocoa/main.mm
+++ b/tests/manual/cocoa/qt_on_cocoa/main.mm
@@ -31,123 +31,35 @@
**
****************************************************************************/
-#include <QtGui>
-#include <QtDeclarative>
+#include "rasterwindow.h"
+#include <QtGui>
#include <QtWidgets/QtWidgets>
-#include <private/qwidgetwindow_p.h>
-#include <QtGui/qpa/qplatformnativeinterface.h>
-
-#include <QtGui/QPixmap>
-
-#include "window.h"
#include <Cocoa/Cocoa.h>
-
-@interface FilledView : NSView
-{
-
+@interface AppDelegate : NSObject <NSApplicationDelegate> {
+ QGuiApplication *m_app;
+ QWindow *m_window;
}
+- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv;
+- (void) applicationWillFinishLaunching: (NSNotification *)notification;
+- (void)applicationWillTerminate:(NSNotification *)notification;
@end
-@implementation FilledView
-
-- (void)drawRect:(NSRect)dirtyRect {
- // set any NSColor for filling, say white:
- [[NSColor redColor] setFill];
- NSRectFill(dirtyRect);
-}
-
-@end
-
-@interface QtMacToolbarDelegate : NSObject <NSToolbarDelegate>
+@implementation AppDelegate
+- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv
{
-@public
- NSToolbar *toolbar;
-}
-
-- (id)init;
-- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted;
-- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)tb;
-- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
-- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;
-@end
-
-@implementation QtMacToolbarDelegate
-
-- (id)init
-{
- self = [super init];
- if (self) {
- }
+ m_app = new QGuiApplication(argc, const_cast<char **>(argv));
return self;
}
-- (void)dealloc
-{
- [super dealloc];
-}
-
-- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)tb
-{
- Q_UNUSED(tb);
- NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
-// [array addObject : NSToolbarPrintItemIdentifier];
-// [array addObject : NSToolbarShowColorsItemIdentifier];
- [array addObject : @"filledView"];
- return array;
-}
-
-- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)tb
-{
- Q_UNUSED(tb);
- NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
-// [array addObject : NSToolbarPrintItemIdentifier];
-// [array addObject : NSToolbarShowColorsItemIdentifier];
- [array addObject : @"filledView"];
- return array;
-}
-
-- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)tb
-{
- Q_UNUSED(tb);
- NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
- return array;
-}
-
-- (IBAction)itemClicked:(id)sender
+- (void) applicationWillFinishLaunching: (NSNotification *)notification
{
+ Q_UNUSED(notification);
-}
-
-- (NSToolbarItem *) toolbar: (NSToolbar *)tb itemForItemIdentifier: (NSString *) itemIdentifier willBeInsertedIntoToolbar:(BOOL) willBeInserted
-{
- Q_UNUSED(tb);
- Q_UNUSED(willBeInserted);
- //const QString identifier = toQString(itemIdentifier);
- //NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];
- //return toolbarItem;
-
- //NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];
- NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];
- FilledView *theView = [[FilledView alloc] init];
- [toolbarItem setView : theView];
- [toolbarItem setMinSize : NSMakeSize(400, 40)];
- [toolbarItem setMaxSize : NSMakeSize(4000, 40)];
- return toolbarItem;
-}
-@end
-
-@interface WindowAndViewAndQtCreator : NSObject {}
-- (void)createWindowAndViewAndQt;
-@end
-
-@implementation WindowAndViewAndQtCreator
-- (void)createWindowAndViewAndQt {
-
- // Create the window
+ // Create the NSWindow
NSRect frame = NSMakeRect(500, 500, 500, 500);
NSWindow* window = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
@@ -156,49 +68,31 @@
NSString *title = @"This the NSWindow window";
[window setTitle:title];
-
[window setBackgroundColor:[NSColor blueColor]];
- // Create a tool bar, set Qt delegate
- NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier : @"foobartoolbar"];
- QtMacToolbarDelegate *delegate = [[QtMacToolbarDelegate alloc] init];
- [toolbar setDelegate : delegate];
- [window setToolbar : toolbar];
-
- // Create the QWindow, don't show it.
- Window *qtWindow = new Window();
- qtWindow->create();
-
- //QSGView *qtWindow = new QSGView();
- //qtWindow->setSource(QUrl::fromLocalFile("/Users/msorvig/code/qt5/qtdeclarative/examples/declarative/samegame/samegame.qml"));
- // qtWindow->setWindowFlags(Qt::WindowType(13)); // 13: NativeEmbeddedWindow
-
- // Get the nsview from the QWindow, set it as the content view
- // on the NSWindow created above.
- QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
- NSView *qtView = (NSView *)platformNativeInterface->nativeResourceForWindow("nsview", qtWindow);
- [window setContentView:qtView];
+ // Create the QWindow, use its NSView as the content view
+ m_window = new RasterWindow();
+ [window setContentView:reinterpret_cast<NSView *>(m_window->winId())];
+
+ // Show the NSWindow
[window makeKeyAndOrderFront:NSApp];
}
-@end
-int main(int argc, char *argv[])
+- (void)applicationWillTerminate:(NSNotification *)notification
{
- QGuiApplication app(argc, argv);
-
- // fake NSApplicationMain() implementation follows:
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication];
+ Q_UNUSED(notification);
+ delete m_window;
+ delete m_app;
+}
- // schedule call to create the UI.
- WindowAndViewAndQtCreator *windowAndViewAndQtCreator= [WindowAndViewAndQtCreator alloc];
- [NSTimer scheduledTimerWithTimeInterval:0 target:windowAndViewAndQtCreator selector:@selector(createWindowAndViewAndQt) userInfo:nil repeats:NO];
+@end
- [(NSApplication *)NSApp run];
- [NSApp release];
- [pool release];
- exit(0);
- return 0;
+int main(int argc, const char *argv[])
+{
+ // Create NSApplicaiton with delgate
+ NSApplication *app =[NSApplication sharedApplication];
+ app.delegate = [[AppDelegate alloc] initWithArgc:argc argv:argv];
+ return NSApplicationMain (argc, argv);
}
diff --git a/tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro b/tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro
index 3d526909a5..97e4473e15 100644
--- a/tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro
+++ b/tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro
@@ -1,13 +1,11 @@
TEMPLATE = app
OBJECTIVE_SOURCES += main.mm
-HEADERS += window.h
-SOURCES += window.cpp
+HEADERS += rasterwindow.h
+SOURCES += rasterwindow.cpp
LIBS += -framework Cocoa
-QMAKE_INFO_PLIST = Info_mac.plist
-OTHER_FILES = Info_mac.plist
-QT += gui widgets widgets-private gui-private core-private
+QT += gui widgets quick
-QT += declarative
+QT += quick
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/manual/cocoa/qt_on_cocoa/window.cpp b/tests/manual/cocoa/qt_on_cocoa/rasterwindow.cpp
index 9929a50065..9b8f5e63ce 100644
--- a/tests/manual/cocoa/qt_on_cocoa/window.cpp
+++ b/tests/manual/cocoa/qt_on_cocoa/rasterwindow.cpp
@@ -31,9 +31,9 @@
**
****************************************************************************/
-#include "window.h"
+#include "rasterwindow.h"
-#include <private/qguiapplication_p.h>
+//#include <private/qguiapplication_p.h>
#include <QBackingStore>
#include <QPainter>
@@ -48,21 +48,14 @@ QColor colorTable[] =
QColor("#c0ef8f")
};
-Window::Window(QScreen *screen)
- : QWindow(screen)
+RasterWindow::RasterWindow(QRasterWindow *parent)
+ : QRasterWindow(parent)
, m_backgroundColorIndex(colorIndexId++)
{
initialize();
}
-Window::Window(QWindow *parent)
- : QWindow(parent)
- , m_backgroundColorIndex(colorIndexId++)
-{
- initialize();
-}
-
-void Window::initialize()
+void RasterWindow::initialize()
{
if (parent())
setGeometry(QRect(160, 120, 320, 240));
@@ -85,12 +78,12 @@ void Window::initialize()
m_renderTimer = 0;
}
-void Window::mousePressEvent(QMouseEvent *event)
+void RasterWindow::mousePressEvent(QMouseEvent *event)
{
m_lastPos = event->pos();
}
-void Window::mouseMoveEvent(QMouseEvent *event)
+void RasterWindow::mouseMoveEvent(QMouseEvent *event)
{
if (m_lastPos != QPoint(-1, -1)) {
QPainter p(&m_image);
@@ -102,7 +95,7 @@ void Window::mouseMoveEvent(QMouseEvent *event)
scheduleRender();
}
-void Window::mouseReleaseEvent(QMouseEvent *event)
+void RasterWindow::mouseReleaseEvent(QMouseEvent *event)
{
if (m_lastPos != QPoint(-1, -1)) {
QPainter p(&m_image);
@@ -114,16 +107,16 @@ void Window::mouseReleaseEvent(QMouseEvent *event)
scheduleRender();
}
-void Window::exposeEvent(QExposeEvent *)
+void RasterWindow::exposeEvent(QExposeEvent *)
{
scheduleRender();
}
-void Window::resizeEvent(QResizeEvent *)
+void RasterWindow::resizeEvent(QResizeEvent *)
{
QImage old = m_image;
- //qDebug() << "Window::resizeEvent" << width << height;
+ //qDebug() << "RasterWindow::resizeEvent" << width << height;
int width = qMax(geometry().width(), old.width());
int height = qMax(geometry().height(), old.height());
@@ -139,7 +132,7 @@ void Window::resizeEvent(QResizeEvent *)
render();
}
-void Window::keyPressEvent(QKeyEvent *event)
+void RasterWindow::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Backspace:
@@ -156,20 +149,20 @@ void Window::keyPressEvent(QKeyEvent *event)
scheduleRender();
}
-void Window::scheduleRender()
+void RasterWindow::scheduleRender()
{
if (!m_renderTimer)
m_renderTimer = startTimer(1);
}
-void Window::timerEvent(QTimerEvent *)
+void RasterWindow::timerEvent(QTimerEvent *)
{
render();
killTimer(m_renderTimer);
m_renderTimer = 0;
}
-void Window::render()
+void RasterWindow::render()
{
QRect rect(QPoint(), geometry().size());
diff --git a/tests/manual/cocoa/qt_on_cocoa/window.h b/tests/manual/cocoa/qt_on_cocoa/rasterwindow.h
index a36180e0f3..1de66b5302 100644
--- a/tests/manual/cocoa/qt_on_cocoa/window.h
+++ b/tests/manual/cocoa/qt_on_cocoa/rasterwindow.h
@@ -31,14 +31,13 @@
**
****************************************************************************/
-#include <QWindow>
+#include <QRasterWindow>
#include <QImage>
-class Window : public QWindow
+class RasterWindow : public QRasterWindow
{
public:
- Window(QWindow *parent = 0);
- Window(QScreen *screen);
+ RasterWindow(QRasterWindow *parent = 0);
protected:
void mousePressEvent(QMouseEvent *);
diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp
index b35d29cc8a..6df885ebb6 100644
--- a/tests/manual/diaglib/eventfilter.cpp
+++ b/tests/manual/diaglib/eventfilter.cpp
@@ -190,8 +190,13 @@ static void formatApplicationState(QDebug debug)
debug << "\n QGuiApplication::modalWindow = ";
formatObject(mw, debug);
}
- debug << "\n QGuiApplication::focusWindow = ";
- formatObject(QGuiApplication::focusWindow(), debug);
+ const QObject *focusObject = QGuiApplication::focusObject();
+ const QObject *focusWindow = QGuiApplication::focusWindow();
+ debug << "\n QGuiApplication::focusObject = ";
+ formatObject(focusObject, debug);
+ if (focusWindow && focusWindow != focusObject)
+ debug << "\n QGuiApplication::focusWindow = ";
+ formatObject(focusWindow, debug);
#endif // HAVE_GUI_APPLICATION
}
diff --git a/tests/manual/diaglib/textdump.cpp b/tests/manual/diaglib/textdump.cpp
index ed4d5021be..0f69166a43 100644
--- a/tests/manual/diaglib/textdump.cpp
+++ b/tests/manual/diaglib/textdump.cpp
@@ -248,6 +248,15 @@ static const EnumLookup scriptEnumLookup[] =
{QChar::Script_Tirhuta, "Script_Tirhuta"},
{QChar::Script_WarangCiti, "Script_WarangCiti"},
#endif // Qt 5.5
+
+#if QT_VERSION >= 0x050600
+ {QChar::Script_Ahom, "Script_Ahom"},
+ {QChar::Script_AnatolianHieroglyphs, "Script_AnatolianHieroglyphs"},
+ {QChar::Script_Hatran, "Script_Hatran"},
+ {QChar::Script_Multani, "Script_Multani"},
+ {QChar::Script_OldHungarian, "Script_OldHungarian"},
+ {QChar::Script_SignWriting, "Script_SignWriting"},
+#endif // Qt 5.5
};
#endif // Qt 5.1
@@ -364,6 +373,9 @@ static const EnumLookup unicodeVersionEnumLookup[] =
#if QT_VERSION >= 0x050500
{QChar::Unicode_7_0, "Unicode_7_0"},
#endif // Qt 5.5
+#if QT_VERSION >= 0x050600
+ {QChar::Unicode_8_0, "Unicode_8_0"},
+#endif // Qt 5.6
#endif // Qt 5
};
diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp
new file mode 100644
index 0000000000..b203566696
--- /dev/null
+++ b/tests/manual/highdpi/dragwidget.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+ **
+ ** 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 <QtWidgets>
+#include "dragwidget.h"
+
+class FramedLabel : public QLabel
+{
+public:
+ FramedLabel(const QString &text, QWidget *parent)
+ : QLabel(text, parent)
+ {
+ setAutoFillBackground(true);
+ setFrameShape(QFrame::Panel);
+ setFrameShadow(QFrame::Raised);
+ }
+};
+
+DragWidget::DragWidget(QString text, QWidget *parent)
+ : QWidget(parent), otherWindow(0)
+{
+ int x = 5;
+ int y = 5;
+
+ bool createChildWindow = text.isEmpty(); // OK, yes this is a hack...
+ if (text.isEmpty())
+ text = "You can drag from this window and drop text here";
+
+ QStringList words = text.split(' ');
+ foreach (QString word, words) {
+ if (!word.isEmpty()) {
+ FramedLabel *wordLabel = new FramedLabel(word, this);
+ wordLabel->move(x, y);
+ wordLabel->show();
+ x += wordLabel->width() + 2;
+ if (x >= 245) {
+ x = 5;
+ y += wordLabel->height() + 2;
+ }
+ }
+ }
+
+ /*
+ QPalette newPalette = palette();
+ newPalette.setColor(QPalette::Window, Qt::white);
+ setPalette(newPalette);
+ */
+
+ setAcceptDrops(true);
+ setMinimumSize(400, qMax(200, y));
+ setWindowTitle(tr("Draggable Text Window %1").arg(createChildWindow ? 1 : 2));
+ if (createChildWindow)
+ otherWindow = new DragWidget("Here is a second window that accepts drops");
+}
+
+void DragWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasText()) {
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+ } else {
+ event->ignore();
+ }
+}
+
+void DragWidget::dragMoveEvent(QDragMoveEvent * event)
+{
+ dragPos = event->pos();
+ dragTimer.start(500, this);
+ update();
+}
+
+void DragWidget::dragLeaveEvent(QDragLeaveEvent *)
+{
+ dragTimer.stop();
+ update();
+}
+
+
+void DragWidget::dropEvent(QDropEvent *event)
+{
+ if (event->mimeData()->hasText()) {
+ const QMimeData *mime = event->mimeData();
+ QStringList pieces = mime->text().split(QRegExp("\\s+"),
+ QString::SkipEmptyParts);
+ QPoint position = event->pos();
+ QPoint hotSpot;
+
+ QList<QByteArray> hotSpotPos = mime->data("application/x-hotspot").split(' ');
+ if (hotSpotPos.size() == 2) {
+ hotSpot.setX(hotSpotPos.first().toInt());
+ hotSpot.setY(hotSpotPos.last().toInt());
+ }
+ dropPos = position - hotSpot;
+ dropTimer.start(500, this);
+ update();
+
+ foreach (QString piece, pieces) {
+ FramedLabel *newLabel = new FramedLabel(piece, this);
+ newLabel->move(position - hotSpot);
+ newLabel->show();
+
+ position += QPoint(newLabel->width(), 0);
+ }
+
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+ } else {
+ event->ignore();
+ }
+ foreach (QObject *child, children()) {
+ if (child->inherits("QWidget")) {
+ QWidget *widget = static_cast<QWidget *>(child);
+ if (!widget->isVisible())
+ widget->deleteLater();
+ }
+ }
+}
+
+void DragWidget::mousePressEvent(QMouseEvent *event)
+{
+ QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
+ if (!child)
+ return;
+
+ QPoint hotSpot = event->pos() - child->pos();
+
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setText(child->text());
+ mimeData->setData("application/x-hotspot",
+ QByteArray::number(hotSpot.x()) + " " + QByteArray::number(hotSpot.y()));
+
+ QPixmap pixmap(child->size());
+ child->render(&pixmap);
+
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->setPixmap(pixmap);
+ drag->setHotSpot(hotSpot);
+
+ Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
+
+ if (dropAction == Qt::MoveAction)
+ child->close();
+}
+
+void DragWidget::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == dragTimer.timerId())
+ dragTimer.stop();
+ if (e->timerId() == dropTimer.timerId())
+ dropTimer.stop();
+ update();
+}
+
+void DragWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ p.fillRect(rect(), Qt::white);
+
+ if (dropTimer.isActive()) {
+ p.setBrush(Qt::red);
+ p.drawEllipse(dropPos, 50, 50);
+ }
+
+ if (dragTimer.isActive()) {
+ p.setPen(QPen(Qt::blue, 5));
+ QPoint p1 = (rect().topLeft()*3 + rect().bottomRight())/4;
+ QPoint p2 = (rect().topLeft() + rect().bottomRight()*3)/4;
+ p.drawLine(p1, dragPos);
+ p.drawLine(p2, dragPos);
+ }
+}
+
+void DragWidget::showEvent(QShowEvent *)
+{
+ if (otherWindow)
+ otherWindow->show();
+}
+
+void DragWidget::hideEvent(QHideEvent *)
+{
+ if (otherWindow)
+ otherWindow->hide();
+}
diff --git a/tests/manual/highdpi/dragwidget.h b/tests/manual/highdpi/dragwidget.h
new file mode 100644
index 0000000000..0d9631e2f8
--- /dev/null
+++ b/tests/manual/highdpi/dragwidget.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ **
+ ** 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$
+ **
+ ****************************************************************************/
+
+#ifndef DRAGWIDGET_H
+#define DRAGWIDGET_H
+
+#include <QWidget>
+#include <QBasicTimer>
+
+QT_BEGIN_NAMESPACE
+class QDragEnterEvent;
+class QDropEvent;
+QT_END_NAMESPACE
+
+class DragWidget : public QWidget
+{
+public:
+ DragWidget(QString text = QString(), QWidget *parent = 0);
+
+protected:
+ void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
+ void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
+ void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void dragMoveEvent(QDragMoveEvent * event) Q_DECL_OVERRIDE;
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+ void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
+ void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE;
+private:
+ QPoint dragPos;
+ QPoint dropPos;
+ QBasicTimer dragTimer;
+ QBasicTimer dropTimer;
+ QWidget *otherWindow;
+};
+
+#endif // DRAGWIDGET_H
diff --git a/tests/manual/highdpi/highdpi.pro b/tests/manual/highdpi/highdpi.pro
index 7a2979c74c..7d6b42535e 100644
--- a/tests/manual/highdpi/highdpi.pro
+++ b/tests/manual/highdpi/highdpi.pro
@@ -1,10 +1,17 @@
TEMPLATE = app
TARGET = highdpi
INCLUDEPATH += .
-QT += widgets
-CONFIG+=console
+QT += widgets gui-private
+CONFIG +=console
+CONFIG -= app_bundle
+CONFIG += c++11
# Input
-SOURCES += main.cpp
+SOURCES += \
+ dragwidget.cpp \
+ main.cpp
+
+HEADERS += \
+ dragwidget.h
RESOURCES += \
highdpi.qrc
diff --git a/tests/manual/highdpi/highdpi.qrc b/tests/manual/highdpi/highdpi.qrc
index 10efac44fa..0e33ed33d7 100644
--- a/tests/manual/highdpi/highdpi.qrc
+++ b/tests/manual/highdpi/highdpi.qrc
@@ -2,6 +2,7 @@
<qresource prefix="/">
<file>qticon16.png</file>
<file>qticon16@2x.png</file>
+ <file>qticon16@3x.png</file>
<file>qticon32.png</file>
<file>qticon32@2x.png</file>
<file>qticon64.png</file>
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp
index fd14523a97..692a60d511 100644
--- a/tests/manual/highdpi/main.cpp
+++ b/tests/manual/highdpi/main.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include <QMainWindow>
+#include <QMenuBar>
#include <QLabel>
#include <QHBoxLayout>
#include <QApplication>
@@ -39,6 +40,7 @@
#include <QStyle>
#include <QToolBar>
#include <QPushButton>
+#include <QButtonGroup>
#include <QLineEdit>
#include <QScrollBar>
#include <QSlider>
@@ -49,10 +51,219 @@
#include <QWindow>
#include <QScreen>
#include <QFile>
+#include <QMouseEvent>
#include <QTemporaryDir>
+#include <QTimer>
#include <QCommandLineParser>
#include <QCommandLineOption>
+#include <QDebug>
+#include <private/qhighdpiscaling_p.h>
+#include "dragwidget.h"
+
+class DemoContainerBase
+{
+public:
+ DemoContainerBase() : m_widget(0) {}
+ virtual ~DemoContainerBase() {}
+ QString name() { return option().names().first(); }
+ virtual QCommandLineOption &option() = 0;
+ virtual void makeVisible(bool visible, QWidget *parent) = 0;
+ QWidget *widget() { return m_widget; }
+protected:
+ QWidget *m_widget;
+};
+
+typedef QList<DemoContainerBase*> DemoContainerList ;
+
+
+template <class T>
+class DemoContainer : public DemoContainerBase
+{
+public:
+ DemoContainer(const QString &optionName, const QString &description)
+ : m_option(optionName, description)
+ {
+ }
+ ~DemoContainer() { delete m_widget; }
+
+ QCommandLineOption &option() { return m_option; }
+
+ void makeVisible(bool visible, QWidget *parent) {
+ if (visible && !m_widget) {
+ m_widget = new T;
+ m_widget->installEventFilter(parent);
+ }
+ if (m_widget)
+ m_widget->setVisible(visible);
+ }
+private:
+ QCommandLineOption m_option;
+};
+
+class LabelSlider : public QObject
+{
+Q_OBJECT
+public:
+ LabelSlider(QObject *parent, const QString &text, QGridLayout *layout, int row)
+ : QObject(parent)
+ {
+ QLabel *textLabel = new QLabel(text);
+ m_slider = new QSlider();
+ m_slider->setOrientation(Qt::Horizontal);
+ m_slider->setMinimum(1);
+ m_slider->setMaximum(40);
+ m_slider->setValue(10);
+ m_slider->setTracking(false);
+ m_slider->setTickInterval(5);
+ m_slider->setTickPosition(QSlider::TicksBelow);
+ m_label = new QLabel("1.0");
+
+ // set up layouts
+ layout->addWidget(textLabel, row, 0);
+ layout->addWidget(m_slider, row, 1);
+ layout->addWidget(m_label, row, 2);
+
+ // handle slider position change
+ connect(m_slider, &QSlider::sliderMoved, this, &LabelSlider::updateLabel);
+ connect(m_slider, &QSlider::valueChanged, this, &LabelSlider::valueChanged);
+ }
+ void setValue(int scaleFactor) {
+ m_slider->setValue(scaleFactor);
+ updateLabel(scaleFactor);
+ }
+private slots:
+ void updateLabel(int scaleFactor) {
+ // slider value is scale factor times ten;
+ qreal scalefactorF = qreal(scaleFactor) / 10.0;
+
+ // update label, add ".0" if needed.
+ QString number = QString::number(scalefactorF);
+ if (!number.contains("."))
+ number.append(".0");
+ m_label->setText(number);
+ }
+signals:
+ void valueChanged(int scaleFactor);
+private:
+ QSlider *m_slider;
+ QLabel *m_label;
+};
+
+static qreal getScreenFactorWithoutPixelDensity(const QScreen *screen)
+{
+ // this is a hack that relies on knowing the internals of QHighDpiScaling
+ static const char *scaleFactorProperty = "_q_scaleFactor";
+ QVariant screenFactor = screen->property(scaleFactorProperty);
+ return screenFactor.isValid() ? screenFactor.toReal() : 1.0;
+}
+
+static inline qreal getGlobalScaleFactor()
+{
+ QScreen *noScreen = 0;
+ return QHighDpiScaling::factor(noScreen);
+}
+
+class DemoController : public QWidget
+{
+Q_OBJECT
+public:
+ DemoController(DemoContainerList *demos, QCommandLineParser *parser);
+ ~DemoController();
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+ void closeEvent(QCloseEvent *) { qApp->quit(); }
+private slots:
+ void handleButton(int id, bool toggled);
+private:
+ DemoContainerList *m_demos;
+ QButtonGroup *m_group;
+};
+
+DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *parser)
+ : m_demos(demos)
+{
+ setWindowTitle("screen scale factors");
+ setObjectName("controller"); // make WindowScaleFactorSetter skip this window
+
+ QGridLayout *layout = new QGridLayout;
+ setLayout(layout);
+
+ int layoutRow = 0;
+ LabelSlider *globalScaleSlider = new LabelSlider(this, "Global scale factor", layout, layoutRow++);
+ globalScaleSlider->setValue(int(getGlobalScaleFactor() * 10));
+ connect(globalScaleSlider, &LabelSlider::valueChanged, [](int scaleFactor){
+ // slider value is scale factor times ten;
+ qreal scalefactorF = qreal(scaleFactor) / 10.0;
+ QHighDpiScaling::setGlobalFactor(scalefactorF);
+ });
+
+ // set up one scale control line per screen
+ QList<QScreen *> screens = QGuiApplication::screens();
+ foreach (QScreen *screen, screens) {
+ // create scale control line
+ QSize screenSize = screen->geometry().size();
+ QString screenId = screen->name() + " " + QString::number(screenSize.width())
+ + " " + QString::number(screenSize.height());
+ LabelSlider *slider = new LabelSlider(this, screenId, layout, layoutRow++);
+ slider->setValue(getScreenFactorWithoutPixelDensity(screen) * 10);
+
+ // handle slider value change
+ connect(slider, &LabelSlider::valueChanged, [screen](int scaleFactor){
+ // slider value is scale factor times ten;
+ qreal scalefactorF = qreal(scaleFactor) / 10.0;
+
+ // set scale factor for screen
+ qreal oldFactor = QHighDpiScaling::factor(screen);
+ QHighDpiScaling::setScreenFactor(screen, scalefactorF);
+ qreal newFactor = QHighDpiScaling::factor(screen);
+
+ qDebug() << "factor was / is" << oldFactor << newFactor;
+ });
+ }
+
+ m_group = new QButtonGroup(this);
+ m_group->setExclusive(false);
+
+ for (int i = 0; i < m_demos->size(); ++i) {
+ DemoContainerBase *demo = m_demos->at(i);
+ QPushButton *button = new QPushButton(demo->name());
+ button->setToolTip(demo->option().description());
+ button->setCheckable(true);
+ layout->addWidget(button, layoutRow++, 0, 1, -1);
+ m_group->addButton(button, i);
+
+ if (parser->isSet(demo->option())) {
+ demo->makeVisible(true, this);
+ button->setChecked(true);
+ }
+ }
+ connect(m_group, SIGNAL(buttonToggled(int, bool)), this, SLOT(handleButton(int, bool)));
+}
+
+DemoController::~DemoController()
+{
+ qDeleteAll(*m_demos);
+}
+
+bool DemoController::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::Close) {
+ for (int i = 0; i < m_demos->size(); ++i) {
+ DemoContainerBase *demo = m_demos->at(i);
+ if (demo->widget() == object) {
+ m_group->button(i)->setChecked(false);
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+void DemoController::handleButton(int id, bool toggled)
+{
+ m_demos->at(id)->makeVisible(toggled, this);
+}
class PixmapPainter : public QWidget
{
@@ -69,7 +280,6 @@ public:
QIcon qtIcon;
};
-
PixmapPainter::PixmapPainter()
{
pixmap1X = QPixmap(":/qticon32.png");
@@ -172,15 +382,18 @@ class MainWindow : public QMainWindow
{
public:
MainWindow();
+ QMenu *addNewMenu(const QString &title, int itemCount = 5);
QIcon qtIcon;
QIcon qtIcon1x;
QIcon qtIcon2x;
QToolBar *fileToolBar;
+ int menuCount;
};
MainWindow::MainWindow()
+ :menuCount(0)
{
// beware that QIcon auto-loads the @2x versions.
qtIcon1x.addFile(":/qticon16.png");
@@ -192,8 +405,33 @@ MainWindow::MainWindow()
// fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
fileToolBar->addAction(new QAction(qtIcon1x, QString("1x"), this));
fileToolBar->addAction(new QAction(qtIcon2x, QString("2x"), this));
+ addNewMenu("&Edit");
+ addNewMenu("&Build");
+ addNewMenu("&Debug", 4);
+ addNewMenu("&Transmogrify", 7);
+ addNewMenu("T&ools");
+ addNewMenu("&Help", 2);
}
+
+QMenu *MainWindow::addNewMenu(const QString &title, int itemCount)
+{
+ QMenu *menu = menuBar()->addMenu(title);
+ for (int i = 0; i < itemCount; i++) {
+ menuCount++;
+ QString s = "Menu item " + QString::number(menuCount);
+ if (i == 3) {
+ QMenu *subMenu = menu->addMenu(s);
+ for (int j = 1; j < 4; j++)
+ subMenu->addAction(QString::fromLatin1("SubMenu item %1.%2").arg(menuCount).arg(j));
+ } else {
+ menu->addAction(s);
+ }
+ }
+ return menu;
+}
+
+
class StandardIcons : public QWidget
{
public:
@@ -205,7 +443,7 @@ public:
int dy = 50;
int maxX = 500;
- for (int iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) {
+ for (uint iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) {
QIcon icon = qApp->style()->standardIcon(QStyle::StandardPixmap(iconIndex));
QPainter p(this);
p.drawPixmap(x, y, icon.pixmap(dx - 5, dy - 5));
@@ -295,14 +533,27 @@ public:
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
- int y = 40;
- for (int fontSize = 2; fontSize < 18; fontSize += 2) {
+
+ // Points
+ int y = 10;
+ for (int fontSize = 6; fontSize < 18; fontSize += 2) {
QFont font;
font.setPointSize(fontSize);
- QString string = QString(QStringLiteral("%1 The quick brown fox jumped over the lazy Doug.")).arg(fontSize);
+ QString string = QString(QStringLiteral("This text is in point size %1")).arg(fontSize);
+ painter.setFont(font);
+ y += (painter.fontMetrics().lineSpacing());
+ painter.drawText(10, y, string);
+ }
+
+ // Pixels
+ y += painter.fontMetrics().lineSpacing();
+ for (int fontSize = 6; fontSize < 18; fontSize += 2) {
+ QFont font;
+ font.setPixelSize(fontSize);
+ QString string = QString(QStringLiteral("This text is in pixel size %1")).arg(fontSize);
painter.setFont(font);
+ y += (painter.fontMetrics().lineSpacing());
painter.drawText(10, y, string);
- y += (fontSize * 2.5);
}
}
};
@@ -461,97 +712,427 @@ public:
}
};
+class LinePainter : public QWidget
+{
+public:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+
+ QPoint lastMousePoint;
+ QVector<QPoint> linePoints;
+};
-int main(int argc, char **argv)
+void LinePainter::paintEvent(QPaintEvent *)
{
- QApplication app(argc, argv);
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QPainter p(this);
+ p.fillRect(QRect(QPoint(0, 0), size()), QBrush(Qt::gray));
- QCommandLineParser parser;
- parser.setApplicationDescription("High DPI tester");
- parser.addHelpOption();
- parser.addVersionOption();
- QCommandLineOption pixmapPainterOption("pixmap", "Test pixmap painter");
- parser.addOption(pixmapPainterOption);
- QCommandLineOption labelOption("label", "Test Labels");
- parser.addOption(labelOption);
- QCommandLineOption mainWindowOption("mainwindow", "Test QMainWindow");
- parser.addOption(mainWindowOption);
- QCommandLineOption standardIconsOption("standard-icons", "Test standard icons");
- parser.addOption(standardIconsOption);
- QCommandLineOption cachingOption("caching", "Test caching");
- parser.addOption(cachingOption);
- QCommandLineOption styleOption("styles", "Test style");
- parser.addOption(styleOption);
- QCommandLineOption fontsOption("fonts", "Test fonts");
- parser.addOption(fontsOption);
- QCommandLineOption iconDrawingOption("icondrawing", "Test icon drawing");
- parser.addOption(iconDrawingOption);
- QCommandLineOption buttonsOption("buttons", "Test buttons");
- parser.addOption(buttonsOption);
+ // Default antialiased line
+ p.setRenderHint(QPainter::Antialiasing);
+ p.drawLines(linePoints);
+
+ // Cosmetic 1 antialiased line
+ QPen pen;
+ pen.setCosmetic(true);
+ pen.setWidth(1);
+ p.setPen(pen);
+ p.translate(3, 3);
+ p.drawLines(linePoints);
+
+ // Aliased cosmetic 1 line
+ p.setRenderHint(QPainter::Antialiasing, false);
+ p.translate(3, 3);
+ p.drawLines(linePoints);
+}
- parser.process(app);
+void LinePainter::mousePressEvent(QMouseEvent *event)
+{
+ lastMousePoint = event->pos();
+}
- QScopedPointer<PixmapPainter> pixmapPainter;
- if (parser.isSet(pixmapPainterOption)) {
- pixmapPainter.reset(new PixmapPainter);
- pixmapPainter->show();
+void LinePainter::mouseReleaseEvent(QMouseEvent *)
+{
+ lastMousePoint = QPoint();
+}
+
+void LinePainter::mouseMoveEvent(QMouseEvent *event)
+{
+ if (lastMousePoint.isNull())
+ return;
+
+ QPoint newMousePoint = event->pos();
+ if (lastMousePoint == newMousePoint)
+ return;
+ linePoints.append(lastMousePoint);
+ linePoints.append(newMousePoint);
+ lastMousePoint = newMousePoint;
+ update();
+}
+
+class CursorTester : public QWidget
+{
+public:
+ CursorTester()
+ :moveLabel(0), moving(false)
+ {
}
- QScopedPointer<Labels> label;
- if (parser.isSet(labelOption)) {
- label.reset(new Labels);
- label->resize(200, 200);
- label->show();
+ inline QRect getRect(int idx) const
+ {
+ int h = height() / 2;
+ return QRect(10, 10 + h * (idx - 1), width() - 20, h - 20);
+ }
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter p(this);
+ QRect r1 = getRect(1);
+ QRect r2 = getRect(2);
+ p.fillRect(r1, QColor(200, 200, 250));
+ p.drawText(r1, "Drag from here to move a window based on QCursor::pos()");
+ p.fillRect(r2, QColor(250, 200, 200));
+ p.drawText(r2, "Drag from here to move a window based on mouse event position");
+
+ if (moving) {
+ p.setPen(Qt::darkGray);
+ QFont f = font();
+ f.setPointSize(8);
+ p.setFont(f);
+ p.drawEllipse(mousePos, 30,60);
+ QPoint pt = mousePos - QPoint(0, 60);
+ QPoint pt2 = pt - QPoint(30,10);
+ QPoint offs(30, 0);
+ p.drawLine(pt, pt2);
+ p.drawLine(pt2 - offs, pt2 + offs);
+ p.drawText(pt2 - offs, "mouse pos");
+
+ p.setPen(QColor(50,130,70));
+ QPoint cursorPos = mapFromGlobal(QCursor::pos());
+ pt = cursorPos - QPoint(0, 30);
+ pt2 = pt + QPoint(60, -20);
+ p.drawEllipse(cursorPos, 60, 30);
+ p.drawLine(pt, pt2);
+ p.drawLine(pt2 - offs, pt2 + offs);
+ p.drawText(pt2 - offs, "cursor pos");
+ }
}
- QScopedPointer<MainWindow> mainWindow;
- if (parser.isSet(mainWindowOption)) {
- mainWindow.reset(new MainWindow);
- mainWindow->show();
+ void mousePressEvent(QMouseEvent *e)
+ {
+ if (moving)
+ return;
+ QRect r1 = getRect(1);
+ QRect r2 = getRect(2);
+
+ moving = r1.contains(e->pos()) || r2.contains(e->pos());
+ if (!moving)
+ return;
+ useCursorPos = r1.contains(e->pos());
+
+ if (!moveLabel)
+ moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window );
+
+ if (useCursorPos)
+ moveLabel->setText("I'm following QCursor::pos()");
+ else
+ moveLabel->setText("I'm following QMouseEvent::globalPos()");
+ moveLabel->adjustSize();
+ mouseMoveEvent(e);
+ moveLabel->show();
}
- QScopedPointer<StandardIcons> icons;
- if (parser.isSet(standardIconsOption)) {
- icons.reset(new StandardIcons);
- icons->resize(510, 510);
- icons->show();
+ void mouseReleaseEvent(QMouseEvent *)
+ {
+ if (moveLabel)
+ moveLabel->hide();
+ update();
+ moving = false;
}
- QScopedPointer<Caching> caching;
- if (parser.isSet(cachingOption)) {
- caching.reset(new Caching);
- caching->resize(300, 300);
- caching->show();
+ void mouseMoveEvent(QMouseEvent *e)
+ {
+ if (!moving)
+ return;
+ QPoint pos = useCursorPos ? QCursor::pos() : e->globalPos();
+ pos -= moveLabel->rect().center();
+ moveLabel->move(pos);
+ mousePos = e->pos();
+ update();
}
- QScopedPointer<Style> style;
- if (parser.isSet(styleOption)) {
- style.reset(new Style);
- style->show();
+private:
+ QLabel *moveLabel;
+ bool useCursorPos;
+ bool moving;
+ QPoint mousePos;
+};
+
+
+class ScreenDisplayer : public QWidget
+{
+public:
+ ScreenDisplayer()
+ : QWidget(), moveLabel(0), scaleFactor(1.0)
+ {
}
- QScopedPointer<Fonts> fonts;
- if (parser.isSet(fontsOption)) {
- fonts.reset(new Fonts);
- fonts->show();
+ void timerEvent(QTimerEvent *) {
+ update();
}
- QScopedPointer<IconDrawing> iconDrawing;
- if (parser.isSet(iconDrawingOption)) {
- iconDrawing.reset(new IconDrawing);
- iconDrawing->show();
+ void mousePressEvent(QMouseEvent *) {
+ if (!moveLabel)
+ moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window );
+ moveLabel->setText("Hello, Qt this is a label\nwith some text");
+ moveLabel->show();
+ }
+ void mouseMoveEvent(QMouseEvent *e) {
+ if (!moveLabel)
+ return;
+ moveLabel->move(e->pos() / scaleFactor);
+ QString str;
+ QDebug dbg(&str);
+ dbg.setAutoInsertSpaces(false);
+ dbg << moveLabel->geometry();
+ moveLabel->setText(str);
+ }
+ void mouseReleaseEvent(QMouseEvent *) {
+ if (moveLabel)
+ moveLabel->hide();
+ }
+ void showEvent(QShowEvent *) {
+ refreshTimer.start(300, this);
}
+ void hideEvent(QHideEvent *) {
+ refreshTimer.stop();
+ }
+ void paintEvent(QPaintEvent *) {
+ QPainter p(this);
+ QRectF total;
+ QList<QScreen*> screens = qApp->screens();
+ foreach (QScreen *screen, screens) {
+ total |= screen->geometry();
+ }
+ if (total.isEmpty())
+ return;
+
+ scaleFactor = qMin(width()/total.width(), height()/total.height());
+
+ p.fillRect(rect(), Qt::black);
+ p.scale(scaleFactor, scaleFactor);
+ p.translate(-total.topLeft());
+ p.setPen(QPen(Qt::white, 10));
+ p.setBrush(Qt::gray);
+
- QScopedPointer<Buttons> buttons;
- if (parser.isSet(buttonsOption)) {
- buttons.reset(new Buttons);
- buttons->show();
+ foreach (QScreen *screen, screens) {
+ p.drawRect(screen->geometry());
+ QFont f = font();
+ f.setPixelSize(screen->geometry().height() / 8);
+ p.setFont(f);
+ p.drawText(screen->geometry(), Qt::AlignCenter, screen->name());
+ }
+ p.setBrush(QColor(200,220,255,127));
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ if (!widget->isHidden())
+ p.drawRect(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);
+ cursorShape.translate(QCursor::pos());
+ p.drawPolygon(cursorShape);
}
+private:
+ QLabel *moveLabel;
+ QBasicTimer refreshTimer;
+ qreal scaleFactor;
+};
+
+class PhysicalSizeTest : public QWidget
+{
+Q_OBJECT
+public:
+ PhysicalSizeTest() : QWidget(), m_ignoreResize(false) {}
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *) {
+ qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX();
+ QSizeF s = size();
+ if (!m_ignoreResize)
+ m_physicalSize = s / ppi;
+ }
+ bool event(QEvent *event) {
+ if (event->type() == QEvent::ScreenChangeInternal) {
+ // we will get resize events when the scale factor changes
+ m_ignoreResize = true;
+ QTimer::singleShot(100, this, SLOT(handleScreenChange()));
+ }
+ return QWidget::event(event);
+ }
+public slots:
+ void handleScreenChange() {
+ qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX();
+ QSizeF newSize = m_physicalSize * ppi;
+ resize(newSize.toSize());
+ m_ignoreResize = false;
+ }
+private:
+ QSizeF m_physicalSize;
+ bool m_ignoreResize;
+};
+
+void PhysicalSizeTest::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ p.setRenderHint(QPainter::Antialiasing);
+
+ qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX();
+ qreal ppmm = ppi / 25.4;
+ qreal h = 15 * ppmm;
+ QRectF rulerRect(0,0, width(), h);
+ rulerRect.moveCenter(rect().center());
+
+ QFont f = font();
+ f.setPixelSize(18);
+ p.setFont(f);
+
+ // draw a rectangle in (Qt) pixel coordinates, for comparison
+ QRect pixelRect(0, 0, 300, 50);
+ pixelRect.moveTopLeft(QPoint(5 * ppmm, rulerRect.bottom() + 5 * ppmm));
+ p.fillRect(pixelRect, QColor(199,222,255));
+ p.drawText(pixelRect, "This rectangle is 300x50 pixels");
+
+ f.setPixelSize(4 * ppmm);
+ p.setFont(f);
+
+ QRectF topRect(0, 0, width(), rulerRect.top());
+ p.drawText(topRect, Qt::AlignCenter, "The ruler is drawn in physical units.\nThis window tries to keep its physical size\nwhen moved between screens.");
+
+ // draw a ruler in real physical coordinates
+
+ p.fillRect(rulerRect, QColor(255, 222, 111));
+
+ QPen linePen(Qt::black, 0.3 * ppmm);
+ p.setPen(linePen);
+ f.setBold(true);
+ p.setFont(f);
+
+ qreal vCenter = rulerRect.center().y();
+ p.drawLine(0, vCenter, width(), vCenter);
+
+ // cm
+ for (int i = 0;;) {
+ i++;
+ qreal x = i * ppmm;
+ if (x > width())
+ break;
+ qreal y = rulerRect.bottom();
+ qreal len;
+ if (i % 5)
+ len = 2 * ppmm;
+ else if (i % 10)
+ len = 3 * ppmm;
+ else
+ len = h / 2;
+
+ p.drawLine(QPointF(x, y), QPointF(x, y - len));
+ if (i % 10 == 5) {
+ QRectF textR(0, 0, 5 * ppmm, h / 2 - 2 * ppmm);
+ textR.moveTopLeft(QPointF(x, vCenter));
+ int n = i / 10 + 1;
+ if (n % 10 == 0)
+ p.setPen(Qt::red);
+ p.drawText(textR, Qt::AlignCenter, QString::number(n));
+ p.setPen(linePen);
+ }
+ }
+
+ //inches
+ for (int i = 0;;) {
+ i++;
+ qreal x = i * ppi / 16;
+ if (x > width())
+ break;
+ qreal y = rulerRect.top();
+
+ qreal d = h / 10;
+ qreal len;
+ if (i % 2)
+ len = 1 * d;
+ else if (i % 4)
+ len = 2 * d;
+ else if (i % 8)
+ len = 3 * d;
+ else if (i % 16)
+ len = 4 * d;
+ else
+ len = h / 2;
+
+ p.drawLine(QPointF(x, y), QPointF(x, y + len));
+ if (i % 16 == 12) {
+ QRectF textR(0, 0, 0.25 * ppi, h / 2 - 2 * d);
+ textR.moveBottomLeft(QPointF(x, vCenter));
+ p.drawText(textR, Qt::AlignCenter, QString::number(1 + i/16));
+ }
+ }
+
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+
+ int argumentCount = QCoreApplication::arguments().count();
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription("High DPI tester. Pass one or more of the options to\n"
+ "test various high-dpi aspects. \n"
+ "--interactive is a special option and opens a configuration"
+ " window.");
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption controllerOption("interactive", "Show configuration window.");
+ parser.addOption(controllerOption);
+
+
+ DemoContainerList demoList;
+ demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter");
+ demoList << new DemoContainer<Labels>("label", "Test Labels");
+ demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow");
+ demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons");
+ demoList << new DemoContainer<Caching>("caching", "Test caching");
+ demoList << new DemoContainer<Style>("styles", "Test style");
+ demoList << new DemoContainer<Fonts>("fonts", "Test fonts");
+ demoList << new DemoContainer<IconDrawing>("icondrawing", "Test icon drawing");
+ demoList << new DemoContainer<Buttons>("buttons", "Test buttons");
+ demoList << new DemoContainer<LinePainter>("linepainter", "Test line painting");
+ demoList << new DemoContainer<DragWidget>("draganddrop", "Test drag and drop");
+ demoList << new DemoContainer<CursorTester>("cursorpos", "Test cursor and window positioning");
+ demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning");
+ demoList << new DemoContainer<PhysicalSizeTest>("physicalsize", "Test manual highdpi support using physicalDotsPerInch");
+
+
+ foreach (DemoContainerBase *demo, demoList)
+ parser.addOption(demo->option());
+
+ parser.process(app);
+
+ //controller takes ownership of all demos
+ DemoController controller(&demoList, &parser);
+
+ if (parser.isSet(controllerOption) || argumentCount <= 1)
+ controller.show();
if (QApplication::topLevelWidgets().isEmpty())
parser.showHelp(0);
return app.exec();
}
+
+#include "main.moc"
diff --git a/tests/manual/highdpi/qticon16@3x.png b/tests/manual/highdpi/qticon16@3x.png
new file mode 100644
index 0000000000..de92658241
--- /dev/null
+++ b/tests/manual/highdpi/qticon16@3x.png
Binary files differ
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
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
index 04c9b3f72c..2792f6f1a3 100644
--- a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
@@ -61,6 +61,7 @@ QOpenGLTextureBlitWindow::QOpenGLTextureBlitWindow()
m_context->makeCurrent(this);
m_blitter.create();
+ qDebug("GL_TEXTURE_EXTERNAL_OES support: %d", m_blitter.supportsExternalOESTarget());
}
void QOpenGLTextureBlitWindow::render()
@@ -132,6 +133,12 @@ void QOpenGLTextureBlitWindow::render()
m_blitter.setSwizzleRB(false);
m_blitter.release();
+ if (m_blitter.supportsExternalOESTarget()) {
+ // Cannot do much testing here, just verify that bind and release work, meaning that the program is present.
+ m_blitter.bind(0x8D65);
+ m_blitter.release();
+ }
+
m_context->swapBuffers(this);
}
diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp
index aaa48ea60a..a56cea1dfe 100644
--- a/tests/manual/qopenglwidget/openglwidget/main.cpp
+++ b/tests/manual/qopenglwidget/openglwidget/main.cpp
@@ -35,13 +35,108 @@
#include <QApplication>
#include <QPushButton>
#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QMainWindow>
#include <QLCDNumber>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QTabWidget>
+#include <QLabel>
#include <QTimer>
#include <QSurfaceFormat>
#include <QDebug>
+#include <private/qwindow_p.h>
+
+class Tools : public QObject
+{
+ Q_OBJECT
+
+public:
+ Tools(QWidget *root, QWidget *widgetToTurn, const QVector<QWidget *> glwidgets)
+ : m_root(root), m_widgetToTurn(widgetToTurn), m_glWidgets(glwidgets) { }
+ void dump();
+
+private slots:
+ void turnNative();
+ void hideShowAllGL();
+ void dumpCompositingStatus();
+
+signals:
+ void aboutToShowGLWidgets();
+
+private:
+ void dumpWidget(QWidget *w, int indent = 0);
+
+ QWidget *m_root;
+ QWidget *m_widgetToTurn;
+ QVector<QWidget *> m_glWidgets;
+};
+
+void Tools::turnNative()
+{
+ qDebug("Turning into native");
+ m_widgetToTurn->winId();
+ dump();
+}
+
+void Tools::hideShowAllGL()
+{
+ if (m_glWidgets[0]->isVisible()) {
+ qDebug("Hiding all render-to-texture widgets");
+ foreach (QWidget *w, m_glWidgets)
+ w->hide();
+ } else {
+ qDebug("Showing all render-to-texture widgets");
+ emit aboutToShowGLWidgets();
+ foreach (QWidget *w, m_glWidgets)
+ w->show();
+ }
+}
+
+void Tools::dump()
+{
+ qDebug() << "Widget hierarchy";
+ dumpWidget(m_root);
+ qDebug() << "========";
+}
+
+void Tools::dumpWidget(QWidget *w, int indent)
+{
+ QString indentStr;
+ indentStr.fill(' ', indent);
+ qDebug().noquote() << indentStr << w << "winId =" << w->internalWinId();
+ foreach (QObject *obj, w->children()) {
+ if (QWidget *cw = qobject_cast<QWidget *>(obj))
+ dumpWidget(cw, indent + 4);
+ }
+}
+
+void Tools::dumpCompositingStatus()
+{
+ QWindow *w = m_root->window()->windowHandle();
+ qDebug() << "Compositing status for" << w << m_root->window() << "is" << QWindowPrivate::get(w)->compositing;
+}
+
+class TabWidgetResetter : public QObject
+{
+ Q_OBJECT
+public:
+ TabWidgetResetter(QTabWidget *tw) : m_tw(tw) { }
+public slots:
+ void reset() { m_tw->setCurrentIndex(0); }
+private:
+ QTabWidget *m_tw;
+};
int main(int argc, char *argv[])
{
+ if (argc > 1 && !strcmp(argv[1], "--sharecontext")) {
+ qDebug("Requesting all contexts to share");
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ }
+
QApplication a(argc, argv);
QSurfaceFormat format;
@@ -53,28 +148,86 @@ int main(int argc, char *argv[])
}
qDebug() << "Requesting" << format;
- QMdiArea w;
- w.resize(400,400);
+ QMainWindow wnd;
+ wnd.setObjectName("Main Window");
+ wnd.resize(1024, 768);
+
+ QMdiArea *w = new QMdiArea;
+ w->setObjectName("MDI area");
+ w->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ wnd.setCentralWidget(w);
- OpenGLWidget *glw = new OpenGLWidget;
+ OpenGLWidget *glw = new OpenGLWidget(33, QVector3D(0, 0, 1));
+ glw->setObjectName("First GL Widget with 33 ms timer");
glw->setFormat(format);
- w.addSubWindow(glw);
- glw->setMinimumSize(100,100);
+ glw->setMinimumSize(100, 100);
+ QMdiSubWindow *sw = w->addSubWindow(glw);
+ sw->setObjectName("First MDI Sub-Window");
+ sw->setWindowTitle("33 ms timer");
- OpenGLWidget *glw2 = new OpenGLWidget;
+ OpenGLWidget *glw2 = new OpenGLWidget(16);
+ glw2->setObjectName("Second GL Widget with 16 ms timer");
glw2->setFormat(format);
- glw2->setMinimumSize(100,100);
- w.addSubWindow(glw2);
+ glw2->setMinimumSize(100, 100);
+ QOpenGLWidget *glw22 = new OpenGLWidget(16);
+ glw22->setObjectName("Second #2 GLWidget");
+ glw22->setParent(glw2);
+ glw22->resize(40, 40);
+ sw = w->addSubWindow(glw2);
+ sw->setObjectName("Second MDI Sub-Window");
+ sw->setWindowTitle("16 ms timer");
+
+ OpenGLWidget *glw3 = new OpenGLWidget(0); // trigger updates continuously, no timer
+ glw3->setObjectName("GL widget in scroll area (possibly native)");
+ glw3->setFormat(format);
+ glw3->setFixedSize(600, 600);
+ QScrollArea *sa = new QScrollArea;
+ sa->setWidget(glw3);
+ sa->setMinimumSize(100, 100);
+ sa->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ sw = w->addSubWindow(sa);
+ sw->setObjectName("MDI Sub-Window for scroll area");
+ sw->setWindowTitle("Cont. update");
+ sw->resize(300, 300);
+ sa->verticalScrollBar()->setValue(300);
QLCDNumber *lcd = new QLCDNumber;
lcd->display(1337);
- lcd->setMinimumSize(300,100);
- w.addSubWindow(lcd);
+ lcd->setMinimumSize(300, 100);
+ sw = w->addSubWindow(lcd);
+ sw->setObjectName("MDI Sub-Window for LCD widget");
+ sw->setWindowTitle("Ordinary widget");
+
+ QTabWidget *tw = new QTabWidget;
+ QOpenGLWidget *glw4 = new OpenGLWidget(16, QVector3D(1, 0, 0));
+ glw4->setObjectName("GL widget in tab widget");
+ tw->addTab(glw4, "OpenGL");
+ QLabel *label = new QLabel("Another tab");
+ tw->addTab(label, "Not OpenGL");
+ tw->setMinimumSize(100, 100);
+ sw = w->addSubWindow(tw);
+ sw->setObjectName("MDI Sub-Window for tab widget");
+ sw->setWindowTitle("Tabs");
- w.show();
+ TabWidgetResetter twr(tw);
+ Tools t(&wnd, glw3, QVector<QWidget *>() << glw << glw2 << glw3 << glw4);
+ QObject::connect(&t, SIGNAL(aboutToShowGLWidgets()), &twr, SLOT(reset()));
+ QMenu *toolsMenu = wnd.menuBar()->addMenu("&Tools");
+ toolsMenu->addAction("&Turn widgets (or some parent) into native", &t, SLOT(turnNative()));
+ toolsMenu->addAction("&Hide/show all OpenGL widgets", &t, SLOT(hideShowAllGL()));
+
+ QTimer compStatusDumpTimer;
+ QObject::connect(&compStatusDumpTimer, SIGNAL(timeout()), &t, SLOT(dumpCompositingStatus()));
+ compStatusDumpTimer.start(5000);
+
+ wnd.show();
if (glw->isValid())
qDebug() << "Got" << glw->format();
+ t.dump();
+
return a.exec();
}
+
+#include "main.moc"
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
index d47e12edc8..4d2463b84d 100644
--- a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
@@ -75,16 +75,23 @@ public:
int w,h;
QWidget *q;
+
+ int m_interval;
+ QVector3D m_rotAxis;
};
-OpenGLWidget::OpenGLWidget(QWidget *parent)
+OpenGLWidget::OpenGLWidget(int interval, const QVector3D &rotAxis, QWidget *parent)
: QOpenGLWidget(parent)
{
- d = new OpenGLWidgetPrivate(this);
- QTimer *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(update()));
- timer->start(30);
+ d.reset(new OpenGLWidgetPrivate(this));
+ d->m_interval = interval;
+ d->m_rotAxis = rotAxis;
+ if (interval > 0) {
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer->start(interval);
+ }
}
OpenGLWidget::~OpenGLWidget()
@@ -152,7 +159,8 @@ void OpenGLWidgetPrivate::render()
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -2);
- matrix.rotate(100.0f * m_frame / 30/*screen()->refreshRate()*/, 0, 1, 0);
+ const qreal angle = 100.0f * m_frame / 30;
+ matrix.rotate(angle, m_rotAxis);
m_program->setUniformValue(m_matrixUniform, matrix);
@@ -182,4 +190,7 @@ void OpenGLWidgetPrivate::render()
m_program->release();
++m_frame;
+
+ if (m_interval <= 0)
+ q->update();
}
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.h b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
index 4dc5fde067..a1d5490845 100644
--- a/tests/manual/qopenglwidget/openglwidget/openglwidget.h
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
@@ -35,13 +35,14 @@
#define OPENGLWIDGET_H
#include <QtWidgets/QOpenGLWidget>
+#include <QtGui/QVector3D>
class OpenGLWidgetPrivate;
class OpenGLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
- OpenGLWidget(QWidget *parent = 0);
+ OpenGLWidget(int interval = 30, const QVector3D &rotAxis = QVector3D(0, 1, 0), QWidget *parent = 0);
~OpenGLWidget();
void initializeGL();
@@ -49,7 +50,7 @@ public:
void paintGL();
private:
- OpenGLWidgetPrivate *d;
+ QScopedPointer<OpenGLWidgetPrivate> d;
};
#endif // OPENGLWIDGET_H
diff --git a/tests/manual/qscreen/main.cpp b/tests/manual/qscreen/main.cpp
index 1047ffcdfc..298996a59b 100644
--- a/tests/manual/qscreen/main.cpp
+++ b/tests/manual/qscreen/main.cpp
@@ -36,23 +36,127 @@
#include <QScreen>
#include <QWindow>
#include <QDebug>
+#include <QTextStream>
#include <QFormLayout>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QAction>
+#include <QStatusBar>
#include <QLineEdit>
#include <QDesktopWidget>
-int i = 0;
+class ScreenPropertyWatcher : public PropertyWatcher
+{
+ Q_OBJECT
+public:
+ ScreenPropertyWatcher(QWidget *wp = Q_NULLPTR) : PropertyWatcher(Q_NULLPTR, QString(), wp)
+ {
+ // workaround for the fact that virtualSiblings is not a property,
+ // thus there is no change notification:
+ // allow the user to update the field manually
+ connect(this, &PropertyWatcher::updatedAllFields, this, &ScreenPropertyWatcher::updateSiblings);
+ }
+
+ QScreen *screenSubject() const { return qobject_cast<QScreen *>(subject()); }
+ void setScreenSubject(QScreen *s, const QString &annotation = QString())
+ {
+ setSubject(s, annotation);
+ updateSiblings();
+ }
-typedef QHash<QScreen*, PropertyWatcher*> ScreensHash;
-Q_GLOBAL_STATIC(ScreensHash, props);
+public slots:
+ void updateSiblings();
+};
-void updateSiblings(PropertyWatcher* w)
+void ScreenPropertyWatcher::updateSiblings()
{
- QLineEdit *siblingsField = w->findChild<QLineEdit *>("siblings");
- QScreen* screen = (QScreen*)w->subject();
- QStringList siblingsList;
- foreach (QScreen *sibling, screen->virtualSiblings())
- siblingsList << sibling->name();
- siblingsField->setText(siblingsList.join(", "));
+ const QScreen *screen = screenSubject();
+ if (!screen)
+ return;
+ const QString objectName = QLatin1String("siblings");
+ QLineEdit *siblingsField = findChild<QLineEdit *>(objectName);
+ if (!siblingsField) {
+ siblingsField = new QLineEdit(this);
+ siblingsField->setObjectName(objectName);
+ siblingsField->setReadOnly(true);
+ formLayout()->insertRow(0, QLatin1String("virtualSiblings"), siblingsField);
+ }
+ QString text;
+ foreach (const QScreen *sibling, screen->virtualSiblings()) {
+ if (!text.isEmpty())
+ text += QLatin1String(", ");
+ text += sibling->name();
+ }
+ siblingsField->setText(text);
+}
+
+class ScreenWatcherMainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit ScreenWatcherMainWindow(QScreen *screen);
+
+ QScreen *screenSubject() const { return m_watcher->screenSubject(); }
+
+protected:
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
+
+private:
+ const QString m_annotation;
+ ScreenPropertyWatcher *m_watcher;
+};
+
+static int i = 0;
+
+ScreenWatcherMainWindow::ScreenWatcherMainWindow(QScreen *screen)
+ : m_annotation(QLatin1Char('#') + QString::number(i++))
+ , m_watcher(new ScreenPropertyWatcher(this))
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setCentralWidget(m_watcher);
+ m_watcher->setScreenSubject(screen, m_annotation);
+
+ QMenu *fileMenu = menuBar()->addMenu(QLatin1String("&File"));
+ QAction *a = fileMenu->addAction(QLatin1String("Close"));
+ a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
+ connect(a, SIGNAL(triggered()), this, SLOT(close()));
+ a = fileMenu->addAction(QLatin1String("Quit"));
+ a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ connect(a, SIGNAL(triggered()), qApp, SLOT(quit()));
+}
+
+static inline QString msgScreenChange(const QWidget *w, const QScreen *oldScreen, const QScreen *newScreen)
+{
+ QString result;
+ const QRect geometry = w->geometry();
+ const QPoint pos = QCursor::pos();
+ if (!newScreen) {
+ result = QLatin1String("Screen changed --> null");
+ } else if (!oldScreen) {
+ QTextStream(&result) << "Screen changed null --> \""
+ << newScreen->name() << "\" at " << pos.x() << ',' << pos.y() << " geometry: "
+ << geometry.width() << 'x' << geometry.height() << forcesign << geometry.x()
+ << geometry.y() << '.';
+ } else {
+ QTextStream(&result) << "Screen changed \"" << oldScreen->name() << "\" --> \""
+ << newScreen->name() << "\" at " << pos.x() << ',' << pos.y() << " geometry: "
+ << geometry.width() << 'x' << geometry.height() << forcesign << geometry.x()
+ << geometry.y() << '.';
+ }
+ return result;
+}
+
+bool ScreenWatcherMainWindow::event(QEvent *event)
+{
+ if (event->type() == QEvent::ScreenChangeInternal) {
+ QScreen *newScreen = windowHandle()->screen();
+ const QString message = msgScreenChange(this, m_watcher->screenSubject(), newScreen);
+ qDebug().noquote() << message;
+ statusBar()->showMessage(message);
+ m_watcher->setScreenSubject(newScreen, m_annotation);
+ }
+ return QMainWindow::event(event);
}
void screenAdded(QScreen* screen)
@@ -60,12 +164,7 @@ void screenAdded(QScreen* screen)
screen->setOrientationUpdateMask((Qt::ScreenOrientations)0x0F);
qDebug("\nscreenAdded %s siblings %d first %s", qPrintable(screen->name()), screen->virtualSiblings().count(),
(screen->virtualSiblings().isEmpty() ? "none" : qPrintable(screen->virtualSiblings().first()->name())));
- PropertyWatcher *w = new PropertyWatcher(screen, QString::number(i++));
- QLineEdit *siblingsField = new QLineEdit();
- siblingsField->setObjectName("siblings");
- siblingsField->setReadOnly(true);
- w->layout()->insertRow(0, "virtualSiblings", siblingsField);
- updateSiblings(w);
+ ScreenWatcherMainWindow *w = new ScreenWatcherMainWindow(screen);
// Set the screen via QDesktopWidget. This corresponds to setScreen() for the underlying
// QWindow. This is essential when having separate X screens since the the positioning below is
@@ -84,18 +183,17 @@ void screenAdded(QScreen* screen)
geom.setHeight(screen->geometry().height() * 9 / 10);
geom.moveCenter(screen->geometry().center());
w->setGeometry(geom);
-
- props->insert(screen, w);
-
- // workaround for the fact that virtualSiblings is not a property,
- // thus there is no change notification:
- // allow the user to update the field manually
- QObject::connect(w, &PropertyWatcher::updatedAllFields, &updateSiblings);
}
void screenRemoved(QScreen* screen)
{
- delete props->take(screen);
+ const QWidgetList topLevels = QApplication::topLevelWidgets();
+ for (int i = topLevels.size() - 1; i >= 0; --i) {
+ if (ScreenWatcherMainWindow *sw = qobject_cast<ScreenWatcherMainWindow *>(topLevels.at(i))) {
+ if (sw->screenSubject() == screen)
+ sw->close();
+ }
+ }
}
int main(int argc, char *argv[])
@@ -108,3 +206,5 @@ int main(int argc, char *argv[])
QObject::connect((const QGuiApplication*)QGuiApplication::instance(), &QGuiApplication::screenRemoved, &screenRemoved);
return a.exec();
}
+
+#include "main.moc"
diff --git a/tests/manual/qscreen/propertywatcher.cpp b/tests/manual/qscreen/propertywatcher.cpp
index cfb5ea272d..b745ef5125 100644
--- a/tests/manual/qscreen/propertywatcher.cpp
+++ b/tests/manual/qscreen/propertywatcher.cpp
@@ -35,33 +35,82 @@
#include <QMetaProperty>
#include <QFormLayout>
#include <QPushButton>
+#include <QLabel>
#include "propertyfield.h"
PropertyWatcher::PropertyWatcher(QObject *subject, QString annotation, QWidget *parent)
- : QWidget(parent), m_subject(subject), m_layout(new QFormLayout)
+ : QWidget(parent), m_subject(Q_NULLPTR), m_formLayout(new QFormLayout(this))
{
- setWindowTitle(QString("Properties of %1 %2 %3")
- .arg(subject->metaObject()->className()).arg(subject->objectName()).arg(annotation));
setMinimumSize(450, 300);
+ m_formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+ setSubject(subject, annotation);
+}
+
+class UpdatesEnabledBlocker
+{
+ Q_DISABLE_COPY(UpdatesEnabledBlocker);
+public:
+ explicit UpdatesEnabledBlocker(QWidget *w) : m_widget(w)
+ {
+ m_widget->setUpdatesEnabled(false);
+ }
+ ~UpdatesEnabledBlocker()
+ {
+ m_widget->setUpdatesEnabled(true);
+ m_widget->update();
+ }
+
+private:
+ QWidget *m_widget;
+};
+
+void PropertyWatcher::setSubject(QObject *s, const QString &annotation)
+{
+ if (s == m_subject)
+ return;
+
+ UpdatesEnabledBlocker blocker(this);
+
+ if (m_subject) {
+ disconnect(m_subject, &QObject::destroyed, this, &PropertyWatcher::subjectDestroyed);
+ for (int i = m_formLayout->count() - 1; i >= 0; --i) {
+ QLayoutItem *item = m_formLayout->takeAt(i);
+ delete item->widget();
+ delete item;
+ }
+ window()->setWindowTitle(QString());
+ window()->setWindowIconText(QString());
+ }
+
+ m_subject = s;
+ if (!m_subject)
+ return;
+
const QMetaObject* meta = m_subject->metaObject();
+ QString title = QLatin1String("Properties ") + QLatin1String(meta->className());
+ if (!m_subject->objectName().isEmpty())
+ title += QLatin1Char(' ') + m_subject->objectName();
+ if (!annotation.isEmpty())
+ title += QLatin1Char(' ') + annotation;
+ window()->setWindowTitle(title);
- for (int i = 0; i < meta->propertyCount(); ++i) {
- QMetaProperty prop = meta->property(i);
+ for (int i = 0, count = meta->propertyCount(); i < count; ++i) {
+ const QMetaProperty prop = meta->property(i);
if (prop.isReadable()) {
- PropertyField* field = new PropertyField(m_subject, prop);
- m_layout->addRow(prop.name(), field);
+ QLabel *label = new QLabel(prop.name(), this);
+ PropertyField *field = new PropertyField(m_subject, prop, this);
+ m_formLayout->addRow(label, field);
+ if (!qstrcmp(prop.name(), "name"))
+ window()->setWindowIconText(prop.read(m_subject).toString());
+ label->setVisible(true);
+ field->setVisible(true);
}
}
- QPushButton *updateButton = new QPushButton("update");
- connect(updateButton, &QPushButton::clicked, this, &PropertyWatcher::updateAllFields);
- m_layout->addRow("", updateButton);
- m_layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
- setLayout(m_layout);
- connect(subject, &QObject::destroyed, this, &PropertyWatcher::subjectDestroyed);
-}
+ connect(m_subject, &QObject::destroyed, this, &PropertyWatcher::subjectDestroyed);
-PropertyWatcher::~PropertyWatcher()
-{
+ QPushButton *updateButton = new QPushButton(QLatin1String("Update"), this);
+ connect(updateButton, &QPushButton::clicked, this, &PropertyWatcher::updateAllFields);
+ m_formLayout->addRow(QString(), updateButton);
}
void PropertyWatcher::updateAllFields()
diff --git a/tests/manual/qscreen/propertywatcher.h b/tests/manual/qscreen/propertywatcher.h
index 7dccfe3672..01e448845a 100644
--- a/tests/manual/qscreen/propertywatcher.h
+++ b/tests/manual/qscreen/propertywatcher.h
@@ -44,10 +44,12 @@ class PropertyWatcher : public QWidget
Q_OBJECT
public:
- PropertyWatcher(QObject* subject, QString annotation = QString(), QWidget *parent = 0);
- ~PropertyWatcher();
- QFormLayout *layout() { return m_layout; }
- QObject* subject() { return m_subject; }
+ explicit PropertyWatcher(QObject* subject = Q_NULLPTR, QString annotation = QString(), QWidget *parent = Q_NULLPTR);
+
+ QFormLayout *formLayout() { return m_formLayout; }
+
+ QObject *subject() const { return m_subject; }
+ void setSubject(QObject *s, const QString &annotation = QString());
public slots:
void updateAllFields();
@@ -56,9 +58,9 @@ public slots:
signals:
void updatedAllFields(PropertyWatcher* sender);
-protected:
+private:
QObject* m_subject;
- QFormLayout * m_layout;
+ QFormLayout * m_formLayout;
};
#endif // PROPERTY_WATCHER_H
diff --git a/tests/manual/qscreen/qscreen.pro b/tests/manual/qscreen/qscreen.pro
index cec8bbf245..5d587db3f4 100644
--- a/tests/manual/qscreen/qscreen.pro
+++ b/tests/manual/qscreen/qscreen.pro
@@ -1,4 +1,5 @@
QT += core gui widgets
+CONFIG += console
TARGET = qscreen
TEMPLATE = app
diff --git a/tests/manual/qsysinfo/main.cpp b/tests/manual/qsysinfo/main.cpp
index a3f21140cb..9456bd9b03 100644
--- a/tests/manual/qsysinfo/main.cpp
+++ b/tests/manual/qsysinfo/main.cpp
@@ -134,6 +134,7 @@ int main(int argc, char *argv[])
printf("QSysInfo::productType() = %s\n", qPrintable(QSysInfo::productType()));
printf("QSysInfo::productVersion() = %s\n", qPrintable(QSysInfo::productVersion()));
printf("QSysInfo::prettyProductName() = %s\n", qPrintable(QSysInfo::prettyProductName()));
+ printf("QSysInfo::machineHostName() = %s\n", qPrintable(QSysInfo::machineHostName()));
return 0;
}
diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.cpp b/tests/manual/qtabletevent/device_information/tabletwidget.cpp
index 2e4cb6658f..f1d838f01d 100644
--- a/tests/manual/qtabletevent/device_information/tabletwidget.cpp
+++ b/tests/manual/qtabletevent/device_information/tabletwidget.cpp
@@ -73,6 +73,7 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
mRot = event->rotation();
mButton = event->button();
mButtons = event->buttons();
+ mTimestamp = event->timestamp();
if (isVisible())
update();
break;
@@ -84,6 +85,7 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
mType = event->type();
mPos = event->pos();
mGPos = event->globalPos();
+ mTimestamp = event->timestamp();
}
default:
break;
@@ -122,6 +124,7 @@ void TabletWidget::paintEvent(QPaintEvent *)
eventInfo << QString("Global position: %1 %2").arg(QString::number(mGPos.x()), QString::number(mGPos.y()));
eventInfo << QString("Local position: %1 %2").arg(QString::number(mPos.x()), QString::number(mPos.y()));
+ eventInfo << QString("Timestamp: %1").arg(QString::number(mTimestamp));
if (mType == QEvent::TabletEnterProximity || mType == QEvent::TabletLeaveProximity
|| mType == QEvent::TabletMove || mType == QEvent::TabletPress
|| mType == QEvent::TabletRelease) {
diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.h b/tests/manual/qtabletevent/device_information/tabletwidget.h
index 2861eb4814..95631be57b 100644
--- a/tests/manual/qtabletevent/device_information/tabletwidget.h
+++ b/tests/manual/qtabletevent/device_information/tabletwidget.h
@@ -65,6 +65,7 @@ private:
qreal mPress, mTangential, mRot;
qint64 mUnique;
bool mMouseToo;
+ ulong mTimestamp;
};
#endif // TABLETWIDGET_H
diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp
index 5a83decfa2..a6fddd4b18 100644
--- a/tests/manual/qtabletevent/regular_widgets/main.cpp
+++ b/tests/manual/qtabletevent/regular_widgets/main.cpp
@@ -39,6 +39,7 @@
#include <QMenuBar>
#include <QMenu>
#include <QAction>
+#include <QStatusBar>
#include <QVector>
#include <QPainter>
#include <QCursor>
@@ -72,6 +73,9 @@ public:
public slots:
void clearPoints() { m_points.clear(); update(); }
+signals:
+ void stats(QString s);
+
protected:
void mouseDoubleClickEvent(QMouseEvent *event) { outputMouseEvent(event); }
void mouseMoveEvent(QMouseEvent *event) { outputMouseEvent(event); }
@@ -81,6 +85,7 @@ protected:
void tabletEvent(QTabletEvent *);
void paintEvent(QPaintEvent *);
+ void timerEvent(QTimerEvent *);
private:
void outputMouseEvent(QMouseEvent *event);
@@ -89,28 +94,36 @@ private:
bool m_lastIsTabletMove;
Qt::MouseButton m_lastButton;
QVector<TabletPoint> m_points;
+ int m_tabletMoveCount;
+ int m_paintEventCount;
};
EventReportWidget::EventReportWidget()
: m_lastIsMouseMove(false)
, m_lastIsTabletMove(false)
, m_lastButton(Qt::NoButton)
-{ }
+ , m_tabletMoveCount(0)
+ , m_paintEventCount(0)
+{
+ startTimer(1000);
+}
void EventReportWidget::paintEvent(QPaintEvent *)
{
QPainter p(this);
+ int lineSpacing = fontMetrics().lineSpacing();
+ int halfLineSpacing = lineSpacing / 2;
const QRectF geom = QRectF(QPoint(0, 0), size());
p.fillRect(geom, Qt::white);
p.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1,1)));
p.setPen(Qt::white);
QPainterPath ellipse;
- ellipse.addEllipse(0, 0, 50, 10);
+ ellipse.addEllipse(0, 0, halfLineSpacing * 5, halfLineSpacing);
foreach (const TabletPoint &t, m_points) {
if (geom.contains(t.pos)) {
QPainterPath pp;
- pp.addEllipse(t.pos, 8, 8);
- QRectF pointBounds(t.pos.x() - 10, t.pos.y() - 10, 20, 20);
+ pp.addEllipse(t.pos, halfLineSpacing, halfLineSpacing);
+ QRectF pointBounds(t.pos.x() - halfLineSpacing, t.pos.y() - halfLineSpacing, lineSpacing, lineSpacing);
switch (t.type) {
case TabletButtonPress:
p.fillPath(pp, Qt::darkGreen);
@@ -133,7 +146,7 @@ void EventReportWidget::paintEvent(QPaintEvent *)
p.drawPath(ellipse);
p.restore();
} else {
- p.drawEllipse(t.pos, t.pressure * 10.0, t.pressure * 10.0);
+ p.drawEllipse(t.pos, t.pressure * halfLineSpacing, t.pressure * halfLineSpacing);
}
p.setPen(Qt::white);
} else {
@@ -143,6 +156,7 @@ void EventReportWidget::paintEvent(QPaintEvent *)
}
}
}
+ ++m_paintEventCount;
}
void EventReportWidget::tabletEvent(QTabletEvent *event)
@@ -152,11 +166,13 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
switch (event->type()) {
case QEvent::TabletEnterProximity:
case QEvent::TabletLeaveProximity:
+ qDebug() << "proximity" << event;
break;
case QEvent::TabletMove:
m_points.push_back(TabletPoint(event->pos(), TabletMove, m_lastButton, event->pointerType(), event->pressure(), event->rotation()));
update();
isMove = true;
+ ++m_tabletMoveCount;
break;
case QEvent::TabletPress:
m_points.push_back(TabletPoint(event->pos(), TabletButtonPress, event->button(), event->pointerType(), event->rotation()));
@@ -192,6 +208,13 @@ void EventReportWidget::outputMouseEvent(QMouseEvent *event)
qDebug() << event;
}
+void EventReportWidget::timerEvent(QTimerEvent *)
+{
+ emit stats(QString("%1 moves/sec, %2 frames/sec").arg(m_tabletMoveCount).arg(m_paintEventCount));
+ m_tabletMoveCount = 0;
+ m_paintEventCount = 0;
+}
+
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
@@ -201,6 +224,7 @@ int main(int argc, char *argv[])
widget->setMinimumSize(640, 480);
QMenu *fileMenu = mainWindow.menuBar()->addMenu("File");
QObject::connect(fileMenu->addAction("Clear"), SIGNAL(triggered()), widget, SLOT(clearPoints()));
+ QObject::connect(widget, SIGNAL(stats(QString)), mainWindow.statusBar(), SLOT(showMessage(QString)));
QAction *quitAction = fileMenu->addAction("Quit");
QObject::connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp
index e1114d7f57..b7029767c9 100644
--- a/tests/manual/touch/main.cpp
+++ b/tests/manual/touch/main.cpp
@@ -32,21 +32,187 @@
****************************************************************************/
#include <QApplication>
+#include <QGesture>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QMainWindow>
#include <QSplitter>
+#include <QToolBar>
#include <QVector>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QPlainTextEdit>
+#include <QPainter>
+#include <QPainterPath>
#include <QPaintEvent>
#include <QScreen>
+#include <QSharedPointer>
#include <QDebug>
#include <QTextStream>
+bool optIgnoreTouch = false;
+QVector<Qt::GestureType> optGestures;
+
+static inline void drawCircle(const QPointF &center, qreal radius, const QColor &color, QPainter &painter)
+{
+ const QPen oldPen = painter.pen();
+ QPen pen = oldPen;
+ pen.setColor(color);
+ painter.setPen(pen);
+ painter.drawEllipse(center, radius, radius);
+ painter.setPen(oldPen);
+}
+
+static inline void fillCircle(const QPointF &center, qreal radius, const QColor &color, QPainter &painter)
+{
+ QPainterPath painterPath;
+ painterPath.addEllipse(center, radius, radius);
+ painter.fillPath(painterPath, color);
+}
+
+// Draws an arrow assuming a mathematical coordinate system, Y axis pointing
+// upwards, angle counterclockwise (that is, 45' is pointing up/right).
+static void drawArrow(const QPointF &center, qreal length, qreal angleDegrees,
+ const QColor &color, int arrowSize, QPainter &painter)
+{
+ painter.save();
+ painter.translate(center); // Transform center to (0,0) rotate and draw arrow pointing right.
+ painter.rotate(-angleDegrees);
+ QPen pen = painter.pen();
+ pen.setColor(color);
+ pen.setWidth(2);
+ painter.setPen(pen);
+ const QPointF endPoint(length, 0);
+ painter.drawLine(QPointF(0, 0), endPoint);
+ painter.drawLine(endPoint, endPoint + QPoint(-arrowSize, -arrowSize));
+ painter.drawLine(endPoint, endPoint + QPoint(-arrowSize, arrowSize));
+ painter.restore();
+}
+
+QDebug operator<<(QDebug debug, const QTouchDevice *d)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QTouchDevice(" << d->name() << ',';
+ switch (d->type()) {
+ case QTouchDevice::TouchScreen:
+ debug << "TouchScreen";
+ break;
+ case QTouchDevice::TouchPad:
+ debug << "TouchPad";
+ break;
+ }
+ debug << ", capabilities=" << d->capabilities()
+ << ", maximumTouchPoints=" << d->maximumTouchPoints() << ')';
+ return debug;
+}
+
+// Hierarchy of classes containing gesture parameters and drawing functionality.
+class Gesture {
+ Q_DISABLE_COPY(Gesture)
+public:
+ static Gesture *fromQGesture(const QWidget *w, const QGesture *source);
+ virtual ~Gesture() {}
+
+ virtual void draw(const QRectF &rect, QPainter &painter) const = 0;
+
+protected:
+ explicit Gesture(const QWidget *w, const QGesture *source) : m_type(source->gestureType())
+ , m_hotSpot(w->mapFromGlobal(source->hotSpot().toPoint()))
+ , m_hasHotSpot(source->hasHotSpot()) {}
+
+ QPointF drawHotSpot(const QRectF &rect, QPainter &painter) const
+ {
+ const QPointF h = m_hasHotSpot ? m_hotSpot : rect.center();
+ painter.drawEllipse(h, 15, 15);
+ return h;
+ }
+
+private:
+ Qt::GestureType m_type;
+ QPointF m_hotSpot;
+ bool m_hasHotSpot;
+};
+
+class PanGesture : public Gesture {
+public:
+ explicit PanGesture(const QWidget *w, const QPanGesture *source) : Gesture(w, source)
+ , m_offset(source->offset()) {}
+
+ void draw(const QRectF &rect, QPainter &painter) const Q_DECL_OVERRIDE
+ {
+ const QPointF hotSpot = drawHotSpot(rect, painter);
+ painter.drawLine(hotSpot, hotSpot + m_offset);
+ }
+
+private:
+ QPointF m_offset;
+};
+
+class SwipeGesture : public Gesture {
+public:
+ explicit SwipeGesture(const QWidget *w, const QSwipeGesture *source) : Gesture(w, source)
+ , m_horizontal(source->horizontalDirection()), m_vertical(source->verticalDirection())
+ , m_angle(source->swipeAngle()) {}
+
+ void draw(const QRectF &rect, QPainter &painter) const Q_DECL_OVERRIDE;
+
+private:
+ QSwipeGesture::SwipeDirection m_horizontal;
+ QSwipeGesture::SwipeDirection m_vertical;
+ qreal m_angle;
+};
+
+static qreal swipeDirectionAngle(QSwipeGesture::SwipeDirection d)
+{
+ switch (d) {
+ case QSwipeGesture::NoDirection:
+ case QSwipeGesture::Right:
+ break;
+ case QSwipeGesture::Left:
+ return 180;
+ case QSwipeGesture::Up:
+ return 90;
+ case QSwipeGesture::Down:
+ return 270;
+ }
+ return 0;
+}
+
+void SwipeGesture::draw(const QRectF &rect, QPainter &painter) const
+{
+ enum { arrowLength = 50, arrowHeadSize = 10 };
+ const QPointF hotSpot = drawHotSpot(rect, painter);
+ drawArrow(hotSpot, arrowLength, swipeDirectionAngle(m_horizontal), Qt::red, arrowHeadSize, painter);
+ drawArrow(hotSpot, arrowLength, swipeDirectionAngle(m_vertical), Qt::green, arrowHeadSize, painter);
+ drawArrow(hotSpot, arrowLength, m_angle, Qt::blue, arrowHeadSize, painter);
+}
+
+Gesture *Gesture::fromQGesture(const QWidget *w, const QGesture *source)
+{
+ Gesture *result = Q_NULLPTR;
+ switch (source->gestureType()) {
+ case Qt::TapGesture:
+ case Qt::TapAndHoldGesture:
+ case Qt::PanGesture:
+ result = new PanGesture(w, static_cast<const QPanGesture *>(source));
+ break;
+ case Qt::PinchGesture:
+ case Qt::CustomGesture:
+ case Qt::LastGestureType:
+ break;
+ case Qt::SwipeGesture:
+ result = new SwipeGesture(w, static_cast<const QSwipeGesture *>(source));
+ break;
+ }
+ return result;
+}
+
+typedef QSharedPointer<Gesture> GesturePtr;
+typedef QVector<GesturePtr> GesturePtrs;
+
typedef QVector<QEvent::Type> EventTypeVector;
class EventFilter : public QObject {
@@ -68,33 +234,189 @@ bool EventFilter::eventFilter(QObject *o, QEvent *e)
static int n = 0;
if (m_types.contains(e->type())) {
QString message;
- QDebug(&message) << '#' << n++ << ' ' << o->objectName() << ' ' << e;
+ QDebug debug(&message);
+ debug << '#' << n++ << ' ' << o->objectName() << ' ';
+ switch (e->type()) {
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ debug << static_cast<const QGestureEvent *>(e); // Special operator
+ break;
+ default:
+ debug << e;
+ break;
+ }
emit eventReceived(message);
}
return false;
}
+enum PointType {
+ TouchPoint,
+ MousePress,
+ MouseRelease
+};
+
+struct Point
+{
+ Point(const QPointF &p = QPoint(), PointType t = TouchPoint,
+ Qt::MouseEventSource s = Qt::MouseEventNotSynthesized) : pos(p), type(t), source(s) {}
+
+ QColor color() const;
+
+ QPointF pos;
+ PointType type;
+ Qt::MouseEventSource source;
+};
+
+QColor Point::color() const
+{
+ Qt::GlobalColor globalColor = Qt::black;
+ if (type != TouchPoint) {
+ switch (source) {
+ case Qt::MouseEventSynthesizedBySystem:
+ globalColor = Qt::red;
+ break;
+ case Qt::MouseEventSynthesizedByQt:
+ globalColor = Qt::blue;
+ break;
+ case Qt::MouseEventNotSynthesized:
+ break;
+ }
+ }
+ const QColor result(globalColor);
+ return type == MousePress ? result.lighter() : result;
+}
+
class TouchTestWidget : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints)
public:
- explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent)
+ explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent), m_drawPoints(true)
{
setAttribute(Qt::WA_AcceptTouchEvents);
+ foreach (Qt::GestureType t, optGestures)
+ grabGesture(t);
}
- bool event(QEvent *event) Q_DECL_OVERRIDE
- {
- switch (event->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
+ bool drawPoints() const { return m_drawPoints; }
+
+public slots:
+ void clearPoints();
+ void setDrawPoints(bool drawPoints);
+
+signals:
+ void logMessage(const QString &);
+
+protected:
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+
+private:
+ void handleGestureEvent(QGestureEvent *gestureEvent);
+
+ QVector<Point> m_points;
+ GesturePtrs m_gestures;
+ bool m_drawPoints;
+};
+
+void TouchTestWidget::clearPoints()
+{
+ if (!m_points.isEmpty() || !m_gestures.isEmpty()) {
+ m_points.clear();
+ m_gestures.clear();
+ update();
+ }
+}
+
+void TouchTestWidget::setDrawPoints(bool drawPoints)
+{
+ if (m_drawPoints != drawPoints) {
+ clearPoints();
+ m_drawPoints = drawPoints;
+ }
+}
+
+bool TouchTestWidget::event(QEvent *event)
+{
+ const QEvent::Type type = event->type();
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ if (m_drawPoints) {
+ const QMouseEvent *me = static_cast<const QMouseEvent *>(event);
+ m_points.append(Point(me->localPos(),
+ type == QEvent::MouseButtonPress ? MousePress : MouseRelease,
+ me->source()));
+ update();
+ }
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ if (m_drawPoints) {
+ foreach (const QTouchEvent::TouchPoint &p, static_cast<const QTouchEvent *>(event)->touchPoints())
+ m_points.append(Point(p.pos(), TouchPoint));
+ update();
+ }
+ case QEvent::TouchEnd:
+ if (optIgnoreTouch)
+ event->ignore();
+ else
event->accept();
- return true;
- default:
- break;
+ return true;
+ case QEvent::Gesture:
+ handleGestureEvent(static_cast<QGestureEvent *>(event));
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(event);
+}
+
+void TouchTestWidget::handleGestureEvent(QGestureEvent *gestureEvent)
+{
+ foreach (QGesture *gesture, gestureEvent->gestures()) {
+ if (optGestures.contains(gesture->gestureType())) {
+ switch (gesture->state()) {
+ case Qt::NoGesture:
+ break;
+ case Qt::GestureStarted:
+ case Qt::GestureUpdated:
+ gestureEvent->accept(gesture);
+ break;
+ case Qt::GestureFinished:
+ gestureEvent->accept(gesture);
+ if (Gesture *g = Gesture::fromQGesture(this, gesture)) {
+ m_gestures.append(GesturePtr(g));
+ update();
+ }
+ break;
+ case Qt::GestureCanceled:
+ emit logMessage(QLatin1String("=== Qt::GestureCanceled ==="));
+ break;
+ }
}
- return QWidget::event(event);
}
-};
+}
+
+void TouchTestWidget::paintEvent(QPaintEvent *)
+{
+ // Draw touch points as dots, mouse press as light filled circles, mouse release as circles.
+ QPainter painter(this);
+ const QRectF geom = QRectF(QPointF(0, 0), QSizeF(size()));
+ painter.fillRect(geom, Qt::white);
+ painter.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1, 1)));
+ foreach (const Point &point, m_points) {
+ if (geom.contains(point.pos)) {
+ const qreal radius = point.type == TouchPoint ? 1 : 4;
+ if (point.type == MouseRelease) {
+ drawCircle(point.pos, radius, point.color(), painter);
+ } else
+ fillCircle(point.pos, radius, point.color(), painter);
+ }
+ }
+ foreach (const GesturePtr &gp, m_gestures)
+ gp->draw(geom, painter);
+}
class MainWindow : public QMainWindow
{
@@ -108,7 +430,7 @@ public slots:
void dumpTouchDevices();
private:
- QWidget *m_touchWidget;
+ TouchTestWidget *m_touchWidget;
QPlainTextEdit *m_logTextEdit;
};
@@ -119,23 +441,38 @@ MainWindow::MainWindow()
setWindowTitle(QStringLiteral("Touch Event Tester ") + QT_VERSION_STR);
setObjectName("MainWin");
+ QToolBar *toolBar = new QToolBar(this);
+ addToolBar(Qt::TopToolBarArea, toolBar);
QMenu *fileMenu = menuBar()->addMenu("File");
- QAction *da = fileMenu->addAction(QStringLiteral("Dump devices"));
- da->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
- connect(da, SIGNAL(triggered()), this, SLOT(dumpTouchDevices()));
- QAction *qa = fileMenu->addAction(QStringLiteral("Quit"));
- qa->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
- connect(qa, SIGNAL(triggered()), this, SLOT(close()));
+ QAction *dumpDeviceAction = fileMenu->addAction(QStringLiteral("Dump devices"));
+ dumpDeviceAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
+ connect(dumpDeviceAction, SIGNAL(triggered()), this, SLOT(dumpTouchDevices()));
+ toolBar->addAction(dumpDeviceAction);
+ QAction *clearLogAction = fileMenu->addAction(QStringLiteral("Clear Log"));
+ clearLogAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
+ connect(clearLogAction, SIGNAL(triggered()), m_logTextEdit, SLOT(clear()));
+ toolBar->addAction(clearLogAction);
+ QAction *toggleDrawPointAction = fileMenu->addAction(QStringLiteral("Draw Points"));
+ toggleDrawPointAction->setCheckable(true);
+ toggleDrawPointAction->setChecked(m_touchWidget->drawPoints());
+ connect(toggleDrawPointAction, SIGNAL(toggled(bool)), m_touchWidget, SLOT(setDrawPoints(bool)));
+ toolBar->addAction(toggleDrawPointAction);
+ QAction *clearPointAction = fileMenu->addAction(QStringLiteral("Clear Points"));
+ clearPointAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
+ connect(clearPointAction, SIGNAL(triggered()), m_touchWidget, SLOT(clearPoints()));
+ toolBar->addAction(clearPointAction);
+ QAction *quitAction = fileMenu->addAction(QStringLiteral("Quit"));
+ quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+ toolBar->addAction(quitAction);
- QSplitter *mainSplitter = new QSplitter(Qt::Vertical);
+ QSplitter *mainSplitter = new QSplitter(Qt::Vertical, this);
m_touchWidget->setObjectName(QStringLiteral("TouchWidget"));
- const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size();
- m_touchWidget->setMinimumSize(screenSize / 2);
mainSplitter->addWidget(m_touchWidget);
+ connect(m_touchWidget, &TouchTestWidget::logMessage, this, &MainWindow::appendToLog);
m_logTextEdit->setObjectName(QStringLiteral("LogTextEdit"));
- m_logTextEdit->setMinimumHeight(screenSize.height() / 4);
mainSplitter->addWidget(m_logTextEdit);
setCentralWidget(mainSplitter);
@@ -165,19 +502,57 @@ int main(int argc, char *argv[])
const QCommandLineOption globalFilterOption(QStringLiteral("global"),
QStringLiteral("Global event filter"));
parser.addOption(globalFilterOption);
+
+ const QCommandLineOption ignoreTouchOption(QStringLiteral("ignore"),
+ QStringLiteral("Ignore touch events (for testing mouse emulation)."));
+ parser.addOption(ignoreTouchOption);
+ const QCommandLineOption noTouchLogOption(QStringLiteral("notouchlog"),
+ QStringLiteral("Do not log touch events (for testing gestures)."));
+ parser.addOption(noTouchLogOption);
+ const QCommandLineOption noMouseLogOption(QStringLiteral("nomouselog"),
+ QStringLiteral("Do not log mouse events (for testing gestures)."));
+ parser.addOption(noMouseLogOption);
+
+ const QCommandLineOption tapGestureOption(QStringLiteral("tap"), QStringLiteral("Grab tap gesture."));
+ parser.addOption(tapGestureOption);
+ const QCommandLineOption tapAndHoldGestureOption(QStringLiteral("tap-and-hold"),
+ QStringLiteral("Grab tap-and-hold gesture."));
+ parser.addOption(tapAndHoldGestureOption);
+ const QCommandLineOption panGestureOption(QStringLiteral("pan"), QStringLiteral("Grab pan gesture."));
+ parser.addOption(panGestureOption);
+ const QCommandLineOption pinchGestureOption(QStringLiteral("pinch"), QStringLiteral("Grab pinch gesture."));
+ parser.addOption(pinchGestureOption);
+ const QCommandLineOption swipeGestureOption(QStringLiteral("swipe"), QStringLiteral("Grab swipe gesture."));
+ parser.addOption(swipeGestureOption);
parser.process(QApplication::arguments());
+ optIgnoreTouch = parser.isSet(ignoreTouchOption);
+ if (parser.isSet(tapGestureOption))
+ optGestures.append(Qt::TapGesture);
+ if (parser.isSet(tapAndHoldGestureOption))
+ optGestures.append(Qt::TapAndHoldGesture);
+ if (parser.isSet(panGestureOption))
+ optGestures.append(Qt::PanGesture);
+ if (parser.isSet(pinchGestureOption))
+ optGestures.append(Qt::PinchGesture);
+ if (parser.isSet(swipeGestureOption))
+ optGestures.append(Qt::SwipeGesture);
MainWindow w;
+ const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size();
+ w.resize(screenSize / 2);
+ const QSize sizeDiff = screenSize - w.size();
+ w.move(sizeDiff.width() / 2, sizeDiff.height() / 2);
w.show();
- const QSize pos = QGuiApplication::primaryScreen()->availableGeometry().size() - w.size();
- w.move(pos.width() / 2, pos.height() / 2);
EventTypeVector eventTypes;
- eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease
- << QEvent::MouseButtonDblClick
- << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
+ if (!parser.isSet(noMouseLogOption))
+ eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick;
if (parser.isSet(mouseMoveOption))
eventTypes << QEvent::MouseMove;
+ if (!parser.isSet(noTouchLogOption))
+ eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
+ if (!optGestures.isEmpty())
+ eventTypes << QEvent::Gesture << QEvent::GestureOverride;
QObject *filterTarget = parser.isSet(globalFilterOption)
? static_cast<QObject *>(&a)
: static_cast<QObject *>(w.touchWidget());