diff options
author | Lasse Räihä <lasse.raiha@digia.com> | 2013-05-24 15:39:23 +0300 |
---|---|---|
committer | Kimmo Ollila <kimmo.ollila@digia.com> | 2013-05-24 15:42:13 +0300 |
commit | eadf3f9c43bd89358695da72db5e66c96a9d8f39 (patch) | |
tree | 2c301f4cc64f1b27e6d6f37fff62308c0150b9be | |
parent | ff36f8a9997a224f3280091b5d4a2f3a82b3cafe (diff) |
Added support to change rotation.
Change-Id: I0204a48eddbfaa71ab35430c40dc9d06d45e57fe
Reviewed-by: Kimmo Ollila <kimmo.ollila@digia.com>
-rw-r--r-- | QtDemo/android/AndroidManifest.xml | 33 | ||||
-rw-r--r-- | QtDemo/android/src/org/qtproject/qt5/android/bindings/QtActivity.java | 123 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/Button.qml | 4 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/Slide.qml | 2 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/engine.js | 12 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/main.qml | 9 |
6 files changed, 137 insertions, 46 deletions
diff --git a/QtDemo/android/AndroidManifest.xml b/QtDemo/android/AndroidManifest.xml deleted file mode 100644 index 68c1b45..0000000 --- a/QtDemo/android/AndroidManifest.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<manifest android:versionCode="1" package="org.qtproject.example.QtDemo" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0"> - <application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name"> - <activity android:name="org.qtproject.qt5.android.bindings.QtActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|locale|fontScale|keyboard|keyboardHidden" android:screenOrientation="landscape" android:label="@string/app_name"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> - <meta-data android:name="android.app.repository" android:value="@string/repository"/> - <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> - <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> - <meta-data android:name="android.app.lib_name" android:value="QtDemo"/> - <!-- Run with local libs --> - <meta-data android:name="android.app.use_local_qt_libs" android:value="1"/> - <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> - <meta-data android:name="android.app.load_local_libs" android:value="libs/libgnustl_shared.so:plugins/platforms/android/libqtforandroidGL.so:"/> - <meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:"/> - <meta-data android:name="android.app.static_init_classes" android:value=":"/> - <!-- Messages maps --> - <meta-data android:name="android.app.ministro_not_found_msg" android:value="@string/ministro_not_found_msg"/> - <meta-data android:name="android.app.ministro_needed_msg" android:value="@string/ministro_needed_msg"/> - <meta-data android:name="android.app.fatal_error_msg" android:value="@string/fatal_error_msg"/> - <!-- Messages maps --> - <!-- Splash screen --> - <meta-data android:name="android.app.splash_screen" android:resource="@layout/splash"/> - <!-- Splash screen --> - </activity> - </application> - <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> -</manifest> diff --git a/QtDemo/android/src/org/qtproject/qt5/android/bindings/QtActivity.java b/QtDemo/android/src/org/qtproject/qt5/android/bindings/QtActivity.java index 9a8056b..4baf2d1 100644 --- a/QtDemo/android/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/QtDemo/android/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -27,6 +27,11 @@ package org.qtproject.qt5.android.bindings; import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.FileOutputStream; +import java.io.FileInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -47,6 +52,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.Resources.Theme; +import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.Canvas; import android.net.Uri; @@ -89,6 +95,8 @@ public class QtActivity extends Activity private static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables"; private static final String APPLICATION_PARAMETERS_KEY = "application.parameters"; private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries"; + private static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id"; + private static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id"; private static final String MAIN_LIBRARY_KEY = "main.library"; private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes"; private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level"; @@ -120,9 +128,11 @@ public class QtActivity extends Activity // note that the android style plugin in Qt 5.1 is not fully functional. private static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded. + private static final int BUFFER_SIZE = 1024; + private ActivityInfo m_activityInfo = null; // activity info object, used to access the libs and the strings private DexClassLoader m_classLoader = null; // loader object - private String[] m_sources = {"https://files.kde.org/necessitas/ministro/android/necessitas/qt5/latest"}; // Make sure you are using ONLY secure locations + private String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/latest"}; // Make sure you are using ONLY secure locations private String m_repository = "default"; // Overwrites the default Ministro repository // Possible values: // * default - Ministro default repository set with "Ministro configuration tool". @@ -308,6 +318,92 @@ public class QtActivity extends Activity errorDialog.show(); } + static private void copyFile(InputStream inputStream, OutputStream outputStream) + throws IOException + { + byte[] buffer = new byte[BUFFER_SIZE]; + + int count; + while ((count = inputStream.read(buffer)) > 0) + outputStream.write(buffer, 0, count); + } + + + private void copyAsset(String source, String destination) + throws IOException + { + // Already exists, we don't have to do anything + File destinationFile = new File(destination); + if (destinationFile.exists()) + return; + + File parentDirectory = destinationFile.getParentFile(); + if (!parentDirectory.exists()) + parentDirectory.mkdirs(); + + destinationFile.createNewFile(); + + AssetManager assetsManager = getAssets(); + InputStream inputStream = assetsManager.open(source); + OutputStream outputStream = new FileOutputStream(destinationFile); + copyFile(inputStream, outputStream); + } + + private static void createBundledBinary(String source, String destination) + throws IOException + { + // Already exists, we don't have to do anything + File destinationFile = new File(destination); + if (destinationFile.exists()) + return; + + File parentDirectory = destinationFile.getParentFile(); + if (!parentDirectory.exists()) + parentDirectory.mkdirs(); + + destinationFile.createNewFile(); + + InputStream inputStream = new FileInputStream(source); + OutputStream outputStream = new FileOutputStream(destinationFile); + copyFile(inputStream, outputStream); + } + + private void extractBundledPluginsAndImports(String localPrefix) + throws IOException + { + ArrayList<String> libs = new ArrayList<String>(); + + { + String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY; + java.util.Set<String> keys = m_activityInfo.metaData.keySet(); + if (m_activityInfo.metaData.containsKey(key)) { + String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key)); + + for (String bundledImportBinary : list) { + String[] split = bundledImportBinary.split(":"); + String sourceFileName = localPrefix + "lib/" + split[0]; + String destinationFileName = localPrefix + split[1]; + createBundledBinary(sourceFileName, destinationFileName); + } + } + } + + { + String key = BUNDLED_IN_ASSETS_RESOURCE_ID_KEY; + if (m_activityInfo.metaData.containsKey(key)) { + String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key)); + + for (String fileName : list) { + String[] split = fileName.split(":"); + String sourceFileName = split[0]; + String destinationFileName = localPrefix + split[1]; + copyAsset(sourceFileName, destinationFileName); + } + } + + } + } + private void startApp(final boolean firstStart) { try { @@ -328,13 +424,26 @@ public class QtActivity extends Activity && m_activityInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) { ArrayList<String> libraryList = new ArrayList<String>(); + String localPrefix = "/data/local/tmp/qt/"; if (m_activityInfo.metaData.containsKey("android.app.libs_prefix")) localPrefix = m_activityInfo.metaData.getString("android.app.libs_prefix"); + boolean bundlingQtLibs = false; + if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs") + && m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { + localPrefix = getApplicationInfo().dataDir + "/"; + extractBundledPluginsAndImports(localPrefix); + bundlingQtLibs = true; + } + if (m_qtLibs != null) { - for (int i=0;i<m_qtLibs.length;i++) - libraryList.add(localPrefix+"lib/lib"+m_qtLibs[i]+".so"); + for (int i=0;i<m_qtLibs.length;i++) { + libraryList.add(localPrefix + + "lib/lib" + + m_qtLibs[i] + + ".so"); + } } if (m_activityInfo.metaData.containsKey("android.app.load_local_libs")) { @@ -345,9 +454,10 @@ public class QtActivity extends Activity } } + String dexPaths = new String(); String pathSeparator = System.getProperty("path.separator", ":"); - if (m_activityInfo.metaData.containsKey("android.app.load_local_jars")) { + if (!bundlingQtLibs && m_activityInfo.metaData.containsKey("android.app.load_local_jars")) { String[] jarFiles = m_activityInfo.metaData.getString("android.app.load_local_jars").split(":"); for (String jar:jarFiles) { if (jar.length() > 0) { @@ -711,10 +821,10 @@ public class QtActivity extends Activity @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - int newKeyCode = keyCode; + int newKeyCode = keyCode; if ( (keyCode == KeyEvent.KEYCODE_BACK) ) { - newKeyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; + newKeyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; } if (QtApplication.m_delegateObject != null && QtApplication.onKeyDown != null) @@ -1123,7 +1233,6 @@ public class QtActivity extends Activity { super.onBackPressed(); } - //--------------------------------------------------------------------------- @Override diff --git a/QtDemo/qml/QtDemo/Button.qml b/QtDemo/qml/QtDemo/Button.qml index bb8a503..991db78 100644 --- a/QtDemo/qml/QtDemo/Button.qml +++ b/QtDemo/qml/QtDemo/Button.qml @@ -27,7 +27,7 @@ Rectangle { onClicked: root.clicked() onEntered: buttonImage.anchors.margins = -(root.width * 0.1) onExited: buttonImage.anchors.margins = 0 - onPressed: buttonImage.opacity = 1.0 - onReleased: buttonImage.opacity = 0.7 + onPressed: {buttonImage.opacity = 1.0; buttonImage.anchors.margins = -(root.width * 0.1)} + onReleased: { buttonImage.opacity = 0.7; buttonImage.anchors.margins = 0} } } diff --git a/QtDemo/qml/QtDemo/Slide.qml b/QtDemo/qml/QtDemo/Slide.qml index 226c6db..3485d16 100644 --- a/QtDemo/qml/QtDemo/Slide.qml +++ b/QtDemo/qml/QtDemo/Slide.qml @@ -8,7 +8,7 @@ Item { rotation: deltaRot property bool rotAnimationEnabled: false - property bool yAnimationEnabled: true + property bool yAnimationEnabled: false property int uid: 0 property string url: "" property int device: 0 diff --git a/QtDemo/qml/QtDemo/engine.js b/QtDemo/qml/QtDemo/engine.js index 1934d98..31384e5 100644 --- a/QtDemo/qml/QtDemo/engine.js +++ b/QtDemo/qml/QtDemo/engine.js @@ -1,7 +1,7 @@ var positions = [ {x:-500, y:-1180, url: "demos/rssnews/rssnews.qml", device: 3, name: "Rss Reader"}, {x:-1550, y:-1040, url: "demos/gridrssnews/main.qml", device: 5, name: "Rss Reader"}, - {x:-1050, y:-800, url: "demos/tweetsearch/tweetsearch.qml", device: 2, name: "TweetSearch"}, + {x:-1000, y:-820, url: "demos/tweetsearch/tweetsearch.qml", device: 2, name: "TweetSearch"}, {x:1500, y:-1100, url: "demos/heartmonitor/main.qml", device: 4, name: "Heart Monitor"}, {x:800, y:-1000, url: "demos/canvasclock/canvasClock.qml", device: 4, name: "Canvas Clock"}, @@ -16,7 +16,7 @@ var positions = [ {x:-1900, y:200, url: "demos/radio/radio.qml", device: 4, name: "Internet Radio"}, {x:-800, y:900, url: "demos/samegame/samegame.qml", device: 1, name: "SameGame"}, - {x:-1500, y:1100, url: "demos/calqlatr/Calqlatr.qml", device: 0, name: "Calqlatr"} + {x:-1400, y:1000, url: "demos/calqlatr/Calqlatr.qml", device: 0, name: "Calqlatr"} ] var imageSources = ["phone1.png","phone2.png", "phone3.png","tablet1.png", "medical_device.png", "laptop1.png", "laptop2.png", "tv.png"] @@ -85,6 +85,14 @@ function releaseDemos() objects[i].releaseDemo(); } +function getCurrent() +{ + if (currentDemoIndex < 0 || currentDemoIndex >= objects.length) + return null; + + return selectTarget(navigationList[currentDemoIndex]); +} + function getNext() { currentDemoIndex++; diff --git a/QtDemo/qml/QtDemo/main.qml b/QtDemo/qml/QtDemo/main.qml index 6e8aff0..f1286f4 100644 --- a/QtDemo/qml/QtDemo/main.qml +++ b/QtDemo/qml/QtDemo/main.qml @@ -28,9 +28,16 @@ Rectangle{ tapLimitX = Math.max(1,app.width * 0.02); tapLimitY = Math.max(1,app.height * 0.02); - canvas.goHome() + var target = Engine.getCurrent(); + if (navigationState == 1 && target !== null) { + canvas.goTo(target); + zoomAnimation.restart() + } + else + canvas.goHome() } } + function selectTarget(uid) { return Engine.selectTarget(uid) } |