summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rwxr-xr-xtests/sketch/src/com/android/gesture/Gesture.java35
-rw-r--r--tests/sketch/src/com/android/gesture/GestureActionListener.java1
-rw-r--r--tests/sketch/src/com/android/gesture/GestureConstants.java1
-rw-r--r--tests/sketch/src/com/android/gesture/GestureLibrary.java121
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureOverlay.java80
-rw-r--r--tests/sketch/src/com/android/gesture/GesturePoint.java9
-rw-r--r--tests/sketch/src/com/android/gesture/GestureStroke.java95
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureUtilities.java (renamed from tests/sketch/src/com/android/gesture/GestureUtils.java)60
-rwxr-xr-xtests/sketch/src/com/android/gesture/Instance.java12
-rw-r--r--tests/sketch/src/com/android/gesture/InstanceLearner.java4
-rwxr-xr-xtests/sketch/src/com/android/gesture/Learner.java17
-rw-r--r--tests/sketch/src/com/android/gesture/LetterRecognizer.java128
-rw-r--r--tests/sketch/src/com/android/gesture/OrientedBoundingBox.java1
-rw-r--r--tests/sketch/src/com/android/gesture/TouchThroughGesturing.java47
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java2
-rw-r--r--tests/sketch/tools/Converter.java222
16 files changed, 539 insertions, 296 deletions
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/tests/sketch/src/com/android/gesture/Gesture.java
index a5e7a25..44711ca 100755
--- a/tests/sketch/src/com/android/gesture/Gesture.java
+++ b/tests/sketch/src/com/android/gesture/Gesture.java
@@ -34,13 +34,11 @@ import java.util.ArrayList;
*/
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;
@@ -50,7 +48,7 @@ public class Gesture implements Parcelable {
// the same as its instance ID
private long mGestureID;
- private ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();
+ private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();
public Gesture() {
mGestureID = GESTURE_ID_BASE + sGestureCount++;
@@ -93,12 +91,13 @@ public class Gesture implements Parcelable {
*/
public float getLength() {
int len = 0;
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- len += stroke.length;
+ len += strokes.get(i).length;
}
+
return len;
}
@@ -131,11 +130,11 @@ public class Gesture implements Parcelable {
* @param canvas
*/
void draw(Canvas canvas, Paint paint) {
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- stroke.draw(canvas, paint);
+ strokes.get(i).draw(canvas, paint);
}
}
@@ -150,7 +149,6 @@ public class Gesture implements Parcelable {
* @return the bitmap
*/
public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) {
- RectF bbx = getBoundingBox();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.translate(edge, edge);
@@ -162,11 +160,12 @@ public class Gesture implements Parcelable {
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- Path path = stroke.toPath(width - 2 * edge, height - 2 * edge, numSample);
+ Path path = strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample);
canvas.drawPath(path, paint);
}
@@ -183,7 +182,6 @@ public class Gesture implements Parcelable {
* @return the bitmap
*/
public Bitmap toBitmap(int width, int height, int edge, int color) {
- RectF bbx = getBoundingBox();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.translate(edge, edge);
@@ -232,7 +230,8 @@ public class Gesture implements Parcelable {
public void createFromString(String str) {
int startIndex = 0;
int endIndex;
- while ((endIndex = str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) {
+ while ((endIndex =
+ str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) {
String token = str.substring(startIndex, endIndex);
if (startIndex > 0) { // stroke tokens
addStroke(GestureStroke.createFromString(token));
diff --git a/tests/sketch/src/com/android/gesture/GestureActionListener.java b/tests/sketch/src/com/android/gesture/GestureActionListener.java
index 130ac19..c9c5232 100644
--- a/tests/sketch/src/com/android/gesture/GestureActionListener.java
+++ b/tests/sketch/src/com/android/gesture/GestureActionListener.java
@@ -16,7 +16,6 @@
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
index 0e17c8a..cb64791 100644
--- a/tests/sketch/src/com/android/gesture/GestureConstants.java
+++ b/tests/sketch/src/com/android/gesture/GestureConstants.java
@@ -28,4 +28,5 @@ interface GestureConstants {
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 = 8 * 1024; // 8K
+ String LOG_TAG = "GestureLibrary";
}
diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java
index c89aa16..3e753e7 100644
--- a/tests/sketch/src/com/android/gesture/GestureLibrary.java
+++ b/tests/sketch/src/com/android/gesture/GestureLibrary.java
@@ -36,36 +36,33 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Set;
+import static com.android.gesture.GestureConstants.LOG_TAG;
+
/**
* GestureLibrary maintains gesture examples and makes predictions on a new
* gesture
*/
public class GestureLibrary {
- public static final int SEQUENCE_INVARIANT = 1;
+ private static final String NAMESPACE = "";
+ public static final int SEQUENCE_INVARIANT = 1;
// when SEQUENCE_SENSITIVE is used, only single stroke gestures are allowed
public static final int SEQUENCE_SENSITIVE = 2;
- private int mSequenceType = SEQUENCE_SENSITIVE;
-
public static final int ORIENTATION_INVARIANT = 1;
-
// ORIENTATION_SENSITIVE is only available for single stroke gestures
public static final int ORIENTATION_SENSITIVE = 2;
+ private int mSequenceType = SEQUENCE_SENSITIVE;
private int mOrientationStyle = ORIENTATION_SENSITIVE;
- private static final String LOGTAG = "GestureLibrary";
-
- private static final String NAMESPACE = "";
-
private final String mGestureFileName;
- private HashMap<String, ArrayList<Gesture>> mEntryName2gestures = new HashMap<String, ArrayList<Gesture>>();
+ private final HashMap<String, ArrayList<Gesture>> mEntryName2gestures =
+ new HashMap<String, ArrayList<Gesture>>();
private Learner mClassifier;
@@ -128,9 +125,6 @@ public class GestureLibrary {
* @param gesture
*/
public void addGesture(String entryName, Gesture gesture) {
- if (Config.DEBUG) {
- Log.v(LOGTAG, "Add an example for gesture: " + entryName);
- }
if (entryName == null || entryName.length() == 0) {
return;
}
@@ -186,11 +180,10 @@ public class GestureLibrary {
* @param entryName
* @return the list of gestures that is under this name
*/
- @SuppressWarnings("unchecked")
public ArrayList<Gesture> getGestures(String entryName) {
ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName);
if (gestures != null) {
- return (ArrayList<Gesture>)gestures.clone();
+ return new ArrayList<Gesture>(gestures);
} else {
return null;
}
@@ -199,30 +192,33 @@ public class GestureLibrary {
/**
* Save the gesture library
*/
- public void save() {
- if (!mChanged)
- return;
+ public boolean save() {
+ if (!mChanged) {
+ return true;
+ }
+
+ boolean result= false;
+ PrintWriter writer = null;
try {
File file = new File(mGestureFileName);
if (!file.getParentFile().exists()) {
- file.getParentFile().mkdirs();
- }
- if (Config.DEBUG) {
- Log.v(LOGTAG, "Save to " + mGestureFileName);
+ if (!file.getParentFile().mkdirs()) {
+ return false;
+ }
}
- BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(
- mGestureFileName), GestureConstants.IO_BUFFER_SIZE);
- PrintWriter writer = new PrintWriter(outputStream);
- XmlSerializer serializer = Xml.newSerializer();
+ writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(
+ mGestureFileName), GestureConstants.IO_BUFFER_SIZE));
+
+ final XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(writer);
serializer.startDocument(Encoding.ISO_8859_1.name(), null);
serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
- HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures;
- Iterator<String> it = maps.keySet().iterator();
- while (it.hasNext()) {
- String key = it.next();
+
+ final HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures;
+
+ for (String key : maps.keySet()) {
ArrayList<Gesture> examples = maps.get(key);
// save an entry
serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
@@ -235,53 +231,64 @@ public class GestureLibrary {
}
serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
}
+
serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
serializer.endDocument();
serializer.flush();
- writer.close();
- outputStream.close();
+
mChanged = false;
+ result = true;
} catch (IOException ex) {
- Log.d(LOGTAG, "Failed to save gestures:", ex);
+ Log.d(LOG_TAG, "Failed to save gestures:", ex);
+ } finally {
+ GestureUtilities.closeStream(writer);
}
+
+ return result;
}
/**
* Load the gesture library
*/
- public void load() {
- File file = new File(mGestureFileName);
+ public boolean load() {
+ boolean result = false;
+
+ final File file = new File(mGestureFileName);
if (file.exists()) {
+ BufferedInputStream in = null;
try {
if (Config.DEBUG) {
- Log.v(LOGTAG, "Load from " + mGestureFileName);
+ Log.v(LOG_TAG, "Load from " + mGestureFileName);
}
- BufferedInputStream in = new BufferedInputStream(new FileInputStream(
+ in = new BufferedInputStream(new FileInputStream(
mGestureFileName), GestureConstants.IO_BUFFER_SIZE);
Xml.parse(in, Encoding.ISO_8859_1, new CompactInkHandler());
- in.close();
+ result = true;
} catch (SAXException ex) {
- Log.d(LOGTAG, "Failed to load gestures:", ex);
+ Log.d(LOG_TAG, "Failed to load gestures:", ex);
} catch (IOException ex) {
- Log.d(LOGTAG, "Failed to load gestures:", ex);
+ Log.d(LOG_TAG, "Failed to load gestures:", ex);
+ } finally {
+ GestureUtilities.closeStream(in);
}
}
+
+ return result;
}
private class CompactInkHandler implements ContentHandler {
- Gesture currentGesture = null;
-
- StringBuilder buffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
+ final StringBuilder mBuffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
- String entryName;
+ String mEntryName;
- ArrayList<Gesture> gestures;
+ Gesture mCurrentGesture = null;
+ ArrayList<Gesture> mGestures;
CompactInkHandler() {
}
public void characters(char[] ch, int start, int length) {
- buffer.append(ch, start, length);
+ mBuffer.append(ch, start, length);
}
public void endDocument() {
@@ -289,16 +296,16 @@ public class GestureLibrary {
public void endElement(String uri, String localName, String qName) {
if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
- mEntryName2gestures.put(entryName, gestures);
- gestures = null;
+ mEntryName2gestures.put(mEntryName, mGestures);
+ mGestures = null;
} else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
- gestures.add(currentGesture);
+ mGestures.add(mCurrentGesture);
mClassifier.addInstance(Instance.createInstance(GestureLibrary.this,
- currentGesture, entryName));
- currentGesture = null;
+ mCurrentGesture, mEntryName));
+ mCurrentGesture = null;
} else if (localName.equals(GestureConstants.XML_TAG_STROKE)) {
- currentGesture.addStroke(GestureStroke.createFromString(buffer.toString()));
- buffer.setLength(0);
+ mCurrentGesture.addStroke(GestureStroke.createFromString(mBuffer.toString()));
+ mBuffer.setLength(0);
}
}
@@ -322,11 +329,11 @@ public class GestureLibrary {
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
- gestures = new ArrayList<Gesture>();
- entryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME);
+ mGestures = new ArrayList<Gesture>();
+ mEntryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME);
} else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
- currentGesture = new Gesture();
- currentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE,
+ mCurrentGesture = new Gesture();
+ mCurrentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE,
GestureConstants.XML_TAG_ID)));
}
}
diff --git a/tests/sketch/src/com/android/gesture/GestureOverlay.java b/tests/sketch/src/com/android/gesture/GestureOverlay.java
index 9907831..72ab787 100755
--- a/tests/sketch/src/com/android/gesture/GestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/GestureOverlay.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
@@ -37,32 +36,32 @@ import java.util.ArrayList;
*/
public class GestureOverlay extends View {
-
static final float TOUCH_TOLERANCE = 3;
- private static final int TRANSPARENT_BACKGROUND = Color.argb(0, 0, 0, 0);
+ // TODO: Move all these values into XML attributes
+ private static final int TRANSPARENT_BACKGROUND = 0x00000000;
private static final float FADING_ALPHA_CHANGE = 0.03f;
-
private static final long FADING_REFRESHING_RATE = 100;
private static final int GESTURE_STROKE_WIDTH = 12;
-
private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
- private static final BlurMaskFilter BLUR_MASK_FILTER = new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);
-
private static final boolean DITHER_FLAG = true;
+ public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00;
+
private static final int REFRESH_RANGE = 10;
- public static final int DEFAULT_GESTURE_COLOR = Color.argb(255, 255, 255, 0);
+ 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
@@ -71,31 +70,25 @@ public class GestureOverlay extends View {
private Path mPath;
private float mX;
-
private float mY;
private float mCurveEndX;
-
private float mCurveEndY;
// current gesture
private Gesture mCurrentGesture = null;
- // gesture event handlers
- ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>();
-
+ // 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 Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
-
- private Runnable mFadingOut = new Runnable() {
+ private final Runnable mFadingOut = new Runnable() {
public void run() {
if (mIsFadingOut) {
mFadingAlpha -= FADING_ALPHA_CHANGE;
@@ -165,13 +158,15 @@ public class GestureOverlay extends View {
private void init() {
mGesturePaint = new Paint();
- mGesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
- mGesturePaint.setColor(DEFAULT_GESTURE_COLOR);
- mGesturePaint.setStyle(Paint.Style.STROKE);
- mGesturePaint.setStrokeJoin(Paint.Join.ROUND);
- mGesturePaint.setStrokeCap(Paint.Cap.ROUND);
- mGesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
- mGesturePaint.setDither(DITHER_FLAG);
+
+ 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;
}
@@ -179,14 +174,24 @@ public class GestureOverlay extends View {
@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);
- mBitmapCanvas = new Canvas(mBitmap);
+ if (mBitmapCanvas != null) {
+ mBitmapCanvas.setBitmap(mBitmap);
+ } else {
+ mBitmapCanvas = new Canvas(mBitmap);
+ }
mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND);
+
if (mCurrentGesture != null) {
mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
}
@@ -248,7 +253,6 @@ public class GestureOverlay extends View {
@Override
public boolean onTouchEvent(MotionEvent event) {
-
if (!isEnabled()) {
return true;
}
@@ -275,8 +279,8 @@ public class GestureOverlay extends View {
private Rect touchStart(MotionEvent event) {
// pass the event to handlers
- ArrayList<GestureListener> listeners = mGestureListeners;
- int count = listeners.size();
+ 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);
@@ -306,8 +310,8 @@ public class GestureOverlay extends View {
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);
+ mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE,
+ (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE);
mCurveEndX = x;
mCurveEndY = y;
@@ -352,11 +356,10 @@ public class GestureOverlay extends View {
mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
// pass the event to handlers
- ArrayList<GestureListener> listeners = mGestureListeners;
- int count = listeners.size();
+ final ArrayList<GestureListener> listeners = mGestureListeners;
+ final int count = listeners.size();
for (int i = 0; i < count; i++) {
- GestureListener listener = listeners.get(i);
- listener.onGesture(this, event);
+ listeners.get(i).onGesture(this, event);
}
return areaToRefresh;
@@ -372,11 +375,10 @@ public class GestureOverlay extends View {
mGesturePaint.setMaskFilter(null);
// pass the event to handlers
- ArrayList<GestureListener> listeners = mGestureListeners;
- int count = listeners.size();
+ final ArrayList<GestureListener> listeners = mGestureListeners;
+ final int count = listeners.size();
for (int i = 0; i < count; i++) {
- GestureListener listener = listeners.get(i);
- listener.onFinishGesture(this, event);
+ listeners.get(i).onFinishGesture(this, event);
}
mPath = null;
diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/tests/sketch/src/com/android/gesture/GesturePoint.java
index d06eff47..81e59a4 100644
--- a/tests/sketch/src/com/android/gesture/GesturePoint.java
+++ b/tests/sketch/src/com/android/gesture/GesturePoint.java
@@ -21,15 +21,14 @@ package com.android.gesture;
*/
public class GesturePoint {
- public final float xpos;
-
- public final float ypos;
+ public final float x;
+ public final float y;
public final long timestamp;
public GesturePoint(float x, float y, long t) {
- xpos = x;
- ypos = y;
+ this.x = x;
+ this.y = y;
timestamp = t;
}
}
diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/tests/sketch/src/com/android/gesture/GestureStroke.java
index b5e38b7..3555010 100644
--- a/tests/sketch/src/com/android/gesture/GestureStroke.java
+++ b/tests/sketch/src/com/android/gesture/GestureStroke.java
@@ -34,50 +34,48 @@ 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 pts
+ * @param points
*/
- public GestureStroke(ArrayList<GesturePoint> pts) {
- float[] tmpPoints = new float[pts.size() * 2];
- long[] times = new long[pts.size()];
+ 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;
- int count = pts.size();
for (int i = 0; i < count; i++) {
- GesturePoint p = pts.get(i);
- tmpPoints[i * 2] = p.xpos;
- tmpPoints[i * 2 + 1] = p.ypos;
+ 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.ypos;
- bx.left = p.xpos;
- bx.right = p.xpos;
- bx.bottom = p.ypos;
+ 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.xpos - tmpPoints[(i - 1) * 2], 2)
- + Math.pow(p.ypos - tmpPoints[(i -1 ) * 2 + 1], 2));
- bx.union(p.xpos, p.ypos);
+ 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;
- points = tmpPoints;
+ this.points = tmpPoints;
boundingBox = bx;
length = len;
}
@@ -89,13 +87,17 @@ public class GestureStroke {
*/
void draw(Canvas canvas, Paint paint) {
if (mCachedPath == null) {
- float[] pts = points;
- int count = pts.length;
+ final float[] localPoints = points;
+ final int count = localPoints.length;
+
Path path = null;
- float mX = 0, mY = 0;
+
+ float mX = 0;
+ float mY = 0;
+
for (int i = 0; i < count; i += 2) {
- float x = pts[i];
- float y = pts[i + 1];
+ float x = localPoints[i];
+ float y = localPoints[i + 1];
if (path == null) {
path = new Path();
path.moveTo(x, y);
@@ -127,22 +129,22 @@ public class GestureStroke {
* @return the path
*/
public Path toPath(float width, float height, int numSample) {
- float[] pts = GestureUtils.temporalSampling(this, numSample);
- RectF rect = boundingBox;
- float scale = height / rect.height();
- Matrix matrix = new Matrix();
+ 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 scaleMatrix = new Matrix();
- scaleMatrix.setScale(scale, scale);
- matrix.postConcat(scaleMatrix);
- Matrix translate = new Matrix();
- matrix.postConcat(translate);
+ matrix.postScale(scale, scale);
matrix.mapPoints(pts);
- Path path = null;
float mX = 0;
float mY = 0;
- int count = pts.length;
+
+ 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];
@@ -161,6 +163,7 @@ public class GestureStroke {
}
}
}
+
return path;
}
@@ -184,11 +187,14 @@ public class GestureStroke {
* @return the gesture stroke
*/
public static GestureStroke createFromString(String str) {
- ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(
+ final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(
GestureConstants.STROKE_POINT_BUFFER_SIZE);
+
int endIndex;
int startIndex = 0;
- while ((endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) {
+
+ while ((endIndex =
+ str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) {
// parse x
String token = str.substring(startIndex, endIndex);
@@ -209,6 +215,7 @@ public class GestureStroke {
points.add(new GesturePoint(x, y, time));
}
+
return new GestureStroke(points);
}
@@ -217,15 +224,17 @@ public class GestureStroke {
*/
@Override
public String toString() {
- StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
- float[] pts = points;
- long[] times = timestamps;
- int count = points.length;
+ 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(points[i] + GestureConstants.STRING_STROKE_DELIIMITER + points[i + 1]
- + GestureConstants.STRING_STROKE_DELIIMITER + times[i / 2]
- + GestureConstants.STRING_STROKE_DELIIMITER);
+ 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();
}
diff --git a/tests/sketch/src/com/android/gesture/GestureUtils.java b/tests/sketch/src/com/android/gesture/GestureUtilities.java
index 09d2625..2798616 100755
--- a/tests/sketch/src/com/android/gesture/GestureUtils.java
+++ b/tests/sketch/src/com/android/gesture/GestureUtilities.java
@@ -17,15 +17,37 @@
package com.android.gesture;
import android.graphics.RectF;
+import android.graphics.Matrix;
import java.util.ArrayList;
import java.util.Arrays;
+import java.io.Closeable;
+import java.io.IOException;
-public class GestureUtils {
+import static com.android.gesture.GestureConstants.*;
+public final class GestureUtilities {
private static final int TEMPORAL_SAMPLING_RATE = 16;
-
- protected static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
+
+ 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) {
+ android.util.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);
@@ -120,7 +142,6 @@ public class GestureUtils {
return sample;
}
-
private static void plot(float x, float y, float[] sample, int sampleSize) {
x = x < 0 ? 0 : x;
y = y < 0 ? 0 : y;
@@ -175,7 +196,7 @@ public class GestureUtils {
* @param sampleSize
* @return a float array
*/
- protected static float[] temporalSampling(GestureStroke stroke, int sampleSize) {
+ static float[] temporalSampling(GestureStroke stroke, int sampleSize) {
final float increment = stroke.length / (sampleSize - 1);
int vectorLength = sampleSize * 2;
float[] vector = new float[vectorLength];
@@ -237,7 +258,7 @@ public class GestureUtils {
* @param points
* @return the centroid
*/
- public static float[] computeCentroid(float[] points) {
+ static float[] computeCentroid(float[] points) {
float centerX = 0;
float centerY = 0;
int count = points.length;
@@ -283,7 +304,7 @@ public class GestureUtils {
return array;
}
- public static float computeTotalLength(float[] points) {
+ static float computeTotalLength(float[] points) {
float sum = 0;
int count = points.length - 4;
for (int i = 0; i < count; i += 2) {
@@ -294,14 +315,14 @@ public class GestureUtils {
return sum;
}
- public static double computeStraightness(float[] points) {
+ 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;
}
- public static double computeStraightness(float[] points, float 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;
@@ -314,7 +335,7 @@ public class GestureUtils {
* @param vector2
* @return the distance
*/
- protected static double squaredEuclideanDistance(float[] vector1, float[] vector2) {
+ static double squaredEuclideanDistance(float[] vector1, float[] vector2) {
double squaredDistance = 0;
int size = vector1.length;
for (int i = 0; i < size; i++) {
@@ -331,7 +352,7 @@ public class GestureUtils {
* @param in2
* @return the distance between 0 and Math.PI
*/
- protected static double cosineDistance(Instance in1, Instance in2) {
+ static double cosineDistance(Instance in1, Instance in2) {
float sum = 0;
float[] vector1 = in1.vector;
float[] vector2 = in2.vector;
@@ -342,20 +363,19 @@ public class GestureUtils {
return Math.acos(sum / (in1.magnitude * in2.magnitude));
}
- public static OrientedBoundingBox computeOrientedBBX(ArrayList<GesturePoint> pts) {
+ public static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) {
GestureStroke stroke = new GestureStroke(pts);
float[] points = temporalSampling(stroke, TEMPORAL_SAMPLING_RATE);
- return computeOrientedBBX(points);
+ return computeOrientedBoundingBox(points);
}
- public static OrientedBoundingBox computeOrientedBBX(float[] points) {
+ public static OrientedBoundingBox computeOrientedBoundingBox(float[] points) {
float[] meanVector = computeCentroid(points);
- return computeOrientedBBX(points, meanVector);
+ return computeOrientedBoundingBox(points, meanVector);
}
- public static OrientedBoundingBox computeOrientedBBX(float[] points, float[] centroid) {
-
- android.graphics.Matrix tr = new android.graphics.Matrix();
+ public static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
+ Matrix tr = new Matrix();
tr.setTranslate(-centroid[0], -centroid[1]);
tr.mapPoints(points);
@@ -394,9 +414,7 @@ public class GestureUtils {
}
}
- OrientedBoundingBox bbx = new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx
- - minx, maxy - miny);
- return bbx;
+ return new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx - minx, maxy - miny);
}
private static double[] computeOrientation(double[][] covarianceMatrix) {
diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/tests/sketch/src/com/android/gesture/Instance.java
index 4fbebf9..011d1fc 100755
--- a/tests/sketch/src/com/android/gesture/Instance.java
+++ b/tests/sketch/src/com/android/gesture/Instance.java
@@ -21,7 +21,6 @@ package com.android.gesture;
* label is null.
*/
class Instance {
-
private static final int SEQUENCE_SAMPLE_SIZE = 16;
private static final int PATCH_SAMPLE_SIZE = 8;
@@ -40,10 +39,10 @@ class Instance {
final float magnitude;
// the id of the instance
- final long instanceID;
+ final long id;
private Instance(long id, float[] sample, String sampleName) {
- instanceID = id;
+ this.id = id;
vector = sample;
label = sampleName;
float sum = 0;
@@ -72,14 +71,13 @@ class Instance {
}
private static float[] spatialSampler(Gesture gesture) {
- float[] pts = GestureUtils.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
- return pts;
+ return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
}
private static float[] temporalSampler(GestureLibrary gesturelib, Gesture gesture) {
- float[] pts = GestureUtils.temporalSampling(gesture.getStrokes().get(0),
+ float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0),
SEQUENCE_SAMPLE_SIZE);
- float[] center = GestureUtils.computeCentroid(pts);
+ float[] center = GestureUtilities.computeCentroid(pts);
float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]);
orientation *= 180 / Math.PI;
diff --git a/tests/sketch/src/com/android/gesture/InstanceLearner.java b/tests/sketch/src/com/android/gesture/InstanceLearner.java
index 95241d4..335719a 100644
--- a/tests/sketch/src/com/android/gesture/InstanceLearner.java
+++ b/tests/sketch/src/com/android/gesture/InstanceLearner.java
@@ -46,9 +46,9 @@ class InstanceLearner extends Learner {
}
double distance;
if (lib.getGestureType() == GestureLibrary.SEQUENCE_SENSITIVE) {
- distance = GestureUtils.cosineDistance(sample, instance);
+ distance = GestureUtilities.cosineDistance(sample, instance);
} else {
- distance = GestureUtils.squaredEuclideanDistance(sample.vector, instance.vector);
+ distance = GestureUtilities.squaredEuclideanDistance(sample.vector, instance.vector);
}
double weight;
if (distance == 0) {
diff --git a/tests/sketch/src/com/android/gesture/Learner.java b/tests/sketch/src/com/android/gesture/Learner.java
index 63f3156..b4183d2 100755
--- a/tests/sketch/src/com/android/gesture/Learner.java
+++ b/tests/sketch/src/com/android/gesture/Learner.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
* The abstract class of a gesture learner
*/
abstract class Learner {
-
private final ArrayList<Instance> mInstances = new ArrayList<Instance>();
/**
@@ -53,7 +52,7 @@ abstract class Learner {
int count = instances.size();
for (int i = 0; i < count; i++) {
Instance instance = instances.get(i);
- if (id == instance.instanceID) {
+ if (id == instance.id) {
instances.remove(instance);
return;
}
@@ -66,16 +65,18 @@ abstract class Learner {
* @param name the category name
*/
void removeInstances(String name) {
- ArrayList<Instance> toDelete = new ArrayList<Instance>();
- ArrayList<Instance> instances = mInstances;
- int count = instances.size();
+ final ArrayList<Instance> toDelete = new ArrayList<Instance>();
+ final ArrayList<Instance> instances = mInstances;
+ final int count = instances.size();
+
for (int i = 0; i < count; i++) {
- Instance instance = instances.get(i);
- if (instance.label.equals(name)) {
+ 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);
}
}
- mInstances.removeAll(toDelete);
+ instances.removeAll(toDelete);
}
abstract ArrayList<Prediction> classify(GestureLibrary library, Instance instance);
diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
index 1c15c7d..73151de 100644
--- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java
+++ b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
@@ -20,45 +20,44 @@ import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class LetterRecognizer {
+ private static final String LOG_TAG = "LetterRecognizer";
- private static final String LOGTAG = "LetterRecognizer";
-
- public final static int LATTIN_LOWERCASE = 0;
+ public final static int LATIN_LOWERCASE = 0;
private SigmoidUnit[] mHiddenLayer;
-
private SigmoidUnit[] mOutputLayer;
private final String[] mClasses;
private final int mInputCount;
- private class SigmoidUnit {
-
- private float[] mWeights;
+ private static class SigmoidUnit {
+ final float[] mWeights;
- private SigmoidUnit(float[] weights) {
+ SigmoidUnit(float[] weights) {
mWeights = weights;
}
private float compute(float[] inputs) {
float sum = 0;
- int count = inputs.length;
- float[] weights = mWeights;
+
+ 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 / (float)(1 + Math.exp(-sum));
+
+ return 1.0f / (float) (1 + Math.exp(-sum));
}
}
@@ -71,33 +70,35 @@ public class LetterRecognizer {
public static LetterRecognizer getLetterRecognizer(Context context, int type) {
switch (type) {
- case LATTIN_LOWERCASE: {
- return createFromResource(context, com.android.internal.R.raw.lattin_lowercase);
+ case LATIN_LOWERCASE: {
+ return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
}
}
return null;
}
public ArrayList<Prediction> recognize(Gesture gesture) {
- return this.classify(GestureUtils.spatialSampling(gesture, mInputCount));
+ return classify(GestureUtilities.spatialSampling(gesture, mInputCount));
}
private ArrayList<Prediction> classify(float[] vector) {
- float[] intermediateOutput = compute(mHiddenLayer, vector);
- float[] output = compute(mOutputLayer, intermediateOutput);
- ArrayList<Prediction> predictions = new ArrayList<Prediction>();
+ final float[] intermediateOutput = compute(mHiddenLayer, vector);
+ final float[] output = compute(mOutputLayer, intermediateOutput);
+ final ArrayList<Prediction> predictions = new ArrayList<Prediction>();
+
double sum = 0;
- int count = mClasses.length;
+
+ final String[] classes = mClasses;
+ final int count = classes.length;
+
for (int i = 0; i < count; i++) {
- String name = mClasses[i];
double score = output[i];
sum += score;
- predictions.add(new Prediction(name, score));
+ predictions.add(new Prediction(classes[i], score));
}
for (int i = 0; i < count; i++) {
- Prediction name = predictions.get(i);
- name.score /= sum;
+ predictions.get(i).score /= sum;
}
Collections.sort(predictions, new Comparator<Prediction>() {
@@ -117,82 +118,63 @@ public class LetterRecognizer {
}
private float[] compute(SigmoidUnit[] layer, float[] input) {
- float[] output = new float[layer.length];
- int count = layer.length;
+ 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) {
- Resources resources = context.getResources();
- InputStream stream = resources.openRawResource(resourceID);
+ final Resources resources = context.getResources();
+
+ DataInputStream in = null;
+ LetterRecognizer classifier = null;
+
try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-
- String line = reader.readLine();
- int startIndex = 0;
- int endIndex = -1;
- endIndex = line.indexOf(" ", startIndex);
- int iCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- startIndex = endIndex + 1;
- endIndex = line.indexOf(" ", startIndex);
- int hCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- startIndex = endIndex + 1;
- endIndex = line.length();
- int oCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- String[] classes = new String[oCount];
- line = reader.readLine();
- startIndex = 0;
- endIndex = -1;
- for (int i = 0; i < oCount; i++) {
- endIndex = line.indexOf(" ", startIndex);
- classes[i] = line.substring(startIndex, endIndex);
- startIndex = endIndex + 1;
+ in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID)));
+
+ 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();
}
- LetterRecognizer classifier = new LetterRecognizer(iCount, hCount, classes);
+ 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];
- line = reader.readLine();
- startIndex = 0;
for (int j = 0; j < iCount; j++) {
- endIndex = line.indexOf(" ", startIndex);
- weights[j] = Float.parseFloat(line.substring(startIndex, endIndex));
- startIndex = endIndex + 1;
+ weights[j] = in.readFloat();
}
- hiddenLayer[i] = classifier.new SigmoidUnit(weights);
+ hiddenLayer[i] = new SigmoidUnit(weights);
}
for (int i = 0; i < oCount; i++) {
float[] weights = new float[hCount];
- line = reader.readLine();
- startIndex = 0;
for (int j = 0; j < hCount; j++) {
- endIndex = line.indexOf(" ", startIndex);
- weights[j] = Float.parseFloat(line.substring(startIndex, endIndex));
- startIndex = endIndex + 1;
+ weights[j] = in.readFloat();
}
- outputLayer[i] = classifier.new SigmoidUnit(weights);
+ outputLayer[i] = new SigmoidUnit(weights);
}
- reader.close();
-
classifier.mHiddenLayer = hiddenLayer;
classifier.mOutputLayer = outputLayer;
- return classifier;
-
- } catch (IOException ex) {
- Log.d(LOGTAG, "Failed to save gestures:", ex);
+ } catch (IOException e) {
+ Log.d(LOG_TAG, "Failed to load gestures:", e);
+ } finally {
+ GestureUtilities.closeStream(in);
}
- return null;
+
+ return classifier;
}
}
diff --git a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
index 90c3969..a07d125 100644
--- a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
+++ b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
@@ -23,7 +23,6 @@ import android.graphics.Path;
* An oriented bounding box
*/
public class OrientedBoundingBox {
-
public final float squareness;
public final float width;
diff --git a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
index 0ffc370..7fc7e28 100644
--- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
+++ b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
@@ -30,15 +30,11 @@ import java.util.ArrayList;
*/
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;
public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0);
@@ -47,15 +43,18 @@ public class TouchThroughGesturing implements GestureListener {
private float mTotalLength;
- private float mX, mY;
+ private float mX;
+ private float mY;
+ // TODO: Use WeakReference?
private View mModel;
private int mGestureType = SINGLE_STROKE;
-
private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR;
- private ArrayList<GestureActionListener> mActionListeners = new ArrayList<GestureActionListener>();
+ // TODO: Use WeakReferences
+ private final ArrayList<GestureActionListener> mActionListeners =
+ new ArrayList<GestureActionListener>();
public TouchThroughGesturing(View model) {
mModel = model;
@@ -77,14 +76,17 @@ public class TouchThroughGesturing implements GestureListener {
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);
}
@@ -92,40 +94,45 @@ public class TouchThroughGesturing implements GestureListener {
if (mIsGesturing) {
return;
}
- float x = event.getX();
- float y = event.getY();
- float dx = x - mX;
- float dy = y - mY;
+
+ 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) {
- OrientedBoundingBox bbx = GestureUtils.computeOrientedBBX(overlay.getCurrentStroke());
- float angle = Math.abs(bbx.orientation);
+ final OrientedBoundingBox box =
+ GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke());
+ float angle = Math.abs(box.orientation);
if (angle > 90) {
angle = 180 - angle;
}
- if (bbx.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
+ if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
mIsGesturing = true;
overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR);
event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
- MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(), event
- .getMetaState(), event.getXPrecision(), event.getYPrecision(),
+ MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(),
+ event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
event.getDeviceId(), event.getEdgeFlags());
}
}
+
mModel.dispatchTouchEvent(event);
}
public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
if (mIsGesturing) {
overlay.clear(true);
- ArrayList<GestureActionListener> listeners = mActionListeners;
- int count = listeners.size();
+
+ final ArrayList<GestureActionListener> listeners = mActionListeners;
+ final int count = listeners.size();
+
for (int i = 0; i < count; i++) {
- GestureActionListener listener = listeners.get(i);
- listener.onGesturePerformed(overlay, overlay.getCurrentGesture());
+ listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
}
} else {
mModel.dispatchTouchEvent(event);
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index 1d3fdf3..fc26757 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -69,7 +69,7 @@ public class ContactListGestureOverlay extends Activity {
setProgressBarIndeterminateVisibility(true);
// create a letter recognizer
- mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATTIN_LOWERCASE);
+ mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE);
// load the contact list
mContactList = (ListView) findViewById(R.id.list);
diff --git a/tests/sketch/tools/Converter.java b/tests/sketch/tools/Converter.java
new file mode 100644
index 0000000..b4654f8
--- /dev/null
+++ b/tests/sketch/tools/Converter.java
@@ -0,0 +1,222 @@
+import java.io.File;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Closeable;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+
+/**
+ * Converts text-based letter stores to binary-based stores.
+ */
+public class Converter {
+ private final File mFile;
+
+ Converter(File file) {
+ mFile = file;
+ }
+
+ private void convert() {
+ boolean read = false;
+
+ String[] classes = null;
+ int iCount = 0;
+ int hCount = 0;
+ int oCount = 0;
+ float[][] iWeights = null;
+ float[][] oWeights = null;
+
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(mFile));
+
+ long start = System.nanoTime();
+
+ String line = reader.readLine();
+ int startIndex = 0;
+ int endIndex;
+ endIndex = line.indexOf(" ", startIndex);
+ iCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+ startIndex = endIndex + 1;
+ endIndex = line.indexOf(" ", startIndex);
+ hCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+ startIndex = endIndex + 1;
+ endIndex = line.length();
+ oCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+ classes = new String[oCount];
+ line = reader.readLine();
+ startIndex = 0;
+
+ for (int i = 0; i < oCount; i++) {
+ endIndex = line.indexOf(" ", startIndex);
+ classes[i] = line.substring(startIndex, endIndex);
+ startIndex = endIndex + 1;
+ }
+
+ iWeights = new float[hCount][];
+ for (int i = 0; i < hCount; i++) {
+ iWeights[i] = new float[iCount];
+ line = reader.readLine();
+ startIndex = 0;
+ for (int j = 0; j < iCount; j++) {
+ endIndex = line.indexOf(" ", startIndex);
+ iWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
+ startIndex = endIndex + 1;
+ }
+ }
+
+ oWeights = new float[oCount][];
+ for (int i = 0; i < oCount; i++) {
+ oWeights[i] = new float[hCount];
+ line = reader.readLine();
+ startIndex = 0;
+ for (int j = 0; j < hCount; j++) {
+ endIndex = line.indexOf(" ", startIndex);
+ oWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
+ startIndex = endIndex + 1;
+ }
+ }
+
+ long end = System.nanoTime();
+ System.out.println("time to read text file = " +
+ ((end - start) / 1000.0f / 1000.0f) + " ms");
+
+ read = true;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ close(reader);
+ }
+
+ if (read) {
+ boolean wrote = false;
+ DataOutputStream out = null;
+
+ try {
+ out = new DataOutputStream(new FileOutputStream(mFile));
+
+ out.writeInt(iCount);
+ out.writeInt(hCount);
+ out.writeInt(oCount);
+
+ for (String aClass : classes) {
+ out.writeUTF(aClass);
+ }
+
+ for (float[] weights : iWeights) {
+ for (float weight : weights) {
+ out.writeFloat(weight);
+ }
+ }
+
+ for (float[] weights : oWeights) {
+ for (float weight : weights) {
+ out.writeFloat(weight);
+ }
+ }
+
+ out.flush();
+
+ wrote = true;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ close(out);
+ }
+
+ if (wrote) {
+ DataInputStream in = null;
+
+ try {
+ in = new DataInputStream(new BufferedInputStream(new FileInputStream(mFile)));
+
+ long start = System.nanoTime();
+
+ iCount = in.readInt();
+ hCount = in.readInt();
+ oCount = in.readInt();
+
+ classes = new String[oCount];
+ for (int i = 0; i < classes.length; i++) {
+ classes[i] = in.readUTF();
+ }
+
+ iWeights = new float[hCount][];
+ for (int i = 0; i < iWeights.length; i++) {
+ iWeights[i] = new float[iCount];
+ for (int j = 0; j < iCount; j++) {
+ iWeights[i][j] = in.readFloat();
+ }
+ }
+
+ oWeights = new float[oCount][];
+ for (int i = 0; i < oWeights.length; i++) {
+ oWeights[i] = new float[hCount];
+ for (int j = 0; j < hCount; j++) {
+ oWeights[i][j] = in.readFloat();
+ }
+ }
+
+ long end = System.nanoTime();
+ System.out.println("time to read binary file = " +
+ ((end - start) / 1000.0f / 1000.0f) + " ms");
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ close(in);
+ }
+ }
+ }
+ }
+
+ private static void close(Closeable reader) {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ String fileName = args[0];
+ if (fileName != null) {
+ File file = new File(fileName);
+ if (!file.exists()) {
+ printHelp(fileName);
+ } else {
+ new Converter(file).convert();
+ }
+ } else {
+ printHelp(null);
+ }
+ }
+
+ private static void printHelp(String name) {
+ if (name == null) {
+ System.out.println("You must specify the name of the file to convert:");
+ } else {
+ System.out.println("The specified file does not exist: " + name);
+ }
+ System.out.println("java Converter [filename]");
+ System.out.println("");
+ System.out.println("\t[filename]\tPath to the file to convert. The file is replaced by "
+ + "the conversion result.");
+ }
+} \ No newline at end of file