diff options
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<android.gesture.GesturePoint>" @@ -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(); } } |