summaryrefslogtreecommitdiff
path: root/android
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 /android
parentdae9a386bacc08a55eda96e1e8925883a4fa494d (diff)
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.
Diffstat (limited to 'android')
-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
22 files changed, 0 insertions, 3437 deletions
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: