diff options
Diffstat (limited to 'java/src')
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java | 201 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java | 154 |
2 files changed, 210 insertions, 145 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java new file mode 100644 index 000000000..85558f1f6 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.os.Message; +import android.util.SparseArray; +import android.view.View; + +import com.android.inputmethod.keyboard.PointerTracker; +import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params; +import com.android.inputmethod.latin.CollectionUtils; +import com.android.inputmethod.latin.StaticInnerHandlerWrapper; + +/** + * Draw gesture trail preview graphics during gesture. + */ +public final class GestureTrailsPreview extends AbstractDrawingPreview { + private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails = + CollectionUtils.newSparseArray(); + private final Params mGesturePreviewTrailParams; + private final Paint mGesturePaint; + private int mOffscreenWidth; + private int mOffscreenHeight; + private int mOffscreenOffsetY; + private Bitmap mOffscreenBuffer; + private final Canvas mOffscreenCanvas = new Canvas(); + private final Rect mOffscreenSrcRect = new Rect(); + private final Rect mDirtyRect = new Rect(); + private final Rect mGesturePreviewTrailBoundsRect = new Rect(); // per trail + + private final DrawingHandler mDrawingHandler; + + private static final class DrawingHandler + extends StaticInnerHandlerWrapper<GestureTrailsPreview> { + private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 0; + + private final Params mGesturePreviewTrailParams; + + public DrawingHandler(final GestureTrailsPreview outerInstance, + final Params gesturePreviewTrailParams) { + super(outerInstance); + mGesturePreviewTrailParams = gesturePreviewTrailParams; + } + + @Override + public void handleMessage(final Message msg) { + final GestureTrailsPreview preview = getOuterInstance(); + if (preview == null) return; + switch (msg.what) { + case MSG_UPDATE_GESTURE_PREVIEW_TRAIL: + preview.getDrawingView().invalidate(); + break; + } + } + + public void postUpdateGestureTrailPreview() { + removeMessages(MSG_UPDATE_GESTURE_PREVIEW_TRAIL); + sendMessageDelayed(obtainMessage(MSG_UPDATE_GESTURE_PREVIEW_TRAIL), + mGesturePreviewTrailParams.mUpdateInterval); + } + } + + public GestureTrailsPreview(final View drawingView, final TypedArray mainKeyboardViewAttr) { + super(drawingView); + mGesturePreviewTrailParams = new Params(mainKeyboardViewAttr); + mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams); + final Paint gesturePaint = new Paint(); + gesturePaint.setAntiAlias(true); + gesturePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); + mGesturePaint = gesturePaint; + } + + @Override + public void setKeyboardGeometry(final int[] originCoords, final int width, final int height) { + mOffscreenOffsetY = (int)( + height * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO); + mOffscreenWidth = width; + mOffscreenHeight = mOffscreenOffsetY + height; + } + + @Override + public void onDetachFromWindow() { + freeOffscreenBuffer(); + } + + private void freeOffscreenBuffer() { + if (mOffscreenBuffer != null) { + mOffscreenBuffer.recycle(); + mOffscreenBuffer = null; + } + } + + private void mayAllocateOffscreenBuffer() { + if (mOffscreenBuffer != null && mOffscreenBuffer.getWidth() == mOffscreenWidth + && mOffscreenBuffer.getHeight() == mOffscreenHeight) { + return; + } + freeOffscreenBuffer(); + mOffscreenBuffer = Bitmap.createBitmap( + mOffscreenWidth, mOffscreenHeight, Bitmap.Config.ARGB_8888); + mOffscreenCanvas.setBitmap(mOffscreenBuffer); + mOffscreenCanvas.translate(0, mOffscreenOffsetY); + } + + private boolean drawGestureTrails(final Canvas offscreenCanvas, final Paint paint, + final Rect dirtyRect) { + // Clear previous dirty rectangle. + if (!dirtyRect.isEmpty()) { + paint.setColor(Color.TRANSPARENT); + paint.setStyle(Paint.Style.FILL); + offscreenCanvas.drawRect(dirtyRect, paint); + } + dirtyRect.setEmpty(); + boolean needsUpdatingGesturePreviewTrail = false; + // Draw gesture trails to offscreen buffer. + synchronized (mGesturePreviewTrails) { + // Trails count == fingers count that have ever been active. + final int trailsCount = mGesturePreviewTrails.size(); + for (int index = 0; index < trailsCount; index++) { + final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index); + needsUpdatingGesturePreviewTrail |= + trail.drawGestureTrail(offscreenCanvas, paint, + mGesturePreviewTrailBoundsRect, mGesturePreviewTrailParams); + // {@link #mGesturePreviewTrailBoundsRect} has bounding box of the trail. + dirtyRect.union(mGesturePreviewTrailBoundsRect); + } + } + return needsUpdatingGesturePreviewTrail; + } + + /** + * Draws the preview + * @param canvas The canvas where the preview is drawn. + */ + @Override + public void drawPreview(final Canvas canvas) { + if (!isPreviewEnabled()) { + return; + } + mayAllocateOffscreenBuffer(); + // Draw gesture trails to offscreen buffer. + final boolean needsUpdatingGesturePreviewTrail = drawGestureTrails( + mOffscreenCanvas, mGesturePaint, mDirtyRect); + if (needsUpdatingGesturePreviewTrail) { + mDrawingHandler.postUpdateGestureTrailPreview(); + } + // Transfer offscreen buffer to screen. + if (!mDirtyRect.isEmpty()) { + mOffscreenSrcRect.set(mDirtyRect); + mOffscreenSrcRect.offset(0, mOffscreenOffsetY); + canvas.drawBitmap(mOffscreenBuffer, mOffscreenSrcRect, mDirtyRect, null); + // Note: Defer clearing the dirty rectangle here because we will get cleared + // rectangle on the canvas. + } + } + + /** + * Set the position of the preview. + * @param tracker The new location of the preview is based on the points in PointerTracker. + */ + @Override + public void setPreviewPosition(final PointerTracker tracker) { + if (!isPreviewEnabled()) { + return; + } + GesturePreviewTrail trail; + synchronized (mGesturePreviewTrails) { + trail = mGesturePreviewTrails.get(tracker.mPointerId); + if (trail == null) { + trail = new GesturePreviewTrail(); + mGesturePreviewTrails.put(tracker.mPointerId, trail); + } + } + trail.addStroke(tracker.getGestureStrokeWithPreviewPoints(), tracker.getDownTime()); + + // TODO: Should narrow the invalidate region. + getDrawingView().invalidate(); + } +} diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index af8bb78d8..10ef78441 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -18,79 +18,26 @@ package com.android.inputmethod.keyboard.internal; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.os.Message; import android.util.AttributeSet; -import android.util.SparseArray; import android.widget.RelativeLayout; import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params; -import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.CoordinateUtils; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import com.android.inputmethod.latin.SuggestedWords; public final class PreviewPlacerView extends RelativeLayout { private final int[] mKeyboardViewOrigin = CoordinateUtils.newInstance(); - // TODO: Separate gesture preview trail drawing code into separate class. - private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails = - CollectionUtils.newSparseArray(); - private final Params mGesturePreviewTrailParams; - private final Paint mGesturePaint; - private boolean mDrawsGesturePreviewTrail; - private int mOffscreenWidth; - private int mOffscreenHeight; - private int mOffscreenOffsetY; - private Bitmap mOffscreenBuffer; - private final Canvas mOffscreenCanvas = new Canvas(); - private final Rect mOffscreenSrcRect = new Rect(); - private final Rect mDirtyRect = new Rect(); - private final Rect mGesturePreviewTrailBoundsRect = new Rect(); // per trail // TODO: Move these AbstractDrawingPvreiew objects to MainKeyboardView. private final GestureFloatingPreviewText mGestureFloatingPreviewText; + private final GestureTrailsPreview mGestureTrailsPreview; private final SlidingKeyInputPreview mSlidingKeyInputPreview; - private final DrawingHandler mDrawingHandler; - - // TODO: Remove drawing handler. - private static final class DrawingHandler extends StaticInnerHandlerWrapper<PreviewPlacerView> { - private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 0; - - private final Params mGesturePreviewTrailParams; - - public DrawingHandler(final PreviewPlacerView outerInstance, - final Params gesturePreviewTrailParams) { - super(outerInstance); - mGesturePreviewTrailParams = gesturePreviewTrailParams; - } - - @Override - public void handleMessage(final Message msg) { - final PreviewPlacerView placerView = getOuterInstance(); - if (placerView == null) return; - switch (msg.what) { - case MSG_UPDATE_GESTURE_PREVIEW_TRAIL: - placerView.invalidate(); - break; - } - } - - public void postUpdateGestureTrailPreview() { - removeMessages(MSG_UPDATE_GESTURE_PREVIEW_TRAIL); - sendMessageDelayed(obtainMessage(MSG_UPDATE_GESTURE_PREVIEW_TRAIL), - mGesturePreviewTrailParams.mUpdateInterval); - } - } - public PreviewPlacerView(final Context context, final AttributeSet attrs) { this(context, attrs, R.attr.keyboardViewStyle); } @@ -104,17 +51,10 @@ public final class PreviewPlacerView extends RelativeLayout { // TODO: mGestureFloatingPreviewText could be an instance of GestureFloatingPreviewText or // MultiGesturePreviewText, depending on the user's choice in the settings. mGestureFloatingPreviewText = new GestureFloatingPreviewText(this, mainKeyboardViewAttr); - mGesturePreviewTrailParams = new Params(mainKeyboardViewAttr); + mGestureTrailsPreview = new GestureTrailsPreview(this, mainKeyboardViewAttr); mSlidingKeyInputPreview = new SlidingKeyInputPreview(this, mainKeyboardViewAttr); mainKeyboardViewAttr.recycle(); - mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams); - - final Paint gesturePaint = new Paint(); - gesturePaint.setAntiAlias(true); - gesturePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - mGesturePaint = gesturePaint; - final Paint layerPaint = new Paint(); layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); setLayerType(LAYER_TYPE_HARDWARE, layerPaint); @@ -124,36 +64,21 @@ public final class PreviewPlacerView extends RelativeLayout { final int height) { CoordinateUtils.copy(mKeyboardViewOrigin, originCoords); mGestureFloatingPreviewText.setKeyboardGeometry(originCoords, width, height); + mGestureTrailsPreview.setKeyboardGeometry(originCoords, width, height); mSlidingKeyInputPreview.setKeyboardGeometry(originCoords, width, height); - mOffscreenOffsetY = (int)( - height * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO); - mOffscreenWidth = width; - mOffscreenHeight = mOffscreenOffsetY + height; } + // TODO: Move this method to MainKeyboardView public void setGesturePreviewMode(final boolean drawsGesturePreviewTrail, final boolean drawsGestureFloatingPreviewText) { - mDrawsGesturePreviewTrail = drawsGesturePreviewTrail; mGestureFloatingPreviewText.setPreviewEnabled(drawsGestureFloatingPreviewText); + mGestureTrailsPreview.setPreviewEnabled(drawsGesturePreviewTrail); } + // TODO: Move this method to MainKeyboardView public void invalidatePointer(final PointerTracker tracker) { mGestureFloatingPreviewText.setPreviewPosition(tracker); - - if (mDrawsGesturePreviewTrail) { - GesturePreviewTrail trail; - synchronized (mGesturePreviewTrails) { - trail = mGesturePreviewTrails.get(tracker.mPointerId); - if (trail == null) { - trail = new GesturePreviewTrail(); - mGesturePreviewTrails.put(tracker.mPointerId, trail); - } - } - trail.addStroke(tracker.getGestureStrokeWithPreviewPoints(), tracker.getDownTime()); - - // TODO: Should narrow the invalidate region. - invalidate(); - } + mGestureTrailsPreview.setPreviewPosition(tracker); } // TODO: Move this method to MainKeyboardView @@ -170,27 +95,8 @@ public final class PreviewPlacerView extends RelativeLayout { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mGestureFloatingPreviewText.onDetachFromWindow(); + mGestureTrailsPreview.onDetachFromWindow(); mSlidingKeyInputPreview.onDetachFromWindow(); - freeOffscreenBuffer(); - } - - private void freeOffscreenBuffer() { - if (mOffscreenBuffer != null) { - mOffscreenBuffer.recycle(); - mOffscreenBuffer = null; - } - } - - private void mayAllocateOffscreenBuffer() { - if (mOffscreenBuffer != null && mOffscreenBuffer.getWidth() == mOffscreenWidth - && mOffscreenBuffer.getHeight() == mOffscreenHeight) { - return; - } - freeOffscreenBuffer(); - mOffscreenBuffer = Bitmap.createBitmap( - mOffscreenWidth, mOffscreenHeight, Bitmap.Config.ARGB_8888); - mOffscreenCanvas.setBitmap(mOffscreenBuffer); - mOffscreenCanvas.translate(0, mOffscreenOffsetY); } @Override @@ -199,54 +105,12 @@ public final class PreviewPlacerView extends RelativeLayout { final int originX = CoordinateUtils.x(mKeyboardViewOrigin); final int originY = CoordinateUtils.y(mKeyboardViewOrigin); canvas.translate(originX, originY); - if (mDrawsGesturePreviewTrail) { - mayAllocateOffscreenBuffer(); - // Draw gesture trails to offscreen buffer. - final boolean needsUpdatingGesturePreviewTrail = drawGestureTrails( - mOffscreenCanvas, mGesturePaint, mDirtyRect); - if (needsUpdatingGesturePreviewTrail) { - mDrawingHandler.postUpdateGestureTrailPreview(); - } - // Transfer offscreen buffer to screen. - if (!mDirtyRect.isEmpty()) { - mOffscreenSrcRect.set(mDirtyRect); - mOffscreenSrcRect.offset(0, mOffscreenOffsetY); - canvas.drawBitmap(mOffscreenBuffer, mOffscreenSrcRect, mDirtyRect, null); - // Note: Defer clearing the dirty rectangle here because we will get cleared - // rectangle on the canvas. - } - } mGestureFloatingPreviewText.drawPreview(canvas); + mGestureTrailsPreview.drawPreview(canvas); mSlidingKeyInputPreview.drawPreview(canvas); canvas.translate(-originX, -originY); } - private boolean drawGestureTrails(final Canvas offscreenCanvas, final Paint paint, - final Rect dirtyRect) { - // Clear previous dirty rectangle. - if (!dirtyRect.isEmpty()) { - paint.setColor(Color.TRANSPARENT); - paint.setStyle(Paint.Style.FILL); - offscreenCanvas.drawRect(dirtyRect, paint); - } - dirtyRect.setEmpty(); - boolean needsUpdatingGesturePreviewTrail = false; - // Draw gesture trails to offscreen buffer. - synchronized (mGesturePreviewTrails) { - // Trails count == fingers count that have ever been active. - final int trailsCount = mGesturePreviewTrails.size(); - for (int index = 0; index < trailsCount; index++) { - final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index); - needsUpdatingGesturePreviewTrail |= - trail.drawGestureTrail(offscreenCanvas, paint, - mGesturePreviewTrailBoundsRect, mGesturePreviewTrailParams); - // {@link #mGesturePreviewTrailBoundsRect} has bounding box of the trail. - dirtyRect.union(mGesturePreviewTrailBoundsRect); - } - } - return needsUpdatingGesturePreviewTrail; - } - // TODO: Move this method to MainKeyboardView. public void setGestureFloatingPreviewText(final SuggestedWords suggestedWords) { mGestureFloatingPreviewText.setSuggetedWords(suggestedWords); |