Made window orientation API more flexible.
Previously we only had QWindow::setOrientation() which was a hint about the orientation the window's contents were rendered in. However, it's necessary to separate between the orientation corresponding to the window buffer layout and orientation of the contents. A game for example might typically want to use a landscape buffer even on a portrait device. Thus, we replace QWindow::orientation() with QWindow::reportContentOrientationChange() and QWindow::requestWindowOrientation(). Change-Id: I1f07362192daf36c45519cb05b43ac352f1945b5 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
parent
b0a0403daf
commit
b39df8bf92
@ -40,7 +40,6 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QRect>
|
||||
#include <QScreen>
|
||||
|
||||
#include "paintedwindow.h"
|
||||
|
||||
@ -48,15 +47,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
|
||||
QRect screenGeometry = screen->availableGeometry();
|
||||
|
||||
QPoint center = screenGeometry.center();
|
||||
QRect windowRect(0, 0, 480, 640);
|
||||
|
||||
PaintedWindow window;
|
||||
window.setGeometry(QRect(center - windowRect.center(), windowRect.size()));
|
||||
window.show();
|
||||
|
||||
app.exec();
|
||||
|
@ -70,13 +70,22 @@ PaintedWindow::PaintedWindow()
|
||||
m_animation->setEndValue(qreal(1));
|
||||
m_animation->setDuration(500);
|
||||
|
||||
setOrientation(QGuiApplication::primaryScreen()->primaryOrientation());
|
||||
requestWindowOrientation(Qt::PortraitOrientation);
|
||||
|
||||
QRect screenGeometry = screen()->availableGeometry();
|
||||
|
||||
QPoint center = screenGeometry.center();
|
||||
QRect windowRect = screen()->isLandscape(windowOrientation()) ? QRect(0, 0, 640, 480) : QRect(0, 0, 480, 640);
|
||||
setGeometry(QRect(center - windowRect.center(), windowRect.size()));
|
||||
|
||||
m_rotation = 0;
|
||||
|
||||
m_targetOrientation = orientation();
|
||||
m_nextTargetOrientation = Qt::UnknownOrientation;
|
||||
reportContentOrientationChange(screen()->orientation());
|
||||
|
||||
connect(screen(), SIGNAL(currentOrientationChanged(Qt::ScreenOrientation)), this, SLOT(orientationChanged(Qt::ScreenOrientation)));
|
||||
m_targetOrientation = contentOrientation();
|
||||
m_nextTargetOrientation = Qt::PrimaryOrientation;
|
||||
|
||||
connect(screen(), SIGNAL(orientationChanged(Qt::ScreenOrientation)), this, SLOT(orientationChanged(Qt::ScreenOrientation)));
|
||||
connect(m_animation, SIGNAL(finished()), this, SLOT(rotationDone()));
|
||||
connect(this, SIGNAL(rotationChanged(qreal)), this, SLOT(paint()));
|
||||
}
|
||||
@ -93,7 +102,7 @@ void PaintedWindow::exposeEvent(QExposeEvent *)
|
||||
|
||||
void PaintedWindow::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
Qt::ScreenOrientation o = orientation();
|
||||
Qt::ScreenOrientation o = contentOrientation();
|
||||
switch (o) {
|
||||
case Qt::LandscapeOrientation:
|
||||
orientationChanged(Qt::PortraitOrientation);
|
||||
@ -116,7 +125,7 @@ void PaintedWindow::mousePressEvent(QMouseEvent *)
|
||||
|
||||
void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
|
||||
{
|
||||
if (orientation() == newOrientation)
|
||||
if (contentOrientation() == newOrientation)
|
||||
return;
|
||||
|
||||
if (m_animation->state() == QAbstractAnimation::Running) {
|
||||
@ -124,8 +133,6 @@ void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
|
||||
return;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation screenOrientation = screen()->primaryOrientation();
|
||||
|
||||
QRect rect(0, 0, width(), height());
|
||||
|
||||
m_prevImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
|
||||
@ -135,16 +142,16 @@ void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
|
||||
|
||||
QPainter p;
|
||||
p.begin(&m_prevImage);
|
||||
p.setTransform(QScreen::transformBetween(orientation(), screenOrientation, rect));
|
||||
paint(&p, QScreen::mapBetween(orientation(), screenOrientation, rect));
|
||||
p.setTransform(screen()->transformBetween(contentOrientation(), windowOrientation(), rect));
|
||||
paint(&p, screen()->mapBetween(contentOrientation(), windowOrientation(), rect));
|
||||
p.end();
|
||||
|
||||
p.begin(&m_nextImage);
|
||||
p.setTransform(QScreen::transformBetween(newOrientation, screenOrientation, rect));
|
||||
paint(&p, QScreen::mapBetween(newOrientation, screenOrientation, rect));
|
||||
p.setTransform(screen()->transformBetween(newOrientation, windowOrientation(), rect));
|
||||
paint(&p, screen()->mapBetween(newOrientation, windowOrientation(), rect));
|
||||
p.end();
|
||||
|
||||
m_deltaRotation = QScreen::angleBetween(newOrientation, orientation());
|
||||
m_deltaRotation = screen()->angleBetween(newOrientation, contentOrientation());
|
||||
if (m_deltaRotation > 180)
|
||||
m_deltaRotation = 180 - m_deltaRotation;
|
||||
|
||||
@ -154,11 +161,11 @@ void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
|
||||
|
||||
void PaintedWindow::rotationDone()
|
||||
{
|
||||
setOrientation(m_targetOrientation);
|
||||
if (m_nextTargetOrientation != Qt::UnknownOrientation) {
|
||||
reportContentOrientationChange(m_targetOrientation);
|
||||
if (m_nextTargetOrientation != Qt::PrimaryOrientation) {
|
||||
Q_ASSERT(m_animation->state() != QAbstractAnimation::Running);
|
||||
orientationChanged(m_nextTargetOrientation);
|
||||
m_nextTargetOrientation = Qt::UnknownOrientation;
|
||||
m_nextTargetOrientation = Qt::PrimaryOrientation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,9 +181,6 @@ void PaintedWindow::paint()
|
||||
{
|
||||
m_context->makeCurrent(this);
|
||||
|
||||
Qt::ScreenOrientation screenOrientation = screen()->primaryOrientation();
|
||||
Qt::ScreenOrientation appOrientation = orientation();
|
||||
|
||||
QRect rect(0, 0, width(), height());
|
||||
|
||||
QOpenGLPaintDevice device(size());
|
||||
@ -189,7 +193,7 @@ void PaintedWindow::paint()
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
painter.fillPath(path, Qt::blue);
|
||||
|
||||
if (orientation() != m_targetOrientation) {
|
||||
if (contentOrientation() != m_targetOrientation) {
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.save();
|
||||
painter.translate(width() / 2, height() / 2);
|
||||
@ -203,9 +207,9 @@ void PaintedWindow::paint()
|
||||
painter.setOpacity(m_rotation);
|
||||
painter.drawImage(0, 0, m_nextImage);
|
||||
} else {
|
||||
QRect mapped = QScreen::mapBetween(appOrientation, screenOrientation, rect);
|
||||
QRect mapped = screen()->mapBetween(contentOrientation(), windowOrientation(), rect);
|
||||
|
||||
painter.setTransform(QScreen::transformBetween(appOrientation, screenOrientation, rect));
|
||||
painter.setTransform(screen()->transformBetween(contentOrientation(), windowOrientation(), rect));
|
||||
paint(&painter, mapped);
|
||||
painter.end();
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ public:
|
||||
Q_DECLARE_FLAGS(WindowStates, WindowState)
|
||||
|
||||
enum ScreenOrientation {
|
||||
UnknownOrientation = 0x00000000,
|
||||
PrimaryOrientation = 0x00000000,
|
||||
PortraitOrientation = 0x00000001,
|
||||
LandscapeOrientation = 0x00000002,
|
||||
InvertedPortraitOrientation = 0x00000004,
|
||||
|
@ -1821,7 +1821,8 @@
|
||||
|
||||
This enum type specifies the various orientations a screen might have.
|
||||
|
||||
\value UnknownOrientation The orientation is unknown or the platform doesn't support orientations.
|
||||
\value PrimaryOrientation The display's primary orientation. The QWindow and QScreen APIs never return this value,
|
||||
instead it will be mapped to the corresponding QScreen's QScreen::primaryOrientation().
|
||||
\value LandscapeOrientation Landscape orientation, display width is greater than display height.
|
||||
\value PortraitOrientation Portrait orientation, display height is greater than display width,
|
||||
rotated 90 degree clockwise relative to landscape.
|
||||
|
@ -1078,11 +1078,16 @@ void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfac
|
||||
return;
|
||||
|
||||
QScreen *s = e->screen.data();
|
||||
s->d_func()->currentOrientation = e->orientation;
|
||||
s->d_func()->orientation = e->orientation;
|
||||
|
||||
emit s->currentOrientationChanged(s->currentOrientation());
|
||||
reportScreenOrientationChange(s);
|
||||
}
|
||||
|
||||
QScreenOrientationChangeEvent event(s, s->currentOrientation());
|
||||
void QGuiApplicationPrivate::reportScreenOrientationChange(QScreen *s)
|
||||
{
|
||||
emit s->orientationChanged(s->orientation());
|
||||
|
||||
QScreenOrientationChangeEvent event(s, s->orientation());
|
||||
QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
|
||||
}
|
||||
|
||||
@ -1098,6 +1103,10 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
|
||||
QScreen *s = e->screen.data();
|
||||
s->d_func()->geometry = e->geometry;
|
||||
|
||||
Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
|
||||
Qt::ScreenOrientation orientation = s->orientation();
|
||||
s->d_func()->updatePrimaryOrientation();
|
||||
|
||||
emit s->sizeChanged(s->size());
|
||||
emit s->geometryChanged(s->geometry());
|
||||
emit s->physicalDotsPerInchXChanged(s->physicalDotsPerInchX());
|
||||
@ -1105,6 +1114,12 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
|
||||
emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
|
||||
emit s->availableSizeChanged(s->availableSize());
|
||||
emit s->availableGeometryChanged(s->availableGeometry());
|
||||
|
||||
if (s->primaryOrientation() != primaryOrientation)
|
||||
emit s->primaryOrientationChanged(s->primaryOrientation());
|
||||
|
||||
if (s->orientation() != orientation)
|
||||
reportScreenOrientationChange(s);
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::reportAvailableGeometryChange(
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
|
||||
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
|
||||
|
||||
static void reportScreenOrientationChange(QScreen *screen);
|
||||
static void reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
|
||||
static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
|
||||
static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
|
||||
|
@ -159,37 +159,16 @@ QDpi QPlatformScreen::logicalDpi() const
|
||||
25.4 * s.height() / ps.height());
|
||||
}
|
||||
|
||||
/*!
|
||||
Reimplement this function in subclass to return the primary orientation
|
||||
of the screen, i.e. the orientation the display controller or equivalent
|
||||
expects.
|
||||
|
||||
The default implementation returns Qt::PortraitOrientation if the
|
||||
geometry's height is greater or Qt::LandscapeOrientation if the geometry's
|
||||
width is greater.
|
||||
*/
|
||||
Qt::ScreenOrientation QPlatformScreen::primaryOrientation() const
|
||||
{
|
||||
return geometry().height() > geometry().width() ? Qt::PortraitOrientation :
|
||||
Qt::LandscapeOrientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
Reimplement this function in subclass to return the current orientation
|
||||
of the screen, for example based on accelerometer data to determine
|
||||
the physical screen orientation.
|
||||
the device orientation.
|
||||
|
||||
The current orientation is only a hint to the application saying
|
||||
what the preferred application orientation should be, the application
|
||||
is free to limit itself to a certain set of supported orientations.
|
||||
|
||||
The default implementation returns the same as primaryOrientation().
|
||||
|
||||
\sa primaryOrientation()
|
||||
The default implementation returns Qt::PrimaryOrientation.
|
||||
*/
|
||||
Qt::ScreenOrientation QPlatformScreen::currentOrientation() const
|
||||
Qt::ScreenOrientation QPlatformScreen::orientation() const
|
||||
{
|
||||
return primaryOrientation();
|
||||
return Qt::PrimaryOrientation;
|
||||
}
|
||||
|
||||
QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window)
|
||||
|
@ -99,8 +99,7 @@ public:
|
||||
virtual QSizeF physicalSize() const;
|
||||
virtual QDpi logicalDpi() const;
|
||||
|
||||
virtual Qt::ScreenOrientation currentOrientation() const;
|
||||
virtual Qt::ScreenOrientation primaryOrientation() const;
|
||||
virtual Qt::ScreenOrientation orientation() const;
|
||||
|
||||
virtual QWindow *topLevelAt(const QPoint &point) const;
|
||||
virtual QList<QPlatformScreen *> virtualSiblings() const;
|
||||
|
@ -239,19 +239,44 @@ void QPlatformWindow::requestActivateWindow()
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the orientation of the platform window's contents.
|
||||
Handle changes to the orientation of the platform window's contents.
|
||||
|
||||
This is a hint to the window manager in case it needs to display
|
||||
additional content like popups, dialogs, status bars, or similar
|
||||
in relation to the window.
|
||||
|
||||
\sa QWindow::setOrientation()
|
||||
\sa QWindow::reportContentOrientationChange()
|
||||
*/
|
||||
void QPlatformWindow::setOrientation(Qt::ScreenOrientation orientation)
|
||||
void QPlatformWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
Q_UNUSED(orientation);
|
||||
}
|
||||
|
||||
/*!
|
||||
Request a different orientation of the platform window.
|
||||
|
||||
This tells the window manager how the window wants to be rotated in order
|
||||
to be displayed, and how input events should be translated.
|
||||
|
||||
As an example, a portrait compositor might rotate the window by 90 degrees,
|
||||
if the window is in landscape. It will also rotate input coordinates from
|
||||
portrait to landscape such that top right in portrait gets mapped to top
|
||||
left in landscape.
|
||||
|
||||
If the implementation doesn't support the requested orientation it should
|
||||
signal this by returning an actual supported orientation.
|
||||
|
||||
If the implementation doesn't support rotating the window at all it should
|
||||
return Qt::PrimaryOrientation, this is also the default value.
|
||||
|
||||
\sa QWindow::requestWindowOrientation()
|
||||
*/
|
||||
Qt::ScreenOrientation QPlatformWindow::requestWindowOrientation(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
Q_UNUSED(orientation);
|
||||
return Qt::PrimaryOrientation;
|
||||
}
|
||||
|
||||
bool QPlatformWindow::setKeyboardGrabEnabled(bool grab)
|
||||
{
|
||||
Q_UNUSED(grab);
|
||||
|
@ -95,7 +95,8 @@ public:
|
||||
virtual void setOpacity(qreal level);
|
||||
virtual void requestActivateWindow();
|
||||
|
||||
virtual void setOrientation(Qt::ScreenOrientation orientation);
|
||||
virtual void handleContentOrientationChange(Qt::ScreenOrientation orientation);
|
||||
virtual Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation);
|
||||
|
||||
virtual bool setKeyboardGrabEnabled(bool grab);
|
||||
virtual bool setMouseGrabEnabled(bool grab);
|
||||
|
@ -343,35 +343,36 @@ QRect QScreen::availableVirtualGeometry() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QScreen::primaryOrientation
|
||||
\brief the primary screen orientation
|
||||
\property QScreen::orientation
|
||||
\brief the screen orientation
|
||||
|
||||
The primary screen orientation is the orientation that corresponds
|
||||
to an un-rotated screen buffer. When the current orientation is equal
|
||||
to the primary orientation no rotation needs to be done by the
|
||||
application.
|
||||
The screen orientation represents the physical orientation
|
||||
of the display. For example, the screen orientation of a mobile device
|
||||
will change based on the device is being held, and a desktop display
|
||||
might be rotated so that it's in portrait mode.
|
||||
|
||||
\sa primaryOrientation(), orientationChanged()
|
||||
*/
|
||||
Qt::ScreenOrientation QScreen::primaryOrientation() const
|
||||
Qt::ScreenOrientation QScreen::orientation() const
|
||||
{
|
||||
Q_D(const QScreen);
|
||||
return d->platformScreen->primaryOrientation();
|
||||
return d->orientation == Qt::PrimaryOrientation ? primaryOrientation() : d->orientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QScreen::primaryOrientation
|
||||
\brief the current screen orientation
|
||||
\brief the primary screen orientation
|
||||
|
||||
The current orientation is a hint to the application saying
|
||||
what the preferred application orientation should be, based on the
|
||||
current orientation of the physical display and / or other factors.
|
||||
The primary screen orientation is Qt::LandscapeOrientation
|
||||
if the screen geometry's width is greater than or equal to its
|
||||
height, or Qt::PortraitOrientation otherwise.
|
||||
|
||||
\sa primaryOrientation()
|
||||
\sa currentOrientationChanged()
|
||||
\sa primaryOrientationChanged()
|
||||
*/
|
||||
Qt::ScreenOrientation QScreen::currentOrientation() const
|
||||
Qt::ScreenOrientation QScreen::primaryOrientation() const
|
||||
{
|
||||
Q_D(const QScreen);
|
||||
return d->currentOrientation;
|
||||
return d->primaryOrientation;
|
||||
}
|
||||
|
||||
// i must be power of two
|
||||
@ -393,10 +394,18 @@ static int log2(uint i)
|
||||
rotation \a a to rotation \a b.
|
||||
|
||||
The result will be 0, 90, 180, or 270.
|
||||
|
||||
Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
|
||||
*/
|
||||
int QScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
|
||||
{
|
||||
if (a == Qt::UnknownOrientation || b == Qt::UnknownOrientation || a == b)
|
||||
if (a == Qt::PrimaryOrientation)
|
||||
a = primaryOrientation();
|
||||
|
||||
if (b == Qt::PrimaryOrientation)
|
||||
b = primaryOrientation();
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
|
||||
int ia = log2(uint(a));
|
||||
@ -420,10 +429,18 @@ int QScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
|
||||
the resulting transform will be such that the point QPoint(0, 0) is mapped to QPoint(0, w),
|
||||
and QPoint(h, w) is mapped to QPoint(0, h). Thus, the landscape coordinate system QRect(0, 0, h, w)
|
||||
is mapped (with a 90 degree rotation) into the portrait coordinate system QRect(0, 0, w, h).
|
||||
|
||||
Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
|
||||
*/
|
||||
QTransform QScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target)
|
||||
{
|
||||
if (a == Qt::UnknownOrientation || b == Qt::UnknownOrientation || a == b)
|
||||
if (a == Qt::PrimaryOrientation)
|
||||
a = primaryOrientation();
|
||||
|
||||
if (b == Qt::PrimaryOrientation)
|
||||
b = primaryOrientation();
|
||||
|
||||
if (a == b)
|
||||
return QTransform();
|
||||
|
||||
int angle = angleBetween(a, b);
|
||||
@ -453,10 +470,18 @@ QTransform QScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientat
|
||||
This will flip the x and y dimensions of the rectangle if orientation \a is
|
||||
Qt::PortraitOrientation or Qt::InvertedPortraitOrientation and orientation \b is
|
||||
Qt::LandscapeOrientation or Qt::InvertedLandscapeOrientation, or vice versa.
|
||||
|
||||
Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
|
||||
*/
|
||||
QRect QScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect)
|
||||
{
|
||||
if (a == Qt::UnknownOrientation || b == Qt::UnknownOrientation || a == b)
|
||||
if (a == Qt::PrimaryOrientation)
|
||||
a = primaryOrientation();
|
||||
|
||||
if (b == Qt::PrimaryOrientation)
|
||||
b = primaryOrientation();
|
||||
|
||||
if (a == b)
|
||||
return rect;
|
||||
|
||||
if ((a == Qt::PortraitOrientation || a == Qt::InvertedPortraitOrientation)
|
||||
@ -469,14 +494,50 @@ QRect QScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, cons
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QScreen::currentOrientationChanged(Qt::ScreenOrientation orientation)
|
||||
Convenience function to check if a screen orientation is either portrait
|
||||
or inverted portrait.
|
||||
|
||||
This signal is emitted when the current orientation of the screen
|
||||
changes. The current orientation is a hint to the application saying
|
||||
what the preferred application orientation should be, based on the
|
||||
current orientation of the physical display and / or other factors.
|
||||
Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
|
||||
*/
|
||||
bool QScreen::isPortrait(Qt::ScreenOrientation o)
|
||||
{
|
||||
return o == Qt::PortraitOrientation || o == Qt::InvertedPortraitOrientation
|
||||
|| (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::PortraitOrientation);
|
||||
}
|
||||
|
||||
\sa currentOrientation()
|
||||
/*!
|
||||
Convenience function to check if a screen orientation is either landscape
|
||||
or inverted landscape.
|
||||
|
||||
Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
|
||||
*/
|
||||
bool QScreen::isLandscape(Qt::ScreenOrientation o)
|
||||
{
|
||||
return o == Qt::LandscapeOrientation || o == Qt::InvertedLandscapeOrientation
|
||||
|| (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::LandscapeOrientation);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QScreen::orientationChanged(Qt::ScreenOrientation orientation)
|
||||
|
||||
This signal is emitted when the orientation of the screen
|
||||
changes.
|
||||
|
||||
\sa orientation()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation)
|
||||
|
||||
This signal is emitted when the primary orientation of the screen
|
||||
changes.
|
||||
|
||||
\sa primaryOrientation()
|
||||
*/
|
||||
|
||||
void QScreenPrivate::updatePrimaryOrientation()
|
||||
{
|
||||
primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -81,8 +81,8 @@ class Q_GUI_EXPORT QScreen : public QObject
|
||||
Q_PROPERTY(qreal logicalDotsPerInch READ logicalDotsPerInch NOTIFY logicalDotsPerInchChanged)
|
||||
Q_PROPERTY(QSize availableSize READ availableSize NOTIFY availableSizeChanged)
|
||||
Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY availableGeometryChanged)
|
||||
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation CONSTANT)
|
||||
Q_PROPERTY(Qt::ScreenOrientation currentOrientation READ currentOrientation NOTIFY currentOrientationChanged)
|
||||
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ orientation NOTIFY primaryOrientationChanged)
|
||||
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
|
||||
|
||||
public:
|
||||
QPlatformScreen *handle() const;
|
||||
@ -116,11 +116,14 @@ public:
|
||||
QRect availableVirtualGeometry() const;
|
||||
|
||||
Qt::ScreenOrientation primaryOrientation() const;
|
||||
Qt::ScreenOrientation currentOrientation() const;
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
|
||||
static int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b);
|
||||
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
|
||||
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
|
||||
int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b);
|
||||
QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
|
||||
QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
|
||||
|
||||
bool isPortrait(Qt::ScreenOrientation orientation);
|
||||
bool isLandscape(Qt::ScreenOrientation orientation);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sizeChanged(const QSize &size);
|
||||
@ -133,7 +136,8 @@ Q_SIGNALS:
|
||||
void logicalDotsPerInchChanged(qreal dpi);
|
||||
void availableSizeChanged(const QSize &size);
|
||||
void availableGeometryChanged(const QRect &rect);
|
||||
void currentOrientationChanged(Qt::ScreenOrientation orientation);
|
||||
void primaryOrientationChanged(Qt::ScreenOrientation orientation);
|
||||
void orientationChanged(Qt::ScreenOrientation orientation);
|
||||
|
||||
private:
|
||||
QScreen(QPlatformScreen *screen);
|
||||
|
@ -59,13 +59,18 @@ public:
|
||||
QScreenPrivate(QPlatformScreen *screen)
|
||||
: platformScreen(screen)
|
||||
{
|
||||
currentOrientation = screen->currentOrientation();
|
||||
orientation = screen->orientation();
|
||||
geometry = screen->geometry();
|
||||
availableGeometry = screen->availableGeometry();
|
||||
logicalDpi = screen->logicalDpi();
|
||||
|
||||
updatePrimaryOrientation();
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation currentOrientation;
|
||||
void updatePrimaryOrientation();
|
||||
|
||||
Qt::ScreenOrientation orientation;
|
||||
Qt::ScreenOrientation primaryOrientation;
|
||||
QRect geometry;
|
||||
QRect availableGeometry;
|
||||
QDpi logicalDpi;
|
||||
|
@ -72,8 +72,24 @@ QT_BEGIN_NAMESPACE
|
||||
to support double and triple buffering. To release a windows memory
|
||||
resources, the destroy() function.
|
||||
|
||||
*/
|
||||
\section1 Window and content orientation
|
||||
|
||||
QWindow has reportContentOrientationChange() and
|
||||
requestWindowOrientation() that can be used to specify the
|
||||
layout of the window contents in relation to the screen. The
|
||||
window orientation determines the actual buffer layout of the
|
||||
window, and the windowing system uses this value to rotate the
|
||||
window before it ends up on the display, and to ensure that input
|
||||
coordinates are in the correct coordinate space relative to the
|
||||
application.
|
||||
|
||||
On the other hand, the content orientation is simply a hint to the
|
||||
windowing system about which orientation the window contents are in.
|
||||
It's useful when you wish to keep the same buffer layout, but rotate
|
||||
the contents instead, especially when doing rotation animations
|
||||
between different orientations. The windowing system might use this
|
||||
value to determine the layout of system popups or dialogs.
|
||||
*/
|
||||
QWindow::QWindow(QScreen *targetScreen)
|
||||
: QObject(*new QWindowPrivate(), 0)
|
||||
, QSurface(QSurface::Window)
|
||||
@ -375,42 +391,82 @@ bool QWindow::isActive() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the window's currently set orientation.
|
||||
|
||||
The default value is Qt::UnknownOrientation.
|
||||
|
||||
\sa setOrientation(), QScreen::currentOrientation()
|
||||
*/
|
||||
Qt::ScreenOrientation QWindow::orientation() const
|
||||
{
|
||||
Q_D(const QWindow);
|
||||
return d->orientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the orientation of the window's contents.
|
||||
Reports that the orientation of the window's contents have changed.
|
||||
|
||||
This is a hint to the window manager in case it needs to display
|
||||
additional content like popups, dialogs, status bars, or similar
|
||||
in relation to the window.
|
||||
|
||||
The recommended orientation is QScreen::currentOrientation() but
|
||||
The recommended orientation is QScreen::orientation() but
|
||||
an application doesn't have to support all possible orientations,
|
||||
and thus can opt to ignore the current screen orientation.
|
||||
|
||||
\sa QScreen::currentOrientation()
|
||||
The difference between the window and the content orientation
|
||||
determines how much to rotate the content by. QScreen::angleBetween(),
|
||||
QScreen::transformBetween(), and QScreen::mapBetween() can be used
|
||||
to compute the necessary transform.
|
||||
|
||||
\sa requestWindowOrientation(), QScreen::orientation()
|
||||
*/
|
||||
void QWindow::setOrientation(Qt::ScreenOrientation orientation)
|
||||
void QWindow::reportContentOrientationChange(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
Q_D(QWindow);
|
||||
if (orientation == d->orientation)
|
||||
return;
|
||||
if (!d->platformWindow)
|
||||
create();
|
||||
Q_ASSERT(d->platformWindow);
|
||||
d->contentOrientation = orientation;
|
||||
d->platformWindow->handleContentOrientationChange(orientation);
|
||||
}
|
||||
|
||||
d->orientation = orientation;
|
||||
if (d->platformWindow) {
|
||||
d->platformWindow->setOrientation(orientation);
|
||||
}
|
||||
emit orientationChanged(orientation);
|
||||
/*!
|
||||
Returns the actual content orientation.
|
||||
|
||||
This is the last value set with reportContentOrientationChange(),
|
||||
except Qt::PrimaryOrientation gets converted to the screen's
|
||||
primary orientation.
|
||||
*/
|
||||
Qt::ScreenOrientation QWindow::contentOrientation() const
|
||||
{
|
||||
Q_D(const QWindow);
|
||||
return d->contentOrientation == Qt::PrimaryOrientation ? screen()->primaryOrientation() : d->contentOrientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
Requests the given window orientation.
|
||||
|
||||
The window orientation specifies how the window should be rotated
|
||||
by the window manager in order to be displayed. Input events will
|
||||
be correctly mapped to the given orientation.
|
||||
|
||||
The return value is false if the system doesn't support the given
|
||||
orientation (for example when requesting a portrait orientation
|
||||
on a device that only handles landscape buffers, typically a desktop
|
||||
system).
|
||||
|
||||
If the return value is false, call windowOrientation() to get the actual
|
||||
supported orientation.
|
||||
|
||||
\sa windowOrientation(), reportContentOrientationChange(), QScreen::orientation()
|
||||
*/
|
||||
bool QWindow::requestWindowOrientation(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
Q_D(QWindow);
|
||||
if (!d->platformWindow)
|
||||
create();
|
||||
Q_ASSERT(d->platformWindow);
|
||||
d->windowOrientation = d->platformWindow->requestWindowOrientation(orientation);
|
||||
return d->windowOrientation == orientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the actual window orientation.
|
||||
|
||||
\sa requestWindowOrientation()
|
||||
*/
|
||||
Qt::ScreenOrientation QWindow::windowOrientation() const
|
||||
{
|
||||
Q_D(const QWindow);
|
||||
return d->windowOrientation == Qt::PrimaryOrientation ? screen()->primaryOrientation() : d->windowOrientation;
|
||||
}
|
||||
|
||||
Qt::WindowState QWindow::windowState() const
|
||||
|
@ -91,7 +91,6 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
|
||||
Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged)
|
||||
Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged)
|
||||
Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
|
||||
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
|
||||
|
||||
public:
|
||||
enum SurfaceType { RasterSurface, OpenGLSurface };
|
||||
@ -133,8 +132,11 @@ public:
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
void setOrientation(Qt::ScreenOrientation orientation);
|
||||
void reportContentOrientationChange(Qt::ScreenOrientation orientation);
|
||||
Qt::ScreenOrientation contentOrientation() const;
|
||||
|
||||
bool requestWindowOrientation(Qt::ScreenOrientation orientation);
|
||||
Qt::ScreenOrientation windowOrientation() const;
|
||||
|
||||
Qt::WindowState windowState() const;
|
||||
void setWindowState(Qt::WindowState state);
|
||||
@ -252,17 +254,13 @@ Q_SIGNALS:
|
||||
void screenChanged(QScreen *screen);
|
||||
|
||||
void xChanged(int arg);
|
||||
|
||||
void yChanged(int arg);
|
||||
|
||||
void widthChanged(int arg);
|
||||
|
||||
void heightChanged(int arg);
|
||||
|
||||
void visibleChanged(bool arg);
|
||||
|
||||
void orientationChanged(Qt::ScreenOrientation arg);
|
||||
|
||||
private Q_SLOTS:
|
||||
void screenDestroyed(QObject *screen);
|
||||
|
||||
|
@ -76,7 +76,8 @@ public:
|
||||
, windowState(Qt::WindowNoState)
|
||||
, resizeEventPending(true)
|
||||
, positionPolicy(WindowFrameExclusive)
|
||||
, orientation(Qt::UnknownOrientation)
|
||||
, contentOrientation(Qt::PrimaryOrientation)
|
||||
, windowOrientation(Qt::PrimaryOrientation)
|
||||
, maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
|
||||
, modality(Qt::NonModal)
|
||||
, transientParent(0)
|
||||
@ -111,7 +112,8 @@ public:
|
||||
Qt::WindowState windowState;
|
||||
bool resizeEventPending;
|
||||
PositionPolicy positionPolicy;
|
||||
Qt::ScreenOrientation orientation;
|
||||
Qt::ScreenOrientation contentOrientation;
|
||||
Qt::ScreenOrientation windowOrientation;
|
||||
|
||||
QSize minimumSize;
|
||||
QSize maximumSize;
|
||||
|
@ -467,7 +467,7 @@ void QMeeGoPlatformInputContext::inputItemChanged()
|
||||
|
||||
// ### react to orientation changes, too
|
||||
if (window)
|
||||
d->server->appOrientationChanged(orientationAngle(window->screen()->currentOrientation()));
|
||||
d->server->appOrientationChanged(orientationAngle(window->screen()->orientation()));
|
||||
}
|
||||
}
|
||||
d->sendStateUpdate(/*focusChanged*/true);
|
||||
|
@ -90,6 +90,11 @@ void tst_QScreen::angleBetween_data()
|
||||
<< uint(Qt::InvertedLandscapeOrientation)
|
||||
<< uint(Qt::LandscapeOrientation)
|
||||
<< 180;
|
||||
|
||||
QTest::newRow("Landscape Primary")
|
||||
<< uint(Qt::LandscapeOrientation)
|
||||
<< uint(Qt::PrimaryOrientation)
|
||||
<< QGuiApplication::primaryScreen()->angleBetween(Qt::LandscapeOrientation, QGuiApplication::primaryScreen()->primaryOrientation());
|
||||
}
|
||||
|
||||
void tst_QScreen::angleBetween()
|
||||
@ -101,8 +106,8 @@ void tst_QScreen::angleBetween()
|
||||
Qt::ScreenOrientation a = Qt::ScreenOrientation(oa);
|
||||
Qt::ScreenOrientation b = Qt::ScreenOrientation(ob);
|
||||
|
||||
QCOMPARE(QScreen::angleBetween(a, b), expected);
|
||||
QCOMPARE(QScreen::angleBetween(b, a), (360 - expected) % 360);
|
||||
QCOMPARE(QGuiApplication::primaryScreen()->angleBetween(a, b), expected);
|
||||
QCOMPARE(QGuiApplication::primaryScreen()->angleBetween(b, a), (360 - expected) % 360);
|
||||
}
|
||||
|
||||
void tst_QScreen::transformBetween_data()
|
||||
@ -149,6 +154,12 @@ void tst_QScreen::transformBetween_data()
|
||||
<< uint(Qt::LandscapeOrientation)
|
||||
<< rect
|
||||
<< QTransform(-1, 0, 0, -1, rect.width(), rect.height());
|
||||
|
||||
QTest::newRow("Landscape Primary")
|
||||
<< uint(Qt::LandscapeOrientation)
|
||||
<< uint(Qt::PrimaryOrientation)
|
||||
<< rect
|
||||
<< QGuiApplication::primaryScreen()->transformBetween(Qt::LandscapeOrientation, QGuiApplication::primaryScreen()->primaryOrientation(), rect);
|
||||
}
|
||||
|
||||
void tst_QScreen::transformBetween()
|
||||
@ -161,7 +172,7 @@ void tst_QScreen::transformBetween()
|
||||
Qt::ScreenOrientation a = Qt::ScreenOrientation(oa);
|
||||
Qt::ScreenOrientation b = Qt::ScreenOrientation(ob);
|
||||
|
||||
QCOMPARE(QScreen::transformBetween(a, b, rect), expected);
|
||||
QCOMPARE(QGuiApplication::primaryScreen()->transformBetween(a, b, rect), expected);
|
||||
}
|
||||
|
||||
void tst_QScreen::orientationChange()
|
||||
@ -169,10 +180,10 @@ void tst_QScreen::orientationChange()
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
|
||||
QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::LandscapeOrientation);
|
||||
QTRY_COMPARE(screen->currentOrientation(), Qt::LandscapeOrientation);
|
||||
QTRY_COMPARE(screen->orientation(), Qt::LandscapeOrientation);
|
||||
|
||||
QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::PortraitOrientation);
|
||||
QTRY_COMPARE(screen->currentOrientation(), Qt::PortraitOrientation);
|
||||
QTRY_COMPARE(screen->orientation(), Qt::PortraitOrientation);
|
||||
}
|
||||
|
||||
#include <tst_qscreen.moc>
|
||||
|
@ -57,6 +57,7 @@ private slots:
|
||||
void touchToMouseTranslation();
|
||||
void mouseToTouchTranslation();
|
||||
void mouseToTouchLoop();
|
||||
void orientation();
|
||||
void initTestCase()
|
||||
{
|
||||
touchDevice = new QTouchDevice;
|
||||
@ -481,5 +482,22 @@ void tst_QWindow::mouseToTouchLoop()
|
||||
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
||||
}
|
||||
|
||||
void tst_QWindow::orientation()
|
||||
{
|
||||
QWindow window;
|
||||
window.setGeometry(80, 80, 40, 40);
|
||||
window.create();
|
||||
|
||||
window.reportContentOrientationChange(Qt::PortraitOrientation);
|
||||
QCOMPARE(window.contentOrientation(), Qt::PortraitOrientation);
|
||||
|
||||
window.reportContentOrientationChange(Qt::PrimaryOrientation);
|
||||
QCOMPARE(window.contentOrientation(), window.screen()->primaryOrientation());
|
||||
|
||||
QVERIFY(!window.requestWindowOrientation(Qt::LandscapeOrientation) || window.windowOrientation() == Qt::LandscapeOrientation);
|
||||
QVERIFY(!window.requestWindowOrientation(Qt::PortraitOrientation) || window.windowOrientation() == Qt::PortraitOrientation);
|
||||
QVERIFY(!window.requestWindowOrientation(Qt::PrimaryOrientation) || window.windowOrientation() == window.screen()->primaryOrientation());
|
||||
}
|
||||
|
||||
#include <tst_qwindow.moc>
|
||||
QTEST_MAIN(tst_QWindow);
|
||||
|
Loading…
x
Reference in New Issue
Block a user