diff options
-rw-r--r-- | core/java/android/gesture/GestureLibraries.java | 139 | ||||
-rw-r--r-- | core/java/android/gesture/GestureLibrary.java | 319 | ||||
-rw-r--r-- | core/java/android/gesture/GestureStore.java | 330 | ||||
-rwxr-xr-x | core/java/android/gesture/Instance.java | 4 | ||||
-rw-r--r-- | core/java/android/gesture/InstanceLearner.java | 2 | ||||
-rw-r--r-- | core/java/android/gesture/LetterRecognizer.java | 53 | ||||
-rw-r--r-- | core/java/android/gesture/LetterRecognizers.java | 65 | ||||
-rw-r--r-- | core/java/android/widget/AbsListView.java | 77 | ||||
-rw-r--r-- | tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java | 5 | ||||
-rw-r--r-- | tests/sketch/src/com/android/gesture/example/GestureEntry.java | 23 | ||||
-rwxr-xr-x | tests/sketch/src/com/android/gesture/example/GestureLibViewer.java | 31 |
11 files changed, 656 insertions, 392 deletions
diff --git a/core/java/android/gesture/GestureLibraries.java b/core/java/android/gesture/GestureLibraries.java new file mode 100644 index 0000000..2ce7a8e --- /dev/null +++ b/core/java/android/gesture/GestureLibraries.java @@ -0,0 +1,139 @@ +/* + * 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 android.gesture; + +import android.util.Log; +import static android.gesture.GestureConstants.*; +import android.content.Context; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.InputStream; +import java.lang.ref.WeakReference; + +public final class GestureLibraries { + private GestureLibraries() { + } + + public static GestureLibrary fromFile(String path) { + return fromFile(new File(path)); + } + + public static GestureLibrary fromFile(File path) { + return new FileGestureLibrary(path); + } + + public static GestureLibrary fromPrivateFile(Context context, String name) { + return fromFile(context.getFileStreamPath(name)); + } + + public static GestureLibrary fromRawResource(Context context, int resourceId) { + return new ResourceGestureLibrary(context, resourceId); + } + + private static class FileGestureLibrary extends GestureLibrary { + private final File mPath; + + public FileGestureLibrary(File path) { + mPath = path; + } + + @Override + public boolean isReadOnly() { + return !mPath.canWrite(); + } + + public boolean save() { + final File file = mPath; + if (!file.canWrite()) return false; + + if (!file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + return false; + } + } + + boolean result = false; + try { + mStore.save(new FileOutputStream(file), true); + result = true; + } catch (FileNotFoundException e) { + Log.d(LOG_TAG, "Could not save the gesture library in " + mPath, e); + } catch (IOException e) { + Log.d(LOG_TAG, "Could not save the gesture library in " + mPath, e); + } + + return result; + } + + public boolean load() { + boolean result = false; + final File file = mPath; + if (file.exists() && file.canRead()) { + try { + mStore.load(new FileInputStream(file), true); + result = true; + } catch (FileNotFoundException e) { + Log.d(LOG_TAG, "Could not load the gesture library from " + mPath, e); + } catch (IOException e) { + Log.d(LOG_TAG, "Could not load the gesture library from " + mPath, e); + } + } + + return result; + } + } + + private static class ResourceGestureLibrary extends GestureLibrary { + private final WeakReference<Context> mContext; + private final int mResourceId; + + public ResourceGestureLibrary(Context context, int resourceId) { + mContext = new WeakReference<Context>(context); + mResourceId = resourceId; + } + + @Override + public boolean isReadOnly() { + return true; + } + + public boolean save() { + return false; + } + + public boolean load() { + boolean result = false; + final Context context = mContext.get(); + if (context != null) { + final InputStream in = context.getResources().openRawResource(mResourceId); + try { + mStore.load(in, true); + result = true; + } catch (IOException e) { + Log.d(LOG_TAG, "Could not load the gesture library from raw resource " + + context.getResources().getResourceName(mResourceId), e); + } + } + + return result; + } + } +} diff --git a/core/java/android/gesture/GestureLibrary.java b/core/java/android/gesture/GestureLibrary.java index 9020d2b..a29c2c8 100644 --- a/core/java/android/gesture/GestureLibrary.java +++ b/core/java/android/gesture/GestureLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 The Android Open Source Project + * 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. @@ -14,337 +14,68 @@ * limitations under the License. */ -package android.gesture; -import android.util.Log; -import android.os.SystemClock; +package android.gesture; -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 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; +import java.util.ArrayList; - private int mSequenceType = SEQUENCE_SENSITIVE; - private int mOrientationStyle = ORIENTATION_SENSITIVE; +public abstract class GestureLibrary { + protected final GestureStore mStore; - private final String mGestureFileName; + protected GestureLibrary() { + mStore = new GestureStore(); + } - private final HashMap<String, ArrayList<Gesture>> mNamedGestures = - new HashMap<String, ArrayList<Gesture>>(); + public abstract boolean save(); - private Learner mClassifier; + public abstract boolean load(); - private boolean mChanged = false; + public boolean isReadOnly() { + return false; + } - /** - * @param path where gesture data is stored - */ - public GestureLibrary(String path) { - mGestureFileName = path; - mClassifier = new InstanceLearner(); + public Learner getLearner() { + return mStore.getLearner(); } - /** - * Specify how the gesture library will handle orientation. - * Use ORIENTATION_INVARIANT or ORIENTATION_SENSITIVE - * - * @param style - */ public void setOrientationStyle(int style) { - mOrientationStyle = style; + mStore.setOrientationStyle(style); } public int getOrientationStyle() { - return mOrientationStyle; + return mStore.getOrientationStyle(); } - /** - * @param type SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE - */ public void setSequenceType(int type) { - mSequenceType = type; + mStore.setSequenceType(type); } - /** - * @return SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE - */ public int getSequenceType() { - return mSequenceType; + return mStore.getSequenceType(); } - /** - * Get all the gesture entry names in the library - * - * @return a set of strings - */ public Set<String> getGestureEntries() { - return mNamedGestures.keySet(); + return mStore.getGestureEntries(); } - /** - * 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, mOrientationStyle, gesture, null); - return mClassifier.classify(mSequenceType, instance.vector); + return mStore.recognize(gesture); } - /** - * 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, mOrientationStyle, gesture, entryName)); - mChanged = true; + mStore.addGesture(entryName, gesture); } - /** - * 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; + mStore.removeGesture(entryName, gesture); } - /** - * Remove a entry of gestures - * - * @param entryName the entry name - */ public void removeEntry(String entryName) { - mNamedGestures.remove(entryName); - mClassifier.removeInstances(entryName); - mChanged = true; + mStore.removeEntry(entryName); } - /** - * 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, mOrientationStyle, gesture, name)); - } - - namedGestures.put(name, gestures); - } - } - - Learner getLearner() { - return mClassifier; + return mStore.getGestures(entryName); } } diff --git a/core/java/android/gesture/GestureStore.java b/core/java/android/gesture/GestureStore.java new file mode 100644 index 0000000..ddf1c83 --- /dev/null +++ b/core/java/android/gesture/GestureStore.java @@ -0,0 +1,330 @@ +/* + * 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 android.gesture; + +import android.util.Log; +import android.os.SystemClock; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Set; +import java.util.Map; + +import static android.gesture.GestureConstants.LOG_TAG; + +/** + * GestureLibrary maintains gesture examples and makes predictions on a new + * gesture + */ +// +// File format for GestureStore: +// +// 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 GestureStore { + 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 HashMap<String, ArrayList<Gesture>> mNamedGestures = + new HashMap<String, ArrayList<Gesture>>(); + + private Learner mClassifier; + + private boolean mChanged = false; + + public GestureStore() { + 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, + mOrientationStyle, 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, mOrientationStyle, 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 removeEntry(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 void save(OutputStream stream) throws IOException { + save(stream, false); + } + + public void save(OutputStream stream, boolean closeStream) throws IOException { + if (!mChanged) { + return; + } + + DataOutputStream out = null; + + try { + long start; + if (PROFILE_LOADING_SAVING) { + start = SystemClock.elapsedRealtime(); + } + + final HashMap<String, ArrayList<Gesture>> maps = mNamedGestures; + + out = new DataOutputStream((stream instanceof BufferedOutputStream) ? out : + new BufferedOutputStream(out, 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; + } finally { + if (closeStream) GestureUtilities.closeStream(out); + } + } + + /** + * Load the gesture library + */ + public void load(InputStream stream) throws IOException { + load(stream, false); + } + + public void load(InputStream stream, boolean closeStream) throws IOException { + DataInputStream in = null; + try { + in = new DataInputStream((stream instanceof BufferedInputStream) ? stream : + new BufferedInputStream(stream, 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"); + } + } finally { + if (closeStream) GestureUtilities.closeStream(in); + } + } + + 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, mOrientationStyle, gesture, name)); + } + + namedGestures.put(name, gestures); + } + } + + Learner getLearner() { + return mClassifier; + } +} diff --git a/core/java/android/gesture/Instance.java b/core/java/android/gesture/Instance.java index 9ac0a96..ef208ac 100755 --- a/core/java/android/gesture/Instance.java +++ b/core/java/android/gesture/Instance.java @@ -72,7 +72,7 @@ class Instance { static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) { float[] pts; Instance instance; - if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { + if (sequenceType == GestureStore.SEQUENCE_SENSITIVE) { pts = temporalSampler(orientationType, gesture); instance = new Instance(gesture.getID(), pts, label); instance.normalize(); @@ -94,7 +94,7 @@ class Instance { float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]); float adjustment = -orientation; - if (orientationType == GestureLibrary.ORIENTATION_SENSITIVE) { + if (orientationType == GestureStore.ORIENTATION_SENSITIVE) { int count = ORIENTATIONS.length; for (int i = 0; i < count; i++) { float delta = ORIENTATIONS[i] - orientation; diff --git a/core/java/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java index b6feb64..00cdadc 100644 --- a/core/java/android/gesture/InstanceLearner.java +++ b/core/java/android/gesture/InstanceLearner.java @@ -38,7 +38,7 @@ class InstanceLearner extends Learner { continue; } double distance; - if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { + if (sequenceType == GestureStore.SEQUENCE_SENSITIVE) { distance = GestureUtilities.cosineDistance(sample.vector, vector); } else { distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector); diff --git a/core/java/android/gesture/LetterRecognizer.java b/core/java/android/gesture/LetterRecognizer.java index 9e801ed..580fc26 100644 --- a/core/java/android/gesture/LetterRecognizer.java +++ b/core/java/android/gesture/LetterRecognizer.java @@ -23,6 +23,7 @@ import android.util.Log; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -31,10 +32,9 @@ import java.util.HashMap; import static android.gesture.GestureConstants.LOG_TAG; public class LetterRecognizer { - public final static int RECOGNIZER_LATIN_LOWERCASE = 0; static final String GESTURE_FILE_NAME = "letters.gestures"; - private final static int ADJUST_RANGE = 3; + private final static int ADJUST_RANGE = 3; private SigmoidUnit[] mHiddenLayer; private SigmoidUnit[] mOutputLayer; @@ -42,8 +42,8 @@ public class LetterRecognizer { private final String[] mClasses; private final int mPatchSize; - - private GestureLibrary mGestureLibrary; + + private GestureLibrary mGestureStore; private final Comparator<Prediction> mComparator = new PredictionComparator(); @@ -69,15 +69,6 @@ public class LetterRecognizer { } } - public static LetterRecognizer getLetterRecognizer(Context context, int type) { - switch (type) { - case RECOGNIZER_LATIN_LOWERCASE: { - return createFromResource(context, com.android.internal.R.raw.latin_lowercase); - } - } - return null; - } - private LetterRecognizer(int numOfInput, int numOfHidden, String[] classes) { mPatchSize = (int) Math.sqrt(numOfInput); mHiddenLayer = new SigmoidUnit[numOfHidden]; @@ -137,14 +128,18 @@ public class LetterRecognizer { return output; } - private static LetterRecognizer createFromResource(Context context, int resourceID) { + static LetterRecognizer createFromResource(Context context, int resourceID) { final Resources resources = context.getResources(); + final InputStream stream = resources.openRawResource(resourceID); + return createFromStream(stream); + } + static LetterRecognizer createFromStream(InputStream stream) { DataInputStream in = null; LetterRecognizer classifier = null; try { - in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID), + in = new DataInputStream(new BufferedInputStream(stream, GestureConstants.IO_BUFFER_SIZE)); final int version = in.readShort(); @@ -206,49 +201,49 @@ public class LetterRecognizer { } /** - * TODO: Publish this API once we figure out where we should save the personzlied + * TODO: Publish this API once we figure out where we should save the personalized * gestures, and how to do so across all apps * * @hide */ public boolean save() { - if (mGestureLibrary != null) { - return mGestureLibrary.save(); + if (mGestureStore != null) { + return mGestureStore.save(); } return false; } /** - * TODO: Publish this API once we figure out where we should save the personzlied + * TODO: Publish this API once we figure out where we should save the personalized * gestures, and how to do so across all apps * * @hide */ public void setPersonalizationEnabled(boolean enabled) { if (enabled) { - mGestureLibrary = new GestureLibrary(GESTURE_FILE_NAME); - mGestureLibrary.setSequenceType(GestureLibrary.SEQUENCE_INVARIANT); - mGestureLibrary.load(); + mGestureStore = GestureLibraries.fromFile(GESTURE_FILE_NAME); + mGestureStore.setSequenceType(GestureStore.SEQUENCE_INVARIANT); + mGestureStore.load(); } else { - mGestureLibrary = null; + mGestureStore = null; } } /** - * TODO: Publish this API once we figure out where we should save the personzlied + * TODO: Publish this API once we figure out where we should save the personalized * gestures, and how to do so across all apps * * @hide */ public void addExample(String letter, Gesture example) { - if (mGestureLibrary != null) { - mGestureLibrary.addGesture(letter, example); + if (mGestureStore != null) { + mGestureStore.addGesture(letter, example); } } - + private void adjustPrediction(Gesture query, ArrayList<Prediction> predictions) { - if (mGestureLibrary != null) { - final ArrayList<Prediction> results = mGestureLibrary.recognize(query); + if (mGestureStore != null) { + final ArrayList<Prediction> results = mGestureStore.recognize(query); final HashMap<String, Prediction> topNList = new HashMap<String, Prediction>(); for (int j = 0; j < ADJUST_RANGE; j++) { diff --git a/core/java/android/gesture/LetterRecognizers.java b/core/java/android/gesture/LetterRecognizers.java new file mode 100644 index 0000000..e3f45a0 --- /dev/null +++ b/core/java/android/gesture/LetterRecognizers.java @@ -0,0 +1,65 @@ +/* + * 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 android.gesture; + +import android.content.Context; +import android.util.Log; +import static android.gesture.GestureConstants.LOG_TAG; +import static android.gesture.LetterRecognizer.*; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public final class LetterRecognizers { + public final static int RECOGNIZER_LATIN_LOWERCASE = 0; + + private LetterRecognizers() { + } + + public static LetterRecognizer fromType(Context context, int type) { + switch (type) { + case RECOGNIZER_LATIN_LOWERCASE: { + return createFromResource(context, com.android.internal.R.raw.latin_lowercase); + } + } + return null; + } + + public static LetterRecognizer fromResource(Context context, int resourceId) { + return createFromResource(context, resourceId); + } + + public static LetterRecognizer fromFile(String path) { + return fromFile(new File(path)); + } + + public static LetterRecognizer fromFile(File file) { + try { + return createFromStream(new FileInputStream(file)); + } catch (FileNotFoundException e) { + Log.d(LOG_TAG, "Failed to load handwriting data from file " + file, e); + } + return null; + } + + public static LetterRecognizer fromStream(InputStream stream) { + return createFromStream(stream); + } +} diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index f60aba3..ec02143 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -52,6 +52,7 @@ import android.gesture.GestureOverlayView; import android.gesture.Gesture; import android.gesture.LetterRecognizer; import android.gesture.Prediction; +import android.gesture.LetterRecognizers; import com.android.internal.R; @@ -94,7 +95,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public static final int TRANSCRIPT_MODE_NORMAL = 1; /** * The list will automatically scroll to the bottom, no matter what items - * are currently visible. + * are currently visible. * * @see #setTranscriptMode(int) */ @@ -156,7 +157,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * Indicates the view is in the process of being flung */ static final int TOUCH_MODE_FLING = 4; - + /** * Indicates that the user is currently dragging the fast scroll thumb */ @@ -349,7 +350,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * bitmap cache after scrolling. */ boolean mScrollingCacheEnabled; - + /** * Whether or not to enable the fast scroll feature on this list */ @@ -422,7 +423,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * The last CheckForTap runnable we posted, if any */ private Runnable mPendingCheckForTap; - + /** * The last CheckForKeyLongPress runnable we posted, if any */ @@ -576,7 +577,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te int color = a.getColor(R.styleable.AbsListView_cacheColorHint, 0); setCacheColorHint(color); - + boolean enableFastScroll = a.getBoolean(R.styleable.AbsListView_fastScrollEnabled, false); setFastScrollEnabled(enableFastScroll); @@ -605,7 +606,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); mDensityScale = getContext().getResources().getDisplayMetrics().density; } - + /** * <p>Sets the type of gestures to use with this list. When gestures are enabled, * that is if the <code>gestures</code> parameter is not {@link #GESTURES_NONE}, @@ -663,7 +664,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @see #GESTURES_NONE * @see #GESTURES_JUMP * @see #GESTURES_FILTER - * @see #setGestures(int) + * @see #setGestures(int) */ @ViewDebug.ExportedProperty(mapping = { @ViewDebug.IntToString(from = GESTURES_NONE, to = "NONE"), @@ -737,7 +738,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mGesturesOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE); mGesturesOverlay.addOnGesturePerformedListener(new GesturesProcessor()); - mPreviousGesturing = false; + mPreviousGesturing = false; } } @@ -778,10 +779,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** - * Enables fast scrolling by letting the user quickly scroll through lists by - * dragging the fast scroll thumb. The adapter attached to the list may want + * Enables fast scrolling by letting the user quickly scroll through lists by + * dragging the fast scroll thumb. The adapter attached to the list may want * to implement {@link SectionIndexer} if it wishes to display alphabet preview and - * jump between sections of the list. + * jump between sections of the list. * @see SectionIndexer * @see #isFastScrollEnabled() * @param enabled whether or not to enable fast scrolling @@ -799,7 +800,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } - + /** * Returns the current state of the fast scroll feature. * @see #setFastScrollEnabled(boolean) @@ -809,10 +810,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public boolean isFastScrollEnabled() { return mFastScrollEnabled; } - + /** * If fast scroll is visible, then don't draw the vertical scrollbar. - * @hide + * @hide */ @Override protected boolean isVerticalScrollBarHidden() { @@ -830,11 +831,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * When smooth scrollbar is disabled, the position and size of the scrollbar thumb * is based solely on the number of items in the adapter and the position of the * visible items inside the adapter. This provides a stable scrollbar as the user - * navigates through a list of items with varying heights. + * navigates through a list of items with varying heights. * * @param enabled Whether or not to enable smooth scrollbar. * - * @see #setSmoothScrollbarEnabled(boolean) + * @see #setSmoothScrollbarEnabled(boolean) * @attr ref android.R.styleable#AbsListView_smoothScrollbar */ public void setSmoothScrollbarEnabled(boolean enabled) { @@ -1142,7 +1143,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Sets the initial value for the text filter. * @param filterText The text to use for the filter. - * + * * @see #setTextFilterEnabled */ public void setFilterText(String filterText) { @@ -1168,7 +1169,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** - * Returns the list's text filter, if available. + * Returns the list's text filter, if available. * @return the list's text filter or null if filtering isn't enabled */ public CharSequence getTextFilter() { @@ -1177,7 +1178,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } return null; } - + @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); @@ -1740,7 +1741,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te System.arraycopy(state, enabledPos + 1, state, enabledPos, state.length - enabledPos - 1); } - + return state; } @@ -1851,16 +1852,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ private class WindowRunnnable { private int mOriginalAttachCount; - + public void rememberWindowAttachCount() { mOriginalAttachCount = getWindowAttachCount(); } - + public boolean sameWindow() { return hasWindowFocus() && getWindowAttachCount() == mOriginalAttachCount; } } - + private class PerformClick extends WindowRunnnable implements Runnable { View mChild; int mClickMotionPosition; @@ -1887,7 +1888,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final long longPressId = mAdapter.getItemId(mMotionPosition); boolean handled = false; - if (sameWindow() && !mDataChanged) { + if (sameWindow() && !mDataChanged) { handled = performLongPress(child, longPressPosition, longPressId); } if (handled) { @@ -1901,7 +1902,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } - + private class CheckForKeyLongPress extends WindowRunnnable implements Runnable { public void run() { if (isPressed() && mSelectedPosition >= 0) { @@ -1930,7 +1931,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te boolean handled = false; dismissGesturesPopup(); - + if (mOnItemLongClickListener != null) { handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, child, longPressPosition, longPressId); @@ -2079,7 +2080,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_DONE_WAITING; } } else { - mTouchMode = TOUCH_MODE_DONE_WAITING; + mTouchMode = TOUCH_MODE_DONE_WAITING; } } } @@ -2138,7 +2139,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te boolean intercepted = mFastScroller.onTouchEvent(ev); if (intercepted) { return true; - } + } } final int action = ev.getAction(); @@ -2326,10 +2327,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } setPressed(false); - + // Need to redraw since we probably aren't drawing the selector anymore invalidate(); - + final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); @@ -2373,7 +2374,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return true; } - + @Override public void draw(Canvas canvas) { super.draw(canvas); @@ -2388,14 +2389,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te int x = (int) ev.getX(); int y = (int) ev.getY(); View v; - + if (mFastScroller != null) { boolean intercepted = mFastScroller.onInterceptTouchEvent(ev); if (intercepted) { return true; } } - + switch (action) { case MotionEvent.ACTION_DOWN: { int motionPosition = findMotionRow(y); @@ -3245,7 +3246,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } return null; } - + /** * For filtering we proxy an input connection to an internal text editor, * and this allows the proxying to happen. @@ -3254,7 +3255,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public boolean checkInputConnectionProxy(View view) { return view == mTextFilter; } - + /** * Creates the window for the text filter and populates it with an EditText field; * @@ -3647,7 +3648,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mCurrentScrap = scrapViews[0]; mScrapViews = scrapViews; } - + public boolean shouldRecycleViewType(int viewType) { return viewType >= 0; } @@ -3862,8 +3863,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private final char[] mHolder; GesturesProcessor() { - mRecognizer = LetterRecognizer.getLetterRecognizer(getContext(), - LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE); + mRecognizer = LetterRecognizers.fromType(getContext(), + LetterRecognizers.RECOGNIZER_LATIN_LOWERCASE); if (mRecognizer == null) { setGestures(GESTURES_NONE); } diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java index 6767de6..7865a5c 100644 --- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java +++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java @@ -33,6 +33,7 @@ import android.gesture.Gesture; import android.gesture.GestureOverlayView; import android.gesture.LetterRecognizer; import android.gesture.Prediction; +import android.gesture.LetterRecognizers; import java.util.ArrayList; @@ -57,8 +58,8 @@ public class ContactListGestureOverlay extends Activity { setContentView(R.layout.overlaydemo); // create a letter recognizer - mRecognizer = LetterRecognizer.getLetterRecognizer(this, - LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE); + mRecognizer = LetterRecognizers.fromType(this, + LetterRecognizers.RECOGNIZER_LATIN_LOWERCASE); mOverlay = (GestureOverlayView) findViewById(R.id.overlay); // load the contact list diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java index 3f86ed4..8dbec99 100644 --- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java +++ b/tests/sketch/src/com/android/gesture/example/GestureEntry.java @@ -36,9 +36,10 @@ import android.widget.Spinner; import android.widget.AdapterView.OnItemSelectedListener; import android.gesture.Gesture; -import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.Prediction; +import android.gesture.GestureLibraries; +import android.gesture.GestureLibrary; import java.io.File; import java.util.ArrayList; @@ -61,7 +62,7 @@ public class GestureEntry extends Activity { private Spinner mRecognitionResult; - private GestureLibrary mGestureLibrary; + private GestureLibrary mGestureStore; private boolean mChangedByRecognizer = false; @@ -71,8 +72,8 @@ public class GestureEntry extends Activity { setContentView(R.layout.demo); // init the gesture library - mGestureLibrary = new GestureLibrary(GESTURE_FILE_NAME); - mGestureLibrary.load(); + mGestureStore = GestureLibraries.fromFile(GESTURE_FILE_NAME); + mGestureStore.load(); // create the spinner for showing the recognition results // the spinner also allows a user to correct a prediction @@ -82,7 +83,7 @@ public class GestureEntry extends Activity { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // correct the recognition result by adding the new example if (!mChangedByRecognizer) { - mGestureLibrary.addGesture(parent.getSelectedItem().toString(), mGesturePad + mGestureStore.addGesture(parent.getSelectedItem().toString(), mGesturePad .getGesture()); } else { mChangedByRecognizer = false; @@ -109,7 +110,7 @@ public class GestureEntry extends Activity { public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) { overlay.clear(false); } - + public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) { } }); @@ -134,7 +135,7 @@ public class GestureEntry extends Activity { .findViewById(R.id.gesturename_edit); String text = edittext.getText().toString().trim(); if (text.length() > 0) { - mGestureLibrary.addGesture(text, mGesturePad.getGesture()); + mGestureStore.addGesture(text, mGesturePad.getGesture()); } } }).setNegativeButton(R.string.newgesture_dialog_cancel, @@ -173,14 +174,14 @@ public class GestureEntry extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - mGestureLibrary.load(); + mGestureStore.load(); mGesturePad.clear(false); } @Override protected void onPause() { super.onPause(); - mGestureLibrary.save(); + mGestureStore.save(); } @Override @@ -195,12 +196,12 @@ public class GestureEntry extends Activity { if (gesture != null) { outState.putParcelable(PARCEL_KEY, gesture); } - mGestureLibrary.save(); + mGestureStore.save(); } private void recognize(Gesture gesture) { mChangedByRecognizer = true; - ArrayList<Prediction> predictions = mGestureLibrary.recognize(gesture); + ArrayList<Prediction> predictions = mGestureStore.recognize(gesture); ArrayAdapter<Prediction> adapter = new ArrayAdapter<Prediction>(this, android.R.layout.simple_spinner_item, predictions); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java index a561c96..f5bf683 100755 --- a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java +++ b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java @@ -28,8 +28,9 @@ import android.widget.Spinner; import android.widget.AdapterView.OnItemSelectedListener; import android.gesture.Gesture; -import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; +import android.gesture.GestureLibraries; +import android.gesture.GestureLibrary; import java.util.ArrayList; import java.util.Collections; @@ -45,7 +46,7 @@ public class GestureLibViewer extends Activity { private Spinner mGestureCategory; - private GestureLibrary mGesureLibrary; + private GestureLibrary mGesureStore; private ArrayList<Gesture> mGestures; @@ -59,15 +60,15 @@ public class GestureLibViewer extends Activity { String name = (String) mGestureCategory.getSelectedItem(); Gesture gesture = mGestures.get(mCurrentGestureIndex); - mGesureLibrary.removeGesture(name, gesture); + mGesureStore.removeGesture(name, gesture); - mGestures = mGesureLibrary.getGestures(name); + mGestures = mGesureStore.getGestures(name); if (mGestures == null) { // delete the entire entry mCurrentGestureIndex = 0; ArrayList<String> list = new ArrayList<String>(); - list.addAll(mGesureLibrary.getGestureEntries()); + list.addAll(mGesureStore.getGestureEntries()); Collections.sort(list); ArrayAdapter<String> adapter = new ArrayAdapter<String>(GestureLibViewer.this, android.R.layout.simple_spinner_item, list); @@ -83,7 +84,7 @@ public class GestureLibViewer extends Activity { } } } - + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -94,19 +95,19 @@ public class GestureLibViewer extends Activity { mGesturePad.setEnabled(false); // init the gesture library - mGesureLibrary = new GestureLibrary(GestureEntry.GESTURE_FILE_NAME); - mGesureLibrary.load(); + mGesureStore = GestureLibraries.fromFile(GestureEntry.GESTURE_FILE_NAME); + mGesureStore.load(); mGestureCategory = (Spinner) findViewById(R.id.spinner); ArrayList<String> list = new ArrayList<String>(); - if (!mGesureLibrary.getGestureEntries().isEmpty()) { - list.addAll(mGesureLibrary.getGestureEntries()); + if (!mGesureStore.getGestureEntries().isEmpty()) { + list.addAll(mGesureStore.getGestureEntries()); Collections.sort(list); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mGestureCategory.setAdapter(adapter); - mGestures = mGesureLibrary.getGestures(list.get(0)); + mGestures = mGesureStore.getGestures(list.get(0)); mCurrentGestureIndex = 0; Gesture gesture = mGestures.get(mCurrentGestureIndex); mGesturePad.setGesture(gesture); @@ -114,7 +115,7 @@ public class GestureLibViewer extends Activity { mGestureCategory.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - mGestures = mGesureLibrary.getGestures((String) mGestureCategory.getSelectedItem()); + mGestures = mGesureStore.getGestures((String) mGestureCategory.getSelectedItem()); if (!mGestures.isEmpty()) { mCurrentGestureIndex = 0; Gesture gesture = mGestures.get(mCurrentGestureIndex); @@ -160,7 +161,7 @@ public class GestureLibViewer extends Activity { @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - mGesureLibrary.save(); + mGesureStore.save(); setResult(RESULT_OK); finish(); return true; @@ -172,12 +173,12 @@ public class GestureLibViewer extends Activity { @Override protected void onPause() { super.onPause(); - mGesureLibrary.save(); + mGesureStore.save(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - mGesureLibrary.save(); + mGesureStore.save(); } } |