summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2015-05-21 16:54:28 +0100
committerTor Lillqvist <tml@collabora.com>2015-05-21 16:56:48 +0100
commit1b53066433d1db9c3bfc3c6e6618565c15642b59 (patch)
tree9e2d440ff0520c800a6670dbdb01bc587e47742c
parent-fsanitize=bool (during CppunitTest_writerperfect_writer) (diff)
downloadcore-1b53066433d1db9c3bfc3c6e6618565c15642b59.tar.gz
core-1b53066433d1db9c3bfc3c6e6618565c15642b59.zip
Bin the 'DocumentLoader' Android test app
It is the wrong approach, from the time before tiled rendering, and has not been built for a long time.
-rw-r--r--README.cross16
-rw-r--r--android/experimental/DocumentLoader/AndroidManifest.xml23
-rw-r--r--android/experimental/DocumentLoader/Makefile37
-rw-r--r--android/experimental/DocumentLoader/build.xml84
-rw-r--r--android/experimental/DocumentLoader/fonts.conf154
-rw-r--r--android/experimental/DocumentLoader/jni/Android.mk8
-rw-r--r--android/experimental/DocumentLoader/project.properties14
-rw-r--r--android/experimental/DocumentLoader/res/menu/option.xml5
-rw-r--r--android/experimental/DocumentLoader/res/values/strings.xml4
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/Animation.java28
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/Animator.java91
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/FlingAnimation.java70
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/FlingAnimationListener.java24
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/GestureImageView.java718
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewListener.java26
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewTouchListener.java565
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/MathUtils.java76
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/MoveAnimation.java102
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/MoveAnimationListener.java22
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/VectorF.java63
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimation.java162
-rw-r--r--android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimationListener.java21
-rw-r--r--android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java1140
23 files changed, 4 insertions, 3449 deletions
diff --git a/README.cross b/README.cross
index efaa8c24ed7a..ad1475a2ac34 100644
--- a/README.cross
+++ b/README.cross
@@ -352,18 +352,10 @@ And here is an (quite old) autogen.input for Android on X86:
--enable-ccache
--with-distro=LibreOfficeAndroidX86
-There are a couple of (more or less) interactive apps that you can run
-on the emulator or on a device that use LibreOffice code. Look in
-android/experimental. DocumentLoader is just a testbench, really for
-code to load a document (just Writer ones so far) and display one page
-at a time. LibreOffice4Android is what resulted from a Google Summer
-of Code project in 2012, a document viewer. desktop is a totally
-different app, where the actual LibreOffice desktop GUI is present.
-Note that none of these apps in any way are claimed to be ready for
-end-users. No "beta testing" offers needed, it is painfully obvious
-what problems they have.
-
-To run some of the apps, do "make install" followed by either "make run" or
+A LibreOffice app for Android is being developed progress in the
+android/experimental/LOAndroid3 directory.
+
+To run the app, do "make install" followed by either "make run" or
starting it from Android itself. You most likely want to have an "adb logcat"
running in another window. To debug, run "make debugrun".
diff --git a/android/experimental/DocumentLoader/AndroidManifest.xml b/android/experimental/DocumentLoader/AndroidManifest.xml
deleted file mode 100644
index 366a1c909b3e..000000000000
--- a/android/experimental/DocumentLoader/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> <!-- -*- indent-tabs-mode: nil -*- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.libreoffice.android.examples"
- android:installLocation="preferExternal"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="15"
- android:targetSdkVersion="15"/>
- <application android:label="LO Experimental DocumentLoader"
- android:debuggable="true"
- android:largeHeap="true"
- android:hardwareAccelerated="true">
- <activity android:name=".DocumentLoader"
- android:label="LO DocumentLoader"
- android:configChanges="keyboardHidden">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
-<!-- vim:set expandtab: -->
diff --git a/android/experimental/DocumentLoader/Makefile b/android/experimental/DocumentLoader/Makefile
deleted file mode 100644
index dbe2b5ce051c..000000000000
--- a/android/experimental/DocumentLoader/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-ifeq ($(BUILDDIR),)
-include ../../../config_host.mk
-endif
-
-# The default target just builds.
-all: build-ant
-
-# The package of this app
-APP_PACKAGE=org.libreoffice.android.examples
-
-BOOTSTRAPDIR=../../Bootstrap
-include $(BOOTSTRAPDIR)/Makefile.shared
-
-native-code.cxx: $(SRCDIR)/solenv/bin/native-code.py
- $< \
- -g core -g writer \
- > $@
-
-build-ant: android_version_setup copy-stuff link-so properties
-#
-# Copy jar files we need
-#
- for F in java_uno \
- juh \
- jurt \
- ridl \
- unoloader; do \
- $(call COPYJAR,$(INSTDIR)/$(LIBO_URE_SHARE_JAVA_FOLDER)/$${F}.jar); \
- done
- for F in unoil; do \
- $(call COPYJAR,$(INSTDIR)/$(LIBO_SHARE_JAVA_FOLDER)/$${F}.jar); \
- done
-#
- unset JAVA_HOME && $(ANT) $(if $(VERBOSE)$(verbose),,-quiet) debug
-
-run:
- adb shell am start -n org.libreoffice.android.examples/.DocumentLoader -e input /assets/test1.odt
diff --git a/android/experimental/DocumentLoader/build.xml b/android/experimental/DocumentLoader/build.xml
deleted file mode 100644
index a35fbcc5de74..000000000000
--- a/android/experimental/DocumentLoader/build.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="LibreOfficeDocumentLoader" default="help">
-
- <!-- The local.properties file is created and updated by the 'android' tool.
- It contains the path to the SDK. It should *NOT* be checked into
- Version Control Systems. -->
- <loadproperties srcFile="local.properties" />
-
- <!-- The ant.properties file can be created by you. It is only edited by the
- 'android' tool to add properties to it.
- This is the place to change some Ant specific build properties.
- Here are some properties you may want to change/update:
-
- source.dir
- The name of the source directory. Default is 'src'.
- out.dir
- The name of the output directory. Default is 'bin'.
-
- For other overridable properties, look at the beginning of the rules
- files in the SDK, at tools/ant/build.xml
-
- Properties related to the SDK location or the project target should
- be updated using the 'android' tool with the 'update' action.
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems.
-
- -->
- <property file="ant.properties" />
-
- <!-- The project.properties file is created and updated by the 'android'
- tool, as well as ADT.
-
- This contains project specific properties such as project target, and library
- dependencies. Lower level build properties are stored in ant.properties
- (or in .classpath for Eclipse projects).
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems. -->
- <loadproperties srcFile="project.properties" />
-
- <!-- quick check on sdk.dir -->
- <fail
- message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
- unless="sdk.dir"
- />
-
-
-<!-- extension targets. Uncomment the ones where you want to do custom work
- in between standard targets -->
-<!--
- <target name="-pre-build">
- </target>
- <target name="-pre-compile">
- </target>
-
- /* This is typically used for code obfuscation.
- Compiled code location: ${out.classes.absolute.dir}
- If this is not done in place, override ${out.dex.input.absolute.dir} */
- <target name="-post-compile">
- </target>
--->
-
- <!-- Import the actual build file.
-
- To customize existing targets, there are two options:
- - Customize only one target:
- - copy/paste the target into this file, *before* the
- <import> task.
- - customize it to your needs.
- - Customize the whole content of build.xml
- - copy/paste the content of the rules files (minus the top node)
- into this file, replacing the <import> task.
- - customize to your needs.
-
- ***********************
- ****** IMPORTANT ******
- ***********************
- In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
- in order to avoid having your file be overridden by tools such as "android update project"
- -->
- <!-- version-tag: custom -->
- <import file="${android.library.reference.1}/no-resource-compress.xml" />
-</project>
diff --git a/android/experimental/DocumentLoader/fonts.conf b/android/experimental/DocumentLoader/fonts.conf
deleted file mode 100644
index 699e9d101048..000000000000
--- a/android/experimental/DocumentLoader/fonts.conf
+++ /dev/null
@@ -1,154 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-<!-- /etc/fonts/fonts.conf file to configure system font access -->
-<fontconfig>
-
-<!-- Font directory list -->
-
- <dir>/system/fonts</dir>
-
- <alias>
- <family>serif</family>
- <prefer>
- <family>Droid Serif</family>
- </prefer>
- </alias>
- <alias>
- <family>sans-serif</family>
- <prefer>
- <family>Roboto</family>
- <family>Droid Sans Fallback</family>
- </prefer>
- </alias>
- <alias>
- <family>monospace</family>
- <prefer>
- <family>Droid Sans Mono</family>
- </prefer>
- </alias>
-
-<!--
- Accept deprecated 'mono' alias, replacing it with 'monospace'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>mono</string>
- </test>
- <edit name="family" mode="assign">
- <string>monospace</string>
- </edit>
- </match>
-
-<!--
- Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>sans serif</string>
- </test>
- <edit name="family" mode="assign">
- <string>sans-serif</string>
- </edit>
- </match>
-
-<!--
- Accept deprecated 'sans' alias, replacing it with 'sans-serif'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>sans</string>
- </test>
- <edit name="family" mode="assign">
- <string>sans-serif</string>
- </edit>
- </match>
-
-<!--
- Load local system customization file
--->
- <include ignore_missing="yes">conf.d</include>
-
-<!-- Font cache directory list -->
-
- <!-- Yeah this hardcoding is wrong of course, will have to fix
- later to patch in proper code in fontonfig on Android to
- find out a good place.
- -->
- <cachedir>/data/data/org.libreoffice.android.examples/fontconfig</cachedir>
-
- <config>
-<!--
- These are the default Unicode chars that are expected to be blank
- in fonts. All other blank chars are assumed to be broken and
- won't appear in the resulting charsets
- -->
- <blank>
- <int>0x0020</int> <!-- SPACE -->
- <int>0x00A0</int> <!-- NO-BREAK SPACE -->
- <int>0x00AD</int> <!-- SOFT HYPHEN -->
- <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
- <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
- <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
- <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
- <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
- <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
- <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
- <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
- <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
- <int>0x1680</int> <!-- OGHAM SPACE MARK -->
- <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
- <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
- <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
- <int>0x2000</int> <!-- EN QUAD -->
- <int>0x2001</int> <!-- EM QUAD -->
- <int>0x2002</int> <!-- EN SPACE -->
- <int>0x2003</int> <!-- EM SPACE -->
- <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
- <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
- <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
- <int>0x2007</int> <!-- FIGURE SPACE -->
- <int>0x2008</int> <!-- PUNCTUATION SPACE -->
- <int>0x2009</int> <!-- THIN SPACE -->
- <int>0x200A</int> <!-- HAIR SPACE -->
- <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
- <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
- <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
- <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
- <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
- <int>0x2028</int> <!-- LINE SEPARATOR -->
- <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
- <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
- <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
- <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
- <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
- <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
- <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
- <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
- <int>0x2060</int> <!-- WORD JOINER -->
- <int>0x2061</int> <!-- FUNCTION APPLICATION -->
- <int>0x2062</int> <!-- INVISIBLE TIMES -->
- <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
- <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
- <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
- <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
- <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
- <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
- <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
- <int>0x2800</int> <!-- BRAILLE PATTERN BLANK -->
- <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
- <int>0x3164</int> <!-- HANGUL FILLER -->
- <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
- <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
- <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
- <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
- <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
- </blank>
-<!--
- Rescan configuration every 3600 seconds when FcFontSetList is called
- -->
- <rescan>
- <int>3600</int>
- </rescan>
- </config>
-
-</fontconfig>
diff --git a/android/experimental/DocumentLoader/jni/Android.mk b/android/experimental/DocumentLoader/jni/Android.mk
deleted file mode 100644
index 939a1ea503bb..000000000000
--- a/android/experimental/DocumentLoader/jni/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Needed just to satisfy ndk-gdb for now, but maybe later we will actually add
-# some JNI code here
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/android/experimental/DocumentLoader/project.properties b/android/experimental/DocumentLoader/project.properties
deleted file mode 100644
index 3b686189734d..000000000000
--- a/android/experimental/DocumentLoader/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-21
-
-# Use the Bootstrap class
-android.library.reference.1=../../Bootstrap
diff --git a/android/experimental/DocumentLoader/res/menu/option.xml b/android/experimental/DocumentLoader/res/menu/option.xml
deleted file mode 100644
index 3230d83fe0cc..000000000000
--- a/android/experimental/DocumentLoader/res/menu/option.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/go_to_page"
- android:title="@string/go_to_page"/>
-</menu>
diff --git a/android/experimental/DocumentLoader/res/values/strings.xml b/android/experimental/DocumentLoader/res/values/strings.xml
deleted file mode 100644
index 148461bfd621..000000000000
--- a/android/experimental/DocumentLoader/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="go_to_page">Go to page</string>
-</resources>
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/Animation.java b/android/experimental/DocumentLoader/src/com/polites/android/Animation.java
deleted file mode 100644
index a0d218b1e552..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/Animation.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public interface Animation {
-
- /**
- * Transforms the view.
- * @param view
- * @param diffTime
- * @return true if this animation should remain active. False otherwise.
- */
- public boolean update(GestureImageView view, long time);
-
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/Animator.java b/android/experimental/DocumentLoader/src/com/polites/android/Animator.java
deleted file mode 100644
index 6fc82f127503..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/Animator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public class Animator extends Thread {
-
- private GestureImageView view;
- private Animation animation;
- private boolean running = false;
- private boolean active = false;
- private long lastTime = -1L;
-
- public Animator(GestureImageView view, String threadName) {
- super(threadName);
- this.view = view;
- }
-
- @Override
- public void run() {
-
- running = true;
-
- while(running) {
-
- while(active && animation != null) {
- long time = System.currentTimeMillis();
- active = animation.update(view, time - lastTime);
- view.redraw();
- lastTime = time;
-
- while(active) {
- try {
- if(view.waitForDraw(32)) { // 30Htz
- break;
- }
- }
- catch (InterruptedException ignore) {
- active = false;
- }
- }
- }
-
- synchronized(this) {
- if(running) {
- try {
- wait();
- }
- catch (InterruptedException ignore) {}
- }
- }
- }
- }
-
- public synchronized void finish() {
- running = false;
- active = false;
- notifyAll();
- }
-
- public void play(Animation transformer) {
- if(active) {
- cancel();
- }
- this.animation = transformer;
-
- activate();
- }
-
- public synchronized void activate() {
- lastTime = System.currentTimeMillis();
- active = true;
- notifyAll();
- }
-
- public void cancel() {
- active = false;
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimation.java b/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimation.java
deleted file mode 100644
index 9afd54969b50..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimation.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public class FlingAnimation implements Animation {
-
- private float velocityX;
- private float velocityY;
-
- private float factor = 0.85f;
-
- private float threshold = 10;
-
- private FlingAnimationListener listener;
-
- /* (non-Javadoc)
- * @see com.polites.android.Transformer#update(com.polites.android.GestureImageView, long)
- */
- @Override
- public boolean update(GestureImageView view, long time) {
- float seconds = (float) time / 1000.0f;
-
- float dx = velocityX * seconds;
- float dy = velocityY * seconds;
-
- velocityX *= factor;
- velocityY *= factor;
-
- boolean active = (Math.abs(velocityX) > threshold && Math.abs(velocityY) > threshold);
-
- if(listener != null) {
- listener.onMove(dx, dy);
-
- if(!active) {
- listener.onComplete();
- }
- }
-
- return active;
- }
-
- public void setVelocityX(float velocityX) {
- this.velocityX = velocityX;
- }
-
- public void setVelocityY(float velocityY) {
- this.velocityY = velocityY;
- }
-
- public void setFactor(float factor) {
- this.factor = factor;
- }
-
- public void setListener(FlingAnimationListener listener) {
- this.listener = listener;
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimationListener.java b/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimationListener.java
deleted file mode 100644
index 8f0dd3d77e79..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/FlingAnimationListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public interface FlingAnimationListener {
-
- public void onMove(float x, float y);
-
- public void onComplete();
-
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageView.java b/android/experimental/DocumentLoader/src/com/polites/android/GestureImageView.java
deleted file mode 100644
index 4b9278c1cf35..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageView.java
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-import java.io.InputStream;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.provider.MediaStore;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ImageView;
-
-public class GestureImageView extends ImageView {
-
- public static final String GLOBAL_NS = "http://schemas.android.com/apk/res/android";
- public static final String LOCAL_NS = "http://schemas.polites.com/android";
-
- private final Semaphore drawLock = new Semaphore(0);
- private Animator animator;
-
- private Drawable drawable;
-
- private float x = 0, y = 0;
-
- private boolean layout = false;
-
- private float scaleAdjust = 1.0f;
- private float startingScale = -1.0f;
-
- private float scale = 1.0f;
- private float maxScale = 5.0f;
- private float minScale = 0.75f;
- private float fitScaleHorizontal = 1.0f;
- private float fitScaleVertical = 1.0f;
- private float rotation = 0.0f;
-
- private float centerX;
- private float centerY;
-
- private Float startX, startY;
-
- private int hWidth;
- private int hHeight;
-
- private int resId = -1;
- private boolean recycle = false;
- private boolean strict = false;
-
- private int displayHeight;
- private int displayWidth;
-
- private int alpha = 255;
- private ColorFilter colorFilter;
-
- private int deviceOrientation = -1;
- private int imageOrientation;
-
- private GestureImageViewListener gestureImageViewListener;
- private GestureImageViewTouchListener gestureImageViewTouchListener;
-
- private OnTouchListener customOnTouchListener;
- private OnClickListener onClickListener;
-
- GestureDetector.OnGestureListener overflowGestureListener;
-
- public GestureImageView(Context context, GestureDetector.OnGestureListener overflowGestureListener, AttributeSet attrs, int defStyle) {
- this(context, overflowGestureListener, attrs);
- }
-
- public GestureImageView(Context context, GestureDetector.OnGestureListener overflowGestureListener, AttributeSet attrs) {
- super(context, attrs);
-
- this.overflowGestureListener = overflowGestureListener;
- String scaleType = attrs.getAttributeValue(GLOBAL_NS, "scaleType");
-
- if(scaleType == null || scaleType.trim().length() == 0) {
- setScaleType(ScaleType.CENTER_INSIDE);
- }
-
- String strStartX = attrs.getAttributeValue(LOCAL_NS, "start-x");
- String strStartY = attrs.getAttributeValue(LOCAL_NS, "start-y");
-
- if(strStartX != null && strStartX.trim().length() > 0) {
- startX = Float.parseFloat(strStartX);
- }
-
- if(strStartY != null && strStartY.trim().length() > 0) {
- startY = Float.parseFloat(strStartY);
- }
-
- setStartingScale(attrs.getAttributeFloatValue(LOCAL_NS, "start-scale", startingScale));
- setMinScale(attrs.getAttributeFloatValue(LOCAL_NS, "min-scale", minScale));
- setMaxScale(attrs.getAttributeFloatValue(LOCAL_NS, "max-scale", maxScale));
- setStrict(attrs.getAttributeBooleanValue(LOCAL_NS, "strict", strict));
- setRecycle(attrs.getAttributeBooleanValue(LOCAL_NS, "recycle", recycle));
-
- initImage();
- }
-
- public GestureImageView(Context context, GestureDetector.OnGestureListener overflowGestureListener) {
- super(context);
-
- this.overflowGestureListener = overflowGestureListener;
- setScaleType(ScaleType.CENTER_INSIDE);
- initImage();
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- if(drawable != null) {
- int orientation = getResources().getConfiguration().orientation;
- if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
- displayHeight = MeasureSpec.getSize(heightMeasureSpec);
-
- if(getLayoutParams().width == LayoutParams.WRAP_CONTENT) {
- float ratio = (float) getImageWidth() / (float) getImageHeight();
- displayWidth = Math.round( (float) displayHeight * ratio) ;
- }
- else {
- displayWidth = MeasureSpec.getSize(widthMeasureSpec);
- }
- }
- else {
- displayWidth = MeasureSpec.getSize(widthMeasureSpec);
- if(getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
- float ratio = (float) getImageHeight() / (float) getImageWidth();
- displayHeight = Math.round( (float) displayWidth * ratio) ;
- }
- else {
- displayHeight = MeasureSpec.getSize(heightMeasureSpec);
- }
- }
- }
- else {
- displayHeight = MeasureSpec.getSize(heightMeasureSpec);
- displayWidth = MeasureSpec.getSize(widthMeasureSpec);
- }
-
- setMeasuredDimension(displayWidth, displayHeight);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if(changed || !layout) {
- setupCanvas(displayWidth, displayHeight, getResources().getConfiguration().orientation);
- }
- }
-
- protected void setupCanvas(int measuredWidth, int measuredHeight, int orientation) {
-
- if(deviceOrientation != orientation) {
- layout = false;
- deviceOrientation = orientation;
- }
-
- if(drawable != null && !layout) {
- int imageWidth = getImageWidth();
- int imageHeight = getImageHeight();
-
- hWidth = Math.round(((float)imageWidth / 2.0f));
- hHeight = Math.round(((float)imageHeight / 2.0f));
-
- measuredWidth -= (getPaddingLeft() + getPaddingRight());
- measuredHeight -= (getPaddingTop() + getPaddingBottom());
-
- computeCropScale(imageWidth, imageHeight, measuredWidth, measuredHeight);
-
- if(startingScale <= 0.0f) {
- computeStartingScale(imageWidth, imageHeight, measuredWidth, measuredHeight);
- }
-
- scaleAdjust = startingScale;
-
- this.centerX = (float) measuredWidth / 2.0f;
- this.centerY = (float) measuredHeight / 2.0f;
-
- if(startX == null) {
- x = centerX;
- }
- else {
- x = startX;
- }
-
- if(startY == null) {
- y = centerY;
- }
- else {
- y = startY;
- }
-
- gestureImageViewTouchListener = new GestureImageViewTouchListener(this, measuredWidth, measuredHeight);
-
- if(isLandscape()) {
- gestureImageViewTouchListener.setMinScale(minScale * fitScaleHorizontal);
- }
- else {
- gestureImageViewTouchListener.setMinScale(minScale * fitScaleVertical);
- }
-
-
- gestureImageViewTouchListener.setMaxScale(maxScale * startingScale);
-
- gestureImageViewTouchListener.setFitScaleHorizontal(fitScaleHorizontal);
- gestureImageViewTouchListener.setFitScaleVertical(fitScaleVertical);
- gestureImageViewTouchListener.setCanvasWidth(measuredWidth);
- gestureImageViewTouchListener.setCanvasHeight(measuredHeight);
- gestureImageViewTouchListener.setOnClickListener(onClickListener);
-
- drawable.setBounds(-hWidth,-hHeight,hWidth,hHeight);
-
- super.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if(customOnTouchListener != null) {
- customOnTouchListener.onTouch(v, event);
- }
- return gestureImageViewTouchListener.onTouch(v, event);
- }
- });
-
- layout = true;
- }
- }
-
- protected void computeCropScale(int imageWidth, int imageHeight, int measuredWidth, int measuredHeight) {
- fitScaleHorizontal = (float) measuredWidth / (float) imageWidth;
- fitScaleVertical = (float) measuredHeight / (float) imageHeight;
- }
-
- protected void computeStartingScale(int imageWidth, int imageHeight, int measuredWidth, int measuredHeight) {
- switch(getScaleType()) {
- case CENTER:
- // Center the image in the view, but perform no scaling.
- startingScale = 1.0f;
- break;
-
- case CENTER_CROP:
- startingScale = Math.max((float) measuredHeight / (float) imageHeight, (float) measuredWidth/ (float) imageWidth);
- break;
-
- case CENTER_INSIDE:
- if(isLandscape()) {
- startingScale = fitScaleHorizontal;
- }
- else {
- startingScale = fitScaleVertical;
- }
- break;
- }
- }
-
- protected boolean isRecycled() {
- if(drawable != null && drawable instanceof BitmapDrawable) {
- Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
- if(bitmap != null) {
- return bitmap.isRecycled();
- }
- }
- return false;
- }
-
- protected void recycle() {
- if(recycle && drawable != null && drawable instanceof BitmapDrawable) {
- Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
- if(bitmap != null) {
- bitmap.recycle();
- }
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if(layout) {
- if(drawable != null && !isRecycled()) {
- canvas.save();
-
- float adjustedScale = scale * scaleAdjust;
-
- canvas.translate(x, y);
-
- if(rotation != 0.0f) {
- canvas.rotate(rotation);
- }
-
- if(adjustedScale != 1.0f) {
- canvas.scale(adjustedScale, adjustedScale);
- }
-
- drawable.draw(canvas);
-
- canvas.restore();
- }
-
- if(drawLock.availablePermits() <= 0) {
- drawLock.release();
- }
- }
- }
-
- /**
- * Waits for a draw
- * @param max time to wait for draw (ms)
- * @throws InterruptedException
- */
- public boolean waitForDraw(long timeout) throws InterruptedException {
- return drawLock.tryAcquire(timeout, TimeUnit.MILLISECONDS);
- }
-
- @Override
- protected void onAttachedToWindow() {
- animator = new Animator(this, "GestureImageViewAnimator");
- animator.start();
-
- if(resId >= 0 && drawable == null) {
- setImageResource(resId);
- }
-
- super.onAttachedToWindow();
- }
-
- public void animationStart(Animation animation) {
- if(animator != null) {
- animator.play(animation);
- }
- }
-
- public void animationStop() {
- if(animator != null) {
- animator.cancel();
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if(animator != null) {
- animator.finish();
- }
- if(recycle && drawable != null && !isRecycled()) {
- recycle();
- drawable = null;
- }
- super.onDetachedFromWindow();
- }
-
- protected void initImage() {
- if(this.drawable != null) {
- this.drawable.setAlpha(alpha);
- this.drawable.setFilterBitmap(true);
- if(colorFilter != null) {
- this.drawable.setColorFilter(colorFilter);
- }
- }
-
- if(!layout) {
- requestLayout();
- redraw();
- }
- }
-
- public void setImageBitmap(Bitmap image) {
- this.drawable = new BitmapDrawable(getResources(), image);
- initImage();
- }
-
- @Override
- public void setImageDrawable(Drawable drawable) {
- this.drawable = drawable;
- initImage();
- }
-
- public void setImageResource(int id) {
- if(this.drawable != null) {
- this.recycle();
- }
- if(id >= 0) {
- this.resId = id;
- setImageDrawable(getContext().getResources().getDrawable(id));
- }
- }
-
- public int getScaledWidth() {
- return Math.round(getImageWidth() * getScale());
- }
-
- public int getScaledHeight() {
- return Math.round(getImageHeight() * getScale());
- }
-
- public int getImageWidth() {
- if(drawable != null) {
- return drawable.getIntrinsicWidth();
- }
- return 0;
- }
-
- public int getImageHeight() {
- if(drawable != null) {
- return drawable.getIntrinsicHeight();
- }
- return 0;
- }
-
- public void moveBy(float x, float y) {
- this.x += x;
- this.y += y;
- }
-
- public void setPosition(float x, float y) {
- this.x = x;
- this.y = y;
- }
-
- public void redraw() {
- postInvalidate();
- }
-
- public void setMinScale(float min) {
- this.minScale = min;
- if(gestureImageViewTouchListener != null) {
- gestureImageViewTouchListener.setMinScale(min * fitScaleHorizontal);
- }
- }
-
- public void setMaxScale(float max) {
- this.maxScale = max;
- if(gestureImageViewTouchListener != null) {
- gestureImageViewTouchListener.setMaxScale(max * startingScale);
- }
- }
-
- public void setScale(float scale) {
- scaleAdjust = scale;
- }
-
- public float getScale() {
- return scaleAdjust;
- }
-
- public float getImageX() {
- return x;
- }
-
- public float getImageY() {
- return y;
- }
-
- public boolean isStrict() {
- return strict;
- }
-
- public void setStrict(boolean strict) {
- this.strict = strict;
- }
-
- public boolean isRecycle() {
- return recycle;
- }
-
- public void setRecycle(boolean recycle) {
- this.recycle = recycle;
- }
-
- public void reset() {
- x = centerX;
- y = centerY;
- scaleAdjust = startingScale;
- redraw();
- }
-
- public void setRotation(float rotation) {
- this.rotation = rotation;
- }
-
- public void setGestureImageViewListener(GestureImageViewListener pinchImageViewListener) {
- this.gestureImageViewListener = pinchImageViewListener;
- }
-
- public GestureImageViewListener getGestureImageViewListener() {
- return gestureImageViewListener;
- }
-
- @Override
- public Drawable getDrawable() {
- return drawable;
- }
-
- @Override
- public void setAlpha(int alpha) {
- this.alpha = alpha;
- if(drawable != null) {
- drawable.setAlpha(alpha);
- }
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- this.colorFilter = cf;
- if(drawable != null) {
- drawable.setColorFilter(cf);
- }
- }
-
- @Override
- public void setImageURI(Uri mUri) {
- if ("content".equals(mUri.getScheme())) {
- try {
- String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
-
- Cursor cur = getContext().getContentResolver().query(mUri, orientationColumn, null, null, null);
-
- if (cur != null && cur.moveToFirst()) {
- imageOrientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
- }
-
- InputStream in = null;
-
- try {
- in = getContext().getContentResolver().openInputStream(mUri);
- Bitmap bmp = BitmapFactory.decodeStream(in);
-
- if(imageOrientation != 0) {
- Matrix m = new Matrix();
- m.postRotate(imageOrientation);
- Bitmap rotated = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
- bmp.recycle();
- setImageDrawable(new BitmapDrawable(getResources(), rotated));
- }
- else {
- setImageDrawable(new BitmapDrawable(getResources(), bmp));
- }
- }
- finally {
- if(in != null) {
- in.close();
- }
-
- if(cur != null) {
- cur.close();
- }
- }
- }
- catch (Exception e) {
- Log.w("GestureImageView", "Unable to open content: " + mUri, e);
- }
- }
- else {
- setImageDrawable(Drawable.createFromPath(mUri.toString()));
- }
-
- if (drawable == null) {
- Log.e("GestureImageView", "resolveUri failed on bad bitmap uri: " + mUri);
- // Don't try again.
- mUri = null;
- }
- }
-
- @Override
- public Matrix getImageMatrix() {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- return super.getImageMatrix();
- }
-
- @Override
- public void setScaleType(ScaleType scaleType) {
- if(scaleType == ScaleType.CENTER ||
- scaleType == ScaleType.CENTER_CROP ||
- scaleType == ScaleType.CENTER_INSIDE) {
-
- super.setScaleType(scaleType);
- }
- else if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- }
-
- @Override
- public void invalidateDrawable(Drawable dr) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- super.invalidateDrawable(dr);
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- return super.onCreateDrawableState(extraSpace);
- }
-
- @Override
- public void setAdjustViewBounds(boolean adjustViewBounds) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- super.setAdjustViewBounds(adjustViewBounds);
- }
-
- @Override
- public void setImageLevel(int level) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- super.setImageLevel(level);
- }
-
- @Override
- public void setImageMatrix(Matrix matrix) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- }
-
- @Override
- public void setImageState(int[] state, boolean merge) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- }
-
- @Override
- public void setSelected(boolean selected) {
- if(strict) {
- throw new UnsupportedOperationException("Not supported");
- }
- super.setSelected(selected);
- }
-
- @Override
- public void setOnTouchListener(OnTouchListener l) {
- this.customOnTouchListener = l;
- }
-
- public float getCenterX() {
- return centerX;
- }
-
- public float getCenterY() {
- return centerY;
- }
-
- public boolean isLandscape() {
- return getImageWidth() >= getImageHeight();
- }
-
- public boolean isPortrait() {
- return getImageWidth() <= getImageHeight();
- }
-
- public void setStartingScale(float startingScale) {
- this.startingScale = startingScale;
- }
-
- public void setStartingPosition(float x, float y) {
- this.startX = x;
- this.startY = y;
- }
-
- @Override
- public void setOnClickListener(OnClickListener l) {
- this.onClickListener = l;
-
- if(gestureImageViewTouchListener != null) {
- gestureImageViewTouchListener.setOnClickListener(l);
- }
- }
-
- /**
- * Returns true if the image dimensions are aligned with the orientation of the device.
- * @return
- */
- public boolean isOrientationAligned() {
- if(deviceOrientation == Configuration.ORIENTATION_LANDSCAPE) {
- return isLandscape();
- }
- else if(deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
- return isPortrait();
- }
- return true;
- }
-
- public int getDeviceOrientation() {
- return deviceOrientation;
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewListener.java b/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewListener.java
deleted file mode 100644
index 487620a7c225..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewListener.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public interface GestureImageViewListener {
-
- public void onTouch(float x, float y);
-
- public void onScale(float scale);
-
- public void onPosition(float x, float y);
-
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewTouchListener.java b/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewTouchListener.java
deleted file mode 100644
index f39840b60a79..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/GestureImageViewTouchListener.java
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-import android.content.res.Configuration;
-import android.graphics.PointF;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-
-public class GestureImageViewTouchListener implements OnTouchListener {
-
- private GestureImageView image;
- private OnClickListener onClickListener;
-
- private final PointF current = new PointF();
- private final PointF last = new PointF();
- private final PointF next = new PointF();
- private final PointF midpoint = new PointF();
-
- private final VectorF scaleVector = new VectorF();
- private final VectorF pinchVector = new VectorF();
-
- private boolean touched = false;
- private boolean inZoom = false;
-
- private float initialDistance;
- private float lastScale = 1.0f;
- private float currentScale = 1.0f;
-
- private float boundaryLeft = 0;
- private float boundaryTop = 0;
- private float boundaryRight = 0;
- private float boundaryBottom = 0;
-
- private float maxScale = 5.0f;
- private float minScale = 0.25f;
- private float fitScaleHorizontal = 1.0f;
- private float fitScaleVertical = 1.0f;
-
- private int canvasWidth = 0;
- private int canvasHeight = 0;
-
- private float centerX = 0;
- private float centerY = 0;
-
- private float startingScale = 0;
-
- private boolean canDragX = false;
- private boolean canDragY = false;
-
- private boolean multiTouch = false;
-
- private int displayWidth;
- private int displayHeight;
-
- private int imageWidth;
- private int imageHeight;
-
- private FlingListener flingListener;
- private FlingAnimation flingAnimation;
- private ZoomAnimation zoomAnimation;
- private MoveAnimation moveAnimation;
- private GestureDetector tapDetector;
- private GestureDetector flingDetector;
- private GestureImageViewListener imageListener;
-
- class FlingListener extends SimpleOnGestureListener {
-
- private float velocityX;
- private float velocityY;
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- this.velocityX = velocityX;
- this.velocityY = velocityY;
- if (image.overflowGestureListener != null && !canDragX && !canDragY) {
- return image.overflowGestureListener.onFling(e1, e2, velocityX, velocityY);
- }
-
- return true;
- }
-
- public float getVelocityX() {
- return velocityX;
- }
-
- public float getVelocityY() {
- return velocityY;
- }
- }
-
- public GestureImageViewTouchListener(final GestureImageView image, int displayWidth, int displayHeight) {
- super();
-
- this.image = image;
-
- this.displayWidth = displayWidth;
- this.displayHeight = displayHeight;
-
- this.centerX = (float) displayWidth / 2.0f;
- this.centerY = (float) displayHeight / 2.0f;
-
- this.imageWidth = image.getImageWidth();
- this.imageHeight = image.getImageHeight();
-
- startingScale = image.getScale();
-
- currentScale = startingScale;
- lastScale = startingScale;
-
- boundaryRight = displayWidth;
- boundaryBottom = displayHeight;
- boundaryLeft = 0;
- boundaryTop = 0;
-
- next.x = image.getImageX();
- next.y = image.getImageY();
-
- flingListener = new FlingListener();
- flingAnimation = new FlingAnimation();
- zoomAnimation = new ZoomAnimation();
- moveAnimation = new MoveAnimation();
-
- flingAnimation.setListener(new FlingAnimationListener() {
- @Override
- public void onMove(float x, float y) {
- handleDrag(current.x + x, current.y + y);
- }
-
- @Override
- public void onComplete() {}
- });
-
- zoomAnimation.setZoom(2.0f);
- zoomAnimation.setZoomAnimationListener(new ZoomAnimationListener() {
- @Override
- public void onZoom(float scale, float x, float y) {
- if(scale <= maxScale && scale >= minScale) {
- handleScale(scale, x, y);
- }
- }
-
- @Override
- public void onComplete() {
- inZoom = false;
- handleUp();
- }
- });
-
- moveAnimation.setMoveAnimationListener(new MoveAnimationListener() {
-
- @Override
- public void onMove(float x, float y) {
- image.setPosition(x, y);
- image.redraw();
- }
- });
-
- tapDetector = new GestureDetector(image.getContext(), new SimpleOnGestureListener() {
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- startZoom(e);
- return true;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- if(!inZoom) {
- if(onClickListener != null) {
- onClickListener.onClick(image);
- return true;
- }
- }
-
- return false;
- }
- });
-
- flingDetector = new GestureDetector(image.getContext(), flingListener);
- imageListener = image.getGestureImageViewListener();
-
- calculateBoundaries();
- }
-
- private void startFling() {
- flingAnimation.setVelocityX(flingListener.getVelocityX());
- flingAnimation.setVelocityY(flingListener.getVelocityY());
- image.animationStart(flingAnimation);
- }
-
- private void startZoom(MotionEvent e) {
- inZoom = true;
- zoomAnimation.reset();
-
- float zoomTo = 1.0f;
-
- if(image.isLandscape()) {
- if(image.getDeviceOrientation() == Configuration.ORIENTATION_PORTRAIT) {
- int scaledHeight = image.getScaledHeight();
-
- if(scaledHeight < canvasHeight) {
- zoomTo = fitScaleVertical / currentScale;
- zoomAnimation.setTouchX(e.getX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- else {
- zoomTo = fitScaleHorizontal / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- }
- else {
- int scaledWidth = image.getScaledWidth();
-
- if(scaledWidth == canvasWidth) {
- zoomTo = currentScale*4.0f;
- zoomAnimation.setTouchX(e.getX());
- zoomAnimation.setTouchY(e.getY());
- }
- else if(scaledWidth < canvasWidth) {
- zoomTo = fitScaleHorizontal / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(e.getY());
- }
- else {
- zoomTo = fitScaleHorizontal / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- }
- }
- else {
- if(image.getDeviceOrientation() == Configuration.ORIENTATION_PORTRAIT) {
-
- int scaledHeight = image.getScaledHeight();
-
- if(scaledHeight == canvasHeight) {
- zoomTo = currentScale*4.0f;
- zoomAnimation.setTouchX(e.getX());
- zoomAnimation.setTouchY(e.getY());
- }
- else if(scaledHeight < canvasHeight) {
- zoomTo = fitScaleVertical / currentScale;
- zoomAnimation.setTouchX(e.getX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- else {
- zoomTo = fitScaleVertical / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- }
- else {
- int scaledWidth = image.getScaledWidth();
-
- if(scaledWidth < canvasWidth) {
- zoomTo = fitScaleHorizontal / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(e.getY());
- }
- else {
- zoomTo = fitScaleVertical / currentScale;
- zoomAnimation.setTouchX(image.getCenterX());
- zoomAnimation.setTouchY(image.getCenterY());
- }
- }
- }
-
- zoomAnimation.setZoom(zoomTo);
- image.animationStart(zoomAnimation);
- }
-
-
- private void stopAnimations() {
- image.animationStop();
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
-
- if(!inZoom) {
-
- if(!tapDetector.onTouchEvent(event)) {
- if(event.getPointerCount() == 1 && flingDetector.onTouchEvent(event)) {
- startFling();
- }
-
- if(event.getAction() == MotionEvent.ACTION_UP) {
- handleUp();
- }
- else if(event.getAction() == MotionEvent.ACTION_DOWN) {
- stopAnimations();
-
- last.x = event.getX();
- last.y = event.getY();
-
- if(imageListener != null) {
- imageListener.onTouch(last.x, last.y);
- }
-
- touched = true;
- }
- else if(event.getAction() == MotionEvent.ACTION_MOVE) {
- if(event.getPointerCount() > 1) {
- multiTouch = true;
- if(initialDistance > 0) {
-
- pinchVector.set(event);
- pinchVector.calculateLength();
-
- float distance = pinchVector.length;
-
- if(initialDistance != distance) {
-
- float newScale = (distance / initialDistance) * lastScale;
-
- if(newScale <= maxScale) {
- scaleVector.length *= newScale;
-
- scaleVector.calculateEndPoint();
-
- scaleVector.length /= newScale;
-
- float newX = scaleVector.end.x;
- float newY = scaleVector.end.y;
-
- handleScale(newScale, newX, newY);
- }
- }
- }
- else {
- initialDistance = MathUtils.distance(event);
-
- MathUtils.midpoint(event, midpoint);
-
- scaleVector.setStart(midpoint);
- scaleVector.setEnd(next);
-
- scaleVector.calculateLength();
- scaleVector.calculateAngle();
-
- scaleVector.length /= lastScale;
- }
- }
- else {
- if(!touched) {
- touched = true;
- last.x = event.getX();
- last.y = event.getY();
- next.x = image.getImageX();
- next.y = image.getImageY();
- }
- else if(!multiTouch) {
- if(handleDrag(event.getX(), event.getY())) {
- image.redraw();
- }
- }
- }
- }
- }
- }
-
- return true;
- }
-
- protected void handleUp() {
-
- multiTouch = false;
-
- initialDistance = 0;
- lastScale = currentScale;
-
- if(!canDragX) {
- next.x = centerX;
- }
-
- if(!canDragY) {
- next.y = centerY;
- }
-
- boundCoordinates();
-
- if(!canDragX && !canDragY) {
-
- if(image.isLandscape()) {
- currentScale = fitScaleHorizontal;
- lastScale = fitScaleHorizontal;
- }
- else {
- currentScale = fitScaleVertical;
- lastScale = fitScaleVertical;
- }
- }
-
- image.setScale(currentScale);
- image.setPosition(next.x, next.y);
-
- if(imageListener != null) {
- imageListener.onScale(currentScale);
- imageListener.onPosition(next.x, next.y);
- }
-
- image.redraw();
- }
-
- protected void handleScale(float scale, float x, float y) {
-
- currentScale = scale;
-
- if(currentScale > maxScale) {
- currentScale = maxScale;
- }
- else if (currentScale < minScale) {
- currentScale = minScale;
- }
- else {
- next.x = x;
- next.y = y;
- }
-
- calculateBoundaries();
-
- image.setScale(currentScale);
- image.setPosition(next.x, next.y);
-
- if(imageListener != null) {
- imageListener.onScale(currentScale);
- imageListener.onPosition(next.x, next.y);
- }
-
- image.redraw();
- }
-
- protected boolean handleDrag(float x, float y) {
- current.x = x;
- current.y = y;
-
- float diffX = (current.x - last.x);
- float diffY = (current.y - last.y);
-
- if(diffX != 0 || diffY != 0) {
-
- if(canDragX) next.x += diffX;
- if(canDragY) next.y += diffY;
-
- boundCoordinates();
-
- last.x = current.x;
- last.y = current.y;
-
- if(canDragX || canDragY) {
- image.setPosition(next.x, next.y);
-
- if(imageListener != null) {
- imageListener.onPosition(next.x, next.y);
- }
-
- return true;
- }
- }
-
- return false;
- }
-
- public void reset() {
- currentScale = startingScale;
- next.x = centerX;
- next.y = centerY;
- calculateBoundaries();
- image.setScale(currentScale);
- image.setPosition(next.x, next.y);
- image.redraw();
- }
-
-
- public float getMaxScale() {
- return maxScale;
- }
-
- public void setMaxScale(float maxScale) {
- this.maxScale = maxScale;
- }
-
- public float getMinScale() {
- return minScale;
- }
-
- public void setMinScale(float minScale) {
- this.minScale = minScale;
- }
-
- public void setOnClickListener(OnClickListener onClickListener) {
- this.onClickListener = onClickListener;
- }
-
- protected void setCanvasWidth(int canvasWidth) {
- this.canvasWidth = canvasWidth;
- }
-
- protected void setCanvasHeight(int canvasHeight) {
- this.canvasHeight = canvasHeight;
- }
-
- protected void setFitScaleHorizontal(float fitScale) {
- this.fitScaleHorizontal = fitScale;
- }
-
- protected void setFitScaleVertical(float fitScaleVertical) {
- this.fitScaleVertical = fitScaleVertical;
- }
-
- protected void boundCoordinates() {
- if(next.x < boundaryLeft) {
- next.x = boundaryLeft;
- }
- else if(next.x > boundaryRight) {
- next.x = boundaryRight;
- }
-
- if(next.y < boundaryTop) {
- next.y = boundaryTop;
- }
- else if(next.y > boundaryBottom) {
- next.y = boundaryBottom;
- }
- }
-
- protected void calculateBoundaries() {
-
- int effectiveWidth = Math.round( (float) imageWidth * currentScale );
- int effectiveHeight = Math.round( (float) imageHeight * currentScale );
-
- canDragX = effectiveWidth > displayWidth;
- canDragY = effectiveHeight > displayHeight;
-
- if(canDragX) {
- float diff = (float)(effectiveWidth - displayWidth) / 2.0f;
- boundaryLeft = centerX - diff;
- boundaryRight = centerX + diff;
- }
-
- if(canDragY) {
- float diff = (float)(effectiveHeight - displayHeight) / 2.0f;
- boundaryTop = centerY - diff;
- boundaryBottom = centerY + diff;
- }
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/MathUtils.java b/android/experimental/DocumentLoader/src/com/polites/android/MathUtils.java
deleted file mode 100644
index df7f30db54a7..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/MathUtils.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-import android.graphics.PointF;
-import android.util.FloatMath;
-import android.view.MotionEvent;
-
-public class MathUtils {
-
- public static float distance(MotionEvent event) {
- float x = event.getX(0) - event.getX(1);
- float y = event.getY(0) - event.getY(1);
- return FloatMath.sqrt(x * x + y * y);
- }
-
- public static float distance(PointF p1, PointF p2) {
- float x = p1.x - p2.x;
- float y = p1.y - p2.y;
- return FloatMath.sqrt(x * x + y * y);
- }
-
- public static float distance(float x1, float y1, float x2, float y2) {
- float x = x1 - x2;
- float y = y1 - y2;
- return FloatMath.sqrt(x * x + y * y);
- }
-
- public static void midpoint(MotionEvent event, PointF point) {
- float x1 = event.getX(0);
- float y1 = event.getY(0);
- float x2 = event.getX(1);
- float y2 = event.getY(1);
- midpoint(x1, y1, x2, y2, point);
- }
-
- public static void midpoint(float x1, float y1, float x2, float y2, PointF point) {
- point.x = (x1 + x2) / 2.0f;
- point.y = (y1 + y2) / 2.0f;
- }
- /**
- * Rotates p1 around p2 by angle degrees.
- * @param p1
- * @param p2
- * @param angle
- */
- public void rotate(PointF p1, PointF p2, float angle) {
- float px = p1.x;
- float py = p1.y;
- float ox = p2.x;
- float oy = p2.y;
- p1.x = (FloatMath.cos(angle) * (px-ox) - FloatMath.sin(angle) * (py-oy) + ox);
- p1.y = (FloatMath.sin(angle) * (px-ox) + FloatMath.cos(angle) * (py-oy) + oy);
- }
-
- public static float angle(PointF p1, PointF p2) {
- return angle(p1.x, p1.y, p2.x, p2.y);
- }
-
- public static float angle(float x1, float y1, float x2, float y2) {
- return (float) Math.atan2(y2 - y1, x2 - x1);
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimation.java b/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimation.java
deleted file mode 100644
index 8cdebb61838a..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimation.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public class MoveAnimation implements Animation {
-
- private boolean firstFrame = true;
-
- private float startX;
- private float startY;
-
- private float targetX;
- private float targetY;
- private long animationTimeMS = 100;
- private long totalTime = 0;
-
- private MoveAnimationListener moveAnimationListener;
-
- /* (non-Javadoc)
- * @see com.polites.android.Animation#update(com.polites.android.GestureImageView, long)
- */
- @Override
- public boolean update(GestureImageView view, long time) {
- totalTime += time;
-
- if(firstFrame) {
- firstFrame = false;
- startX = view.getImageX();
- startY = view.getImageY();
- }
-
- if(totalTime < animationTimeMS) {
-
- float ratio = (float) totalTime / animationTimeMS;
-
- float newX = ((targetX - startX) * ratio) + startX;
- float newY = ((targetY - startY) * ratio) + startY;
-
- if(moveAnimationListener != null) {
- moveAnimationListener.onMove(newX, newY);
- }
-
- return true;
- }
- else {
- if(moveAnimationListener != null) {
- moveAnimationListener.onMove(targetX, targetY);
- }
- }
-
- return false;
- }
-
- public void reset() {
- firstFrame = true;
- totalTime = 0;
- }
-
-
- public float getTargetX() {
- return targetX;
- }
-
-
- public void setTargetX(float targetX) {
- this.targetX = targetX;
- }
-
-
- public float getTargetY() {
- return targetY;
- }
-
- public void setTargetY(float targetY) {
- this.targetY = targetY;
- }
-
- public long getAnimationTimeMS() {
- return animationTimeMS;
- }
-
- public void setAnimationTimeMS(long animationTimeMS) {
- this.animationTimeMS = animationTimeMS;
- }
-
- public void setMoveAnimationListener(MoveAnimationListener moveAnimationListener) {
- this.moveAnimationListener = moveAnimationListener;
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimationListener.java b/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimationListener.java
deleted file mode 100644
index 4574caa3a938..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/MoveAnimationListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public interface MoveAnimationListener {
-
- public void onMove(float x, float y);
-
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/VectorF.java b/android/experimental/DocumentLoader/src/com/polites/android/VectorF.java
deleted file mode 100644
index 1ff4b19d7e4f..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/VectorF.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-import android.graphics.PointF;
-import android.util.FloatMath;
-import android.view.MotionEvent;
-
-public class VectorF {
-
- public float angle;
- public float length;
-
- public final PointF start = new PointF();
- public final PointF end = new PointF();
-
- public void calculateEndPoint() {
- end.x = FloatMath.cos(angle) * length + start.x;
- end.y = FloatMath.sin(angle) * length + start.y;
- }
-
- public void setStart(PointF p) {
- this.start.x = p.x;
- this.start.y = p.y;
- }
-
- public void setEnd(PointF p) {
- this.end.x = p.x;
- this.end.y = p.y;
- }
-
- public void set(MotionEvent event) {
- this.start.x = event.getX(0);
- this.start.y = event.getY(0);
- this.end.x = event.getX(1);
- this.end.y = event.getY(1);
- }
-
- public float calculateLength() {
- length = MathUtils.distance(start, end);
- return length;
- }
-
- public float calculateAngle() {
- angle = MathUtils.angle(start, end);
- return angle;
- }
-
-
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimation.java b/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimation.java
deleted file mode 100644
index c709a1b7b513..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimation.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-import android.graphics.PointF;
-
-public class ZoomAnimation implements Animation {
-
- private boolean firstFrame = true;
-
- private float touchX;
- private float touchY;
-
- private float zoom;
-
- private float startX;
- private float startY;
- private float startScale;
-
- private float xDiff;
- private float yDiff;
- private float scaleDiff;
-
- private long animationLengthMS = 200;
- private long totalTime = 0;
-
- private ZoomAnimationListener zoomAnimationListener;
-
- /* (non-Javadoc)
- * @see com.polites.android.Animation#update(com.polites.android.GestureImageView, long)
- */
- @Override
- public boolean update(GestureImageView view, long time) {
- if(firstFrame) {
- firstFrame = false;
-
- startX = view.getImageX();
- startY = view.getImageY();
- startScale = view.getScale();
- scaleDiff = (zoom * startScale) - startScale;
-
- if(scaleDiff > 0) {
- // Calculate destination for midpoint
- VectorF vector = new VectorF();
-
- // Set the touch point as start because we want to move the end
- vector.setStart(new PointF(touchX, touchY));
- vector.setEnd(new PointF(startX, startY));
-
- vector.calculateAngle();
-
- // Get the current length
- float length = vector.calculateLength();
-
- // Multiply length by zoom to get the new length
- vector.length = length*zoom;
-
- // Now deduce the new endpoint
- vector.calculateEndPoint();
-
- xDiff = vector.end.x - startX;
- yDiff = vector.end.y - startY;
- }
- else {
- // Zoom out to center
- xDiff = view.getCenterX() - startX;
- yDiff = view.getCenterY() - startY;
- }
- }
-
- totalTime += time;
-
- float ratio = (float) totalTime / (float) animationLengthMS;
-
- if(ratio < 1) {
-
- if(ratio > 0) {
- // we still have time left
- float newScale = (ratio * scaleDiff) + startScale;
- float newX = (ratio * xDiff) + startX;
- float newY = (ratio * yDiff) + startY;
-
- if(zoomAnimationListener != null) {
- zoomAnimationListener.onZoom(newScale, newX, newY);
- }
- }
-
- return true;
- }
- else {
-
- float newScale = scaleDiff + startScale;
- float newX = xDiff + startX;
- float newY = yDiff + startY;
-
- if(zoomAnimationListener != null) {
- zoomAnimationListener.onZoom(newScale, newX, newY);
- zoomAnimationListener.onComplete();
- }
-
- return false;
- }
- }
-
- public void reset() {
- firstFrame = true;
- totalTime = 0;
- }
-
- public float getZoom() {
- return zoom;
- }
-
- public void setZoom(float zoom) {
- this.zoom = zoom;
- }
-
- public float getTouchX() {
- return touchX;
- }
-
- public void setTouchX(float touchX) {
- this.touchX = touchX;
- }
-
- public float getTouchY() {
- return touchY;
- }
-
- public void setTouchY(float touchY) {
- this.touchY = touchY;
- }
-
- public long getAnimationLengthMS() {
- return animationLengthMS;
- }
-
- public void setAnimationLengthMS(long animationLengthMS) {
- this.animationLengthMS = animationLengthMS;
- }
-
- public ZoomAnimationListener getZoomAnimationListener() {
- return zoomAnimationListener;
- }
-
- public void setZoomAnimationListener(ZoomAnimationListener zoomAnimationListener) {
- this.zoomAnimationListener = zoomAnimationListener;
- }
-}
diff --git a/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimationListener.java b/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimationListener.java
deleted file mode 100644
index 21b6ec9a6fb0..000000000000
--- a/android/experimental/DocumentLoader/src/com/polites/android/ZoomAnimationListener.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2012 Jason Polites
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.polites.android;
-
-public interface ZoomAnimationListener {
- public void onZoom(float scale, float x, float y);
- public void onComplete();
-}
diff --git a/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java b/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
deleted file mode 100644
index a7a2214e792f..000000000000
--- a/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
+++ /dev/null
@@ -1,1140 +0,0 @@
-// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-//
-// This file is part of the LibreOffice project.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// This is just a testbed for ideas and implementations. (Still, it might turn
-// out to be somewhat useful as such while waiting for "real" apps.)
-
-// Important points:
-
-// Everything that might take a long time should be done asynchronously:
-// - loading the document (loadComponentFromURL())
-// - counting number of pages (getRendererCount())
-// - rendering a page (render())
-
-// Unclear whether pages can be rendered in parallel. Probably best to
-// serialize all the above in the same worker thread. We use
-// AsyncTask.SERIAL_EXECUTOR below.
-
-// While a page is loading ideally should display some animated spinner (but
-// for now just a static "please wait" text).
-
-// ===
-
-// How should we handle re-rendering at higher resolution when zooming in, and
-// then panning around?
-
-// Hopefully when LO is asked to render just a part of a page (i.e. the
-// MapMode of the device rendered to causes significant parts of the page to
-// be outside the device) the code is clever enough to quickly skip stuff that
-// will be clipped. But I don't hold my breath.
-
-// How could we do it?
-
-// 1/ Re-render just the zoomed-in area. Probably not a good idea, as probably
-// the user will almost immediately also pan a bit or zoom out a bit, which
-// would cause a re-render.
-
-// 2/ Some kind of tiled approach. Initially just one tile for the whole
-// page. When zooming in, at some point (2x?) split the currently visible
-// tiles into four sub-tiles, each initially displaying the same resolution as
-// the parent tile. Start asynchronous rendering of visible sub-tiles at
-// double resolution. Keep the "parent" rendered bitmap but don't keep bitmaps
-// that go out of view. (Except perhaps for some caching.) When zooming out,
-// at some point (0.5x?) merge four sub-tiles back into one. Hmm. Is this the
-// right approach?
-
-// In any case, also this rendering at higher resolution should be done
-// asynchronously, of course. If the user zooms in and pans around, the
-// existing bitmap will be shown scaled (and ugly) until required rendering
-// has finished and then the affected tiles are replaced with
-// higher-resolution ones.
-
-package org.libreoffice.android.examples;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.PixelFormat;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.TranslateAnimation;
-import android.widget.ImageView;
-import android.widget.NumberPicker;
-import android.widget.TextView;
-import android.widget.ViewFlipper;
-import android.widget.ViewSwitcher;
-
-import junit.framework.Assert;
-
-import com.polites.android.GestureImageView;
-
-import com.sun.star.awt.Size;
-import com.sun.star.awt.XBitmap;
-import com.sun.star.awt.XControl;
-import com.sun.star.awt.XDevice;
-import com.sun.star.awt.XToolkitExperimental;
-import com.sun.star.beans.PropertyValue;
-import com.sun.star.frame.XComponentLoader;
-import com.sun.star.frame.XController;
-import com.sun.star.frame.XFrame;
-import com.sun.star.frame.XModel;
-import com.sun.star.lang.XEventListener;
-import com.sun.star.lang.XMultiComponentFactory;
-import com.sun.star.lang.XTypeProvider;
-import com.sun.star.uno.Type;
-import com.sun.star.uno.UnoRuntime;
-import com.sun.star.uno.XComponentContext;
-import com.sun.star.view.XRenderable;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-
-import org.libreoffice.android.Bootstrap;
-
-public class DocumentLoader
- extends Activity
-{
- private static final String TAG = "DocumentLoader";
-
- // Size of a small virtual (bitmap) device used to find out page count and
- // page sizes
- private static final int SMALLSIZE = 128;
-
- // We pre-render this many pages preceding and succeeding the currently
- // viewed one, i.e. the total number of rendered pages kept is
- // PAGECACHE_PLUSMINUS*2+1.
- private static final int PAGECACHE_PLUSMINUS = 2;
- private static final int PAGECACHE_SIZE = PAGECACHE_PLUSMINUS*2 + 1;
-
- BootstrapContext bootstrapContext;
- DocumentContext documentContext;
-
- GestureDetector.OnGestureListener gestureListener;
- GestureDetector gestureDetector;
-
- ViewGroup.LayoutParams matchParent;
-
- ViewFlipper flipper;
-
- Bundle extras;
-
- PageViewer getPageViewerAt(int index)
- {
- return (PageViewer)flipper.getChildAt(index);
- }
-
- PageViewer getCurrentPageViewer()
- {
- return (PageViewer)flipper.getCurrentView();
- }
-
- class GestureListener
- extends GestureDetector.SimpleOnGestureListener
- {
- @Override
- public boolean onFling(MotionEvent event1,
- MotionEvent event2,
- float velocityX,
- float velocityY)
- {
- Log.i(TAG, "onFling: " + event1 + " " + event2);
- if (event1.getX() - event2.getX() > 120) {
- if (getCurrentPageViewer().currentPageNumber == documentContext.pageCount-1)
- return false;
-
- Animation inFromRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
- int duration = Math.abs((int)((float)flipper.getWidth()/velocityX*1000f));
- inFromRight.setDuration(duration);
- flipper.setInAnimation(inFromRight);
-
- Animation outToLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1,
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
- outToLeft.setDuration(duration);
- flipper.setOutAnimation(outToLeft);
-
- flipper.showNext();
-
- // The entry after the next, both child index and next is 0..PAGECACHE_SIZE.
- int next = (flipper.getDisplayedChild() + PAGECACHE_PLUSMINUS) % PAGECACHE_SIZE;
- getPageViewerAt(next).display(getCurrentPageViewer().currentPageNumber + PAGECACHE_PLUSMINUS);
- return true;
- } else if (event2.getX() - event1.getX() > 120) {
- if (getCurrentPageViewer().currentPageNumber == 0)
- return false;
-
- Animation inFromLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
- int duration = Math.abs((int)((float)flipper.getWidth()/velocityX*1000f));
- inFromLeft.setDuration(duration);
- flipper.setInAnimation(inFromLeft);
-
- Animation outToRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
- outToRight.setDuration(duration);
- flipper.setOutAnimation(outToRight);
-
- flipper.showPrevious();
-
- // The entry before the previous, both child index and previous is 0..PAGECACHE_SIZE.
- int previous = (flipper.getDisplayedChild() + PAGECACHE_SIZE - PAGECACHE_PLUSMINUS) % PAGECACHE_SIZE;
- getPageViewerAt(previous).display(getCurrentPageViewer().currentPageNumber - PAGECACHE_PLUSMINUS);
-
- return true;
- }
- return false;
- }
- }
-
- class MyXController
- implements XController
- {
-
- XFrame frame;
- XModel model;
-
- public void attachFrame(XFrame frame)
- {
- Log.i(TAG, "attachFrame");
- this.frame = frame;
- }
-
- public boolean attachModel(XModel model)
- {
- Log.i(TAG, "attachModel");
- this.model = model;
- return true;
- }
-
- public boolean suspend(boolean doSuspend)
- {
- Log.i(TAG, "suspend");
- return false;
- }
-
- public Object getViewData()
- {
- Log.i(TAG, "getViewData");
- return null;
- }
-
- public void restoreViewData(Object data)
- {
- Log.i(TAG, "restoreViewData");
- }
-
- public XModel getModel()
- {
- Log.i(TAG, "getModel");
- return model;
- }
-
- public XFrame getFrame()
- {
- Log.i(TAG, "getFrame");
- return frame;
- }
-
- public void dispose()
- {
- Log.i(TAG, "dispose");
- }
-
- public void addEventListener(XEventListener listener)
- {
- Log.i(TAG, "addEventListener");
- }
-
- public void removeEventListener(XEventListener listener)
- {
- Log.i(TAG, "removeEventListener");
- }
- }
-
- static int zoomLevel(float scale)
- {
- if (scale <= 1)
- return 0;
-
- int result = 1;
- int power = 2;
-
- while (scale > power) {
- result++;
- power *= 2;
- }
- return result;
- }
-
- static int scaleOfZoom(int zoom)
- {
- int result = 1;
-
- while (zoom > 0) {
- result *= 2;
- zoom--;
- }
-
- return result;
- }
-
- static int setColorAlpha(int color,
- double alpha)
- {
- return Color.argb((int)(alpha*255), Color.red(color), Color.green(color), Color.blue(color));
- }
-
- // Each (Gesture)ImageView is showing an object of this subclass of
- // BitmapDrawable, the root of a quadtree of higher-resolution partial
- // page bitmaps. Obviously these should be rendered asynchronously on
- // demand but that code is not here yet. And anyway, rendering partial
- // pages won't work until I have figured out why offsetting VirtualDevice
- // has no effect.
- class QuadTree
- extends BitmapDrawable
- {
- final int pageNumber;
- final int level;
- final int location;
- final int w, h;
-
- static final int NW = 0;
- static final int NE = 1;
- static final int SE = 2;
- static final int SW = 3;
-
- QuadTree sub[] = new QuadTree[4];
-
- QuadTree(Bitmap bm,
- int level,
- int pageNumber,
- int location)
- {
- super(bm);
-
- w = getIntrinsicWidth();
- h = getIntrinsicHeight();
-
- this.pageNumber = pageNumber;
- this.level = level;
- this.location = location;
-
- // I spent several days wondering why nothing showed up for the
- // sub-tiles, desperately tweaking stuff left and right, until I
- // found out I need to call setBounds()... (For the level 0
- // drawable the GestureImageView handles calling setBounds(), but
- // it doesn't hurt to do it here for all levels.)
- setBounds(0, 0, w, h);
-
- // Just for testing until properly doing this asynchronously and
- // with insert()
- if (level == 0) {
- // Don't do it anyway for now
-
- // 1) offsetting of VirtualDevice doesn't seem to work so this
- // would work for the NW sub-tile only anyway.
-
- // 2) LO renders Windows-style "Y grows upwards" bitmaps, thus
- // the imageView.setScaleY(-1) below in
- // PageLoadTask.onPostExecute(), but that means that the
- // scaling and translation stuff here in QuadTree needs to be
- // twiddled for Y coordinates. (Just try: comment out the
- // createSub(NW) call below. If you also comment out the
- // setScaleY() call, the sub-tile will show up in the correct
- // location, otherwise not. Or something like that. It's hard
- // to try to write up sevral nights of desperate hacking back
- // and forth... which in the end turned out to be just chasing
- // the wrong ducks. If that is how the metaphor goes?)
-
- // So probably should write a native method to reflect the
- // rendered byte buffer in the Y direction, and call that
- // after rendering, instead? Or maybe the tweaks needed aren't
- // that large anyway, and I just am mixing up my memory of the
- // trouble caused by that with the trouble caused by not
- // calling setBounds()...
-
- //createSub(NW);
- //createSub(NE);
- //createSub(SE);
- //createSub(SW);
- }
- }
-
- QuadTree(QuadTree rhs,
- Bitmap bm)
- {
- this(bm, rhs.level, rhs.pageNumber, rhs.location);
-
- sub = rhs.sub;
- }
-
- QuadTree(Bitmap bm,
- int pageNumber)
- {
- this(bm, 0, pageNumber, 0);
- }
-
- QuadTree(int level,
- int pageNumber,
- int location)
- {
- this.level = level;
- this.pageNumber = pageNumber;
- this.location = location;
- w = -1;
- h = -1;
- }
-
- void createSub(int q)
- {
- if (true) {
- ByteBuffer bb = renderPage(pageNumber, level+1, (location<<2)+q);
- Bitmap subbm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- subbm.copyPixelsFromBuffer(bb);
- sub[q] = new QuadTree(subbm, level+1, pageNumber, (location<<2)+q);
- } else {
- // Test... just use transparent single colour subtiles
- Bitmap subbm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- int color = 0;
- switch (q) {
- case NW: color = Color.RED; break;
- case NE: color = Color.GREEN; break;
- case SE: color = Color.BLUE; break;
- case SW: color = Color.YELLOW; break;
- }
- subbm.eraseColor(setColorAlpha(color, 0.5));
- sub[q] = new QuadTree(subbm, 1, pageNumber, (location<<2)+q);
- }
- }
-
- int quadrantOf(int x,
- int y)
- {
- if (x < 0 || y < 0 || x >= w || y >= h)
- return -1;
-
- if (x < w/2 && y < h/2)
- return NW;
- if (x >= w/2 && y < h/2)
- return NE;
- if (x >= w/2 && y >= h/2)
- return SE;
- if (x < w/2 && y >= h/2)
- return SW;
-
- return -1;
- }
-
- int quadrantOf(Point p)
- {
- return quadrantOf(p.x, p.y);
- }
-
- Point subCoord(Point p)
- {
- return subCoord(quadrantOf(p), p);
- }
-
- Point subCoord(int q,
- Point p)
- {
- switch (q) {
- case NW:
- return new Point(p.x*2, p.y*2);
- case NE:
- return new Point((p.x-w/2)*2, p.y*2);
- case SE:
- return new Point((p.x-w/2)*2, (p.y-h/2)*2);
- case SW:
- return new Point(p.x*2, (p.y-h/2)*2);
- }
- return null;
- }
-
- // The insert() stuff has not been tested and is just a draft
- void insert(Bitmap bm,
- int level,
- int x,
- int y)
- {
- insert(bm, level, 1, new Point(x, y));
- }
-
- void insert(Bitmap bm,
- int level,
- int recursionDepth,
- Point p)
- {
- int q = quadrantOf(p);
-
- if (q == -1)
- return;
-
- if (recursionDepth == level) {
- if (sub[q] == null)
- sub[q] = new QuadTree(bm, level);
- else
- sub[q] = new QuadTree(sub[q], bm);
- } else {
- if (sub[q] == null)
- sub[q] = new QuadTree(this.level+1, pageNumber, location);
- sub[q].insert(bm, level, recursionDepth+1, subCoord(q, p));
- }
- }
-
- // Ditto for find()
-
- QuadTree find(int levelCountdown,
- int x,
- int y)
- {
- return find(levelCountdown, new Point(x, y));
- }
-
- QuadTree find(int levelCountdown,
- Point p)
- {
- final int x = p.x, y = p.y;
-
- Log.i(TAG, "find(" + levelCountdown + ", (" + p.x + ", " + p.y + "))");
-
- if (x < 0 || y < 0 || x >= w || y >= h)
- return null;
-
- if (levelCountdown == 0) {
- Log.i(TAG, "Returning this at level " + this.level);
- return this;
- }
-
- int q = quadrantOf(p);
-
- if (sub[q] != null)
- return sub[q].find(levelCountdown-1, subCoord(q, p));
-
- return null;
- }
-
- void subDraw(Canvas canvas,
- int q)
- {
- if (q == -1 || sub[q] == null)
- return;
-
- Log.i(TAG, "subDraw 1: q=" + q + ", matrix=" + canvas.getMatrix() + ", clip=" + canvas.getClipBounds());
-
- canvas.save();
- canvas.scale(0.5f, 0.5f);
-
- float[] values = new float[9];
- canvas.getMatrix().getValues(values);
-
- Log.i(TAG, "subDraw 2: q=" + q + ", matrix=" + canvas.getMatrix() + ", clip=" + canvas.getClipBounds() + ", translate(" +
- (((q == NW || q == SW) ? -w : w) /* * values[Matrix.MSCALE_X]*/) + "," +
- (((q == NW || q == NE) ? -h : h) /* * values[Matrix.MSCALE_X]*/) + ")");
-
- canvas.translate(((q == NW || q == SW) ? -w : 0) /* * values[Matrix.MSCALE_X]*/,
- ((q == NW || q == NE) ? -h : 0) /* * values[Matrix.MSCALE_X]*/);
-
- Log.i(TAG, "subDraw 3: q=" + q + ", matrix=" + canvas.getMatrix() + ", clip=" + canvas.getClipBounds());
-
- sub[q].draw(canvas);
-
- canvas.restore();
- }
-
- @Override
- public void draw(Canvas canvas)
- {
- float[] values = new float[9];
- canvas.getMatrix().getValues(values);
-
- float scale = values[Matrix.MSCALE_X];
- int zoom = zoomLevel(scale);
-
- Log.i(TAG, "draw: level=" + level + ", scale=" + scale + ", zoom=" + zoom + ", matrix=" + canvas.getMatrix());
- Rect bounds = new Rect();
- if (canvas.getClipBounds(bounds))
- Log.i(TAG, " clip=" + bounds + ", bounds=" + getBounds());
- else
- Log.i(TAG, " no clip");
-
- int l = (int)(w/2 - values[Matrix.MTRANS_X]/scale);
- int t = (int)(h/2 - values[Matrix.MTRANS_Y]/scale);
- Log.i(TAG, "Unzoomed rect: " + l + ", " + t + ", " + (int)(l+w/scale) + ", " + (int)(t+h/scale));
-
- Log.i(TAG, "Scales: " + values[Matrix.MSCALE_X] + ", " + values[Matrix.MSCALE_Y]);
-
- // Assert.assertTrue(values[Matrix.MSCALE_X] == values[Matrix.MSCALE_Y]);
-
- super.draw(canvas);
-
- if (/*zoom > 0 */ scale >= 1) {
- subDraw(canvas, quadrantOf(l, t));
- subDraw(canvas, quadrantOf((int)(l+w/scale)-1, t));
- subDraw(canvas, quadrantOf((int)(l+w/scale)-1, (int)(t+h/scale)-1));
- subDraw(canvas, quadrantOf(l, (int)(t+h/scale)-1));
- }
- }
- }
-
- ByteBuffer renderPage(int number)
- {
- return renderPage(number, 0, 0);
- }
-
- ByteBuffer renderPage(final int number,
- final int level,
- final int location)
- {
- Log.i(TAG, "renderPage(" + number + ", " + level + ", " + location + ")");
- try {
- // Use dummySmallDevice with no scale or offset just to find out
- // the paper size of this page.
-
- PropertyValue renderProps[] = new PropertyValue[3];
- renderProps[0] = new PropertyValue();
- renderProps[0].Name = "IsPrinter";
- renderProps[0].Value = Boolean.TRUE;
- renderProps[1] = new PropertyValue();
- renderProps[1].Name = "RenderDevice";
- renderProps[1].Value = bootstrapContext.dummySmallDevice;
- renderProps[2] = new PropertyValue();
- renderProps[2].Name = "View";
- renderProps[2].Value = new MyXController();
-
- // getRenderer returns a set of properties that include the PageSize
- long t0 = System.currentTimeMillis();
- PropertyValue rendererProps[] = documentContext.renderable.getRenderer(number, documentContext.doc, renderProps);
- long t1 = System.currentTimeMillis();
- Log.i(TAG, "getRenderer took " + ((t1-t0)-bootstrapContext.timingOverhead) + " ms");
-
- int pageWidth = 0, pageHeight = 0;
- for (int i = 0; i < rendererProps.length; i++) {
- if (rendererProps[i].Name.equals("PageSize")) {
- pageWidth = ((Size) rendererProps[i].Value).Width;
- pageHeight = ((Size) rendererProps[i].Value).Height;
- Log.i(TAG, "PageSize: " + pageWidth + "x" + pageHeight);
- }
- }
-
- // Create a new device with the correct scale and offset
- ByteBuffer bb = ByteBuffer.allocateDirect(flipper.getWidth()*flipper.getHeight()*4);
- long wrapped_bb = Bootstrap.new_byte_buffer_wrapper(bb);
-
- XDevice device;
- if (pageWidth == 0) {
- // Huh?
- device = bootstrapContext.toolkit.createScreenCompatibleDeviceUsingBuffer(flipper.getWidth(), flipper.getHeight(), 1, 1, 0, 0, wrapped_bb);
- } else {
-
- // Scale so that it fits our device which has a resolution of
- // 96/inch (see SvpSalGraphics::GetResolution()). The page
- // size returned from getRenderer() is in 1/mm * 100. 2540 is
- // one inch in mm/100.
-
- int scaleNumerator, scaleDenominator;
-
- // If the view has a wider aspect ratio than the page, fit
- // height; otherwise, fit width
- if ((double) flipper.getWidth() / flipper.getHeight() > (double) pageWidth / pageHeight) {
- scaleNumerator = flipper.getHeight();
- scaleDenominator = pageHeight / 2540 * 96;
- } else {
- scaleNumerator = flipper.getWidth();
- scaleDenominator = pageWidth / 2540 * 96;
- }
- scaleNumerator *= scaleOfZoom(level);
-
- int xOffset = 0, yOffset = 0;
- int hiX = pageWidth, hiY = pageHeight;
- int lvl = level;
- int loc = location;
- while (lvl > 0) {
- int q = (loc & 0x03);
-
- if (q == QuadTree.NE || q == QuadTree.SE) {
- xOffset += (hiX - xOffset)/2;
- } else {
- hiX -= (hiX - xOffset)/2;
- }
- if (q == QuadTree.SW || q == QuadTree.SE) {
- yOffset += (hiY - yOffset)/2;
- } else {
- hiY -= (hiY - yOffset)/2;
- }
- lvl--;
- loc >>= 2;
- }
-
- // Seems that the offsets passed in (which get passed to
- // MapMode::SetOrigin() in
- // VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer()
- // are ignored... try a random value, no effect ;(
- xOffset = 12345; xOffset = 789;
-
- Log.i(TAG, "Rendering page " + number + " level=" + level + " scale=" + scaleNumerator + "/" + scaleDenominator + ", offset=(" + xOffset + ", " + yOffset + ")");
-
- device = bootstrapContext.toolkit.createScreenCompatibleDeviceUsingBuffer(flipper.getWidth(), flipper.getHeight(),
- scaleNumerator, scaleDenominator,
- -xOffset, -yOffset,
- wrapped_bb);
- }
-
- // Update the property that points to the device
- renderProps[1].Value = device;
-
- t0 = System.currentTimeMillis();
- documentContext.renderable.render(number, documentContext.doc, renderProps);
- t1 = System.currentTimeMillis();
- Log.i(TAG, "Rendering page " + number + " took " + ((t1-t0)-bootstrapContext.timingOverhead) + " ms");
-
- Bootstrap.force_full_alpha_bb(bb, 0, flipper.getWidth() * flipper.getHeight() * 4);
-
- return bb;
- }
- catch (Exception e) {
- e.printStackTrace(System.err);
- finish();
- }
-
- return null;
- }
-
- enum PageState { NONEXISTENT, LOADING, READY };
-
- class PageViewer
- extends ViewSwitcher
- {
- int currentPageNumber = -1;
- TextView waitView;
- PageState state = PageState.NONEXISTENT;
- Bitmap bm;
-
- class PageLoadTask
- extends AsyncTask<Integer, Void, Integer>
- {
- protected Integer doInBackground(Integer... params)
- {
- int number = params[0];
-
- Log.i(TAG, "doInBackground(" + number + ")");
-
- if (number >= documentContext.pageCount)
- return -1;
-
- state = PageState.LOADING;
- currentPageNumber = number;
- ByteBuffer bb = renderPage(currentPageNumber);
- bm = Bitmap.createBitmap(flipper.getWidth(), flipper.getHeight(), Bitmap.Config.ARGB_8888);
- bm.copyPixelsFromBuffer(bb);
-
- return currentPageNumber;
- }
-
- protected void onPostExecute(Integer result)
- {
- Log.i(TAG, "onPostExecute: " + result);
- if (result == -1)
- return;
-
- GestureImageView imageView = new GestureImageView(DocumentLoader.this, gestureListener);
- imageView.setImageDrawable(new QuadTree(bm, result));
-
- imageView.setScaleY(-1);
-
- if (getChildCount() == 2)
- removeViewAt(1);
- addView(imageView, 1, matchParent);
- showNext();
- state = PageState.READY;
- }
- }
-
- void display(int number)
- {
- Log.i(TAG, "PageViewer display(" + number + ")");
- if (number >= 0)
- waitView.setText("Page " + (number+1) + ", wait...");
- state = PageState.NONEXISTENT;
-
- if (getDisplayedChild() == 1) {
- showPrevious();
- removeViewAt(1);
- }
-
- if (number >= 0) {
- new PageLoadTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, number);
- }
- }
-
- PageViewer(int number)
- {
- super(DocumentLoader.this);
-
- waitView = new TextView(DocumentLoader.this);
- waitView.setTextSize(24);
- waitView.setGravity(Gravity.CENTER);
- waitView.setBackgroundColor(Color.WHITE);
- waitView.setTextColor(Color.BLACK);
- addView(waitView, 0, matchParent);
-
- display(number);
- }
- }
-
- class DocumentLoadTask
- extends AsyncTask<String, Void, Void>
- {
- protected Void doInBackground(String... params)
- {
- try {
- String url = params[0];
- Log.i(TAG, "Attempting to load " + url);
-
- PropertyValue loadProps[] = new PropertyValue[3];
- loadProps[0] = new PropertyValue();
- loadProps[0].Name = "Hidden";
- loadProps[0].Value = Boolean.TRUE;
- loadProps[1] = new PropertyValue();
- loadProps[1].Name = "ReadOnly";
- loadProps[1].Value = Boolean.TRUE;
- loadProps[2] = new PropertyValue();
- loadProps[2].Name = "Preview";
- loadProps[2].Value = Boolean.TRUE;
-
- long t0 = System.currentTimeMillis();
- documentContext.doc = bootstrapContext.componentLoader.loadComponentFromURL(url, "_blank", 0, loadProps);
- long t1 = System.currentTimeMillis();
- Log.i(TAG, "Loading took " + ((t1-t0)-bootstrapContext.timingOverhead) + " ms");
-
- documentContext.renderable = (XRenderable) UnoRuntime.queryInterface(XRenderable.class, documentContext.doc);
-
- PropertyValue renderProps[] = new PropertyValue[3];
- renderProps[0] = new PropertyValue();
- renderProps[0].Name = "IsPrinter";
- renderProps[0].Value = Boolean.TRUE;
- renderProps[1] = new PropertyValue();
- renderProps[1].Name = "RenderDevice";
- renderProps[1].Value = bootstrapContext.dummySmallDevice;
- renderProps[2] = new PropertyValue();
- renderProps[2].Name = "View";
- renderProps[2].Value = new MyXController();
-
- t0 = System.currentTimeMillis();
- documentContext.pageCount = documentContext.renderable.getRendererCount(documentContext.doc, renderProps);
- t1 = System.currentTimeMillis();
- Log.i(TAG, "getRendererCount: " + documentContext.pageCount + ", took " + ((t1-t0)-bootstrapContext.timingOverhead) + " ms");
- }
- catch (Exception e) {
- e.printStackTrace(System.err);
- finish();
- }
- return null;
- }
- }
-
- /**
- * This class contains the state that is initialized once and never changes
- * (not specific to a document or a view).
- */
- class BootstrapContext
- {
- public long timingOverhead;
- public XComponentContext componentContext;
- public XMultiComponentFactory mcf;
- public XComponentLoader componentLoader;
- public XToolkitExperimental toolkit;
- public XDevice dummySmallDevice;
- }
-
- /**
- * This class contains the state that is specific to a document, but
- * independent from a view.
- */
- class DocumentContext
- {
- public Object doc;
- public int pageCount;
- public XRenderable renderable;
- public String input;
- // This is not updated constantly, just in onRetainNonConfigurationInstance()
- public int currentPageNumber;
- }
-
- static void dumpUNOObject(String objectName, Object object)
- {
- Log.i(TAG, objectName + " is " + (object != null ? object.toString() : "null"));
-
- if (object == null)
- return;
-
- XTypeProvider typeProvider = (XTypeProvider)
- UnoRuntime.queryInterface(XTypeProvider.class, object);
- if (typeProvider == null)
- return;
-
- Type[] types = typeProvider.getTypes();
- if (types == null)
- return;
-
- for (Type t : types)
- Log.i(TAG, " " + t.getTypeName());
- }
-
- static void dumpBytes(String name, byte[] bytes, int offset)
- {
- if (bytes == null) {
- Log.i(TAG, name + " is null");
- return;
- }
- Log.i(TAG, name + ":");
-
- if (offset != 0)
- Log.i(TAG, " (offset " + offset + ")");
-
- for (int i = offset; i < Math.min(bytes.length, offset+160); i += 16) {
- String s = "";
- for (int j = i; j < Math.min(bytes.length, i+16); j++)
- s = s + String.format(" %02x", bytes[j]);
-
- Log.i(TAG, s);
- }
- }
-
- static void dumpBytes(String name, ByteBuffer bytes, int offset)
- {
- if (bytes == null) {
- Log.i(TAG, name + " is null");
- return;
- }
- Log.i(TAG, name + ":");
-
- if (offset != 0)
- Log.i(TAG, " (offset " + offset + ")");
-
- for (int i = offset; i < Math.min(bytes.limit(), offset+160); i += 16) {
- String s = "";
- for (int j = i; j < Math.min(bytes.limit(), i+16); j++)
- s = s + String.format(" %02x", bytes.get(j));
-
- Log.i(TAG, s);
- }
- }
-
- @Override
- public Object onRetainNonConfigurationInstance() {
- ArrayList ret = new ArrayList(2);
- ret.add(bootstrapContext);
- documentContext.currentPageNumber = getCurrentPageViewer().currentPageNumber;
- ret.add(documentContext);
- return ret;
- }
-
- private void initBootstrapContext()
- {
- try
- {
- bootstrapContext = new BootstrapContext();
-
- long t0 = System.currentTimeMillis();
- long t1 = System.currentTimeMillis();
- bootstrapContext.timingOverhead = t1 - t0;
-
- Bootstrap.setup(this);
-
- // Avoid all the old style OSL_TRACE calls especially in vcl
- Bootstrap.putenv("SAL_LOG=+WARN+INFO");
-
- // Log.i(TAG, "Sleeping NOW");
- // Thread.sleep(20000);
-
- bootstrapContext.componentContext = com.sun.star.comp.helper.Bootstrap.defaultBootstrap_InitialComponentContext();
-
- Log.i(TAG, "context is" + (bootstrapContext.componentContext!=null ? " not" : "") + " null");
-
- bootstrapContext.mcf = bootstrapContext.componentContext.getServiceManager();
-
- Log.i(TAG, "mcf is" + (bootstrapContext.mcf!=null ? " not" : "") + " null");
-
- Bootstrap.initVCL();
-
- Object desktop = bootstrapContext.mcf.createInstanceWithContext
- ("com.sun.star.frame.Desktop", bootstrapContext.componentContext);
-
- Log.i(TAG, "desktop is" + (desktop!=null ? " not" : "") + " null");
-
- bootstrapContext.componentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktop);
-
- Log.i(TAG, "componentLoader is" + (bootstrapContext.componentLoader!=null ? " not" : "") + " null");
-
- Object toolkitService = bootstrapContext.mcf.createInstanceWithContext
- ("com.sun.star.awt.Toolkit", bootstrapContext.componentContext);
- bootstrapContext.toolkit = (XToolkitExperimental) UnoRuntime.queryInterface(XToolkitExperimental.class, toolkitService);
-
- // Set up dummySmallDevice and use it to find out the number
- // of pages ("renderers").
- ByteBuffer smallbb = ByteBuffer.allocateDirect(SMALLSIZE*SMALLSIZE*4);
- long wrapped_smallbb = Bootstrap.new_byte_buffer_wrapper(smallbb);
- bootstrapContext.dummySmallDevice = bootstrapContext.toolkit.createScreenCompatibleDeviceUsingBuffer(SMALLSIZE, SMALLSIZE, 1, 1, 0, 0, wrapped_smallbb);
-
- }
- catch (Exception e)
- {
- e.printStackTrace(System.err);
- finish();
- }
- }
-
- private void initDocumentContext(String input)
- {
- documentContext = new DocumentContext();
- documentContext.input = input;
- // Load the wanted document
- new DocumentLoadTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, "file://" + input);
- }
-
- private void goToPage(int number)
- {
- // Remove old views.
- flipper.removeAllViews();
-
- // Add new ones.
- flipper.addView(new PageViewer(number), 0, matchParent);
- for (int i = 0; i < PAGECACHE_PLUSMINUS; i++)
- flipper.addView(new PageViewer(number + i + 1), i + 1, matchParent);
- for (int i = 0; i < PAGECACHE_PLUSMINUS; i++)
- flipper.addView(new PageViewer(number + (i * -1) - 1), PAGECACHE_PLUSMINUS + i + 1, matchParent);
- }
-
- private void askPageNumber()
- {
- AlertDialog.Builder alert = new AlertDialog.Builder(this);
- alert.setTitle(R.string.go_to_page);
- final NumberPicker input = new NumberPicker(this);
- input.setMinValue(1);
- input.setMaxValue(documentContext.pageCount);
- alert.setView(input);
- alert.setPositiveButton("OK", new DialogInterface.OnClickListener()
- {
- public void onClick(DialogInterface dialog, int whichButton)
- {
- goToPage(input.getValue() - 1);
- }
- });
-
- alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
- {
- public void onClick(DialogInterface dialog, int whichButton)
- {
- }
- });
- alert.show();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
-
- ArrayList contexts = (ArrayList)getLastNonConfigurationInstance();
- if (contexts != null)
- {
- bootstrapContext = (BootstrapContext)contexts.get(0);
- documentContext = (DocumentContext)contexts.get(1);
- }
-
- extras = getIntent().getExtras();
-
- gestureListener = new GestureListener();
- gestureDetector = new GestureDetector(this, gestureListener);
-
- try {
- String input = getIntent().getStringExtra("input");
- if (input == null)
- input = "/assets/test1.odt";
-
- // We need to fake up an argv, and the argv[0] even needs to
- // point to some file name that we can pretend is the "program".
- // setCommandArgs() will prefix argv[0] with the app's data
- // directory.
-
- String[] argv = { "lo-document-loader", input };
-
- Bootstrap.setCommandArgs(argv);
-
- if (bootstrapContext == null)
- initBootstrapContext();
-
- if (documentContext == null || !documentContext.input.equals(input))
- initDocumentContext(input);
-
- flipper = new ViewFlipper(this);
-
- matchParent = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-
- goToPage(documentContext.currentPageNumber);
-
- setContentView(flipper);
- }
- catch (Exception e) {
- e.printStackTrace(System.err);
- finish();
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event)
- {
- return gestureDetector.onTouchEvent(event);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.option, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
- // Handle item selection
- switch (item.getItemId()) {
- case R.id.go_to_page:
- askPageNumber();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-}
-
-// vim:set shiftwidth=4 softtabstop=4 expandtab: