Cleanup keyboard drawing code
Change-Id: I084e3ac835ee60b8e463ac10c075adbf08b9a7cbmain
parent
eaa091da78
commit
f2fd472dcc
|
@ -68,8 +68,7 @@ import java.util.WeakHashMap;
|
||||||
* @attr ref R.styleable#KeyboardView_popupLayout
|
* @attr ref R.styleable#KeyboardView_popupLayout
|
||||||
*/
|
*/
|
||||||
public class KeyboardView extends View implements PointerTracker.UIProxy {
|
public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
private static final String TAG = "KeyboardView";
|
private static final String TAG = KeyboardView.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
|
||||||
private static final boolean DEBUG_SHOW_ALIGN = false;
|
private static final boolean DEBUG_SHOW_ALIGN = false;
|
||||||
private static final boolean DEBUG_KEYBOARD_GRID = false;
|
private static final boolean DEBUG_KEYBOARD_GRID = false;
|
||||||
|
|
||||||
|
@ -115,7 +114,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
private int[] mOffsetInWindow;
|
private int[] mOffsetInWindow;
|
||||||
private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY;
|
private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY;
|
||||||
private boolean mShowPreview = true;
|
private boolean mShowPreview = true;
|
||||||
private boolean mShowTouchPoints = true;
|
|
||||||
private int mPopupPreviewOffsetX;
|
private int mPopupPreviewOffsetX;
|
||||||
private int mPopupPreviewOffsetY;
|
private int mPopupPreviewOffsetY;
|
||||||
private int mWindowY;
|
private int mWindowY;
|
||||||
|
@ -158,18 +156,20 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
// Drawing
|
// Drawing
|
||||||
/** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/
|
/** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/
|
||||||
private boolean mDrawPending;
|
private boolean mDrawPending;
|
||||||
/** The dirty region in the keyboard bitmap */
|
|
||||||
private final Rect mDirtyRect = new Rect();
|
|
||||||
/** The keyboard bitmap for faster updates */
|
|
||||||
private Bitmap mBuffer;
|
|
||||||
/** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */
|
/** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */
|
||||||
private boolean mKeyboardChanged;
|
private boolean mKeyboardChanged;
|
||||||
|
/** The dirty region in the keyboard bitmap */
|
||||||
|
private final Rect mDirtyRect = new Rect();
|
||||||
|
/** The key to invalidate. */
|
||||||
private Key mInvalidatedKey;
|
private Key mInvalidatedKey;
|
||||||
|
/** The dirty region for single key drawing */
|
||||||
|
private final Rect mInvalidatedKeyRect = new Rect();
|
||||||
|
/** The keyboard bitmap for faster updates */
|
||||||
|
private Bitmap mBuffer;
|
||||||
/** The canvas for the above mutable keyboard bitmap */
|
/** The canvas for the above mutable keyboard bitmap */
|
||||||
private Canvas mCanvas;
|
private Canvas mCanvas;
|
||||||
private final Paint mPaint;
|
private final Paint mPaint;
|
||||||
private final Rect mPadding;
|
private final Rect mPadding;
|
||||||
private final Rect mClipRegion = new Rect(0, 0, 0, 0);
|
|
||||||
// This map caches key label text height in pixel as value and key label text size as map key.
|
// This map caches key label text height in pixel as value and key label text size as map key.
|
||||||
private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>();
|
private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>();
|
||||||
// Distance from horizontal center of the key, proportional to key label text height and width.
|
// Distance from horizontal center of the key, proportional to key label text height and width.
|
||||||
|
@ -506,7 +506,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
tracker.setKeyboard(keyboard, mKeys, mKeyHysteresisDistance);
|
tracker.setKeyboard(keyboard, mKeys, mKeyHysteresisDistance);
|
||||||
}
|
}
|
||||||
requestLayout();
|
requestLayout();
|
||||||
// Hint to reallocate the buffer if the size changed
|
|
||||||
mKeyboardChanged = true;
|
mKeyboardChanged = true;
|
||||||
invalidateAllKeys();
|
invalidateAllKeys();
|
||||||
computeProximityThreshold(keyboard, mKeys);
|
computeProximityThreshold(keyboard, mKeys);
|
||||||
|
@ -625,13 +624,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
mKeyDetector.setProximityThreshold(mostCommonWidth);
|
mKeyDetector.setProximityThreshold(mostCommonWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSizeChanged(int w, int h, int oldw, int oldh) {
|
|
||||||
super.onSizeChanged(w, h, oldw, oldh);
|
|
||||||
// Release the buffer, if any and it will be reallocated on the next draw
|
|
||||||
mBuffer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDraw(Canvas canvas) {
|
public void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
@ -641,19 +633,18 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
canvas.drawBitmap(mBuffer, 0, 0, null);
|
canvas.drawBitmap(mBuffer, 0, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private void onBufferDraw() {
|
private void onBufferDraw() {
|
||||||
|
final int width = getWidth();
|
||||||
|
final int height = getHeight();
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
return;
|
||||||
if (mBuffer == null || mKeyboardChanged) {
|
if (mBuffer == null || mKeyboardChanged) {
|
||||||
if (mBuffer == null || mKeyboardChanged &&
|
|
||||||
(mBuffer.getWidth() != getWidth() || mBuffer.getHeight() != getHeight())) {
|
|
||||||
// Make sure our bitmap is at least 1x1
|
|
||||||
final int width = Math.max(1, getWidth());
|
|
||||||
final int height = Math.max(1, getHeight());
|
|
||||||
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
mCanvas = new Canvas(mBuffer);
|
|
||||||
}
|
|
||||||
invalidateAllKeys();
|
|
||||||
mKeyboardChanged = false;
|
mKeyboardChanged = false;
|
||||||
|
mDirtyRect.union(0, 0, width, height);
|
||||||
|
}
|
||||||
|
if (mBuffer == null || mBuffer.getWidth() != width || mBuffer.getHeight() != height) {
|
||||||
|
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
mCanvas = new Canvas(mBuffer);
|
||||||
}
|
}
|
||||||
final Canvas canvas = mCanvas;
|
final Canvas canvas = mCanvas;
|
||||||
canvas.clipRect(mDirtyRect, Op.REPLACE);
|
canvas.clipRect(mDirtyRect, Op.REPLACE);
|
||||||
|
@ -662,30 +653,19 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
|
|
||||||
final Paint paint = mPaint;
|
final Paint paint = mPaint;
|
||||||
final Drawable keyBackground = mKeyBackground;
|
final Drawable keyBackground = mKeyBackground;
|
||||||
final Rect clipRegion = mClipRegion;
|
|
||||||
final Rect padding = mPadding;
|
final Rect padding = mPadding;
|
||||||
final int kbdPaddingLeft = getPaddingLeft();
|
final int kbdPaddingLeft = getPaddingLeft();
|
||||||
final int kbdPaddingTop = getPaddingTop();
|
final int kbdPaddingTop = getPaddingTop();
|
||||||
final Key[] keys = mKeys;
|
final Key[] keys = mKeys;
|
||||||
final Key invalidKey = mInvalidatedKey;
|
|
||||||
final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
|
final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
|
||||||
|
final boolean drawSingleKey = (mInvalidatedKey != null
|
||||||
|
&& mInvalidatedKeyRect.contains(mDirtyRect));
|
||||||
|
|
||||||
boolean drawSingleKey = false;
|
|
||||||
if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
|
|
||||||
// TODO we should use Rect.inset and Rect.contains here.
|
|
||||||
// Is clipRegion completely contained within the invalidated key?
|
|
||||||
if (invalidKey.mX + kbdPaddingLeft - 1 <= clipRegion.left &&
|
|
||||||
invalidKey.mY + kbdPaddingTop - 1 <= clipRegion.top &&
|
|
||||||
invalidKey.mX + invalidKey.mWidth + kbdPaddingLeft + 1 >= clipRegion.right &&
|
|
||||||
invalidKey.mY + invalidKey.mHeight + kbdPaddingTop + 1 >= clipRegion.bottom) {
|
|
||||||
drawSingleKey = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
|
canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
|
||||||
final int keyCount = keys.length;
|
final int keyCount = keys.length;
|
||||||
for (int i = 0; i < keyCount; i++) {
|
for (int i = 0; i < keyCount; i++) {
|
||||||
final Key key = keys[i];
|
final Key key = keys[i];
|
||||||
if (drawSingleKey && invalidKey != key) {
|
if (drawSingleKey && key != mInvalidatedKey) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int[] drawableState = key.getCurrentDrawableState();
|
int[] drawableState = key.getCurrentDrawableState();
|
||||||
|
@ -739,8 +719,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
} else {
|
} else {
|
||||||
positionX = (key.mWidth + padding.left - padding.right) / 2;
|
positionX = (key.mWidth + padding.left - padding.right) / 2;
|
||||||
paint.setTextAlign(Align.CENTER);
|
paint.setTextAlign(Align.CENTER);
|
||||||
if (DEBUG_SHOW_ALIGN && label.length() > 1)
|
if (DEBUG_SHOW_ALIGN) {
|
||||||
drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
|
if (label.length() > 1)
|
||||||
|
drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
|
if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
|
||||||
paint.setColor(mKeyTextColorDisabled);
|
paint.setColor(mKeyTextColorDisabled);
|
||||||
|
@ -811,32 +793,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
canvas.drawLine(0, i * ch, cw * mKeyboard.GRID_WIDTH, i * ch, p);
|
canvas.drawLine(0, i * ch, cw * mKeyboard.GRID_WIDTH, i * ch, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
mInvalidatedKey = null;
|
|
||||||
// Overlay a dark rectangle to dim the keyboard
|
// Overlay a dark rectangle to dim the keyboard
|
||||||
if (mMiniKeyboardView != null) {
|
if (mMiniKeyboardView != null) {
|
||||||
paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
|
paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
|
||||||
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
|
canvas.drawRect(0, 0, width, height, paint);
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
if (mShowTouchPoints) {
|
|
||||||
for (PointerTracker tracker : mPointerTrackers) {
|
|
||||||
int startX = tracker.getStartX();
|
|
||||||
int startY = tracker.getStartY();
|
|
||||||
int lastX = tracker.getLastX();
|
|
||||||
int lastY = tracker.getLastY();
|
|
||||||
paint.setAlpha(128);
|
|
||||||
paint.setColor(0xFFFF0000);
|
|
||||||
canvas.drawCircle(startX, startY, 3, paint);
|
|
||||||
canvas.drawLine(startX, startY, lastX, lastY, paint);
|
|
||||||
paint.setColor(0xFF0000FF);
|
|
||||||
canvas.drawCircle(lastX, lastY, 3, paint);
|
|
||||||
paint.setColor(0xFF00FF00);
|
|
||||||
canvas.drawCircle((startX + lastX) / 2, (startY + lastY) / 2, 2, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInvalidatedKey = null;
|
||||||
mDrawPending = false;
|
mDrawPending = false;
|
||||||
mDirtyRect.setEmpty();
|
mDirtyRect.setEmpty();
|
||||||
}
|
}
|
||||||
|
@ -1050,12 +1013,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
if (key == null)
|
if (key == null)
|
||||||
return;
|
return;
|
||||||
mInvalidatedKey = key;
|
mInvalidatedKey = key;
|
||||||
// TODO we should clean up this and record key's region to use in onBufferDraw.
|
mInvalidatedKeyRect.set(0, 0, key.mWidth, key.mHeight);
|
||||||
mDirtyRect.union(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
|
mInvalidatedKeyRect.offset(key.mX + getPaddingLeft(), key.mY + getPaddingTop());
|
||||||
key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
|
mDirtyRect.union(mInvalidatedKeyRect);
|
||||||
onBufferDraw();
|
onBufferDraw();
|
||||||
invalidate(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
|
invalidate(mInvalidatedKeyRect);
|
||||||
key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
|
private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
|
||||||
|
|
|
@ -490,15 +490,6 @@ public class PointerTracker {
|
||||||
return mKeyState.getDownTime();
|
return mKeyState.getDownTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// These package scope methods are only for debugging purpose.
|
|
||||||
/* package */ int getStartX() {
|
|
||||||
return mKeyState.getStartX();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package */ int getStartY() {
|
|
||||||
return mKeyState.getStartY();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMinorMoveBounce(int x, int y, int newKey) {
|
private boolean isMinorMoveBounce(int x, int y, int newKey) {
|
||||||
if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
|
if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
|
||||||
throw new IllegalStateException("keyboard and/or hysteresis not set");
|
throw new IllegalStateException("keyboard and/or hysteresis not set");
|
||||||
|
|
|
@ -23,8 +23,6 @@ package com.android.inputmethod.keyboard;
|
||||||
private final KeyDetector mKeyDetector;
|
private final KeyDetector mKeyDetector;
|
||||||
|
|
||||||
// The position and time at which first down event occurred.
|
// The position and time at which first down event occurred.
|
||||||
private int mStartX;
|
|
||||||
private int mStartY;
|
|
||||||
private long mDownTime;
|
private long mDownTime;
|
||||||
private long mUpTime;
|
private long mUpTime;
|
||||||
|
|
||||||
|
@ -54,14 +52,6 @@ package com.android.inputmethod.keyboard;
|
||||||
return mKeyY;
|
return mKeyY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStartX() {
|
|
||||||
return mStartX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStartY() {
|
|
||||||
return mStartY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDownTime() {
|
public long getDownTime() {
|
||||||
return mDownTime;
|
return mDownTime;
|
||||||
}
|
}
|
||||||
|
@ -79,8 +69,6 @@ package com.android.inputmethod.keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int onDownKey(int x, int y, long eventTime) {
|
public int onDownKey(int x, int y, long eventTime) {
|
||||||
mStartX = x;
|
|
||||||
mStartY = y;
|
|
||||||
mDownTime = eventTime;
|
mDownTime = eventTime;
|
||||||
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue