From e48737ae778b8ef5e8e905825a2787b97deea23d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 20 Mar 2014 12:58:22 +0100 Subject: Introduce QOpenGLWindow [ChangeLog] Added QOpenGLWindow. This serves as a convenience class for creating windows showing OpenGL content via an API similar to QGLWidget and without any widget dependencies. Done-with: Jorgen Lind Task-number: QTBUG-36899 Change-Id: I52e9bc61acb129dbfd3841b3adeffab2dbcf7f05 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qpaintdevicewindow.cpp | 214 ++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 src/gui/kernel/qpaintdevicewindow.cpp (limited to 'src/gui/kernel/qpaintdevicewindow.cpp') diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp new file mode 100644 index 0000000000..232e8b5d6d --- /dev/null +++ b/src/gui/kernel/qpaintdevicewindow.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpaintdevicewindow_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QPaintDeviceWindow + \inmodule QtGui + \since 5.4 + \brief Convenience subclass of QWindow that is also a QPaintDevice. + + QPaintDeviceWindow is like a regular QWindow, with the added functionality + of being a paint device too. Whenever the content needs to be updated, + the virtual paintEvent() function is called. Subclasses, that reimplement + this function, can then simply open a QPainter on the window. + + \note This class cannot directly be used in applications. It rather serves + as a base for subclasses like QOpenGLWindow. + + \sa QOpenGLWindow +*/ + +/*! + Marks the entire window as dirty and schedules a repaint. + + \note Subsequent calls to this function before the next paint + event will get ignored. +*/ +void QPaintDeviceWindow::update() +{ + update(QRect(QPoint(0,0), size())); +} + +/*! + Marks the \a rect of the window as dirty and schedules a repaint. + + \note Subsequent calls to this function before the next paint + event will get ignored. +*/ +void QPaintDeviceWindow::update(const QRect &rect) +{ + Q_D(QPaintDeviceWindow); + d->dirtyRegion += rect; + d->triggerUpdate(); +} + +/*! + Marks the \a region of the window as dirty and schedules a repaint. + + \note Subsequent calls to this function before the next paint + event will get ignored. +*/ +void QPaintDeviceWindow::update(const QRegion ®ion) +{ + Q_D(QPaintDeviceWindow); + d->dirtyRegion += region; + d->triggerUpdate(); +} + +/*! + Handles paint events passed in the \a event parameter. + + The default implementation does nothing. Reimplement this function to + perform painting. If necessary, the dirty area is retrievable from + the \a event. +*/ +void QPaintDeviceWindow::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + // Do nothing +} + +/*! + \internal + */ +int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const +{ + QScreen *screen = this->screen(); + if (!screen && QGuiApplication::primaryScreen()) + screen = QGuiApplication::primaryScreen(); + + switch (metric) { + case PdmWidth: + return width(); + case PdmWidthMM: + if (screen) + return width() * screen->physicalSize().width() / screen->geometry().width(); + break; + case PdmHeight: + return height(); + case PdmHeightMM: + if (screen) + return height() * screen->physicalSize().height() / screen->geometry().height(); + break; + case PdmDpiX: + if (screen) + return qRound(screen->logicalDotsPerInchX()); + break; + case PdmDpiY: + if (screen) + return qRound(screen->logicalDotsPerInchY()); + break; + case PdmPhysicalDpiX: + if (screen) + return qRound(screen->physicalDotsPerInchX()); + break; + case PdmPhysicalDpiY: + if (screen) + return qRound(screen->physicalDotsPerInchY()); + break; + case PdmDevicePixelRatio: + if (screen) + return screen->devicePixelRatio(); + break; + default: + break; + } + + return QPaintDevice::metric(metric); +} + +/*! + \internal + */ +void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent) +{ + Q_UNUSED(exposeEvent); + Q_D(QPaintDeviceWindow); + if (isExposed()) { + d->markWindowAsDirty(); + // Do not rely on exposeEvent->region() as it has some issues for the + // time being, namely that it is sometimes in local coordinates, + // sometimes relative to the parent, depending on the platform plugin. + // We require local coords here. + d->doFlush(QRect(QPoint(0, 0), size())); + } +} + +/*! + \internal + */ +bool QPaintDeviceWindow::event(QEvent *event) +{ + Q_D(QPaintDeviceWindow); + + if (event->type() == QEvent::UpdateRequest) { + d->paintEventSent = false; + d->handleUpdateEvent(); + return true; + } + + return QWindow::event(event); +} + +/*! + \internal + */ +QPaintDeviceWindow::QPaintDeviceWindow(QPaintDeviceWindowPrivate &dd, QWindow *parent) + : QWindow(dd, parent) +{ +} + +/*! + \internal + */ +QPaintEngine *QPaintDeviceWindow::paintEngine() const +{ + return 0; +} + +QT_END_NAMESPACE -- cgit v1.2.3