summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/opengl/paintedwindow/main.cpp3
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.cpp135
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.h26
3 files changed, 141 insertions, 23 deletions
diff --git a/examples/opengl/paintedwindow/main.cpp b/examples/opengl/paintedwindow/main.cpp
index d4eead9d40..c672798558 100644
--- a/examples/opengl/paintedwindow/main.cpp
+++ b/examples/opengl/paintedwindow/main.cpp
@@ -53,7 +53,7 @@ int main(int argc, char **argv)
QRect screenGeometry = screen->availableGeometry();
QPoint center = screenGeometry.center();
- QRect windowRect(0, 0, 640, 480);
+ QRect windowRect(0, 0, 480, 640);
PaintedWindow window;
window.setGeometry(QRect(center - windowRect.center(), windowRect.size()));
@@ -61,3 +61,4 @@ int main(int argc, char **argv)
app.exec();
}
+
diff --git a/examples/opengl/paintedwindow/paintedwindow.cpp b/examples/opengl/paintedwindow/paintedwindow.cpp
index 543c13eab3..78539d7ff1 100644
--- a/examples/opengl/paintedwindow/paintedwindow.cpp
+++ b/examples/opengl/paintedwindow/paintedwindow.cpp
@@ -64,6 +64,21 @@ PaintedWindow::PaintedWindow()
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
m_context->create();
+
+ m_animation = new QPropertyAnimation(this, "rotation");
+ m_animation->setStartValue(qreal(0));
+ m_animation->setEndValue(qreal(1));
+ m_animation->setDuration(500);
+
+ setOrientation(QGuiApplication::primaryScreen()->primaryOrientation());
+ m_rotation = 0;
+
+ m_targetOrientation = orientation();
+ m_nextTargetOrientation = Qt::UnknownOrientation;
+
+ connect(screen(), SIGNAL(currentOrientationChanged(Qt::ScreenOrientation)), this, SLOT(orientationChanged(Qt::ScreenOrientation)));
+ connect(m_animation, SIGNAL(finished()), this, SLOT(rotationDone()));
+ connect(this, SIGNAL(rotationChanged(qreal)), this, SLOT(paint()));
}
void PaintedWindow::resizeEvent(QResizeEvent *)
@@ -79,21 +94,18 @@ void PaintedWindow::exposeEvent(QExposeEvent *)
void PaintedWindow::mousePressEvent(QMouseEvent *)
{
Qt::ScreenOrientation o = orientation();
- if (o == Qt::UnknownOrientation)
- o = QGuiApplication::primaryScreen()->primaryOrientation();
-
switch (o) {
case Qt::LandscapeOrientation:
- setOrientation(Qt::PortraitOrientation);
+ orientationChanged(Qt::PortraitOrientation);
break;
case Qt::PortraitOrientation:
- setOrientation(Qt::InvertedLandscapeOrientation);
+ orientationChanged(Qt::InvertedLandscapeOrientation);
break;
case Qt::InvertedLandscapeOrientation:
- setOrientation(Qt::InvertedPortraitOrientation);
+ orientationChanged(Qt::InvertedPortraitOrientation);
break;
case Qt::InvertedPortraitOrientation:
- setOrientation(Qt::LandscapeOrientation);
+ orientationChanged(Qt::LandscapeOrientation);
break;
default:
Q_ASSERT(false);
@@ -102,31 +114,110 @@ void PaintedWindow::mousePressEvent(QMouseEvent *)
paint();
}
+void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
+{
+ if (orientation() == newOrientation)
+ return;
+
+ if (m_animation->state() == QAbstractAnimation::Running) {
+ m_nextTargetOrientation = newOrientation;
+ return;
+ }
+
+ Qt::ScreenOrientation screenOrientation = screen()->primaryOrientation();
+
+ QRect rect(0, 0, width(), height());
+
+ m_prevImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
+ m_nextImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
+ m_prevImage.fill(0);
+ m_nextImage.fill(0);
+
+ QPainter p;
+ p.begin(&m_prevImage);
+ p.setTransform(QScreen::transformBetween(orientation(), screenOrientation, rect));
+ paint(&p, QScreen::mapBetween(orientation(), screenOrientation, rect));
+ p.end();
+
+ p.begin(&m_nextImage);
+ p.setTransform(QScreen::transformBetween(newOrientation, screenOrientation, rect));
+ paint(&p, QScreen::mapBetween(newOrientation, screenOrientation, rect));
+ p.end();
+
+ m_deltaRotation = QScreen::angleBetween(newOrientation, orientation());
+ if (m_deltaRotation > 180)
+ m_deltaRotation = 180 - m_deltaRotation;
+
+ m_targetOrientation = newOrientation;
+ m_animation->start();
+}
+
+void PaintedWindow::rotationDone()
+{
+ setOrientation(m_targetOrientation);
+ if (m_nextTargetOrientation != Qt::UnknownOrientation) {
+ Q_ASSERT(m_animation->state() != QAbstractAnimation::Running);
+ orientationChanged(m_nextTargetOrientation);
+ m_nextTargetOrientation = Qt::UnknownOrientation;
+ }
+}
+
+void PaintedWindow::setRotation(qreal r)
+{
+ if (r != m_rotation) {
+ m_rotation = r;
+ emit rotationChanged(r);
+ }
+}
+
void PaintedWindow::paint()
{
m_context->makeCurrent(this);
- QOpenGLPaintDevice device(size());
-
- Qt::ScreenOrientation screenOrientation = QGuiApplication::primaryScreen()->primaryOrientation();
+ Qt::ScreenOrientation screenOrientation = screen()->primaryOrientation();
Qt::ScreenOrientation appOrientation = orientation();
QRect rect(0, 0, width(), height());
- QRect mapped = QScreen::mapBetween(appOrientation, screenOrientation, rect);
-
- QPainterPath path;
- path.addEllipse(mapped);
+ QOpenGLPaintDevice device(size());
QPainter painter(&device);
- painter.setTransform(QScreen::transformBetween(appOrientation, screenOrientation, rect));
- painter.fillRect(mapped, Qt::white);
- painter.setRenderHint(QPainter::Antialiasing);
+
+ QPainterPath path;
+ path.addEllipse(rect);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(rect, Qt::transparent);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.fillPath(path, Qt::blue);
- QFont font;
- font.setPixelSize(64);
- painter.setFont(font);
- painter.drawText(mapped, Qt::AlignCenter, "Hello");
- painter.end();
+
+ if (orientation() != m_targetOrientation) {
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ painter.save();
+ painter.translate(width() / 2, height() / 2);
+ painter.rotate(m_deltaRotation * m_rotation);
+ painter.translate(-width() / 2, -height() / 2);
+ painter.drawImage(0, 0, m_prevImage);
+ painter.restore();
+ painter.translate(width() / 2, height() / 2);
+ painter.rotate(m_deltaRotation * m_rotation - m_deltaRotation);
+ painter.translate(-width() / 2, -height() / 2);
+ painter.setOpacity(m_rotation);
+ painter.drawImage(0, 0, m_nextImage);
+ } else {
+ QRect mapped = QScreen::mapBetween(appOrientation, screenOrientation, rect);
+
+ painter.setTransform(QScreen::transformBetween(appOrientation, screenOrientation, rect));
+ paint(&painter, mapped);
+ painter.end();
+ }
m_context->swapBuffers(this);
}
+
+void PaintedWindow::paint(QPainter *painter, const QRect &rect)
+{
+ painter->setRenderHint(QPainter::Antialiasing);
+ QFont font;
+ font.setPixelSize(64);
+ painter->setFont(font);
+ painter->drawText(rect, Qt::AlignCenter, "Hello");
+}
diff --git a/examples/opengl/paintedwindow/paintedwindow.h b/examples/opengl/paintedwindow/paintedwindow.h
index dcf8110e24..28e06ec4df 100644
--- a/examples/opengl/paintedwindow/paintedwindow.h
+++ b/examples/opengl/paintedwindow/paintedwindow.h
@@ -44,7 +44,10 @@
#include <QtGui/qopenglshaderprogram.h>
#include <QtGui/qopenglframebufferobject.h>
+#include <QPropertyAnimation>
+
#include <QColor>
+#include <QImage>
#include <QTime>
QT_BEGIN_NAMESPACE
@@ -54,16 +57,39 @@ QT_END_NAMESPACE
class PaintedWindow : public QWindow
{
Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
+
public:
PaintedWindow();
+ qreal rotation() const { return m_rotation; }
+
+signals:
+ void rotationChanged(qreal rotation);
+
private slots:
void paint();
+ void setRotation(qreal r);
+ void orientationChanged(Qt::ScreenOrientation newOrientation);
+ void rotationDone();
private:
void resizeEvent(QResizeEvent *);
void exposeEvent(QExposeEvent *);
void mousePressEvent(QMouseEvent *);
+ void paint(QPainter *painter, const QRect &rect);
+
QOpenGLContext *m_context;
+ qreal m_rotation;
+
+ QImage m_prevImage;
+ QImage m_nextImage;
+ qreal m_deltaRotation;
+
+ Qt::ScreenOrientation m_targetOrientation;
+ Qt::ScreenOrientation m_nextTargetOrientation;
+
+ QPropertyAnimation *m_animation;
+ QTimer *m_paintTimer;
};