| /* |
| * Copyright (C) 2012 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.Canvas; |
| import android.graphics.Paint; |
| import android.graphics.Paint.Align; |
| import android.graphics.Rect; |
| import android.graphics.RectF; |
| import android.text.TextUtils; |
| import android.view.View; |
| |
| import com.android.inputmethod.keyboard.PointerTracker; |
| import com.android.inputmethod.latin.CoordinateUtils; |
| import com.android.inputmethod.latin.R; |
| import com.android.inputmethod.latin.SuggestedWords; |
| |
| /** |
| * The class for single gesture preview text. The class for multiple gesture preview text will be |
| * derived from it. |
| * |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextSize |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextColor |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextOffset |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewColor |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewHorizontalPadding |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewVerticalPadding |
| * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewRoundRadius |
| */ |
| public class GestureFloatingPreviewText extends AbstractDrawingPreview { |
| protected static final class GesturePreviewTextParams { |
| public final int mGesturePreviewTextOffset; |
| public final int mGesturePreviewTextHeight; |
| public final float mGesturePreviewHorizontalPadding; |
| public final float mGesturePreviewVerticalPadding; |
| public final float mGesturePreviewRoundRadius; |
| |
| private final int mGesturePreviewTextSize; |
| private final int mGesturePreviewTextColor; |
| private final int mGesturePreviewColor; |
| private final Paint mPaint = new Paint(); |
| |
| private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' }; |
| |
| public GesturePreviewTextParams(final TypedArray mainKeyboardViewAttr) { |
| mGesturePreviewTextSize = mainKeyboardViewAttr.getDimensionPixelSize( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewTextSize, 0); |
| mGesturePreviewTextColor = mainKeyboardViewAttr.getColor( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewTextColor, 0); |
| mGesturePreviewTextOffset = mainKeyboardViewAttr.getDimensionPixelOffset( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewTextOffset, 0); |
| mGesturePreviewColor = mainKeyboardViewAttr.getColor( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewColor, 0); |
| mGesturePreviewHorizontalPadding = mainKeyboardViewAttr.getDimension( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewHorizontalPadding, 0.0f); |
| mGesturePreviewVerticalPadding = mainKeyboardViewAttr.getDimension( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewVerticalPadding, 0.0f); |
| mGesturePreviewRoundRadius = mainKeyboardViewAttr.getDimension( |
| R.styleable.MainKeyboardView_gestureFloatingPreviewRoundRadius, 0.0f); |
| |
| final Paint textPaint = getTextPaint(); |
| final Rect textRect = new Rect(); |
| textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect); |
| mGesturePreviewTextHeight = textRect.height(); |
| } |
| |
| public Paint getTextPaint() { |
| mPaint.setAntiAlias(true); |
| mPaint.setTextAlign(Align.CENTER); |
| mPaint.setTextSize(mGesturePreviewTextSize); |
| mPaint.setColor(mGesturePreviewTextColor); |
| return mPaint; |
| } |
| |
| public Paint getBackgroundPaint() { |
| mPaint.setColor(mGesturePreviewColor); |
| return mPaint; |
| } |
| } |
| |
| private final GesturePreviewTextParams mParams; |
| private final RectF mGesturePreviewRectangle = new RectF(); |
| private int mPreviewTextX; |
| private int mPreviewTextY; |
| private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; |
| private final int[] mLastPointerCoords = CoordinateUtils.newInstance(); |
| |
| public GestureFloatingPreviewText(final View drawingView, final TypedArray typedArray) { |
| super(drawingView); |
| mParams = new GesturePreviewTextParams(typedArray); |
| } |
| |
| public void setSuggetedWords(final SuggestedWords suggestedWords) { |
| if (!isPreviewEnabled()) { |
| return; |
| } |
| mSuggestedWords = suggestedWords; |
| updatePreviewPosition(); |
| } |
| |
| @Override |
| public void setPreviewPosition(final PointerTracker tracker) { |
| final boolean needsToUpdateLastPointer = |
| tracker.isOldestTrackerInQueue() && isPreviewEnabled(); |
| if (!needsToUpdateLastPointer) { |
| return; |
| } |
| tracker.getLastCoordinates(mLastPointerCoords); |
| updatePreviewPosition(); |
| } |
| |
| /** |
| * Draws gesture preview text |
| * @param canvas The canvas where preview text is drawn. |
| */ |
| @Override |
| public void drawPreview(final Canvas canvas) { |
| if (!isPreviewEnabled() || mSuggestedWords.isEmpty() |
| || TextUtils.isEmpty(mSuggestedWords.getWord(0))) { |
| return; |
| } |
| final float round = mParams.mGesturePreviewRoundRadius; |
| canvas.drawRoundRect( |
| mGesturePreviewRectangle, round, round, mParams.getBackgroundPaint()); |
| final String text = mSuggestedWords.getWord(0); |
| canvas.drawText(text, mPreviewTextX, mPreviewTextY, mParams.getTextPaint()); |
| } |
| |
| /** |
| * Updates gesture preview text position based on mLastPointerCoords. |
| */ |
| protected void updatePreviewPosition() { |
| if (mSuggestedWords.isEmpty() || TextUtils.isEmpty(mSuggestedWords.getWord(0))) { |
| getDrawingView().invalidate(); |
| return; |
| } |
| final String text = mSuggestedWords.getWord(0); |
| |
| final RectF rectangle = mGesturePreviewRectangle; |
| |
| final int textHeight = mParams.mGesturePreviewTextHeight; |
| final float textWidth = mParams.getTextPaint().measureText(text); |
| final float hPad = mParams.mGesturePreviewHorizontalPadding; |
| final float vPad = mParams.mGesturePreviewVerticalPadding; |
| final float rectWidth = textWidth + hPad * 2.0f; |
| final float rectHeight = textHeight + vPad * 2.0f; |
| |
| final int displayWidth = getDrawingView().getResources().getDisplayMetrics().widthPixels; |
| final float rectX = Math.min( |
| Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f), |
| displayWidth - rectWidth); |
| final float rectY = CoordinateUtils.y(mLastPointerCoords) |
| - mParams.mGesturePreviewTextOffset - rectHeight; |
| rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight); |
| |
| mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f); |
| mPreviewTextY = (int)(rectY + vPad) + textHeight; |
| // TODO: Should narrow the invalidate region. |
| getDrawingView().invalidate(); |
| } |
| } |