summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml605
-rwxr-xr-xcore/java/android/gesture/Gesture.java39
-rwxr-xr-xcore/java/android/gesture/GestureOverlayView.java564
-rw-r--r--core/java/android/gesture/GestureStroke.java59
-rwxr-xr-xcore/java/android/gesture/GestureUtilities.java2
-rw-r--r--core/java/android/gesture/TouchThroughGestureListener.java178
-rw-r--r--core/java/android/widget/AbsListView.java43
-rw-r--r--core/java/android/widget/FastScroller.java21
-rw-r--r--core/java/android/widget/FrameLayout.java29
-rw-r--r--core/res/res/values/attrs.xml16
-rw-r--r--core/res/res/values/public.xml5
-rw-r--r--core/res/res/values/styles.xml12
-rwxr-xr-xtests/sketch/res/layout/demo.xml5
-rwxr-xr-xtests/sketch/res/layout/gestureviewer.xml4
-rw-r--r--tests/sketch/res/layout/overlaydemo.xml13
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java41
-rw-r--r--tests/sketch/src/com/android/gesture/example/GestureEntry.java17
-rwxr-xr-xtests/sketch/src/com/android/gesture/example/GestureLibViewer.java10
18 files changed, 901 insertions, 762 deletions
diff --git a/api/current.xml b/api/current.xml
index 1743bd4..9cf0dc2 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3606,61 +3606,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad34"
- type="int"
- transient="false"
- volatile="false"
- value="16843390"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad35"
- type="int"
- transient="false"
- volatile="false"
- value="16843389"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad36"
- type="int"
- transient="false"
- volatile="false"
- value="16843388"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad37"
- type="int"
- transient="false"
- volatile="false"
- value="16843387"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad38"
- type="int"
- transient="false"
- volatile="false"
- value="16843386"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad4"
type="int"
transient="false"
@@ -4024,6 +3969,17 @@
visibility="public"
>
</field>
+<field name="eventsInterceptionEnabled"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843390"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="excludeFromRecents"
type="int"
transient="false"
@@ -4497,6 +4453,50 @@
visibility="public"
>
</field>
+<field name="gestureStrokeAngleThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843389"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeLengthThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843387"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeSquarenessThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843388"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeType"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843386"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="gestureStrokeWidth"
type="int"
transient="false"
@@ -49479,6 +49479,70 @@
<parameter name="color" type="int">
</parameter>
</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="android.graphics.Path">
+</parameter>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="android.graphics.Path">
+</parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+</method>
<method name="writeToParcel"
return="void"
abstract="false"
@@ -49719,7 +49783,7 @@
</field>
</class>
<class name="GestureOverlayView"
- extends="android.view.View"
+ extends="android.widget.FrameLayout"
abstract="false"
static="false"
final="false"
@@ -49775,7 +49839,7 @@
<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
</parameter>
</method>
-<method name="cancelFadingOut"
+<method name="addOnGesturePerformedListener"
return="void"
abstract="false"
native="false"
@@ -49785,8 +49849,10 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
+</parameter>
</method>
-<method name="clear"
+<method name="cancelClearAnimation"
return="void"
abstract="false"
native="false"
@@ -49796,11 +49862,20 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fadeOut" type="boolean">
-</parameter>
</method>
-<method name="getCurrentGesture"
- return="android.gesture.Gesture"
+<method name="cancelGesture"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="clear"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -49809,6 +49884,8 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="animated" type="boolean">
+</parameter>
</method>
<method name="getCurrentStroke"
return="java.util.ArrayList&lt;android.gesture.GesturePoint&gt;"
@@ -49821,6 +49898,17 @@
visibility="public"
>
</method>
+<method name="getGesture"
+ return="android.gesture.Gesture"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getGestureColor"
return="int"
abstract="false"
@@ -49832,7 +49920,51 @@
visibility="public"
>
</method>
-<method name="getGestureStroke"
+<method name="getGestureStrokeAngleThreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeLengthThreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeSquarenessTreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeWidth"
return="float"
abstract="false"
native="false"
@@ -49854,8 +49986,19 @@
visibility="public"
>
</method>
-<method name="processEvent"
- return="void"
+<method name="isEventsInterceptionEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isGesturing"
+ return="boolean"
abstract="false"
native="false"
synchronized="false"
@@ -49864,8 +50007,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
</method>
<method name="removeAllOnGestureListeners"
return="void"
@@ -49878,6 +50019,17 @@
visibility="public"
>
</method>
+<method name="removeAllOnGesturePerformedListeners"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="removeOnGestureListener"
return="void"
abstract="false"
@@ -49891,7 +50043,33 @@
<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
</parameter>
</method>
-<method name="setCurrentGesture"
+<method name="removeOnGesturePerformedListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
+</parameter>
+</method>
+<method name="setEventsInterceptionEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
+<method name="setGesture"
return="void"
abstract="false"
native="false"
@@ -49917,7 +50095,7 @@
<parameter name="color" type="int">
</parameter>
</method>
-<method name="setGestureDrawingColor"
+<method name="setGestureStrokeAngleThreshold"
return="void"
abstract="false"
native="false"
@@ -49927,10 +50105,36 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="color" type="int">
+<parameter name="gestureStrokeAngleThreshold" type="float">
+</parameter>
+</method>
+<method name="setGestureStrokeLengthThreshold"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeLengthThreshold" type="float">
+</parameter>
+</method>
+<method name="setGestureStrokeSquarenessTreshold"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeSquarenessTreshold" type="float">
</parameter>
</method>
-<method name="setGestureStroke"
+<method name="setGestureStrokeType"
return="void"
abstract="false"
native="false"
@@ -49940,7 +50144,20 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="gestureStroke" type="float">
+<parameter name="gestureStrokeType" type="int">
+</parameter>
+</method>
+<method name="setGestureStrokeWidth"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeWidth" type="float">
</parameter>
</method>
<method name="setUncertainGestureColor"
@@ -49956,6 +50173,28 @@
<parameter name="color" type="int">
</parameter>
</method>
+<field name="GESTURE_STROKE_TYPE_MULTIPLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GESTURE_STROKE_TYPE_SINGLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<interface name="GestureOverlayView.OnGestureListener"
abstract="true"
@@ -50025,6 +50264,29 @@
</parameter>
</method>
</interface>
+<interface name="GestureOverlayView.OnGesturePerformedListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onGesturePerformed"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+</interface>
<class name="GesturePoint"
extends="java.lang.Object"
abstract="false"
@@ -50118,6 +50380,17 @@
visibility="public"
>
</method>
+<method name="getPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="toPath"
return="android.graphics.Path"
abstract="false"
@@ -50328,194 +50601,6 @@
>
</field>
</class>
-<class name="TouchThroughGestureListener"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.gesture.GestureOverlayView.OnGestureListener">
-</implements>
-<constructor name="TouchThroughGestureListener"
- type="android.gesture.TouchThroughGestureListener"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="model" type="android.view.View">
-</parameter>
-</constructor>
-<constructor name="TouchThroughGestureListener"
- type="android.gesture.TouchThroughGestureListener"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="model" type="android.view.View">
-</parameter>
-<parameter name="stealEvents" type="boolean">
-</parameter>
-</constructor>
-<method name="addOnGestureActionListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.TouchThroughGestureListener.OnGesturePerformedListener">
-</parameter>
-</method>
-<method name="isGesturing"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="onGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureCancelled"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureEnded"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureStarted"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="removeOnGestureActionListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.TouchThroughGestureListener.OnGesturePerformedListener">
-</parameter>
-</method>
-<method name="setGestureType"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="int">
-</parameter>
-</method>
-<field name="MULTIPLE_STROKE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SINGLE_STROKE"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<interface name="TouchThroughGestureListener.OnGesturePerformedListener"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="onGesturePerformed"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-</interface>
</package>
<package name="android.graphics"
>
diff --git a/core/java/android/gesture/Gesture.java b/core/java/android/gesture/Gesture.java
index 14530a1..6aca105 100755
--- a/core/java/android/gesture/Gesture.java
+++ b/core/java/android/gesture/Gesture.java
@@ -57,6 +57,11 @@ public class Gesture implements Parcelable {
mGestureID = GESTURE_ID_BASE + sGestureCount++;
}
+ void recycle() {
+ mStrokes.clear();
+ mBoundingBox.setEmpty();
+ }
+
/**
* @return all the strokes of the gesture
*/
@@ -111,6 +116,40 @@ public class Gesture implements Parcelable {
return mBoundingBox;
}
+ public Path toPath() {
+ return toPath(null);
+ }
+
+ public Path toPath(Path path) {
+ if (path == null) path = new Path();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
+ for (int i = 0; i < count; i++) {
+ path.addPath(strokes.get(i).getPath());
+ }
+
+ return path;
+ }
+
+ public Path toPath(int width, int height, int edge, int numSample) {
+ return toPath(null, width, height, edge, numSample);
+ }
+
+ public Path toPath(Path path, int width, int height, int edge, int numSample) {
+ if (path == null) path = new Path();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
+ for (int i = 0; i < count; i++) {
+ path.addPath(strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample));
+ }
+
+ return path;
+ }
+
/**
* Set the id of the gesture
*
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 64ddbbd..012c01f 100755
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -18,51 +18,62 @@ package android.gesture;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
-import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.os.SystemClock;
import com.android.internal.R;
import java.util.ArrayList;
/**
- * A (transparent) overlay for gesture input that can be placed on top of other
- * widgets.
+ * A transparent overlay for gesture input that can be placed on top of other
+ * widgets or contain other widgets.
*
+ * @attr ref android.R.styleable#GestureOverlayView_eventsInterceptionEnabled
+ * @attr ref android.R.styleable#GestureOverlayView_fadeDuration
+ * @attr ref android.R.styleable#GestureOverlayView_fadeOffset
* @attr ref android.R.styleable#GestureOverlayView_gestureStrokeWidth
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeAngleThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeLengthThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeSquarenessThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeType
* @attr ref android.R.styleable#GestureOverlayView_gestureColor
* @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor
- * @attr ref android.R.styleable#GestureOverlayView_fadeDuration
- * @attr ref android.R.styleable#GestureOverlayView_fadeOffset
*/
-public class GestureOverlayView extends View {
- private static final int TRANSPARENT_BACKGROUND = 0x00000000;
+public class GestureOverlayView extends FrameLayout {
+ public static final int GESTURE_STROKE_TYPE_SINGLE = 0;
+ public static final int GESTURE_STROKE_TYPE_MULTIPLE = 1;
+
+ private static final int FADE_ANIMATION_RATE = 16;
private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
private static final boolean DITHER_FLAG = true;
- private Paint mGesturePaint;
-
- private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
- private Bitmap mBitmap;
- private Canvas mBitmapCanvas;
+ private final Paint mGesturePaint = new Paint();
- private long mFadeDuration = 300;
- private long mFadeOffset = 300;
+ private long mFadeDuration = 150;
+ private long mFadeOffset = 420;
private long mFadingStart;
+ private boolean mFadingHasStarted;
- private float mGestureStroke = 12.0f;
+ private int mCurrentColor;
private int mCertainGestureColor = 0xFFFFFF00;
- private int mUncertainGestureColor = 0x3CFFFF00;
+ private int mUncertainGestureColor = 0x48FFFF00;
+ private float mGestureStrokeWidth = 12.0f;
private int mInvalidateExtraBorder = 10;
- // for rendering immediate ink feedback
+ private int mGestureStrokeType = GESTURE_STROKE_TYPE_SINGLE;
+ private float mGestureStrokeLengthThreshold = 30.0f;
+ private float mGestureStrokeSquarenessTreshold = 0.275f;
+ private float mGestureStrokeAngleThreshold = 40.0f;
+
private final Rect mInvalidRect = new Rect();
private final Path mPath = new Path();
@@ -72,41 +83,31 @@ public class GestureOverlayView extends View {
private float mCurveEndX;
private float mCurveEndY;
+ private float mTotalLength;
+ private boolean mIsGesturing = false;
+ private boolean mInterceptEvents = true;
+ private boolean mIsListeningForGestures;
+
// current gesture
- private Gesture mCurrentGesture = null;
+ private Gesture mCurrentGesture;
+ private final ArrayList<GesturePoint> mStrokeBuffer = new ArrayList<GesturePoint>(100);
// TODO: Make this a list of WeakReferences
private final ArrayList<OnGestureListener> mOnGestureListeners =
new ArrayList<OnGestureListener>();
- private final ArrayList<GesturePoint> mPointBuffer = new ArrayList<GesturePoint>(100);
+ // TODO: Make this a list of WeakReferences
+ private final ArrayList<OnGesturePerformedListener> mOnGesturePerformedListeners =
+ new ArrayList<OnGesturePerformedListener>();
+
+ private boolean mHandleGestureActions;
// fading out effect
private boolean mIsFadingOut = false;
- private float mFadingAlpha = 1;
+ private float mFadingAlpha = 1.0f;
private final AccelerateDecelerateInterpolator mInterpolator =
new AccelerateDecelerateInterpolator();
- private final Runnable mFadingOut = new Runnable() {
- public void run() {
- if (mIsFadingOut) {
- final long now = AnimationUtils.currentAnimationTimeMillis();
- final long duration = now - mFadingStart;
-
- if (duration > mFadeDuration) {
- mIsFadingOut = false;
- mPath.rewind();
- mCurrentGesture = null;
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- } else {
- float interpolatedTime = Math.max(0.0f,
- Math.min(1.0f, duration / (float) mFadeDuration));
- mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime);
- postDelayed(this, 16);
- }
- invalidate();
- }
- }
- };
+ private final FadeOutRunnable mFadingOut = new FadeOutRunnable();
public GestureOverlayView(Context context) {
super(context);
@@ -123,41 +124,52 @@ public class GestureOverlayView extends View {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.GestureOverlayView, defStyle, 0);
- mGestureStroke = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
- mGestureStroke);
- mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1);
+ mGestureStrokeWidth = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
+ mGestureStrokeWidth);
+ mInvalidateExtraBorder = Math.max(1, ((int) mGestureStrokeWidth) - 1);
mCertainGestureColor = a.getColor(R.styleable.GestureOverlayView_gestureColor,
mCertainGestureColor);
mUncertainGestureColor = a.getColor(R.styleable.GestureOverlayView_uncertainGestureColor,
mUncertainGestureColor);
mFadeDuration = a.getInt(R.styleable.GestureOverlayView_fadeDuration, (int) mFadeDuration);
mFadeOffset = a.getInt(R.styleable.GestureOverlayView_fadeOffset, (int) mFadeOffset);
+ mGestureStrokeType = a.getInt(R.styleable.GestureOverlayView_gestureStrokeType,
+ mGestureStrokeType);
+ mGestureStrokeLengthThreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeLengthThreshold,
+ mGestureStrokeLengthThreshold);
+ mGestureStrokeAngleThreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeAngleThreshold,
+ mGestureStrokeAngleThreshold);
+ mGestureStrokeSquarenessTreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeSquarenessThreshold,
+ mGestureStrokeSquarenessTreshold);
+ mInterceptEvents = a.getBoolean(R.styleable.GestureOverlayView_eventsInterceptionEnabled,
+ mInterceptEvents);
a.recycle();
init();
}
- public ArrayList<GesturePoint> getCurrentStroke() {
- return mPointBuffer;
- }
+ private void init() {
+ setWillNotDraw(false);
- public Gesture getCurrentGesture() {
- return mCurrentGesture;
+ final Paint gesturePaint = mGesturePaint;
+ gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
+ gesturePaint.setColor(mCertainGestureColor);
+ gesturePaint.setStyle(Paint.Style.STROKE);
+ gesturePaint.setStrokeJoin(Paint.Join.ROUND);
+ gesturePaint.setStrokeCap(Paint.Cap.ROUND);
+ gesturePaint.setStrokeWidth(mGestureStrokeWidth);
+ gesturePaint.setDither(DITHER_FLAG);
+
+ mCurrentColor = mCertainGestureColor;
+ setPaintAlpha(255);
}
- /**
- * Set Gesture color
- *
- * @param color
- */
- public void setGestureDrawingColor(int color) {
- mGesturePaint.setColor(color);
- if (mCurrentGesture != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
- }
- invalidate();
+ public ArrayList<GesturePoint> getCurrentStroke() {
+ return mStrokeBuffer;
}
public void setGestureColor(int color) {
@@ -176,73 +188,77 @@ public class GestureOverlayView extends View {
return mCertainGestureColor;
}
- public float getGestureStroke() {
- return mGestureStroke;
+ public float getGestureStrokeWidth() {
+ return mGestureStrokeWidth;
}
- public void setGestureStroke(float gestureStroke) {
- mGestureStroke = gestureStroke;
- mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1);
- mGesturePaint.setStrokeWidth(mGestureStroke);
+ public void setGestureStrokeWidth(float gestureStrokeWidth) {
+ mGestureStrokeWidth = gestureStrokeWidth;
+ mInvalidateExtraBorder = Math.max(1, ((int) gestureStrokeWidth) - 1);
+ mGesturePaint.setStrokeWidth(gestureStrokeWidth);
}
- /**
- * Set the gesture to be shown in the view
- *
- * @param gesture
- */
- public void setCurrentGesture(Gesture gesture) {
- if (mCurrentGesture != null) {
- clear(false);
- }
+ public int getGestureStrokeType() {
+ return mGestureStrokeType;
+ }
- mCurrentGesture = gesture;
+ public void setGestureStrokeType(int gestureStrokeType) {
+ mGestureStrokeType = gestureStrokeType;
+ }
- if (gesture != null) {
- if (mBitmapCanvas != null) {
- gesture.draw(mBitmapCanvas, mGesturePaint);
- invalidate();
- }
- }
+ public float getGestureStrokeLengthThreshold() {
+ return mGestureStrokeLengthThreshold;
}
- private void init() {
- mGesturePaint = new Paint();
+ public void setGestureStrokeLengthThreshold(float gestureStrokeLengthThreshold) {
+ mGestureStrokeLengthThreshold = gestureStrokeLengthThreshold;
+ }
- final Paint gesturePaint = mGesturePaint;
- gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
- gesturePaint.setColor(mCertainGestureColor);
- gesturePaint.setStyle(Paint.Style.STROKE);
- gesturePaint.setStrokeJoin(Paint.Join.ROUND);
- gesturePaint.setStrokeCap(Paint.Cap.ROUND);
- gesturePaint.setStrokeWidth(mGestureStroke);
- gesturePaint.setDither(DITHER_FLAG);
+ public float getGestureStrokeSquarenessTreshold() {
+ return mGestureStrokeSquarenessTreshold;
}
- @Override
- protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
- super.onSizeChanged(width, height, oldWidth, oldHeight);
+ public void setGestureStrokeSquarenessTreshold(float gestureStrokeSquarenessTreshold) {
+ mGestureStrokeSquarenessTreshold = gestureStrokeSquarenessTreshold;
+ }
- if (width <= 0 || height <= 0) {
- return;
- }
+ public float getGestureStrokeAngleThreshold() {
+ return mGestureStrokeAngleThreshold;
+ }
- int targetWidth = width > oldWidth ? width : oldWidth;
- int targetHeight = height > oldHeight ? height : oldHeight;
+ public void setGestureStrokeAngleThreshold(float gestureStrokeAngleThreshold) {
+ mGestureStrokeAngleThreshold = gestureStrokeAngleThreshold;
+ }
- if (mBitmap != null) mBitmap.recycle();
+ public boolean isEventsInterceptionEnabled() {
+ return mInterceptEvents;
+ }
- mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
- if (mBitmapCanvas != null) {
- mBitmapCanvas.setBitmap(mBitmap);
- } else {
- mBitmapCanvas = new Canvas(mBitmap);
- }
- mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND);
+ public void setEventsInterceptionEnabled(boolean enabled) {
+ mInterceptEvents = enabled;
+ }
+
+ public Gesture getGesture() {
+ return mCurrentGesture;
+ }
+ public void setGesture(Gesture gesture) {
if (mCurrentGesture != null) {
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
+ clear(false);
}
+
+ setCurrentColor(mCertainGestureColor);
+ mCurrentGesture = gesture;
+
+ final Path path = mCurrentGesture.toPath();
+ final RectF bounds = new RectF();
+ path.computeBounds(bounds, true);
+
+ mPath.rewind();
+ mPath.addPath(path, (getWidth() - bounds.width()) / 2.0f,
+ (getHeight() - bounds.height()) / 2.0f);
+
+ invalidate();
}
public void addOnGestureListener(OnGestureListener listener) {
@@ -257,100 +273,172 @@ public class GestureOverlayView extends View {
mOnGestureListeners.clear();
}
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ public void addOnGesturePerformedListener(OnGesturePerformedListener listener) {
+ mOnGesturePerformedListeners.add(listener);
+ if (mOnGesturePerformedListeners.size() > 0) {
+ mHandleGestureActions = true;
+ }
+ }
+
+ public void removeOnGesturePerformedListener(OnGesturePerformedListener listener) {
+ mOnGesturePerformedListeners.remove(listener);
+ if (mOnGesturePerformedListeners.size() <= 0) {
+ mHandleGestureActions = false;
+ }
+ }
+
+ public void removeAllOnGesturePerformedListeners() {
+ mOnGesturePerformedListeners.clear();
+ mHandleGestureActions = false;
+ }
- // draw double buffer
- if (mIsFadingOut) {
- mBitmapPaint.setAlpha((int) (255 * mFadingAlpha));
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
+ public boolean isGesturing() {
+ return mIsGesturing;
+ }
+
+ private void setCurrentColor(int color) {
+ mCurrentColor = color;
+ if (mFadingHasStarted) {
+ setPaintAlpha((int) (255 * mFadingAlpha));
} else {
- mBitmapPaint.setAlpha(255);
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
+ setPaintAlpha(255);
+ }
+ invalidate();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ if (mCurrentGesture != null) {
+ canvas.drawPath(mPath, mGesturePaint);
}
+ }
+
+ private void setPaintAlpha(int alpha) {
+ alpha += alpha >> 7;
+ final int baseAlpha = mCurrentColor >>> 24;
+ final int useAlpha = baseAlpha * alpha >> 8;
+ mGesturePaint.setColor((mCurrentColor << 8 >>> 8) | (useAlpha << 24));
+ }
- // draw the current stroke
- canvas.drawPath(mPath, mGesturePaint);
+ public void clear(boolean animated) {
+ clear(animated, false);
}
- /**
- * Clear up the overlay
- *
- * @param fadeOut whether the gesture on the overlay should fade out
- * gradually or disappear immediately
- */
- public void clear(boolean fadeOut) {
- if (fadeOut) {
+ private void clear(boolean animated, boolean fireActionPerformed) {
+ setPaintAlpha(255);
+ if (animated && mCurrentGesture != null) {
mFadingAlpha = 1.0f;
mIsFadingOut = true;
+ mFadingHasStarted = false;
+ mFadingOut.fireActionPerformed = fireActionPerformed;
removeCallbacks(mFadingOut);
mFadingStart = AnimationUtils.currentAnimationTimeMillis() + mFadeOffset;
postDelayed(mFadingOut, mFadeOffset);
} else {
mPath.rewind();
mCurrentGesture = null;
- if (mBitmap != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- invalidate();
- }
}
}
- public void cancelFadingOut() {
+ public void cancelClearAnimation() {
+ setPaintAlpha(255);
mIsFadingOut = false;
+ mFadingHasStarted = false;
removeCallbacks(mFadingOut);
+ mPath.rewind();
+ mCurrentGesture = null;
+ }
+
+ public void cancelGesture() {
+ mIsListeningForGestures = false;
+
+ // add the stroke to the current gesture
+ mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer));
+
+ // pass the event to handlers
+ final long now = SystemClock.uptimeMillis();
+ final MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGestureCancelled(this, event);
+ }
+
+ event.recycle();
+
+ clear(false);
+ mIsGesturing = false;
+ mStrokeBuffer.clear();
}
@Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
+ protected void onDetachedFromWindow() {
+ cancelClearAnimation();
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ if (isEnabled()) {
+ boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null &&
+ mCurrentGesture.getStrokesCount() > 0)) && mInterceptEvents;
+ processEvent(event);
+
+ if (cancelDispatch) {
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ }
+
+ super.dispatchTouchEvent(event);
return true;
}
- processEvent(event);
-
- return true;
+ return super.dispatchTouchEvent(event);
}
- public void processEvent(MotionEvent event) {
+ private boolean processEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
- Rect rect = touchStart(event);
- invalidate(rect);
- break;
+ touchStart(event);
+ invalidate();
+ return true;
case MotionEvent.ACTION_MOVE:
- rect = touchMove(event);
- if (rect != null) {
- invalidate(rect);
+ if (mIsListeningForGestures) {
+ Rect rect = touchMove(event);
+ if (rect != null) {
+ invalidate(rect);
+ }
+ return true;
}
break;
case MotionEvent.ACTION_UP:
- touchUp(event, false);
- invalidate();
+ if (mIsListeningForGestures) {
+ touchUp(event, false);
+ invalidate();
+ return true;
+ }
break;
case MotionEvent.ACTION_CANCEL:
- touchUp(event, true);
- invalidate();
- break;
+ if (mIsListeningForGestures) {
+ touchUp(event, true);
+ invalidate();
+ return true;
+ }
}
+
+ return false;
}
- private Rect touchStart(MotionEvent event) {
+ private void touchStart(MotionEvent event) {
+ mIsListeningForGestures = true;
+
// pass the event to handlers
final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
final int count = listeners.size();
for (int i = 0; i < count; i++) {
- OnGestureListener listener = listeners.get(i);
- listener.onGestureStarted(this, event);
- }
-
- // if there is fading out going on, stop it.
- if (mIsFadingOut) {
- mIsFadingOut = false;
- removeCallbacks(mFadingOut);
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture = null;
+ listeners.get(i).onGestureStarted(this, event);
}
float x = event.getX();
@@ -359,22 +447,39 @@ public class GestureOverlayView extends View {
mX = x;
mY = y;
+ mTotalLength = 0;
+ mIsGesturing = false;
+
+ if (mGestureStrokeType == GESTURE_STROKE_TYPE_SINGLE) {
+ if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor);
+ mCurrentGesture = null;
+ mPath.rewind();
+ } else if (mCurrentGesture == null || mCurrentGesture.getStrokesCount() == 0) {
+ if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor);
+ }
+
+ // if there is fading out going on, stop it.
+ if (mFadingHasStarted) {
+ cancelClearAnimation();
+ } else if (mIsFadingOut) {
+ setPaintAlpha(255);
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+ removeCallbacks(mFadingOut);
+ }
+
if (mCurrentGesture == null) {
mCurrentGesture = new Gesture();
}
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
-
- mPath.rewind();
+ mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime()));
mPath.moveTo(x, y);
- mInvalidRect.set((int) x - mInvalidateExtraBorder, (int) y - mInvalidateExtraBorder,
- (int) x + mInvalidateExtraBorder, (int) y + mInvalidateExtraBorder);
-
+ final int border = mInvalidateExtraBorder;
+ mInvalidRect.set((int) x - border, (int) y - border, (int) x + border, (int) y + border);
+
mCurveEndX = x;
mCurveEndY = y;
-
- return mInvalidRect;
}
private Rect touchMove(MotionEvent event) {
@@ -393,36 +498,28 @@ public class GestureOverlayView extends View {
areaToRefresh = mInvalidRect;
// start with the curve end
- areaToRefresh.set(
- (int) mCurveEndX - mInvalidateExtraBorder,
- (int) mCurveEndY - mInvalidateExtraBorder,
- (int) mCurveEndX + mInvalidateExtraBorder,
- (int) mCurveEndY + mInvalidateExtraBorder);
+ final int border = mInvalidateExtraBorder;
+ areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border,
+ (int) mCurveEndX + border, (int) mCurveEndY + border);
- mCurveEndX = (x + previousX) / 2;
- mCurveEndY = (y + previousY) / 2;
+ float cX = mCurveEndX = (x + previousX) / 2;
+ float cY = mCurveEndY = (y + previousY) / 2;
- mPath.quadTo(previousX, previousY, mCurveEndX, mCurveEndY);
+ mPath.quadTo(previousX, previousY, cX, cY);
// union with the control point of the new curve
- areaToRefresh.union(
- (int) previousX - mInvalidateExtraBorder,
- (int) previousY - mInvalidateExtraBorder,
- (int) previousX + mInvalidateExtraBorder,
- (int) previousY + mInvalidateExtraBorder);
+ areaToRefresh.union((int) previousX - border, (int) previousY - border,
+ (int) previousX + border, (int) previousY + border);
// union with the end point of the new curve
- areaToRefresh.union(
- (int) mCurveEndX - mInvalidateExtraBorder,
- (int) mCurveEndY - mInvalidateExtraBorder,
- (int) mCurveEndX + mInvalidateExtraBorder,
- (int) mCurveEndY + mInvalidateExtraBorder);
+ areaToRefresh.union((int) cX - border, (int) cY - border,
+ (int) cX + border, (int) cY + border);
mX = x;
mY = y;
}
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
+ mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime()));
// pass the event to handlers
final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
@@ -430,24 +527,48 @@ public class GestureOverlayView extends View {
for (int i = 0; i < count; i++) {
listeners.get(i).onGesture(this, event);
}
-
+
+ if (mHandleGestureActions && !mIsGesturing) {
+ mTotalLength += (float) Math.sqrt(dx * dx + dy * dy);
+
+ if (mTotalLength > mGestureStrokeLengthThreshold) {
+ final OrientedBoundingBox box =
+ GestureUtilities.computeOrientedBoundingBox(mStrokeBuffer);
+
+ float angle = Math.abs(box.orientation);
+ if (angle > 90) {
+ angle = 180 - angle;
+ }
+
+ if (box.squareness > mGestureStrokeSquarenessTreshold ||
+ angle < mGestureStrokeAngleThreshold) {
+
+ mIsGesturing = true;
+ setCurrentColor(mCertainGestureColor);
+ }
+ }
+ }
+
return areaToRefresh;
}
private void touchUp(MotionEvent event, boolean cancel) {
- // add the stroke to the current gesture
- mCurrentGesture.addStroke(new GestureStroke(mPointBuffer));
+ mIsListeningForGestures = false;
- // add the stroke to the double buffer
- mBitmapCanvas.drawPath(mPath, mGesturePaint);
+ // add the stroke to the current gesture
+ mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer));
if (!cancel) {
// pass the event to handlers
final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
- final int count = listeners.size();
+ int count = listeners.size();
for (int i = 0; i < count; i++) {
listeners.get(i).onGestureEnded(this, event);
}
+
+ if (mHandleGestureActions) {
+ clear(true, mIsGesturing);
+ }
} else {
// pass the event to handlers
final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
@@ -455,15 +576,52 @@ public class GestureOverlayView extends View {
for (int i = 0; i < count; i++) {
listeners.get(i).onGestureCancelled(this, event);
}
+
+ clear(false);
}
- mPath.rewind();
- mPointBuffer.clear();
+ mIsGesturing = false;
+ mStrokeBuffer.clear();
+ }
+
+ private class FadeOutRunnable implements Runnable {
+ boolean fireActionPerformed;
+
+ public void run() {
+ if (mIsFadingOut) {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+ final long duration = now - mFadingStart;
+
+ if (duration > mFadeDuration) {
+ if (fireActionPerformed) {
+ final ArrayList<OnGesturePerformedListener> actionListeners =
+ mOnGesturePerformedListeners;
+ final int count = actionListeners.size();
+ for (int i = 0; i < count; i++) {
+ actionListeners.get(i).onGesturePerformed(GestureOverlayView.this,
+ mCurrentGesture);
+ }
+ }
+
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+ mPath.rewind();
+ mCurrentGesture = null;
+ setPaintAlpha(255);
+ } else {
+ mFadingHasStarted = true;
+ float interpolatedTime = Math.max(0.0f,
+ Math.min(1.0f, duration / (float) mFadeDuration));
+ mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime);
+ setPaintAlpha((int) (255 * mFadingAlpha));
+ postDelayed(this, FADE_ANIMATION_RATE);
+ }
+
+ invalidate();
+ }
+ }
}
- /**
- * An interface for processing gesture events
- */
public static interface OnGestureListener {
void onGestureStarted(GestureOverlayView overlay, MotionEvent event);
@@ -473,4 +631,8 @@ public class GestureOverlayView extends View {
void onGestureCancelled(GestureOverlayView overlay, MotionEvent event);
}
+
+ public static interface OnGesturePerformedListener {
+ void onGesturePerformed(GestureOverlayView overlay, Gesture gesture);
+ }
}
diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java
index 6d022b4..0d7bc2d 100644
--- a/core/java/android/gesture/GestureStroke.java
+++ b/core/java/android/gesture/GestureStroke.java
@@ -89,37 +89,49 @@ public class GestureStroke {
*/
void draw(Canvas canvas, Paint paint) {
if (mCachedPath == null) {
- final float[] localPoints = points;
- final int count = localPoints.length;
+ makePath();
+ }
- Path path = null;
+ canvas.drawPath(mCachedPath, paint);
+ }
- float mX = 0;
- float mY = 0;
+ public Path getPath() {
+ if (mCachedPath == null) {
+ makePath();
+ }
+
+ return mCachedPath;
+ }
+
+ private void makePath() {
+ final float[] localPoints = points;
+ final int count = localPoints.length;
+
+ Path path = null;
+
+ float mX = 0;
+ float mY = 0;
- for (int i = 0; i < count; i += 2) {
- float x = localPoints[i];
- float y = localPoints[i + 1];
- if (path == null) {
- path = new Path();
- path.moveTo(x, y);
+ for (int i = 0; i < count; i += 2) {
+ float x = localPoints[i];
+ float y = localPoints[i + 1];
+ if (path == null) {
+ path = new Path();
+ path.moveTo(x, y);
+ mX = x;
+ mY = y;
+ } else {
+ float dx = Math.abs(x - mX);
+ float dy = Math.abs(y - mY);
+ if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
+ path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
- } else {
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
- if (dx >= 3 || dy >= 3) {
- path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- }
}
}
-
- mCachedPath = path;
}
- canvas.drawPath(mCachedPath, paint);
+ mCachedPath = path;
}
/**
@@ -158,8 +170,7 @@ public class GestureStroke {
} else {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
- if (dx >= TOUCH_TOLERANCE ||
- dy >= TOUCH_TOLERANCE) {
+ if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java
index e47856c..0f9253d 100755
--- a/core/java/android/gesture/GestureUtilities.java
+++ b/core/java/android/gesture/GestureUtilities.java
@@ -388,7 +388,7 @@ final class GestureUtilities {
} else { // -PI<alpha<PI
angle = (float) Math.atan2(targetVector[1], targetVector[0]);
angle = (float) (180 * angle / Math.PI);
- android.graphics.Matrix trans = new android.graphics.Matrix();
+ Matrix trans = new Matrix();
trans.setRotate(-angle);
trans.mapPoints(points);
}
diff --git a/core/java/android/gesture/TouchThroughGestureListener.java b/core/java/android/gesture/TouchThroughGestureListener.java
deleted file mode 100644
index 09a528d..0000000
--- a/core/java/android/gesture/TouchThroughGestureListener.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.gesture;
-
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.ArrayList;
-import java.lang.ref.WeakReference;
-
-/**
- * TouchThroughGesturing implements the interaction behavior that allows a user
- * to gesture over a regular UI widget such as ListView and at the same time,
- * still allows a user to perform basic interactions (clicking, scrolling and panning)
- * with the underlying widget.
- */
-public class TouchThroughGestureListener implements GestureOverlayView.OnGestureListener {
- public static final int SINGLE_STROKE = 0;
- public static final int MULTIPLE_STROKE = 1;
-
- // TODO: Add properties for all these
- private static final float STROKE_LENGTH_THRESHOLD = 30;
- private static final float SQUARENESS_THRESHOLD = 0.275f;
- private static final float ANGLE_THRESHOLD = 40;
-
- private boolean mIsGesturing = false;
-
- private float mTotalLength;
-
- private float mX;
- private float mY;
-
- private WeakReference<View> mModel;
-
- private int mGestureType = SINGLE_STROKE;
-
- // TODO: Use WeakReferences
- private final ArrayList<OnGesturePerformedListener> mPerformedListeners =
- new ArrayList<OnGesturePerformedListener>();
-
- private boolean mStealEvents = false;
-
- public TouchThroughGestureListener(View model) {
- this(model, true);
- }
-
- public TouchThroughGestureListener(View model, boolean stealEvents) {
- mModel = new WeakReference<View>(model);
- mStealEvents = stealEvents;
- }
-
- /**
- *
- * @param type SINGLE_STROKE or MULTIPLE_STROKE
- */
- public void setGestureType(int type) {
- mGestureType = type;
- }
-
- public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
- if (mGestureType == MULTIPLE_STROKE) {
- overlay.cancelFadingOut();
- }
-
- mX = event.getX();
- mY = event.getY();
- mTotalLength = 0;
- mIsGesturing = false;
-
- if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null
- || overlay.getCurrentGesture().getStrokesCount() == 0) {
- overlay.setGestureDrawingColor(overlay.getUncertainGestureColor());
- }
-
- dispatchEventToModel(event);
- }
-
- private void dispatchEventToModel(MotionEvent event) {
- View v = mModel.get();
- if (v != null) v.dispatchTouchEvent(event);
- }
-
- public void onGesture(GestureOverlayView overlay, MotionEvent event) {
- //noinspection PointlessBooleanExpression
- if (!mStealEvents) {
- dispatchEventToModel(event);
- }
-
- if (mIsGesturing) {
- return;
- }
-
- final float x = event.getX();
- final float y = event.getY();
- final float dx = x - mX;
- final float dy = y - mY;
-
- mTotalLength += (float) Math.sqrt(dx * dx + dy * dy);
- mX = x;
- mY = y;
-
- if (mTotalLength > STROKE_LENGTH_THRESHOLD) {
- final OrientedBoundingBox box =
- GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke());
- float angle = Math.abs(box.orientation);
- if (angle > 90) {
- angle = 180 - angle;
- }
- if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
- mIsGesturing = true;
- overlay.setGestureDrawingColor(overlay.getGestureColor());
- if (mStealEvents) {
- event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
- MotionEvent.ACTION_CANCEL, x, y, event.getPressure(), event.getSize(),
- event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
- event.getDeviceId(), event.getEdgeFlags());
- }
- }
- }
-
- if (mStealEvents) {
- dispatchEventToModel(event);
- }
- }
-
- public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
- if (mIsGesturing) {
- overlay.clear(true);
-
- final ArrayList<OnGesturePerformedListener> listeners = mPerformedListeners;
- final int count = listeners.size();
-
- for (int i = 0; i < count; i++) {
- listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
- }
- } else {
- dispatchEventToModel(event);
- overlay.clear(false);
- }
- }
-
- public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
- overlay.clear(mIsGesturing);
- if (!mIsGesturing) {
- dispatchEventToModel(event);
- }
- }
-
- public void addOnGestureActionListener(OnGesturePerformedListener listener) {
- mPerformedListeners.add(listener);
- }
-
- public void removeOnGestureActionListener(OnGesturePerformedListener listener) {
- mPerformedListeners.remove(listener);
- }
-
- public boolean isGesturing() {
- return mIsGesturing;
- }
-
- public static interface OnGesturePerformedListener {
- public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture);
- }
-}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 8a538d7..ccb876f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -49,7 +49,6 @@ import android.view.inputmethod.InputConnectionWrapper;
import android.view.inputmethod.InputMethodManager;
import android.view.ContextMenu.ContextMenuInfo;
import android.gesture.GestureOverlayView;
-import android.gesture.TouchThroughGestureListener;
import android.gesture.Gesture;
import android.gesture.LetterRecognizer;
import android.gesture.Prediction;
@@ -472,7 +471,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private ViewTreeObserver.OnGlobalLayoutListener mGesturesLayoutListener;
private boolean mGlobalLayoutListenerAddedGestures;
private boolean mInstallGesturesOverlay;
- private TouchThroughGestureListener mGesturesListener;
private boolean mPreviousGesturing;
private boolean mGlobalLayoutListenerAddedFilter;
@@ -736,10 +734,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mGesturesPopup = p;
mGesturesOverlay.removeAllOnGestureListeners();
- mGesturesListener = new TouchThroughGestureListener(null);
- mGesturesListener.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE);
- mGesturesListener.addOnGestureActionListener(new GesturesProcessor());
- mGesturesOverlay.addOnGestureListener(mGesturesListener);
+ mGesturesOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
+ mGesturesOverlay.addOnGesturePerformedListener(new GesturesProcessor());
mPreviousGesturing = false;
}
@@ -756,19 +752,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mGestures != GESTURES_NONE) {
- mGesturesOverlay.processEvent(ev);
-
- final boolean isGesturing = mGesturesListener.isGesturing();
-
- if (!isGesturing) {
- mPreviousGesturing = isGesturing;
- return super.dispatchTouchEvent(ev);
- } else if (!mPreviousGesturing){
- mPreviousGesturing = isGesturing;
- final MotionEvent event = MotionEvent.obtain(ev);
- event.setAction(MotionEvent.ACTION_CANCEL);
- super.dispatchTouchEvent(event);
- return true;
+ if (ev.getAction() != MotionEvent.ACTION_DOWN || mFastScroller == null ||
+ !mFastScroller.isPointInside(ev.getX(), ev.getY())) {
+
+ mGesturesOverlay.dispatchTouchEvent(ev);
+
+ final boolean isGesturing = mGesturesOverlay.isGesturing();
+
+ if (!isGesturing) {
+ mPreviousGesturing = isGesturing;
+ return super.dispatchTouchEvent(ev);
+ } else if (!mPreviousGesturing){
+ mPreviousGesturing = isGesturing;
+ final MotionEvent event = MotionEvent.obtain(ev);
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ super.dispatchTouchEvent(event);
+ return true;
+ }
}
}
@@ -2130,13 +2130,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@Override
public boolean onTouchEvent(MotionEvent ev) {
-
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onTouchEvent(ev);
if (intercepted) {
return true;
}
}
+
final int action = ev.getAction();
final int x = (int) ev.getX();
final int y = (int) ev.getY();
@@ -3848,8 +3848,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- private class GesturesProcessor implements
- TouchThroughGestureListener.OnGesturePerformedListener {
+ private class GesturesProcessor implements GestureOverlayView.OnGesturePerformedListener {
private static final double SCORE_THRESHOLD = 0.1;
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index b9fd5a6..cd965fc 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -402,8 +402,7 @@ class FastScroller {
boolean onInterceptTouchEvent(MotionEvent ev) {
if (mState > STATE_NONE && ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (ev.getX() > mList.getWidth() - mThumbW && ev.getY() >= mThumbY &&
- ev.getY() <= mThumbY + mThumbH) {
+ if (isPointInside(ev.getX(), ev.getY())) {
setState(STATE_DRAGGING);
return true;
}
@@ -415,11 +414,11 @@ class FastScroller {
if (mState == STATE_NONE) {
return false;
}
- if (me.getAction() == MotionEvent.ACTION_DOWN) {
- if (me.getX() > mList.getWidth() - mThumbW
- && me.getY() >= mThumbY
- && me.getY() <= mThumbY + mThumbH) {
-
+
+ final int action = me.getAction();
+
+ if (action == MotionEvent.ACTION_DOWN) {
+ if (isPointInside(me.getX(), me.getY())) {
setState(STATE_DRAGGING);
if (mListAdapter == null && mList != null) {
getSectionsFromIndexer();
@@ -428,7 +427,7 @@ class FastScroller {
cancelFling();
return true;
}
- } else if (me.getAction() == MotionEvent.ACTION_UP) {
+ } else if (action == MotionEvent.ACTION_UP) {
if (mState == STATE_DRAGGING) {
setState(STATE_VISIBLE);
final Handler handler = mHandler;
@@ -436,7 +435,7 @@ class FastScroller {
handler.postDelayed(mScrollFade, 1000);
return true;
}
- } else if (me.getAction() == MotionEvent.ACTION_MOVE) {
+ } else if (action == MotionEvent.ACTION_MOVE) {
if (mState == STATE_DRAGGING) {
final int viewHeight = mList.getHeight();
// Jitter
@@ -460,6 +459,10 @@ class FastScroller {
return false;
}
+ boolean isPointInside(float x, float y) {
+ return x > mList.getWidth() - mThumbW && y >= mThumbY && y <= mThumbY + mThumbH;
+ }
+
public class ScrollFade implements Runnable {
long mStartTime;
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 80fbf9e..3afd5d4 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -353,25 +353,24 @@ public class FrameLayout extends ViewGroup {
if (mForeground != null) {
final Drawable foreground = mForeground;
+
if (mForegroundBoundsChanged) {
mForegroundBoundsChanged = false;
- if (foreground != null) {
- final Rect selfBounds = mSelfBounds;
- final Rect overlayBounds = mOverlayBounds;
-
- final int w = mRight-mLeft;
- final int h = mBottom-mTop;
-
- if (mForegroundInPadding) {
- selfBounds.set(0, 0, w, h);
- } else {
- selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
- }
+ final Rect selfBounds = mSelfBounds;
+ final Rect overlayBounds = mOverlayBounds;
- Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
- foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
- foreground.setBounds(overlayBounds);
+ final int w = mRight-mLeft;
+ final int h = mBottom-mTop;
+
+ if (mForegroundInPadding) {
+ selfBounds.set(0, 0, w, h);
+ } else {
+ selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
}
+
+ Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
+ foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
+ foreground.setBounds(overlayBounds);
}
foreground.draw(canvas);
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2193dbf..bc65957 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2091,6 +2091,22 @@
<!-- Duration, in milliseconds, of the fade out effect after the user is done
drawing a gesture. -->
<attr name="fadeDuration" format="integer" />
+ <!-- Defines the type of strokes that define a gesture. -->
+ <attr name="gestureStrokeType">
+ <!-- A gesture is made of only one stroke. -->
+ <enum name="single" value="0" />
+ <!-- A gesture is made of multiple strokes. -->
+ <enum name="multiple" value="1" />
+ </attr>
+ <!-- Minimum length of a stroke before it is recognized as a gesture. -->
+ <attr name="gestureStrokeLengthThreshold" format="float" />
+ <!-- Squareness threshold of a stroke before it is recognized as a gesture. -->
+ <attr name="gestureStrokeSquarenessThreshold" format="float" />
+ <!-- Minimum curve angle a stroke must contain before it is recognized as a gesture. -->
+ <attr name="gestureStrokeAngleThreshold" format="float" />
+ <!-- Defines whether the overlay should intercept the motion events when a gesture
+ is recognized. -->
+ <attr name="eventsInterceptionEnabled" format="boolean" />
</declare-styleable>
<!-- ======================================= -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1dd5c36..d727bf6 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1107,6 +1107,11 @@
<public type="attr" name="fadeOffset" />
<public type="attr" name="fadeDuration" />
<public type="attr" name="gestures" />
+ <public type="attr" name="gestureStrokeType" />
+ <public type="attr" name="gestureStrokeLengthThreshold" />
+ <public type="attr" name="gestureStrokeSquarenessThreshold" />
+ <public type="attr" name="gestureStrokeAngleThreshold" />
+ <public type="attr" name="eventsInterceptionEnabled" />
<public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 09e299a..490abde 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -174,14 +174,18 @@
<style name="Widget.GestureOverlayView">
<item name="android:gestureStrokeWidth">12.0</item>
<item name="android:gestureColor">#ffffff00</item>
- <item name="android:uncertainGestureColor">#3cffff00</item>
- <item name="android:fadeOffset">300</item>
- <item name="android:fadeDuration">300</item>
+ <item name="android:uncertainGestureColor">#48ffff00</item>
+ <item name="android:fadeOffset">420</item>
+ <item name="android:fadeDuration">150</item>
+ <item name="android:gestureStrokeLengthThreshold">30.0</item>
+ <item name="android:gestureStrokeSquarenessThreshold">0.275</item>
+ <item name="android:gestureStrokeAngleThreshold">40.0</item>
+ <item name="android:eventsInterceptionEnabled">true</item>
</style>
<style name="Widget.GestureOverlayView.White">
<item name="android:gestureColor">#ff00ff00</item>
- <item name="android:uncertainGestureColor">#3c00ff00</item>
+ <item name="android:uncertainGestureColor">#4800ff00</item>
</style>
<style name="Widget.Button">
diff --git a/tests/sketch/res/layout/demo.xml b/tests/sketch/res/layout/demo.xml
index 2ef291a..c3a78cf 100755
--- a/tests/sketch/res/layout/demo.xml
+++ b/tests/sketch/res/layout/demo.xml
@@ -17,7 +17,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
+ android:layout_height="fill_parent">
+
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
@@ -29,6 +30,6 @@
android:id="@+id/drawingpad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"/>
+ android:layout_weight="1" />
</LinearLayout>
diff --git a/tests/sketch/res/layout/gestureviewer.xml b/tests/sketch/res/layout/gestureviewer.xml
index 1503736..e4cca52 100755
--- a/tests/sketch/res/layout/gestureviewer.xml
+++ b/tests/sketch/res/layout/gestureviewer.xml
@@ -17,7 +17,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
+ android:layout_height="fill_parent">
<Spinner
android:id="@+id/spinner"
@@ -30,7 +30,7 @@
android:id="@+id/drawingpad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"/>
+ android:layout_weight="1" />
<LinearLayout
android:orientation="horizontal"
diff --git a/tests/sketch/res/layout/overlaydemo.xml b/tests/sketch/res/layout/overlaydemo.xml
index 75c86ed..4d5a657 100644
--- a/tests/sketch/res/layout/overlaydemo.xml
+++ b/tests/sketch/res/layout/overlaydemo.xml
@@ -14,7 +14,14 @@
limitations under the License.
-->
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/list"
+<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/overlay"
android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
+ android:layout_height="fill_parent">
+
+ <ListView
+ android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+</android.gesture.GestureOverlayView>
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index f3081b7..6767de6 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -25,7 +25,6 @@ import android.os.Bundle;
import android.provider.Contacts.People;
import android.util.Log;
import android.view.View;
-import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
@@ -34,16 +33,12 @@ import android.gesture.Gesture;
import android.gesture.GestureOverlayView;
import android.gesture.LetterRecognizer;
import android.gesture.Prediction;
-import android.gesture.TouchThroughGestureListener;
import java.util.ArrayList;
public class ContactListGestureOverlay extends Activity {
-
- private static final String LOGTAG = "ContactListGestureOverlay";
-
+ private static final String LOG_TAG = "ContactListGestureOverlay";
private static final String SORT_ORDER = People.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
-
private static final String[] CONTACTS_PROJECTION = new String[] {
People._ID, // 0
People.DISPLAY_NAME, // 1
@@ -51,11 +46,9 @@ public class ContactListGestureOverlay extends Activity {
private ContactAdapter mContactAdapter;
- private TouchThroughGestureListener mGestureProcessor;
-
- private LetterRecognizer mRecognizer;
-
private ListView mContactList;
+ private LetterRecognizer mRecognizer;
+ private GestureOverlayView mOverlay;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -63,10 +56,10 @@ public class ContactListGestureOverlay extends Activity {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.overlaydemo);
- setProgressBarIndeterminateVisibility(true);
-
// create a letter recognizer
- mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
+ mRecognizer = LetterRecognizer.getLetterRecognizer(this,
+ LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
+ mOverlay = (GestureOverlayView) findViewById(R.id.overlay);
// load the contact list
mContactList = (ListView) findViewById(R.id.list);
@@ -74,13 +67,14 @@ public class ContactListGestureOverlay extends Activity {
mContactList.setTextFilterEnabled(true);
mContactList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- if (!mGestureProcessor.isGesturing()) {
+ if (!mOverlay.isGesturing()) {
Intent intent = new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(
People.CONTENT_URI, id));
startActivity(intent);
}
}
});
+
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(People.CONTENT_URI, CONTACTS_PROJECTION, null, null,
SORT_ORDER);
@@ -91,21 +85,16 @@ public class ContactListGestureOverlay extends Activity {
mContactAdapter = new ContactAdapter(this, list);
mContactList.setAdapter(mContactAdapter);
- setProgressBarIndeterminateVisibility(false);
-
- // add a gesture overlay on top of the ListView
- GestureOverlayView overlay = new GestureOverlayView(this);
- mGestureProcessor = new TouchThroughGestureListener(mContactList);
- mGestureProcessor.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE);
- mGestureProcessor.addOnGestureActionListener(new TouchThroughGestureListener.OnGesturePerformedListener() {
+ mOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
+ mOverlay.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mRecognizer.recognize(gesture);
if (!predictions.isEmpty()) {
- Log.v(LOGTAG, "1st Prediction : " + predictions.get(0).name +
+ Log.v(LOG_TAG, "1st Prediction : " + predictions.get(0).name +
" @" + predictions.get(0).score);
- Log.v(LOGTAG, "2nd Prediction : " + predictions.get(1).name +
+ Log.v(LOG_TAG, "2nd Prediction : " + predictions.get(1).name +
" @" + predictions.get(1).score);
- Log.v(LOGTAG, "3rd Prediction : " + predictions.get(2).name +
+ Log.v(LOG_TAG, "3rd Prediction : " + predictions.get(2).name +
" @" + predictions.get(2).score);
int index = mContactAdapter.search(predictions.get(0).name);
if (index != -1) {
@@ -114,9 +103,5 @@ public class ContactListGestureOverlay extends Activity {
}
}
});
- overlay.addOnGestureListener(mGestureProcessor);
- ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
- this.addContentView(overlay, params);
}
}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
index bc2503c..3f86ed4 100644
--- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
@@ -47,8 +47,9 @@ public class GestureEntry extends Activity {
private static final String PARCEL_KEY = "gesture";
- static final String GESTURE_FILE_NAME = Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + "demo_library.gestures";
+ static final String GESTURE_FILE_NAME =
+ Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +
+ "demo_library.gestures";
private static final int DIALOG_NEW_ENTRY = 1;
@@ -82,7 +83,7 @@ public class GestureEntry extends Activity {
// correct the recognition result by adding the new example
if (!mChangedByRecognizer) {
mGestureLibrary.addGesture(parent.getSelectedItem().toString(), mGesturePad
- .getCurrentGesture());
+ .getGesture());
} else {
mChangedByRecognizer = false;
}
@@ -99,7 +100,7 @@ public class GestureEntry extends Activity {
mGesturePad.setBackgroundColor(Color.BLACK);
mGesturePad.addOnGestureListener(new GestureOverlayView.OnGestureListener() {
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
- recognize(overlay.getCurrentGesture());
+ recognize(overlay.getGesture());
}
public void onGesture(GestureOverlayView overlay, MotionEvent event) {
@@ -116,7 +117,7 @@ public class GestureEntry extends Activity {
if (savedInstanceState != null) {
Gesture gesture = (Gesture) savedInstanceState.getParcelable(PARCEL_KEY);
if (gesture != null) {
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
}
}
@@ -133,7 +134,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.getCurrentGesture());
+ mGestureLibrary.addGesture(text, mGesturePad.getGesture());
}
}
}).setNegativeButton(R.string.newgesture_dialog_cancel,
@@ -157,7 +158,7 @@ public class GestureEntry extends Activity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case NEW_ID:
- if (mGesturePad.getCurrentGesture() != null) {
+ if (mGesturePad.getGesture() != null) {
showDialog(DIALOG_NEW_ENTRY);
}
break;
@@ -190,7 +191,7 @@ public class GestureEntry extends Activity {
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- Gesture gesture = mGesturePad.getCurrentGesture();
+ Gesture gesture = mGesturePad.getGesture();
if (gesture != null) {
outState.putParcelable(PARCEL_KEY, gesture);
}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
index aa07e7b..a561c96 100755
--- a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
@@ -78,7 +78,7 @@ public class GestureLibViewer extends Activity {
mCurrentGestureIndex--;
}
gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
}
@@ -109,7 +109,7 @@ public class GestureLibViewer extends Activity {
mGestures = mGesureLibrary.getGestures(list.get(0));
mCurrentGestureIndex = 0;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
mGestureCategory.setOnItemSelectedListener(new OnItemSelectedListener() {
@@ -118,7 +118,7 @@ public class GestureLibViewer extends Activity {
if (!mGestures.isEmpty()) {
mCurrentGestureIndex = 0;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
mGesturePad.invalidate();
}
@@ -139,7 +139,7 @@ public class GestureLibViewer extends Activity {
}
mCurrentGestureIndex++;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
});
@@ -150,7 +150,7 @@ public class GestureLibViewer extends Activity {
if (mCurrentGestureIndex >= 1 && !mGestures.isEmpty()) {
mCurrentGestureIndex--;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
}