summaryrefslogtreecommitdiffstats
path: root/tests/sketch/src/com/android
diff options
context:
space:
mode:
authorRomain Guy <romainguy@android.com>2009-05-21 16:23:21 -0700
committerRomain Guy <romainguy@android.com>2009-05-21 18:12:56 -0700
commitdb567c390bd56c05614eaa83c02dbb99f97ad9cc (patch)
tree86399406ca7a53c3d902b3863bf7a944cb7c5c3f /tests/sketch/src/com/android
parent384bfa270cdcb5dc3bc9ec396b783e25eb2d9b4d (diff)
downloadframeworks_base-db567c390bd56c05614eaa83c02dbb99f97ad9cc.zip
frameworks_base-db567c390bd56c05614eaa83c02dbb99f97ad9cc.tar.gz
frameworks_base-db567c390bd56c05614eaa83c02dbb99f97ad9cc.tar.bz2
Move the Gestures API to the framework in android.gesture.
Diffstat (limited to 'tests/sketch/src/com/android')
-rwxr-xr-xtests/sketch/src/com/android/gesture/Gesture.java320
-rw-r--r--tests/sketch/src/com/android/gesture/GestureActionListener.java21
-rw-r--r--tests/sketch/src/com/android/gesture/GestureConstants.java29
-rw-r--r--tests/sketch/src/com/android/gesture/GestureLibrary.java346
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureListener.java30
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureOverlay.java390
-rw-r--r--tests/sketch/src/com/android/gesture/GesturePoint.java46
-rw-r--r--tests/sketch/src/com/android/gesture/GestureStroke.java233
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureUtilities.java444
-rwxr-xr-xtests/sketch/src/com/android/gesture/Instance.java115
-rw-r--r--tests/sketch/src/com/android/gesture/InstanceLearner.java105
-rwxr-xr-xtests/sketch/src/com/android/gesture/Learner.java83
-rw-r--r--tests/sketch/src/com/android/gesture/LetterRecognizer.java228
-rw-r--r--tests/sketch/src/com/android/gesture/OrientedBoundingBox.java80
-rwxr-xr-xtests/sketch/src/com/android/gesture/Prediction.java33
-rw-r--r--tests/sketch/src/com/android/gesture/TouchThroughGesturing.java165
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java27
-rw-r--r--tests/sketch/src/com/android/gesture/example/GestureEntry.java21
-rwxr-xr-xtests/sketch/src/com/android/gesture/example/GestureLibViewer.java10
19 files changed, 28 insertions, 2698 deletions
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/tests/sketch/src/com/android/gesture/Gesture.java
deleted file mode 100755
index d5dcc65..0000000
--- a/tests/sketch/src/com/android/gesture/Gesture.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.RectF;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.DataInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-
-import static com.android.gesture.GestureConstants.LOG_TAG;
-
-/**
- * A gesture can have a single or multiple strokes
- */
-
-public class Gesture implements Parcelable {
- private static final long GESTURE_ID_BASE = System.currentTimeMillis();
-
- private static final int BITMAP_RENDERING_WIDTH = 2;
-
- private static final boolean BITMAP_RENDERING_ANTIALIAS = true;
- private static final boolean BITMAP_RENDERING_DITHER = true;
-
- private static int sGestureCount = 0;
-
- private RectF mBoundingBox;
-
- // the same as its instance ID
- private long mGestureID;
-
- private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();
-
- public Gesture() {
- mGestureID = GESTURE_ID_BASE + sGestureCount++;
- }
-
- /**
- * @return all the strokes of the gesture
- */
- public ArrayList<GestureStroke> getStrokes() {
- return mStrokes;
- }
-
- /**
- * @return the number of strokes included by this gesture
- */
- public int getStrokesCount() {
- return mStrokes.size();
- }
-
- /**
- * Add a stroke to the gesture
- *
- * @param stroke
- */
- public void addStroke(GestureStroke stroke) {
- mStrokes.add(stroke);
-
- if (mBoundingBox == null) {
- mBoundingBox = new RectF(stroke.boundingBox);
- } else {
- mBoundingBox.union(stroke.boundingBox);
- }
- }
-
- /**
- * Get the total length of the gesture. When there are multiple strokes in
- * the gesture, this returns the sum of the lengths of all the strokes
- *
- * @return the length of the gesture
- */
- public float getLength() {
- int len = 0;
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- for (int i = 0; i < count; i++) {
- len += strokes.get(i).length;
- }
-
- return len;
- }
-
- /**
- * @return the bounding box of the gesture
- */
- public RectF getBoundingBox() {
- return mBoundingBox;
- }
-
- /**
- * Set the id of the gesture
- *
- * @param id
- */
- void setID(long id) {
- mGestureID = id;
- }
-
- /**
- * @return the id of the gesture
- */
- public long getID() {
- return mGestureID;
- }
-
- /**
- * draw the gesture
- *
- * @param canvas
- */
- void draw(Canvas canvas, Paint paint) {
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- for (int i = 0; i < count; i++) {
- strokes.get(i).draw(canvas, paint);
- }
- }
-
- /**
- * Create a bitmap of the gesture with a transparent background
- *
- * @param width width of the target bitmap
- * @param height height of the target bitmap
- * @param edge the edge
- * @param numSample
- * @param color
- * @return the bitmap
- */
- public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) {
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- final Canvas canvas = new Canvas(bitmap);
-
- canvas.translate(edge, edge);
-
- final Paint paint = new Paint();
- paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS);
- paint.setDither(BITMAP_RENDERING_DITHER);
- paint.setColor(color);
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeJoin(Paint.Join.ROUND);
- paint.setStrokeCap(Paint.Cap.ROUND);
- paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
-
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- for (int i = 0; i < count; i++) {
- Path path = strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample);
- canvas.drawPath(path, paint);
- }
-
- return bitmap;
- }
-
- /**
- * Create a bitmap of the gesture with a transparent background
- *
- * @param width
- * @param height
- * @param edge
- * @param color
- * @return the bitmap
- */
- public Bitmap toBitmap(int width, int height, int edge, int color) {
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- final Canvas canvas = new Canvas(bitmap);
-
- canvas.translate(edge, edge);
-
- final Paint paint = new Paint();
- paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS);
- paint.setDither(BITMAP_RENDERING_DITHER);
- paint.setColor(color);
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeJoin(Paint.Join.ROUND);
- paint.setStrokeCap(Paint.Cap.ROUND);
- paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
-
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- for (int i = 0; i < count; i++) {
- strokes.get(i).draw(canvas, paint);
- }
-
- return bitmap;
- }
-
- void serialize(DataOutputStream out) throws IOException {
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- // Write gesture ID
- out.writeLong(mGestureID);
- // Write number of strokes
- out.writeInt(count);
-
- for (int i = 0; i < count; i++) {
- strokes.get(i).serialize(out);
- }
- }
-
- static Gesture deserialize(DataInputStream in) throws IOException {
- final Gesture gesture = new Gesture();
-
- // Gesture ID
- gesture.mGestureID = in.readLong();
- // Number of strokes
- final int count = in.readInt();
-
- for (int i = 0; i < count; i++) {
- gesture.addStroke(GestureStroke.deserialize(in));
- }
-
- return gesture;
- }
-
- /**
- * Convert the gesture to string
- */
- @Override
- public String toString() {
- final StringBuilder str = new StringBuilder();
- str.append(mGestureID);
-
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
-
- for (int i = 0; i < count; i++) {
- final GestureStroke stroke = strokes.get(i);
- str.append(GestureConstants.STRING_GESTURE_DELIIMITER);
- str.append(stroke.toString());
- }
-
- return str.toString();
- }
-
- public static final Parcelable.Creator<Gesture> CREATOR = new Parcelable.Creator<Gesture>() {
- public Gesture createFromParcel(Parcel in) {
- Gesture gesture = null;
- final long gestureID = in.readLong();
-
- final DataInputStream inStream = new DataInputStream(
- new ByteArrayInputStream(in.createByteArray()));
-
- try {
- gesture = deserialize(inStream);
- } catch (IOException e) {
- Log.e(LOG_TAG, "Error reading Gesture from parcel:", e);
- } finally {
- GestureUtilities.closeStream(inStream);
- }
-
- if (gesture != null) {
- gesture.mGestureID = gestureID;
- }
-
- return gesture;
- }
-
- public Gesture[] newArray(int size) {
- return new Gesture[size];
- }
- };
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeLong(mGestureID);
-
- boolean result = false;
- final ByteArrayOutputStream byteStream =
- new ByteArrayOutputStream(GestureConstants.IO_BUFFER_SIZE);
- final DataOutputStream outStream = new DataOutputStream(byteStream);
-
- try {
- serialize(outStream);
- result = true;
- } catch (IOException e) {
- Log.e(LOG_TAG, "Error writing Gesture to parcel:", e);
- } finally {
- GestureUtilities.closeStream(outStream);
- GestureUtilities.closeStream(byteStream);
- }
-
- if (result) {
- out.writeByteArray(byteStream.toByteArray());
- }
- }
-
- public int describeContents() {
- return 0;
- }
-}
-
diff --git a/tests/sketch/src/com/android/gesture/GestureActionListener.java b/tests/sketch/src/com/android/gesture/GestureActionListener.java
deleted file mode 100644
index c9c5232..0000000
--- a/tests/sketch/src/com/android/gesture/GestureActionListener.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-public interface GestureActionListener {
- public void onGesturePerformed(GestureOverlay overlay, Gesture gesture);
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/tests/sketch/src/com/android/gesture/GestureConstants.java
deleted file mode 100644
index c0f2f3d..0000000
--- a/tests/sketch/src/com/android/gesture/GestureConstants.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-interface GestureConstants {
- static final String STRING_GESTURE_DELIIMITER = "#";
- static final String STRING_STROKE_DELIIMITER = ",";
-
- static final int STROKE_STRING_BUFFER_SIZE = 1024;
- static final int STROKE_POINT_BUFFER_SIZE = 100; // number of points
-
- static final int IO_BUFFER_SIZE = 32 * 1024; // 32K
-
- static final String LOG_TAG = "Gestures";
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java
deleted file mode 100644
index 7b5480c..0000000
--- a/tests/sketch/src/com/android/gesture/GestureLibrary.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.util.Log;
-import android.os.SystemClock;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.DataInputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.Map;
-
-import static com.android.gesture.GestureConstants.LOG_TAG;
-
-/**
- * GestureLibrary maintains gesture examples and makes predictions on a new
- * gesture
- */
-//
-// File format for GestureLibrary:
-//
-// Nb. bytes Java type Description
-// -----------------------------------
-// Header
-// 2 bytes short File format version number
-// 4 bytes int Number of entries
-// Entry
-// X bytes UTF String Entry name
-// 4 bytes int Number of gestures
-// Gesture
-// 8 bytes long Gesture ID
-// 4 bytes int Number of strokes
-// Stroke
-// 4 bytes int Number of points
-// Point
-// 4 bytes float X coordinate of the point
-// 4 bytes float Y coordinate of the point
-// 8 bytes long Time stamp
-//
-public class GestureLibrary {
- public static final int SEQUENCE_INVARIANT = 1;
- // when SEQUENCE_SENSITIVE is used, only single stroke gestures are currently allowed
- public static final int SEQUENCE_SENSITIVE = 2;
-
- // ORIENTATION_SENSITIVE and ORIENTATION_INVARIANT are only for SEQUENCE_SENSITIVE gestures
- public static final int ORIENTATION_INVARIANT = 1;
- public static final int ORIENTATION_SENSITIVE = 2;
-
- private static final short FILE_FORMAT_VERSION = 1;
-
- private static final boolean PROFILE_LOADING_SAVING = false;
-
- private int mSequenceType = SEQUENCE_SENSITIVE;
- private int mOrientationStyle = ORIENTATION_SENSITIVE;
-
- private final String mGestureFileName;
-
- private final HashMap<String, ArrayList<Gesture>> mNamedGestures =
- new HashMap<String, ArrayList<Gesture>>();
-
- private Learner mClassifier;
-
- private boolean mChanged = false;
-
- /**
- * @param path where gesture data is stored
- */
- public GestureLibrary(String path) {
- mGestureFileName = path;
- mClassifier = new InstanceLearner();
- }
-
- /**
- * Specify how the gesture library will handle orientation.
- * Use ORIENTATION_INVARIANT or ORIENTATION_SENSITIVE
- *
- * @param style
- */
- public void setOrientationStyle(int style) {
- mOrientationStyle = style;
- }
-
- public int getOrientationStyle() {
- return mOrientationStyle;
- }
-
- /**
- * @param type SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE
- */
- public void setSequenceType(int type) {
- mSequenceType = type;
- }
-
- /**
- * @return SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE
- */
- public int getSequenceType() {
- return mSequenceType;
- }
-
- /**
- * Get all the gesture entry names in the library
- *
- * @return a set of strings
- */
- public Set<String> getGestureEntries() {
- return mNamedGestures.keySet();
- }
-
- /**
- * Recognize a gesture
- *
- * @param gesture the query
- * @return a list of predictions of possible entries for a given gesture
- */
- public ArrayList<Prediction> recognize(Gesture gesture) {
- Instance instance = Instance.createInstance(mSequenceType, gesture, null);
- return mClassifier.classify(mSequenceType, instance.vector);
- }
-
- /**
- * Add a gesture for the entry
- *
- * @param entryName entry name
- * @param gesture
- */
- public void addGesture(String entryName, Gesture gesture) {
- if (entryName == null || entryName.length() == 0) {
- return;
- }
- ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
- if (gestures == null) {
- gestures = new ArrayList<Gesture>();
- mNamedGestures.put(entryName, gestures);
- }
- gestures.add(gesture);
- mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName));
- mChanged = true;
- }
-
- /**
- * Remove a gesture from the library. If there are no more gestures for the
- * given entry, the gesture entry will be removed.
- *
- * @param entryName entry name
- * @param gesture
- */
- public void removeGesture(String entryName, Gesture gesture) {
- ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
- if (gestures == null) {
- return;
- }
-
- gestures.remove(gesture);
-
- // if there are no more samples, remove the entry automatically
- if (gestures.isEmpty()) {
- mNamedGestures.remove(entryName);
- }
-
- mClassifier.removeInstance(gesture.getID());
-
- mChanged = true;
- }
-
- /**
- * Remove a entry of gestures
- *
- * @param entryName the entry name
- */
- public void removeEntireEntry(String entryName) {
- mNamedGestures.remove(entryName);
- mClassifier.removeInstances(entryName);
- mChanged = true;
- }
-
- /**
- * Get all the gestures of an entry
- *
- * @param entryName
- * @return the list of gestures that is under this name
- */
- public ArrayList<Gesture> getGestures(String entryName) {
- ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
- if (gestures != null) {
- return new ArrayList<Gesture>(gestures);
- } else {
- return null;
- }
- }
-
- /**
- * Save the gesture library
- */
- public boolean save() {
- if (!mChanged) {
- return true;
- }
-
- boolean result = false;
- DataOutputStream out = null;
-
- try {
- File file = new File(mGestureFileName);
- if (!file.getParentFile().exists()) {
- if (!file.getParentFile().mkdirs()) {
- return false;
- }
- }
-
- long start;
- if (PROFILE_LOADING_SAVING) {
- start = SystemClock.elapsedRealtime();
- }
-
- final HashMap<String, ArrayList<Gesture>> maps = mNamedGestures;
-
- out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file),
- GestureConstants.IO_BUFFER_SIZE));
- // Write version number
- out.writeShort(FILE_FORMAT_VERSION);
- // Write number of entries
- out.writeInt(maps.size());
-
- for (Map.Entry<String, ArrayList<Gesture>> entry : maps.entrySet()) {
- final String key = entry.getKey();
- final ArrayList<Gesture> examples = entry.getValue();
- final int count = examples.size();
-
- // Write entry name
- out.writeUTF(key);
- // Write number of examples for this entry
- out.writeInt(count);
-
- for (int i = 0; i < count; i++) {
- examples.get(i).serialize(out);
- }
- }
-
- out.flush();
-
- if (PROFILE_LOADING_SAVING) {
- long end = SystemClock.elapsedRealtime();
- Log.d(LOG_TAG, "Saving gestures library = " + (end - start) + " ms");
- }
-
- mChanged = false;
- result = true;
- } catch (IOException ex) {
- Log.d(LOG_TAG, "Failed to save gestures:", ex);
- } finally {
- GestureUtilities.closeStream(out);
- }
-
- return result;
- }
-
- /**
- * Load the gesture library
- */
- public boolean load() {
- boolean result = false;
-
- final File file = new File(mGestureFileName);
- if (file.exists()) {
- DataInputStream in = null;
- try {
- in = new DataInputStream(new BufferedInputStream(
- new FileInputStream(mGestureFileName), GestureConstants.IO_BUFFER_SIZE));
-
- long start;
- if (PROFILE_LOADING_SAVING) {
- start = SystemClock.elapsedRealtime();
- }
-
- // Read file format version number
- final short versionNumber = in.readShort();
- switch (versionNumber) {
- case 1:
- readFormatV1(in);
- break;
- }
-
- if (PROFILE_LOADING_SAVING) {
- long end = SystemClock.elapsedRealtime();
- Log.d(LOG_TAG, "Loading gestures library = " + (end - start) + " ms");
- }
-
- result = true;
- } catch (IOException ex) {
- Log.d(LOG_TAG, "Failed to load gestures:", ex);
- } finally {
- GestureUtilities.closeStream(in);
- }
- }
-
- return result;
- }
-
- private void readFormatV1(DataInputStream in) throws IOException {
- final Learner classifier = mClassifier;
- final HashMap<String, ArrayList<Gesture>> namedGestures = mNamedGestures;
- namedGestures.clear();
-
- // Number of entries in the library
- final int entriesCount = in.readInt();
-
- for (int i = 0; i < entriesCount; i++) {
- // Entry name
- final String name = in.readUTF();
- // Number of gestures
- final int gestureCount = in.readInt();
-
- final ArrayList<Gesture> gestures = new ArrayList<Gesture>(gestureCount);
- for (int j = 0; j < gestureCount; j++) {
- final Gesture gesture = Gesture.deserialize(in);
- gestures.add(gesture);
- classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name));
- }
-
- namedGestures.put(name, gestures);
- }
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureListener.java b/tests/sketch/src/com/android/gesture/GestureListener.java
deleted file mode 100755
index 9b50714..0000000
--- a/tests/sketch/src/com/android/gesture/GestureListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.view.MotionEvent;
-
-/**
- * An interface for processing gesture events
- */
-public interface GestureListener {
- public void onStartGesture(GestureOverlay overlay, MotionEvent event);
-
- public void onGesture(GestureOverlay overlay, MotionEvent event);
-
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event);
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureOverlay.java b/tests/sketch/src/com/android/gesture/GestureOverlay.java
deleted file mode 100755
index 454cecb..0000000
--- a/tests/sketch/src/com/android/gesture/GestureOverlay.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * A (transparent) overlay for gesture input that can be placed on top of other
- * widgets. The view can also be opaque.
- */
-
-public class GestureOverlay extends View {
- static final float TOUCH_TOLERANCE = 3;
-
- // TODO: Move all these values into XML attributes
- private static final int TRANSPARENT_BACKGROUND = 0x00000000;
-
- // TODO: SHOULD BE A TOTAL DURATION
- private static final float FADING_ALPHA_CHANGE = 0.15f;
- private static final long FADING_OFFSET = 300;
- private static final long FADING_REFRESHING_RATE = 16;
-
- private static final int GESTURE_STROKE_WIDTH = 12;
- private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
-
- private static final boolean DITHER_FLAG = true;
-
- public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00;
-
- private static final int REFRESH_RANGE = 10;
-
- private static final BlurMaskFilter BLUR_MASK_FILTER =
- new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);
-
-
- // double buffering
- private Paint mGesturePaint;
-
- private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
- private Bitmap mBitmap; // with transparent background
- private Canvas mBitmapCanvas;
-
- // for rendering immediate ink feedback
- private Rect mInvalidRect = new Rect();
-
- private Path mPath;
-
- private float mX;
- private float mY;
-
- private float mCurveEndX;
- private float mCurveEndY;
-
- // current gesture
- private Gesture mCurrentGesture = null;
-
- // TODO: Make this a list of WeakReferences
- private final ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>();
- private ArrayList<GesturePoint> mPointBuffer = null;
-
- // fading out effect
- private boolean mIsFadingOut = false;
- private float mFadingAlpha = 1;
-
- private Handler mHandler = new Handler();
-
- private final Runnable mFadingOut = new Runnable() {
- public void run() {
- if (mIsFadingOut) {
- mFadingAlpha -= FADING_ALPHA_CHANGE;
- if (mFadingAlpha <= 0) {
- mIsFadingOut = false;
- mPath = null;
- mCurrentGesture = null;
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- } else {
- mHandler.postDelayed(this, FADING_REFRESHING_RATE);
- }
- invalidate();
- }
- }
- };
-
- public GestureOverlay(Context context) {
- super(context);
- init();
- }
-
- public GestureOverlay(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- public ArrayList<GesturePoint> getCurrentStroke() {
- return mPointBuffer;
- }
-
- public Gesture getCurrentGesture() {
- return mCurrentGesture;
- }
-
- /**
- * Set Gesture color
- *
- * @param color
- */
- public void setGestureColor(int color) {
- mGesturePaint.setColor(color);
- if (mCurrentGesture != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
- }
- }
-
- /**
- * Set the gesture to be shown in the view
- *
- * @param gesture
- */
- public void setCurrentGesture(Gesture gesture) {
- if (mCurrentGesture != null) {
- clear(false);
- }
-
- mCurrentGesture = gesture;
-
- if (gesture != null) {
- if (mBitmapCanvas != null) {
- gesture.draw(mBitmapCanvas, mGesturePaint);
- invalidate();
- }
- }
- }
-
- private void init() {
- mGesturePaint = new Paint();
-
- final Paint gesturePaint = mGesturePaint;
- gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
- gesturePaint.setColor(DEFAULT_GESTURE_COLOR);
- gesturePaint.setStyle(Paint.Style.STROKE);
- gesturePaint.setStrokeJoin(Paint.Join.ROUND);
- gesturePaint.setStrokeCap(Paint.Cap.ROUND);
- gesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
- gesturePaint.setDither(DITHER_FLAG);
-
- mPath = null;
- }
-
- @Override
- protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
- super.onSizeChanged(width, height, oldWidth, oldHeight);
-
- if (width <= 0 || height <= 0) {
- return;
- }
-
- int targetWidth = width > oldWidth ? width : oldWidth;
- int targetHeight = height > oldHeight ? height : oldHeight;
-
- if (mBitmap != null) mBitmap.recycle();
-
- mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
- if (mBitmapCanvas != null) {
- mBitmapCanvas.setBitmap(mBitmap);
- } else {
- mBitmapCanvas = new Canvas(mBitmap);
- }
- mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND);
-
- if (mCurrentGesture != null) {
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
- }
- }
-
- public void addGestureListener(GestureListener listener) {
- mGestureListeners.add(listener);
- }
-
- public void removeGestureListener(GestureListener listener) {
- mGestureListeners.remove(listener);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // draw double buffer
- if (mIsFadingOut) {
- mBitmapPaint.setAlpha((int) (255 * mFadingAlpha));
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- } else {
- mBitmapPaint.setAlpha(255);
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- }
-
- // draw the current stroke
- if (mPath != null) {
- canvas.drawPath(mPath, mGesturePaint);
- }
- }
-
- /**
- * Clear up the overlay
- *
- * @param fadeOut whether the gesture on the overlay should fade out
- * gradually or disappear immediately
- */
- public void clear(boolean fadeOut) {
- if (fadeOut) {
- mFadingAlpha = 1;
- mIsFadingOut = true;
- mHandler.removeCallbacks(mFadingOut);
- mHandler.postDelayed(mFadingOut, FADING_OFFSET);
- } else {
- mPath = null;
- mCurrentGesture = null;
- if (mBitmap != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- invalidate();
- }
- }
- }
-
- public void cancelFadingOut() {
- mIsFadingOut = false;
- mHandler.removeCallbacks(mFadingOut);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
- return true;
- }
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Rect rect = touchStart(event);
- invalidate(rect);
- break;
- case MotionEvent.ACTION_MOVE:
- rect = touchMove(event);
- if (rect != null) {
- invalidate(rect);
- }
- break;
- case MotionEvent.ACTION_UP:
- touchUp(event);
- invalidate();
- break;
- }
-
- return true;
- }
-
- private Rect touchStart(MotionEvent event) {
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- GestureListener listener = listeners.get(i);
- listener.onStartGesture(this, event);
- }
-
- // if there is fading out going on, stop it.
- if (mIsFadingOut) {
- mIsFadingOut = false;
- mHandler.removeCallbacks(mFadingOut);
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture = null;
- }
-
- float x = event.getX();
- float y = event.getY();
-
- mX = x;
- mY = y;
-
- if (mCurrentGesture == null) {
- mCurrentGesture = new Gesture();
- }
-
- mPointBuffer = new ArrayList<GesturePoint>();
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
-
- mPath = new Path();
- mPath.moveTo(x, y);
-
- mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE,
- (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE);
-
- mCurveEndX = x;
- mCurveEndY = y;
-
- return mInvalidRect;
- }
-
- private Rect touchMove(MotionEvent event) {
- Rect areaToRefresh = null;
-
- float x = event.getX();
- float y = event.getY();
-
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
-
- if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
-
- // start with the curve end
- mInvalidRect.set((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
- (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);
-
- mCurveEndX = (x + mX) / 2;
- mCurveEndY = (y + mY) / 2;
- mPath.quadTo(mX, mY, mCurveEndX, mCurveEndY);
-
- // union with the control point of the new curve
- mInvalidRect.union((int) mX - REFRESH_RANGE, (int) mY - REFRESH_RANGE,
- (int) mX + REFRESH_RANGE, (int) mY + REFRESH_RANGE);
-
- // union with the end point of the new curve
- mInvalidRect.union((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
- (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);
-
- areaToRefresh = mInvalidRect;
-
- mX = x;
- mY = y;
- }
-
-
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
-
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- listeners.get(i).onGesture(this, event);
- }
-
- return areaToRefresh;
- }
-
- private void touchUp(MotionEvent event) {
- // add the stroke to the current gesture
- mCurrentGesture.addStroke(new GestureStroke(mPointBuffer));
-
- // add the stroke to the double buffer
- mGesturePaint.setMaskFilter(BLUR_MASK_FILTER);
- mBitmapCanvas.drawPath(mPath, mGesturePaint);
- mGesturePaint.setMaskFilter(null);
-
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- listeners.get(i).onFinishGesture(this, event);
- }
-
- mPath = null;
- mPointBuffer = null;
- }
-
-}
diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/tests/sketch/src/com/android/gesture/GesturePoint.java
deleted file mode 100644
index 560f893..0000000
--- a/tests/sketch/src/com/android/gesture/GesturePoint.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-
-/**
- * A timed point of a gesture stroke
- */
-
-public class GesturePoint {
- public final float x;
- public final float y;
-
- public final long timestamp;
-
- public GesturePoint(float x, float y, long t) {
- this.x = x;
- this.y = y;
- timestamp = t;
- }
-
- static GesturePoint deserialize(DataInputStream in) throws IOException {
- // Read X and Y
- final float x = in.readFloat();
- final float y = in.readFloat();
- // Read timestamp
- final long timeStamp = in.readLong();
- return new GesturePoint(x, y, timeStamp);
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/tests/sketch/src/com/android/gesture/GestureStroke.java
deleted file mode 100644
index 79b42fe..0000000
--- a/tests/sketch/src/com/android/gesture/GestureStroke.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.RectF;
-
-import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.DataInputStream;
-import java.util.ArrayList;
-
-/**
- * A gesture stroke started on a touch down and ended on a touch up.
- */
-public class GestureStroke {
- public final RectF boundingBox;
-
- public final float length;
- public final float[] points;
-
- private final long[] timestamps;
- private Path mCachedPath;
-
- /**
- * Construct a gesture stroke from a list of gesture points
- *
- * @param points
- */
- public GestureStroke(ArrayList<GesturePoint> points) {
- final int count = points.size();
- final float[] tmpPoints = new float[count * 2];
- final long[] times = new long[count];
-
- RectF bx = null;
- float len = 0;
- int index = 0;
-
- for (int i = 0; i < count; i++) {
- final GesturePoint p = points.get(i);
- tmpPoints[i * 2] = p.x;
- tmpPoints[i * 2 + 1] = p.y;
- times[index] = p.timestamp;
-
- if (bx == null) {
- bx = new RectF();
- bx.top = p.y;
- bx.left = p.x;
- bx.right = p.x;
- bx.bottom = p.y;
- len = 0;
- } else {
- len += Math.sqrt(Math.pow(p.x - tmpPoints[(i - 1) * 2], 2)
- + Math.pow(p.y - tmpPoints[(i -1 ) * 2 + 1], 2));
- bx.union(p.x, p.y);
- }
- index++;
- }
-
- timestamps = times;
- this.points = tmpPoints;
- boundingBox = bx;
- length = len;
- }
-
- /**
- * Draw the gesture with a given canvas and paint
- *
- * @param canvas
- */
- void draw(Canvas canvas, Paint paint) {
- if (mCachedPath == null) {
- final float[] localPoints = points;
- final int count = localPoints.length;
-
- Path path = null;
-
- float mX = 0;
- float mY = 0;
-
- for (int i = 0; i < count; i += 2) {
- float x = localPoints[i];
- float y = localPoints[i + 1];
- if (path == null) {
- path = new Path();
- path.moveTo(x, y);
- mX = x;
- mY = y;
- } else {
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
- if (dx >= 3 || dy >= 3) {
- path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- }
- }
- }
-
- mCachedPath = path;
- }
-
- canvas.drawPath(mCachedPath, paint);
- }
-
- /**
- * Convert the stroke to a Path based on the number of points
- *
- * @param width the width of the bounding box of the target path
- * @param height the height of the bounding box of the target path
- * @param numSample the number of points needed
- * @return the path
- */
- public Path toPath(float width, float height, int numSample) {
- final float[] pts = GestureUtilities.temporalSampling(this, numSample);
- final RectF rect = boundingBox;
- final float scale = height / rect.height();
-
- final Matrix matrix = new Matrix();
- matrix.setTranslate(-rect.left, -rect.top);
- matrix.postScale(scale, scale);
- matrix.mapPoints(pts);
-
- float mX = 0;
- float mY = 0;
-
- Path path = null;
-
- final int count = pts.length;
-
- for (int i = 0; i < count; i += 2) {
- float x = pts[i];
- float y = pts[i + 1];
- if (path == null) {
- path = new Path();
- path.moveTo(x, y);
- mX = x;
- mY = y;
- } else {
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
- if (dx >= GestureOverlay.TOUCH_TOLERANCE || dy >= GestureOverlay.TOUCH_TOLERANCE) {
- path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- }
- }
- }
-
- return path;
- }
-
- void serialize(DataOutputStream out) throws IOException {
- final float[] pts = points;
- final long[] times = timestamps;
- final int count = points.length;
-
- // Write number of points
- out.writeInt(count / 2);
-
- for (int i = 0; i < count; i += 2) {
- // Write X
- out.writeFloat(pts[i]);
- // Write Y
- out.writeFloat(pts[i + 1]);
- // Write timestamp
- out.writeLong(times[i / 2]);
- }
- }
-
- static GestureStroke deserialize(DataInputStream in) throws IOException {
- // Number of points
- final int count = in.readInt();
-
- final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(count);
- for (int i = 0; i < count; i++) {
- points.add(GesturePoint.deserialize(in));
- }
-
- return new GestureStroke(points);
- }
-
- /**
- * Convert the stroke to string
- */
- @Override
- public String toString() {
- final StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
- final float[] pts = points;
- final long[] times = timestamps;
- final int count = points.length;
-
- for (int i = 0; i < count; i += 2) {
- str.append(pts[i]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- str.append(pts[i + 1]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- str.append(times[i / 2]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- }
-
- return str.toString();
- }
-
- /**
- * Invalidate the cached path that is used for rendering the stroke
- */
- public void invalidate() {
- mCachedPath = null;
- }
-
- /**
- * Compute an oriented bounding box of the stroke
- * @return OrientedBoundingBox
- */
- public OrientedBoundingBox computeOrientedBoundingBox() {
- return GestureUtilities.computeOrientedBoundingBox(points);
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureUtilities.java b/tests/sketch/src/com/android/gesture/GestureUtilities.java
deleted file mode 100755
index 6d73c2d..0000000
--- a/tests/sketch/src/com/android/gesture/GestureUtilities.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.RectF;
-import android.graphics.Matrix;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.io.Closeable;
-import java.io.IOException;
-
-import static com.android.gesture.GestureConstants.*;
-
-final class GestureUtilities {
- private static final int TEMPORAL_SAMPLING_RATE = 16;
-
- private GestureUtilities() {
- }
-
- /**
- * Closes the specified stream.
- *
- * @param stream The stream to close.
- */
- static void closeStream(Closeable stream) {
- if (stream != null) {
- try {
- stream.close();
- } catch (IOException e) {
- Log.e(LOG_TAG, "Could not close stream", e);
- }
- }
- }
-
- static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
- final float targetPatchSize = sampleMatrixDimension - 1; // edge inclusive
- float[] sample = new float[sampleMatrixDimension * sampleMatrixDimension];
- Arrays.fill(sample, 0);
-
- RectF rect = gesture.getBoundingBox();
- float sx = targetPatchSize / rect.width();
- float sy = targetPatchSize / rect.height();
- float scale = sx < sy ? sx : sy;
-
- Matrix trans = new Matrix();
- trans.setScale(scale, scale);
- trans.preTranslate(-rect.centerX(), -rect.centerY());
- trans.postTranslate(targetPatchSize / 2, targetPatchSize / 2);
-
- final ArrayList<GestureStroke> strokes = gesture.getStrokes();
- final int count = strokes.size();
-
- int size;
- float xpos;
- float ypos;
-
- for (int index = 0; index < count; index++) {
- final GestureStroke stroke = strokes.get(index);
- size = stroke.points.length;
-
- final float[] pts = new float[size];
-
- trans.mapPoints(pts, 0, stroke.points, 0, size / 2);
- float segmentEndX = -1;
- float segmentEndY = -1;
-
- for (int i = 0; i < size; i += 2) {
-
- float segmentStartX = pts[i] < 0 ? 0 : pts[i];
- float segmentStartY = pts[i + 1] < 0 ? 0 : pts[i + 1];
-
- if (segmentStartX > targetPatchSize) {
- segmentStartX = targetPatchSize;
- }
-
- if (segmentStartY > targetPatchSize) {
- segmentStartY = targetPatchSize;
- }
-
- plot(segmentStartX, segmentStartY, sample, sampleMatrixDimension);
-
- if (segmentEndX != -1) {
- // evaluate horizontally
- if (segmentEndX > segmentStartX) {
- xpos = (float) Math.ceil(segmentStartX);
- float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
- while (xpos < segmentEndX) {
- ypos = slope * (xpos - segmentStartX) + segmentStartY;
- plot(xpos, ypos, sample, sampleMatrixDimension);
- xpos++;
- }
- } else if (segmentEndX < segmentStartX){
- xpos = (float) Math.ceil(segmentEndX);
- float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
- while (xpos < segmentStartX) {
- ypos = slope * (xpos - segmentStartX) + segmentStartY;
- plot(xpos, ypos, sample, sampleMatrixDimension);
- xpos++;
- }
- }
-
- // evaluating vertically
- if (segmentEndY > segmentStartY) {
- ypos = (float) Math.ceil(segmentStartY);
- float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
- while (ypos < segmentEndY) {
- xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
- plot(xpos, ypos, sample, sampleMatrixDimension);
- ypos++;
- }
- } else if (segmentEndY < segmentStartY) {
- ypos = (float) Math.ceil(segmentEndY);
- float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
- while (ypos < segmentStartY) {
- xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
- plot(xpos, ypos, sample, sampleMatrixDimension);
- ypos++;
- }
- }
- }
-
- segmentEndX = segmentStartX;
- segmentEndY = segmentStartY;
- }
- }
-
-
- return sample;
- }
-
- private static void plot(float x, float y, float[] sample, int sampleSize) {
- x = x < 0 ? 0 : x;
- y = y < 0 ? 0 : y;
- int xFloor = (int) Math.floor(x);
- int xCeiling = (int) Math.ceil(x);
- int yFloor = (int) Math.floor(y);
- int yCeiling = (int) Math.ceil(y);
-
- // if it's an integer
- if (x == xFloor && y == yFloor) {
- int index = yCeiling * sampleSize + xCeiling;
- if (sample[index] < 1){
- sample[index] = 1;
- }
- } else {
- double topLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yFloor - y, 2));
- double topRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yFloor - y, 2));
- double btmLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yCeiling - y, 2));
- double btmRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yCeiling - y, 2));
- double sum = topLeft + topRight + btmLeft + btmRight;
-
- double value = topLeft / sum;
- int index = yFloor * sampleSize + xFloor;
- if (value > sample[index]){
- sample[index] = (float) value;
- }
-
- value = topRight / sum;
- index = yFloor * sampleSize + xCeiling;
- if (value > sample[index]){
- sample[index] = (float) value;
- }
-
- value = btmLeft / sum;
- index = yCeiling * sampleSize + xFloor;
- if (value > sample[index]){
- sample[index] = (float) value;
- }
-
- value = btmRight / sum;
- index = yCeiling * sampleSize + xCeiling;
- if (value > sample[index]){
- sample[index] = (float) value;
- }
- }
- }
-
- /**
- * Featurize a stroke into a vector of a given number of elements
- *
- * @param stroke
- * @param sampleSize
- * @return a float array
- */
- static float[] temporalSampling(GestureStroke stroke, int sampleSize) {
- final float increment = stroke.length / (sampleSize - 1);
- int vectorLength = sampleSize * 2;
- float[] vector = new float[vectorLength];
- float distanceSoFar = 0;
- float[] pts = stroke.points;
- float lstPointX = pts[0];
- float lstPointY = pts[1];
- int index = 0;
- float currentPointX = Float.MIN_VALUE;
- float currentPointY = Float.MIN_VALUE;
- vector[index] = lstPointX;
- index++;
- vector[index] = lstPointY;
- index++;
- int i = 0;
- int count = pts.length / 2;
- while (i < count) {
- if (currentPointX == Float.MIN_VALUE) {
- i++;
- if (i >= count) {
- break;
- }
- currentPointX = pts[i * 2];
- currentPointY = pts[i * 2 + 1];
- }
- float deltaX = currentPointX - lstPointX;
- float deltaY = currentPointY - lstPointY;
- float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- if (distanceSoFar + distance >= increment) {
- float ratio = (increment - distanceSoFar) / distance;
- float nx = lstPointX + ratio * deltaX;
- float ny = lstPointY + ratio * deltaY;
- vector[index] = nx;
- index++;
- vector[index] = ny;
- index++;
- lstPointX = nx;
- lstPointY = ny;
- distanceSoFar = 0;
- } else {
- lstPointX = currentPointX;
- lstPointY = currentPointY;
- currentPointX = Float.MIN_VALUE;
- currentPointY = Float.MIN_VALUE;
- distanceSoFar += distance;
- }
- }
-
- for (i = index; i < vectorLength; i += 2) {
- vector[i] = lstPointX;
- vector[i + 1] = lstPointY;
- }
- return vector;
- }
-
- /**
- * Calculate the centroid
- *
- * @param points
- * @return the centroid
- */
- static float[] computeCentroid(float[] points) {
- float centerX = 0;
- float centerY = 0;
- int count = points.length;
- for (int i = 0; i < count; i++) {
- centerX += points[i];
- i++;
- centerY += points[i];
- }
- float[] center = new float[2];
- center[0] = 2 * centerX / count;
- center[1] = 2 * centerY / count;
-
- return center;
- }
-
- /**
- * calculate the variance-covariance matrix, treat each point as a sample
- *
- * @param points
- * @return the covariance matrix
- */
- private static double[][] computeCoVariance(float[] points) {
- double[][] array = new double[2][2];
- array[0][0] = 0;
- array[0][1] = 0;
- array[1][0] = 0;
- array[1][1] = 0;
- int count = points.length;
- for (int i = 0; i < count; i++) {
- float x = points[i];
- i++;
- float y = points[i];
- array[0][0] += x * x;
- array[0][1] += x * y;
- array[1][0] = array[0][1];
- array[1][1] += y * y;
- }
- array[0][0] /= (count / 2);
- array[0][1] /= (count / 2);
- array[1][0] /= (count / 2);
- array[1][1] /= (count / 2);
-
- return array;
- }
-
- static float computeTotalLength(float[] points) {
- float sum = 0;
- int count = points.length - 4;
- for (int i = 0; i < count; i += 2) {
- float dx = points[i + 2] - points[i];
- float dy = points[i + 3] - points[i + 1];
- sum += Math.sqrt(dx * dx + dy * dy);
- }
- return sum;
- }
-
- static double computeStraightness(float[] points) {
- float totalLen = computeTotalLength(points);
- float dx = points[2] - points[0];
- float dy = points[3] - points[1];
- return Math.sqrt(dx * dx + dy * dy) / totalLen;
- }
-
- static double computeStraightness(float[] points, float totalLen) {
- float dx = points[2] - points[0];
- float dy = points[3] - points[1];
- return Math.sqrt(dx * dx + dy * dy) / totalLen;
- }
-
- /**
- * Calculate the squared Euclidean distance between two vectors
- *
- * @param vector1
- * @param vector2
- * @return the distance
- */
- static double squaredEuclideanDistance(float[] vector1, float[] vector2) {
- double squaredDistance = 0;
- int size = vector1.length;
- for (int i = 0; i < size; i++) {
- float difference = vector1[i] - vector2[i];
- squaredDistance += difference * difference;
- }
- return squaredDistance / size;
- }
-
- /**
- * Calculate the cosine distance between two instances
- *
- * @param vector1
- * @param vector2
- * @return the distance between 0 and Math.PI
- */
- static double cosineDistance(float[] vector1, float[] vector2) {
- float sum = 0;
- int len = vector1.length;
- for (int i = 0; i < len; i++) {
- sum += vector1[i] * vector2[i];
- }
- return Math.acos(sum);
- }
-
- static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) {
- GestureStroke stroke = new GestureStroke(pts);
- float[] points = temporalSampling(stroke, TEMPORAL_SAMPLING_RATE);
- return computeOrientedBoundingBox(points);
- }
-
- static OrientedBoundingBox computeOrientedBoundingBox(float[] points) {
- float[] meanVector = computeCentroid(points);
- return computeOrientedBoundingBox(points, meanVector);
- }
-
- static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
- Matrix tr = new Matrix();
- tr.setTranslate(-centroid[0], -centroid[1]);
- tr.mapPoints(points);
-
- double[][] array = computeCoVariance(points);
- double[] targetVector = computeOrientation(array);
-
- float angle;
- if (targetVector[0] == 0 && targetVector[1] == 0) {
- angle = -90;
- } else { // -PI<alpha<PI
- angle = (float) Math.atan2(targetVector[1], targetVector[0]);
- angle = (float) (180 * angle / Math.PI);
- android.graphics.Matrix trans = new android.graphics.Matrix();
- trans.setRotate(-angle);
- trans.mapPoints(points);
- }
-
- float minx = Float.MAX_VALUE;
- float miny = Float.MAX_VALUE;
- float maxx = Float.MIN_VALUE;
- float maxy = Float.MIN_VALUE;
- int count = points.length;
- for (int i = 0; i < count; i++) {
- if (points[i] < minx) {
- minx = points[i];
- }
- if (points[i] > maxx) {
- maxx = points[i];
- }
- i++;
- if (points[i] < miny) {
- miny = points[i];
- }
- if (points[i] > maxy) {
- maxy = points[i];
- }
- }
-
- return new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx - minx, maxy - miny);
- }
-
- private static double[] computeOrientation(double[][] covarianceMatrix) {
- double[] targetVector = new double[2];
- if (covarianceMatrix[0][1] == 0 || covarianceMatrix[1][0] == 0) {
- targetVector[0] = 1;
- targetVector[1] = 0;
- }
-
- double a = -covarianceMatrix[0][0] - covarianceMatrix[1][1];
- double b = covarianceMatrix[0][0] * covarianceMatrix[1][1] - covarianceMatrix[0][1]
- * covarianceMatrix[1][0];
- double value = a / 2;
- double rightside = Math.sqrt(Math.pow(value, 2) - b);
- double lambda1 = -value + rightside;
- double lambda2 = -value - rightside;
- if (lambda1 == lambda2) {
- targetVector[0] = 0;
- targetVector[1] = 0;
- } else {
- double lambda = lambda1 > lambda2 ? lambda1 : lambda2;
- targetVector[0] = 1;
- targetVector[1] = (lambda - covarianceMatrix[0][0]) / covarianceMatrix[0][1];
- }
- return targetVector;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/tests/sketch/src/com/android/gesture/Instance.java
deleted file mode 100755
index 502a0fa..0000000
--- a/tests/sketch/src/com/android/gesture/Instance.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.Matrix;
-
-/**
- * An instance represents a sample if the label is available or a query if the
- * label is null.
- */
-class Instance {
- private static final int SEQUENCE_SAMPLE_SIZE = 16;
-
- private static final int PATCH_SAMPLE_SIZE = 16;
-
- private final static float[] ORIENTATIONS = {
- 0, 45, 90, 135, 180, -0, -45, -90, -135, -180
- };
-
- // the feature vector
- final float[] vector;
-
- // the label can be null
- final String label;
-
- // the id of the instance
- final long id;
-
- private Instance(long id, float[] sample, String sampleName) {
- this.id = id;
- vector = sample;
- label = sampleName;
- }
-
- private void normalize() {
- float[] sample = vector;
- float sum = 0;
-
- int size = sample.length;
- for (int i = 0; i < size; i++) {
- sum += sample[i] * sample[i];
- }
-
- float magnitude = (float) Math.sqrt(sum);
- for (int i = 0; i < size; i++) {
- sample[i] /= magnitude;
- }
- }
-
- /**
- * create a learning instance for a single stroke gesture
- *
- * @param gesture
- * @param label
- * @return the instance
- */
- static Instance createInstance(int samplingType, Gesture gesture, String label) {
- float[] pts;
- Instance instance;
- if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) {
- pts = temporalSampler(samplingType, gesture);
- instance = new Instance(gesture.getID(), pts, label);
- instance.normalize();
- } else {
- pts = spatialSampler(gesture);
- instance = new Instance(gesture.getID(), pts, label);
- }
- return instance;
- }
-
- private static float[] spatialSampler(Gesture gesture) {
- return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
- }
-
- private static float[] temporalSampler(int samplingType, Gesture gesture) {
- float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0),
- SEQUENCE_SAMPLE_SIZE);
- float[] center = GestureUtilities.computeCentroid(pts);
- float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]);
- orientation *= 180 / Math.PI;
-
- float adjustment = -orientation;
- if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) {
- int count = ORIENTATIONS.length;
- for (int i = 0; i < count; i++) {
- float delta = ORIENTATIONS[i] - orientation;
- if (Math.abs(delta) < Math.abs(adjustment)) {
- adjustment = delta;
- }
- }
- }
-
- Matrix m = new Matrix();
- m.setTranslate(-center[0], -center[1]);
- m.postRotate(adjustment);
- m.mapPoints(pts);
-
- return pts;
- }
-
-}
diff --git a/tests/sketch/src/com/android/gesture/InstanceLearner.java b/tests/sketch/src/com/android/gesture/InstanceLearner.java
deleted file mode 100644
index 4495256..0000000
--- a/tests/sketch/src/com/android/gesture/InstanceLearner.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.util.Config;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.TreeMap;
-
-/**
- * An implementation of an instance-based learner
- */
-
-class InstanceLearner extends Learner {
-
- private static final String LOGTAG = "InstanceLearner";
-
- @Override
- ArrayList<Prediction> classify(int gestureType, float[] vector) {
- ArrayList<Prediction> predictions = new ArrayList<Prediction>();
- ArrayList<Instance> instances = getInstances();
- int count = instances.size();
- TreeMap<String, Double> label2score = new TreeMap<String, Double>();
- for (int i = 0; i < count; i++) {
- Instance sample = instances.get(i);
- if (sample.vector.length != vector.length) {
- continue;
- }
- double distance;
- if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) {
- distance = GestureUtilities.cosineDistance(sample.vector, vector);
- } else {
- distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector);
- }
- double weight;
- if (distance == 0) {
- weight = Double.MAX_VALUE;
- } else {
- weight = 1 / distance;
- }
- Double score = label2score.get(sample.label);
- if (score == null || weight > score) {
- label2score.put(sample.label, weight);
- }
- }
-
- double sum = 0;
- Iterator<String> lableIterator = label2score.keySet().iterator();
- while (lableIterator.hasNext()) {
- String name = lableIterator.next();
- double score = label2score.get(name);
- sum += score;
- predictions.add(new Prediction(name, score));
- }
-
- // normalize
- Iterator<Prediction> predictionIterator = predictions.iterator();
- while (predictionIterator.hasNext()) {
- Prediction name = predictionIterator.next();
- name.score /= sum;
- }
-
- Collections.sort(predictions, new Comparator<Prediction>() {
- public int compare(Prediction object1, Prediction object2) {
- double score1 = object1.score;
- double score2 = object2.score;
- if (score1 > score2) {
- return -1;
- } else if (score1 < score2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
-
- if (Config.DEBUG) {
- predictionIterator = predictions.iterator();
- while (predictionIterator.hasNext()) {
- Prediction name = predictionIterator.next();
- Log.v(LOGTAG, "prediction [" + name.name + " = " + name.score + "]");
- }
- }
-
- return predictions;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/Learner.java b/tests/sketch/src/com/android/gesture/Learner.java
deleted file mode 100755
index 15b2053..0000000
--- a/tests/sketch/src/com/android/gesture/Learner.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import java.util.ArrayList;
-
-/**
- * The abstract class of a gesture learner
- */
-abstract class Learner {
- private final ArrayList<Instance> mInstances = new ArrayList<Instance>();
-
- /**
- * Add an instance to the learner
- *
- * @param instance
- */
- void addInstance(Instance instance) {
- mInstances.add(instance);
- }
-
- /**
- * Retrieve all the instances
- *
- * @return instances
- */
- ArrayList<Instance> getInstances() {
- return mInstances;
- }
-
- /**
- * Remove an instance based on its id
- *
- * @param id
- */
- void removeInstance(long id) {
- ArrayList<Instance> instances = mInstances;
- int count = instances.size();
- for (int i = 0; i < count; i++) {
- Instance instance = instances.get(i);
- if (id == instance.id) {
- instances.remove(instance);
- return;
- }
- }
- }
-
- /**
- * Remove all the instances of a category
- *
- * @param name the category name
- */
- void removeInstances(String name) {
- final ArrayList<Instance> toDelete = new ArrayList<Instance>();
- final ArrayList<Instance> instances = mInstances;
- final int count = instances.size();
-
- for (int i = 0; i < count; i++) {
- final Instance instance = instances.get(i);
- // the label can be null, as specified in Instance
- if ((instance.label == null && name == null) || instance.label.equals(name)) {
- toDelete.add(instance);
- }
- }
- instances.removeAll(toDelete);
- }
-
- abstract ArrayList<Prediction> classify(int gestureType, float[] vector);
-}
diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
deleted file mode 100644
index 07a5f31..0000000
--- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-
-import static com.android.gesture.GestureConstants.LOG_TAG;
-
-public class LetterRecognizer {
- public final static int LATIN_LOWERCASE = 0;
-
- private SigmoidUnit[] mHiddenLayer;
- private SigmoidUnit[] mOutputLayer;
-
- private final String[] mClasses;
-
- private final int mPatchSize;
-
- static final String GESTURE_FILE_NAME = "letters.gestures";
-
- private GestureLibrary mGestureLibrary;
- private final static int ADJUST_RANGE = 3;
-
- private static class SigmoidUnit {
- final float[] mWeights;
-
- SigmoidUnit(float[] weights) {
- mWeights = weights;
- }
-
- private float compute(float[] inputs) {
- float sum = 0;
-
- final int count = inputs.length;
- final float[] weights = mWeights;
-
- for (int i = 0; i < count; i++) {
- sum += inputs[i] * weights[i];
- }
- sum += weights[weights.length - 1];
-
- return 1.0f / (float) (1 + Math.exp(-sum));
- }
- }
-
- private LetterRecognizer(int numOfInput, int numOfHidden, String[] classes) {
- mPatchSize = (int)Math.sqrt(numOfInput);
- mHiddenLayer = new SigmoidUnit[numOfHidden];
- mClasses = classes;
- mOutputLayer = new SigmoidUnit[classes.length];
- }
-
- public void save() {
- mGestureLibrary.save();
- }
-
- public static LetterRecognizer getLetterRecognizer(Context context, int type) {
- switch (type) {
- case LATIN_LOWERCASE: {
- return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
- }
- }
- return null;
- }
-
- public ArrayList<Prediction> recognize(Gesture gesture) {
- float[] query = GestureUtilities.spatialSampling(gesture, mPatchSize);
- ArrayList<Prediction> predictions = classify(query);
- if (mGestureLibrary != null) {
- adjustPrediction(gesture, predictions);
- }
- return predictions;
- }
-
- private ArrayList<Prediction> classify(float[] vector) {
- final float[] intermediateOutput = compute(mHiddenLayer, vector);
- final float[] output = compute(mOutputLayer, intermediateOutput);
- final ArrayList<Prediction> predictions = new ArrayList<Prediction>();
-
- double sum = 0;
-
- final String[] classes = mClasses;
- final int count = classes.length;
-
- for (int i = 0; i < count; i++) {
- double score = output[i];
- sum += score;
- predictions.add(new Prediction(classes[i], score));
- }
-
- for (int i = 0; i < count; i++) {
- predictions.get(i).score /= sum;
- }
-
- Collections.sort(predictions, new Comparator<Prediction>() {
- public int compare(Prediction object1, Prediction object2) {
- double score1 = object1.score;
- double score2 = object2.score;
- if (score1 > score2) {
- return -1;
- } else if (score1 < score2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- return predictions;
- }
-
- private float[] compute(SigmoidUnit[] layer, float[] input) {
- final float[] output = new float[layer.length];
- final int count = layer.length;
-
- for (int i = 0; i < count; i++) {
- output[i] = layer[i].compute(input);
- }
-
- return output;
- }
-
- private static LetterRecognizer createFromResource(Context context, int resourceID) {
- final Resources resources = context.getResources();
-
- DataInputStream in = null;
- LetterRecognizer classifier = null;
-
- try {
- in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID),
- GestureConstants.IO_BUFFER_SIZE));
-
- final int iCount = in.readInt();
- final int hCount = in.readInt();
- final int oCount = in.readInt();
-
- final String[] classes = new String[oCount];
- for (int i = 0; i < classes.length; i++) {
- classes[i] = in.readUTF();
- }
-
- classifier = new LetterRecognizer(iCount, hCount, classes);
- SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount];
- SigmoidUnit[] outputLayer = new SigmoidUnit[oCount];
-
- for (int i = 0; i < hCount; i++) {
- float[] weights = new float[iCount + 1];
- for (int j = 0; j <= iCount; j++) {
- weights[j] = in.readFloat();
- }
- hiddenLayer[i] = new SigmoidUnit(weights);
- }
-
- for (int i = 0; i < oCount; i++) {
- float[] weights = new float[hCount + 1];
- for (int j = 0; j <= hCount; j++) {
- weights[j] = in.readFloat();
- }
- outputLayer[i] = new SigmoidUnit(weights);
- }
-
- classifier.mHiddenLayer = hiddenLayer;
- classifier.mOutputLayer = outputLayer;
-
- } catch (IOException e) {
- Log.d(LOG_TAG, "Failed to load handwriting data:", e);
- } finally {
- GestureUtilities.closeStream(in);
- }
-
- return classifier;
- }
-
- public void enablePersonalization(boolean enable) {
- if (enable) {
- mGestureLibrary = new GestureLibrary(GESTURE_FILE_NAME);
- mGestureLibrary.setSequenceType(GestureLibrary.SEQUENCE_INVARIANT);
- mGestureLibrary.load();
- } else {
- mGestureLibrary = null;
- }
- }
-
- public void addExample(String letter, Gesture example) {
- mGestureLibrary.addGesture(letter, example);
- }
-
- private void adjustPrediction(Gesture query, ArrayList<Prediction> predictions) {
- ArrayList<Prediction> results = mGestureLibrary.recognize(query);
- HashMap<String, Prediction> topNList = new HashMap<String, Prediction>();
- for (int j = 0; j < ADJUST_RANGE; j++) {
- Prediction prediction = predictions.remove(0);
- topNList.put(prediction.name, prediction);
- }
- int count = results.size();
- for (int j = count - 1; j >= 0 && !topNList.isEmpty(); j--) {
- Prediction item = results.get(j);
- Prediction original = topNList.get(item.name);
- if (original != null) {
- predictions.add(0, original);
- topNList.remove(item.name);
- }
- }
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
deleted file mode 100644
index a07d125..0000000
--- a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.Matrix;
-import android.graphics.Path;
-
-/**
- * An oriented bounding box
- */
-public class OrientedBoundingBox {
- public final float squareness;
-
- public final float width;
- public final float height;
-
- public final float orientation;
-
- public final float centerX;
- public final float centerY;
-
- OrientedBoundingBox(float angle, float cx, float cy, float w, float h) {
- orientation = angle;
- width = w;
- height = h;
- centerX = cx;
- centerY = cy;
- float ratio = w / h;
- if (ratio > 1) {
- squareness = 1 / ratio;
- } else {
- squareness = ratio;
- }
- }
-
- public Path toPath() {
- Path path = new Path();
- float[] point = new float[2];
- point[0] = -width / 2;
- point[1] = height / 2;
- Matrix matrix = new Matrix();
- matrix.setRotate(orientation);
- matrix.postTranslate(centerX, centerY);
- matrix.mapPoints(point);
- path.moveTo(point[0], point[1]);
-
- point[0] = -width / 2;
- point[1] = -height / 2;
- matrix.mapPoints(point);
- path.lineTo(point[0], point[1]);
-
- point[0] = width / 2;
- point[1] = -height / 2;
- matrix.mapPoints(point);
- path.lineTo(point[0], point[1]);
-
- point[0] = width / 2;
- point[1] = height / 2;
- matrix.mapPoints(point);
- path.lineTo(point[0], point[1]);
-
- path.close();
-
- return path;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/Prediction.java b/tests/sketch/src/com/android/gesture/Prediction.java
deleted file mode 100755
index 92d3ba4..0000000
--- a/tests/sketch/src/com/android/gesture/Prediction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-public class Prediction {
- public final String name;
-
- public double score;
-
- Prediction(String label, double predictionScore) {
- name = label;
- score = predictionScore;
- }
-
- @Override
- public String toString() {
- return name;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
deleted file mode 100644
index fc878c8..0000000
--- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * 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.android.gesture;
-
-import android.graphics.Color;
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * TouchThroughGesturing implements the interaction behavior that allows a user
- * to gesture over a regular UI widget such as ListView and at the same time,
- * still allows a user to perform basic interactions (clicking, scrolling and panning)
- * with the underlying widget.
- */
-
-public class TouchThroughGesturing implements GestureListener {
- public static final int SINGLE_STROKE = 0;
- public static final int MULTIPLE_STROKE = 1;
-
- private static final float STROKE_LENGTH_THRESHOLD = 30;
- private static final float SQUARENESS_THRESHOLD = 0.275f;
- private static final float ANGLE_THRESHOLD = 40;
-
- private static final boolean STEAL_EVENTS = false;
-
- public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0);
-
- private boolean mIsGesturing = false;
-
- private float mTotalLength;
-
- private float mX;
- private float mY;
-
- // TODO: Use WeakReference?
- private View mModel;
-
- private int mGestureType = SINGLE_STROKE;
- private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR;
-
- // TODO: Use WeakReferences
- private final ArrayList<GestureActionListener> mActionListeners =
- new ArrayList<GestureActionListener>();
-
- public TouchThroughGesturing(View model) {
- mModel = model;
- }
-
- /**
- *
- * @param type SINGLE_STROKE or MULTIPLE_STROKE
- */
- public void setGestureType(int type) {
- mGestureType = type;
- }
-
- public void setUncertainGestureColor(int color) {
- mUncertainGestureColor = color;
- }
-
- public void onStartGesture(GestureOverlay overlay, MotionEvent event) {
- if (mGestureType == MULTIPLE_STROKE) {
- overlay.cancelFadingOut();
- }
-
- mX = event.getX();
- mY = event.getY();
- mTotalLength = 0;
- mIsGesturing = false;
-
- if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null
- || overlay.getCurrentGesture().getStrokesCount() == 0) {
- overlay.setGestureColor(mUncertainGestureColor);
- }
-
- mModel.dispatchTouchEvent(event);
- }
-
- public void onGesture(GestureOverlay overlay, MotionEvent event) {
- //noinspection PointlessBooleanExpression
- if (!STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
- }
-
- if (mIsGesturing) {
- return;
- }
-
- final float x = event.getX();
- final float y = event.getY();
- final float dx = x - mX;
- final float dy = y - mY;
-
- mTotalLength += (float)Math.sqrt(dx * dx + dy * dy);
- mX = x;
- mY = y;
-
- if (mTotalLength > STROKE_LENGTH_THRESHOLD) {
- final OrientedBoundingBox box =
- GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke());
- float angle = Math.abs(box.orientation);
- if (angle > 90) {
- angle = 180 - angle;
- }
- if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
- mIsGesturing = true;
- overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR);
- if (STEAL_EVENTS) {
- event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
- MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(),
- event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
- event.getDeviceId(), event.getEdgeFlags());
- }
- }
- }
-
- if (STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
- }
- }
-
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
- if (mIsGesturing) {
- overlay.clear(true);
-
- final ArrayList<GestureActionListener> listeners = mActionListeners;
- final int count = listeners.size();
-
- for (int i = 0; i < count; i++) {
- listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
- }
- } else {
- mModel.dispatchTouchEvent(event);
- overlay.clear(false);
- }
- }
-
- public void addGestureActionListener(GestureActionListener listener) {
- mActionListeners.add(listener);
- }
-
- public void removeGestureActionListener(GestureActionListener listener) {
- mActionListeners.remove(listener);
- }
-
- public boolean isGesturing() {
- return mIsGesturing;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index 6eb2f23..eda4224 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -30,12 +30,11 @@ import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureActionListener;
-import com.android.gesture.GestureOverlay;
-import com.android.gesture.LetterRecognizer;
-import com.android.gesture.Prediction;
-import com.android.gesture.TouchThroughGesturing;
+import android.gesture.Gesture;
+import android.gesture.GestureOverlayView;
+import android.gesture.LetterRecognizer;
+import android.gesture.Prediction;
+import android.gesture.TouchThroughGestureListener;
import java.util.ArrayList;
@@ -52,7 +51,7 @@ public class ContactListGestureOverlay extends Activity {
private ContactAdapter mContactAdapter;
- private TouchThroughGesturing mGestureProcessor;
+ private TouchThroughGestureListener mGestureProcessor;
private LetterRecognizer mRecognizer;
@@ -67,7 +66,7 @@ public class ContactListGestureOverlay extends Activity {
setProgressBarIndeterminateVisibility(true);
// create a letter recognizer
- mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE);
+ mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
// load the contact list
mContactList = (ListView) findViewById(R.id.list);
@@ -95,11 +94,11 @@ public class ContactListGestureOverlay extends Activity {
setProgressBarIndeterminateVisibility(false);
// add a gesture overlay on top of the ListView
- GestureOverlay overlay = new GestureOverlay(this);
- mGestureProcessor = new TouchThroughGesturing(mContactList);
- mGestureProcessor.setGestureType(TouchThroughGesturing.MULTIPLE_STROKE);
- mGestureProcessor.addGestureActionListener(new GestureActionListener() {
- public void onGesturePerformed(GestureOverlay overlay, Gesture gesture) {
+ GestureOverlayView overlay = new GestureOverlayView(this);
+ mGestureProcessor = new TouchThroughGestureListener(mContactList);
+ mGestureProcessor.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE);
+ mGestureProcessor.addOnGestureActionListener(new TouchThroughGestureListener.OnGesturePerformedListener() {
+ public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mRecognizer.recognize(gesture);
if (!predictions.isEmpty()) {
Log.v(LOGTAG, "1st Prediction : " + predictions.get(0).name);
@@ -112,7 +111,7 @@ public class ContactListGestureOverlay extends Activity {
}
}
});
- overlay.addGestureListener(mGestureProcessor);
+ overlay.addOnGestureListener(mGestureProcessor);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
this.addContentView(overlay, params);
diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
index 53ba481..200f89f 100644
--- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
@@ -34,12 +34,11 @@ import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.gesture.Gesture;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureLibrary;
-import com.android.gesture.GestureListener;
-import com.android.gesture.GestureOverlay;
-import com.android.gesture.Prediction;
+import android.gesture.GestureLibrary;
+import android.gesture.GestureOverlayView;
+import android.gesture.Prediction;
import java.io.File;
import java.util.ArrayList;
@@ -57,7 +56,7 @@ public class GestureEntry extends Activity {
private static final int VIEW_ID = Menu.FIRST + 1;
- private GestureOverlay mGesturePad;
+ private GestureOverlayView mGesturePad;
private Spinner mRecognitionResult;
@@ -96,17 +95,17 @@ public class GestureEntry extends Activity {
});
// create the area for drawing a gesture
- mGesturePad = (GestureOverlay) findViewById(R.id.drawingpad);
+ mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
mGesturePad.setBackgroundColor(Color.BLACK);
- mGesturePad.addGestureListener(new GestureListener() {
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
+ mGesturePad.addOnGestureListener(new GestureOverlayView.OnGestureListener() {
+ public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
recognize(overlay.getCurrentGesture());
}
- public void onGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGesture(GestureOverlayView overlay, MotionEvent event) {
}
- public void onStartGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
overlay.clear(false);
}
});
diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
index ca54110..aa07e7b 100755
--- a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
@@ -26,10 +26,10 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.gesture.Gesture;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureLibrary;
-import com.android.gesture.GestureOverlay;
+import android.gesture.GestureLibrary;
+import android.gesture.GestureOverlayView;
import java.util.ArrayList;
import java.util.Collections;
@@ -41,7 +41,7 @@ import java.util.Collections;
public class GestureLibViewer extends Activity {
- private GestureOverlay mGesturePad;
+ private GestureOverlayView mGesturePad;
private Spinner mGestureCategory;
@@ -90,7 +90,7 @@ public class GestureLibViewer extends Activity {
setContentView(R.layout.gestureviewer);
// create the area for drawing a gesture
- mGesturePad = (GestureOverlay) findViewById(R.id.drawingpad);
+ mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
mGesturePad.setEnabled(false);
// init the gesture library