Added rotation animation to paintedwindow example.

This serves as a useful test case for the QScreen orientation API.

Change-Id: I009ebd8b6d345453620420d84f3ff9d2d2e2663e
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Samuel Rødal 2011-11-23 09:36:51 +01:00 committed by Qt by Nokia
parent f1a67c6531
commit c7ba279815
3 changed files with 141 additions and 23 deletions

View File

@ -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();
}

View File

@ -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);
QOpenGLPaintDevice device(size());
QPainter painter(&device);
QPainterPath path;
path.addEllipse(mapped);
QPainter painter(&device);
painter.setTransform(QScreen::transformBetween(appOrientation, screenOrientation, rect));
painter.fillRect(mapped, Qt::white);
painter.setRenderHint(QPainter::Antialiasing);
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");
}

View File

@ -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;
};