From 83d9aba0b1710881d7bc49106aa96182765b99d9 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 15 Jul 2010 17:48:28 +1000 Subject: [PATCH] Add new runtime.systemOrientation property Task-number: QTBUG-12142 Reviewed-by: --- demos/declarative/calculator/calculator.qml | 29 ++++++- doc/src/declarative/qmlviewer.qdoc | 24 +++++- src/declarative/QmlChanges.txt | 2 + .../qdeclarativeviewer/tst_qdeclarativeviewer.cpp | 34 ++++++++- tools/qml/deviceorientation.cpp | 7 ++ tools/qml/deviceorientation.h | 5 + tools/qml/deviceorientation_maemo5.cpp | 26 ++++-- tools/qml/deviceorientation_symbian.cpp | 85 +++++++++++++++++--- tools/qml/qml.pro | 1 + tools/qml/qmlruntime.cpp | 11 +++ 10 files changed, 192 insertions(+), 32 deletions(-) diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml index 63b6c55..adbdf42 100644 --- a/demos/declarative/calculator/calculator.qml +++ b/demos/declarative/calculator/calculator.qml @@ -62,8 +62,12 @@ Rectangle { Item { id: main state: "orientation " + runtime.orientation + property real rotationDelta: runtime.systemOrientation == Orientation.Landscape ? 90 : 0 + rotation: -rotationDelta - width: parent.width; height: parent.height; anchors.centerIn: parent + width: runtime.systemOrientation == Orientation.Landscape ? window.height : window.width + height: runtime.systemOrientation == Orientation.Landscape ? window.width : window.height + anchors.centerIn: parent Column { id: box; spacing: 8 @@ -134,17 +138,32 @@ Rectangle { states: [ State { name: "orientation " + Orientation.Landscape - PropertyChanges { target: main; rotation: -90; width: window.height; height: window.width } + PropertyChanges { + target: main + rotation: 90 - rotationDelta + width: runtime.systemOrientation == Orientation.Landscape ? window.width : window.height + height: runtime.systemOrientation == Orientation.Landscape ? window.height : window.width + } PropertyChanges { target: rotateButton; operation: rotateRight } }, State { name: "orientation " + Orientation.PortraitInverted - PropertyChanges { target: main; rotation: -180; } + PropertyChanges { + target: main + rotation: 180 - rotationDelta + width: runtime.systemOrientation == Orientation.Landscape ? window.height : window.width + height: runtime.systemOrientation == Orientation.Landscape ? window.width : window.height + } PropertyChanges { target: rotateButton; operation: rotateLeft } }, State { name: "orientation " + Orientation.LandscapeInverted - PropertyChanges { target: main; rotation: -270; width: window.height; height: window.width } + PropertyChanges { + target: main + rotation: 270 - rotationDelta + width: runtime.systemOrientation == Orientation.Landscape ? window.width : window.height + height: runtime.systemOrientation == Orientation.Landscape ? window.height : window.width + } PropertyChanges { target: rotateButton; operation: rotateRight } } ] @@ -157,4 +176,6 @@ Rectangle { } } } + // lock the system orientation to the current system orientation + Component.onCompleted: runtime.systemOrientation = runtime.systemOrientation; } diff --git a/doc/src/declarative/qmlviewer.qdoc b/doc/src/declarative/qmlviewer.qdoc index 5efc0ce..70fdc1b 100644 --- a/doc/src/declarative/qmlviewer.qdoc +++ b/doc/src/declarative/qmlviewer.qdoc @@ -197,10 +197,10 @@ Rectangle { \o \c runtime.orientation \o This property indicates the current orientation of the QML Viewer. On the -N900 platform, this property automatically updates to reflect the device's -actual orientation; on other platforms, this indicates the orientation currently -selected in the QML Viewer's \e {Settings -> Properties} menu. The -\c orientation value can be one of the following: +N900 platform and most S60 5.0-based or newer Symbian devices, this property +automatically updates to reflect the device's actual orientation; on other platforms, +this indicates the orientation currently selected in the QML Viewer's +\e {Settings -> Properties} menu. The \c orientation value can be one of the following: \list \o \c Orientation.Portrait @@ -228,7 +228,21 @@ Rectangle { } \endqml -\endtable +\row + +\o \c runtime.systemOrientation +\o This property indicates the current system orientation. On desktop the system +orientation is always set to \c Orientation.Portrait. On the N900 platform the system +orientation is always set to \c Orientation.Landscape. + +On Symbian the \c systemOrientation property can have values \c Orientation.Portrait +or \c Orientation.Landscape. You can set the system orientation on Symbian to lock the +root item to certain aspect ratio, and handle orientation changes yourself by listening to +the \c runtime.orientation property. Changing the system orientation on Symbian causes +the root item to resize and initiates platform's own orientation change transition +effect. On Symbian touch devices the system orientation also controls what kind of virtual +input panel, virtual QWERTY or alphanumeric keypad, is available for the text input. +\endtable */ diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 872f6cb..f6ca4b4 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,6 +1,8 @@ ============================================================================= The changes below are pre Qt 4.7.0 tech preview +QML Viewer + - new runtime property runtime.systemOrientation added TextInput - copy(), cut() and paste() functions added diff --git a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp index de8d222..4cf6fc8 100644 --- a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp +++ b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include "deviceorientation.h" #include #include "../../../shared/util.h" #include "qmlruntime.h" @@ -67,7 +69,7 @@ public: tst_QDeclarativeViewer(); private slots: - void orientation(); + void runtimeContextProperty(); void loading(); void fileBrowser(); void resizing(); @@ -94,7 +96,7 @@ tst_QDeclarativeViewer::tst_QDeclarativeViewer() QCOMPARE(viewer->size(), viewer->sizeHint()); \ } -void tst_QDeclarativeViewer::orientation() +void tst_QDeclarativeViewer::runtimeContextProperty() { QDeclarativeViewer *viewer = new QDeclarativeViewer(); QVERIFY(viewer); @@ -104,16 +106,30 @@ void tst_QDeclarativeViewer::orientation() QDeclarativeItem* rootItem = qobject_cast(viewer->view()->rootObject()); QVERIFY(rootItem); viewer->show(); + QObject *runtimeObject = qvariant_cast(viewer->view()->engine()->rootContext()->contextProperty("runtime")); + QVERIFY(runtimeObject); + + // test systemOrientation property + QCOMPARE(runtimeObject->property("systemOrientation").toInt(), int(DeviceOrientation::Portrait)); + + // test isActiveWindow property + QVERIFY(!runtimeObject->property("isActiveWindow").toBool()); QApplication::setActiveWindow(viewer); QTest::qWaitForWindowShown(viewer); QTRY_COMPARE(QApplication::activeWindow(), static_cast(viewer)); + QVERIFY(runtimeObject->property("isActiveWindow").toBool()); + TEST_INITIAL_SIZES(viewer); + // test orientation property + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Portrait)); + viewer->rotateOrientation(); qApp->processEvents(); + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Landscape)); QCOMPARE(rootItem->width(), 300.0); QCOMPARE(rootItem->height(), 200.0); QTRY_COMPARE(viewer->view()->size(), QSize(300, 200)); @@ -124,6 +140,7 @@ void tst_QDeclarativeViewer::orientation() viewer->rotateOrientation(); qApp->processEvents(); + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::PortraitInverted)); QCOMPARE(rootItem->width(), 200.0); QCOMPARE(rootItem->height(), 300.0); QTRY_COMPARE(viewer->view()->size(), QSize(200, 300)); @@ -131,6 +148,19 @@ void tst_QDeclarativeViewer::orientation() QCOMPARE(viewer->size(), QSize(200, 300 + MENUBAR_HEIGHT(viewer))); QCOMPARE(viewer->size(), viewer->sizeHint()); + viewer->rotateOrientation(); + qApp->processEvents(); + + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::LandscapeInverted)); + + viewer->rotateOrientation(); + qApp->processEvents(); + + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Portrait)); + + viewer->hide(); + QVERIFY(!runtimeObject->property("isActiveWindow").toBool()); + delete viewer; } diff --git a/tools/qml/deviceorientation.cpp b/tools/qml/deviceorientation.cpp index e7c70d5..f0fdf30 100644 --- a/tools/qml/deviceorientation.cpp +++ b/tools/qml/deviceorientation.cpp @@ -60,6 +60,13 @@ public: } } + Orientation systemOrientation() const { + return Portrait; + } + + void setSystemOrientation(Orientation systemOrientation) { Q_UNUSED(systemOrientation) } + void resetSystemOrientation() {} + Orientation m_orientation; }; diff --git a/tools/qml/deviceorientation.h b/tools/qml/deviceorientation.h index 817bfc8..b310bdb 100644 --- a/tools/qml/deviceorientation.h +++ b/tools/qml/deviceorientation.h @@ -65,8 +65,13 @@ public: static DeviceOrientation *instance(); + virtual Orientation systemOrientation() const = 0; + virtual void setSystemOrientation(Orientation) = 0; + virtual void resetSystemOrientation() = 0; + signals: void orientationChanged(); + void systemOrientationChanged(); protected: DeviceOrientation() {} diff --git a/tools/qml/deviceorientation_maemo5.cpp b/tools/qml/deviceorientation_maemo5.cpp index e942579..3ffa7bf 100644 --- a/tools/qml/deviceorientation_maemo5.cpp +++ b/tools/qml/deviceorientation_maemo5.cpp @@ -50,7 +50,7 @@ class MaemoOrientation : public DeviceOrientation Q_OBJECT public: MaemoOrientation() - : o(UnknownOrientation) + : m_currentOrientation(UnknownOrientation) { // enable the orientation sensor QDBusConnection::systemBus().call( @@ -64,7 +64,7 @@ public: if (reply.type() == QDBusMessage::ErrorMessage) { qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage())); } else { - o = toOrientation(reply.arguments().value(0).toString()); + m_currentOrientation = toOrientation(reply.arguments().value(0).toString()); } // connect to the orientation change signal @@ -84,20 +84,30 @@ public: inline Orientation orientation() const { - return o; + return m_currentOrientation; } void setOrientation(Orientation o) { } + inline Orientation systemOrientation() const + { + return Landscape; + } + + void setSystemOrientation(Orientation systemOrientation) {} + + void resetSystemOrientation() { } + private Q_SLOTS: void deviceOrientationChanged(const QString &newOrientation) { - o = toOrientation(newOrientation); - - emit orientationChanged(); -// printf("%d\n", o); + Orientation orientation = toOrientation(newOrientation); + if (m_currentOrientation != orientation && orientation != UnknownOrientation) { + m_currentOrientation = orientation; + emit this->orientationChanged(); + } } private: @@ -115,7 +125,7 @@ private: } private: - Orientation o; + Orientation m_currentOrientation; }; DeviceOrientation* DeviceOrientation::instance() diff --git a/tools/qml/deviceorientation_symbian.cpp b/tools/qml/deviceorientation_symbian.cpp index c305f94..98287f2 100644 --- a/tools/qml/deviceorientation_symbian.cpp +++ b/tools/qml/deviceorientation_symbian.cpp @@ -47,16 +47,31 @@ #include #include +#include // For orientation handling + class SymbianOrientation : public DeviceOrientation, public MSensrvDataListener { Q_OBJECT public: SymbianOrientation() - : DeviceOrientation(), m_current(UnknownOrientation), m_sensorChannel(0) + : DeviceOrientation(), m_systemOrientationImplicit(true), m_currentOrientation(UnknownOrientation), m_systemOrientation(UnknownOrientation), m_sensorChannel(0) { TRAP_IGNORE(initL()); if (!m_sensorChannel) qWarning("No valid sensors found."); + + // query the current platform orientation + CAknAppUi *appUi = static_cast(CEikonEnv::Static()->AppUi()); + if (appUi) { + CAknAppUi::TAppUiOrientation orientation = appUi->Orientation(); + if (orientation == CAknAppUi::EAppUiOrientationLandscape) { + m_systemOrientation = Landscape; + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape); + } else { // CAknAppUi::EAppUiOrientationPortrait + m_systemOrientation = Portrait; + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait); + } + } } ~SymbianOrientation() @@ -97,15 +112,54 @@ public: CleanupStack::PopAndDestroy(channelFinder); } - Orientation orientation() const + inline Orientation orientation() const + { + return m_currentOrientation; + } + + void setOrientation(Orientation) { } + + inline Orientation systemOrientation() const + { + return m_systemOrientation; + } + + void setSystemOrientation(Orientation systemOrientation) { - return m_current; + changeSystemOrientation(systemOrientation); + m_systemOrientationImplicit = false; + } + + void changeSystemOrientation(Orientation systemOrientation) + { + if (systemOrientation != m_systemOrientation) { + bool orientationChanged(false); + CAknAppUi *appUi = static_cast(CEikonEnv::Static()->AppUi()); + if (appUi) { + if (systemOrientation == Portrait) { + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait); + orientationChanged = true; + } else if (systemOrientation == Landscape) { + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape); + orientationChanged = true; + } + } + if (orientationChanged) { + m_systemOrientation = systemOrientation; + emit this->systemOrientationChanged(); + } + } } - void setOrientation(Orientation) { } + void resetSystemOrientation() { + changeSystemOrientation(m_currentOrientation); + m_systemOrientationImplicit = true; + } private: - DeviceOrientation::Orientation m_current; + bool m_systemOrientationImplicit; + Orientation m_currentOrientation; + Orientation m_systemOrientation; CSensrvChannel *m_sensorChannel; void DataReceived(CSensrvChannel &channel, TInt count, TInt dataLost) @@ -116,26 +170,32 @@ private: TPckgBuf dataBuf; channel.GetData(dataBuf); data = dataBuf(); - Orientation o = UnknownOrientation; + Orientation orientation = UnknownOrientation; switch (data.iDeviceOrientation) { case TSensrvOrientationData::EOrientationDisplayUp: - o = Portrait; + orientation = Portrait; break; case TSensrvOrientationData::EOrientationDisplayRightUp: - o = Landscape; + orientation = Landscape; break; case TSensrvOrientationData::EOrientationDisplayLeftUp: + orientation = LandscapeInverted; + break; case TSensrvOrientationData::EOrientationDisplayDown: + orientation = PortraitInverted; + break; case TSensrvOrientationData::EOrientationUndefined: case TSensrvOrientationData::EOrientationDisplayUpwards: case TSensrvOrientationData::EOrientationDisplayDownwards: default: break; } - - if (m_current != o && o != UnknownOrientation) { - m_current = o; - emit orientationChanged(); + if (m_currentOrientation != orientation && orientation != UnknownOrientation) { + m_currentOrientation = orientation; + emit this->orientationChanged(); + if (m_systemOrientationImplicit) { + changeSystemOrientation(m_currentOrientation); + } } } } @@ -150,7 +210,6 @@ private: } }; - DeviceOrientation* DeviceOrientation::instance() { static SymbianOrientation *o = 0; diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index bb69e8a..0a51c0b 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -39,6 +39,7 @@ symbian { TARGET.CAPABILITY = NetworkServices ReadUserData !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { LIBS += -lsensrvclient -lsensrvutil + contains(QT_CONFIG, s60): LIBS += -lavkon -lcone } } mac { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 951b187..ee89978 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -108,6 +108,7 @@ class Runtime : public QObject Q_PROPERTY(bool isActiveWindow READ isActiveWindow NOTIFY isActiveWindowChanged) Q_PROPERTY(DeviceOrientation::Orientation orientation READ orientation NOTIFY orientationChanged) + Q_PROPERTY(DeviceOrientation::Orientation systemOrientation READ systemOrientation WRITE setSystemOrientation RESET resetSystemOrientation NOTIFY systemOrientationChanged) public: static Runtime* instance() @@ -128,16 +129,23 @@ public: } DeviceOrientation::Orientation orientation() const { return DeviceOrientation::instance()->orientation(); } + DeviceOrientation::Orientation systemOrientation() const { return DeviceOrientation::instance()->systemOrientation(); } + + void setSystemOrientation(DeviceOrientation::Orientation systemOrientation) { DeviceOrientation::instance()->setSystemOrientation(systemOrientation); }; + void resetSystemOrientation() { DeviceOrientation::instance()->resetSystemOrientation(); } Q_SIGNALS: void isActiveWindowChanged(); void orientationChanged(); + void systemOrientationChanged(); private: Runtime(QObject *parent=0) : QObject(parent), activeWindow(false) { connect(DeviceOrientation::instance(), SIGNAL(orientationChanged()), this, SIGNAL(orientationChanged())); + connect(DeviceOrientation::instance(), SIGNAL(systemOrientationChanged()), + this, SIGNAL(systemOrientationChanged())); } bool activeWindow; @@ -1020,6 +1028,9 @@ bool QDeclarativeViewer::open(const QString& file_or_url) ctxt->setContextProperty("runtime", Runtime::instance()); + // reset preferred orientation + Runtime::instance()->resetSystemOrientation(); + QString fileName = url.toLocalFile(); if (!fileName.isEmpty()) { fi.setFile(fileName); -- 1.7.0.2.msysgit.0