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:
parent
f1a67c6531
commit
c7ba279815
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user