Android: handle inverted orientations

Add logic to detect InvertedPortrait and InvertedLandscape orientations
and implement QPlatformScreen::nativeOrientation() for Android.

Task-number: QTBUG-32144

Change-Id: I294506714ea0faa9eacd7a15e1cfc45342659964
Reviewed-by: BogDan Vatra <bogdan@kde.org>
bb10
Paul Olav Tvete 2013-09-13 13:11:45 +02:00 committed by The Qt Project
parent dd6b053b6c
commit 74d2249e37
12 changed files with 110 additions and 18 deletions

View File

@ -70,6 +70,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.view.Surface;
public class QtActivityDelegate
{
@ -93,7 +94,8 @@ public class QtActivityDelegate
private static String m_environmentVariables = null;
private static String m_applicationParameters = null;
private int m_currentOrientation = Configuration.ORIENTATION_UNDEFINED;
private int m_currentRotation = -1; // undefined
private int m_nativeOrientation = Configuration.ORIENTATION_UNDEFINED;
private String m_mainLib;
private long m_metaState;
@ -587,7 +589,17 @@ public class QtActivityDelegate
m_layout.bringChildToFront(m_surface);
m_activity.registerForContextMenu(m_layout);
m_currentOrientation = m_activity.getResources().getConfiguration().orientation;
int orientation = m_activity.getResources().getConfiguration().orientation;
int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
boolean rot90 = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
boolean currentlyLandscape = (orientation == Configuration.ORIENTATION_LANDSCAPE);
if ((currentlyLandscape && !rot90) || (!currentlyLandscape && rot90))
m_nativeOrientation = Configuration.ORIENTATION_LANDSCAPE;
else
m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT;
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
m_currentRotation = rotation;
}
public void onConfigurationChanged(Configuration configuration)
@ -597,13 +609,12 @@ public class QtActivityDelegate
} catch (Exception e) {
e.printStackTrace();
}
if (configuration.orientation != m_currentOrientation
&& m_currentOrientation != Configuration.ORIENTATION_UNDEFINED) {
QtNative.handleOrientationChanged(configuration.orientation);
int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
if (rotation != m_currentRotation) {
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
}
m_currentOrientation = configuration.orientation;
m_currentRotation = rotation;
}
public void onDestroy()

View File

@ -553,7 +553,7 @@ public class QtNative
double XDpi,
double YDpi,
double scaledDensity);
public static native void handleOrientationChanged(int newOrientation);
public static native void handleOrientationChanged(int newRotation, int nativeOrientation);
// screen methods
// pointer methods

View File

@ -675,17 +675,37 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
}
static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation)
static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newRotation, jint nativeOrientation)
{
if (m_androidPlatformIntegration == 0)
return;
// Array of orientations rotated in 90 degree increments, counterclockwise
// (same direction as Android measures angles)
static const Qt::ScreenOrientation orientations[] = {
Qt::PortraitOrientation,
Qt::LandscapeOrientation,
Qt::InvertedPortraitOrientation,
Qt::InvertedLandscapeOrientation
};
Qt::ScreenOrientation screenOrientation = newOrientation == 1
? Qt::PortraitOrientation
: Qt::LandscapeOrientation;
QPlatformScreen *screen = m_androidPlatformIntegration->screen();
QWindowSystemInterface::handleScreenOrientationChange(screen->screen(),
screenOrientation);
// The Android API defines the following constants:
// ROTATION_0 : 0
// ROTATION_90 : 1
// ROTATION_180 : 2
// ROTATION_270 : 3
// ORIENTATION_PORTRAIT : 1
// ORIENTATION_LANDSCAPE : 2
// and newRotation is how much the current orientation is rotated relative to nativeOrientation
// which means that we can be really clever here :)
Qt::ScreenOrientation screenOrientation = orientations[(nativeOrientation - 1 + newRotation) % 4];
Qt::ScreenOrientation native = orientations[nativeOrientation - 1];
QAndroidPlatformIntegration::setScreenOrientation(screenOrientation, native);
if (m_androidPlatformIntegration) {
QPlatformScreen *screen = m_androidPlatformIntegration->screen();
QWindowSystemInterface::handleScreenOrientationChange(screen->screen(),
screenOrientation);
}
}
static JNINativeMethod methods[] = {
@ -702,7 +722,7 @@ static JNINativeMethod methods[] = {
{"unlockSurface", "()V", (void *)unlockSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
{"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged}
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}
};
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \

View File

@ -57,6 +57,8 @@ public:
QSize screenSize() const;
QSizeF physicalScreenSize() const;
QDpi logicalDpi() const;
Qt::ScreenOrientation orientation() const;
Qt::ScreenOrientation nativeOrientation() const;
int screenDepth() const;
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format);
@ -94,6 +96,15 @@ QDpi QEglFSAndroidHooks::logicalDpi() const
return QDpi(lDpi, lDpi);
}
Qt::ScreenOrientation QEglFSAndroidHooks::orientation() const
{
return QAndroidPlatformIntegration::m_orientation;
}
Qt::ScreenOrientation QEglFSAndroidHooks::nativeOrientation() const
{
return QAndroidPlatformIntegration::m_nativeOrientation;
}
EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
{

View File

@ -76,6 +76,9 @@ int QAndroidPlatformIntegration::m_defaultGeometryHeight = 455;
int QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth = 50;
int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation;
void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
{
if (resource=="JavaVM")
@ -268,6 +271,13 @@ void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh)
m_defaultGeometryHeight = gh;
}
void QAndroidPlatformIntegration::setScreenOrientation(Qt::ScreenOrientation currentOrientation,
Qt::ScreenOrientation nativeOrientation)
{
m_orientation = currentOrientation;
m_nativeOrientation = nativeOrientation;
}
#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
{

View File

@ -129,6 +129,8 @@ public:
void resumeApp();
static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh);
static void setDefaultDesktopSize(int gw, int gh);
static void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
Qt::ScreenOrientation nativeOrientation);
static QSize defaultDesktopSize()
{
@ -156,6 +158,9 @@ private:
static int m_defaultPhysicalSizeWidth;
static int m_defaultPhysicalSizeHeight;
static Qt::ScreenOrientation m_orientation;
static Qt::ScreenOrientation m_nativeOrientation;
QPlatformFontDatabase *m_androidFDB;
QImage *m_FbScreenImage;
QPainter *m_compositePainter;

View File

@ -75,3 +75,13 @@ QDpi QAndroidPlatformScreen::logicalDpi() const
qreal lDpi = QtAndroid::scaledDensity() * 72;
return QDpi(lDpi, lDpi);
}
Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
{
return QAndroidPlatformIntegration::m_orientation;
}
Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
{
return QAndroidPlatformIntegration::m_nativeOrientation;
}

View File

@ -51,6 +51,8 @@ public:
QAndroidPlatformScreen();
void topWindowChanged(QWindow *w);
QDpi logicalDpi() const;
Qt::ScreenOrientation orientation() const;
Qt::ScreenOrientation nativeOrientation() const;
public slots:
QRegion doRedraw();

View File

@ -63,6 +63,8 @@ public:
virtual QSizeF physicalScreenSize() const;
virtual QSize screenSize() const;
virtual QDpi logicalDpi() const;
virtual Qt::ScreenOrientation nativeOrientation() const;
virtual Qt::ScreenOrientation orientation() const;
virtual int screenDepth() const;
virtual QImage::Format screenFormat() const;
virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;

View File

@ -192,6 +192,16 @@ QDpi QEglFSHooks::logicalDpi() const
25.4 * s.height() / ps.height());
}
Qt::ScreenOrientation QEglFSHooks::nativeOrientation() const
{
return Qt::PrimaryOrientation;
}
Qt::ScreenOrientation QEglFSHooks::orientation() const
{
return Qt::PrimaryOrientation;
}
int QEglFSHooks::screenDepth() const
{
static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();

View File

@ -90,6 +90,15 @@ QDpi QEglFSScreen::logicalDpi() const
return QEglFSHooks::hooks()->logicalDpi();
}
Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const
{
return QEglFSHooks::hooks()->nativeOrientation();
}
Qt::ScreenOrientation QEglFSScreen::orientation() const
{
return QEglFSHooks::hooks()->orientation();
}
QPlatformCursor *QEglFSScreen::cursor() const
{

View File

@ -65,6 +65,8 @@ public:
QSizeF physicalSize() const;
QDpi logicalDpi() const;
Qt::ScreenOrientation nativeOrientation() const;
Qt::ScreenOrientation orientation() const;
QPlatformCursor *cursor() const;