Merge "Refactor key preview methods" into gingerbread
commit
dc406a2db6
|
@ -204,7 +204,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
/** Listener for {@link OnKeyboardActionListener}. */
|
/** Listener for {@link OnKeyboardActionListener}. */
|
||||||
private OnKeyboardActionListener mKeyboardActionListener;
|
private OnKeyboardActionListener mKeyboardActionListener;
|
||||||
|
|
||||||
private final KeyDebouncer mDebouncer = new KeyDebouncer();
|
private final KeyDebouncer mDebouncer;
|
||||||
private final float mDebounceHysteresis;
|
private final float mDebounceHysteresis;
|
||||||
private int mCurrentKey = NOT_A_KEY;
|
private int mCurrentKey = NOT_A_KEY;
|
||||||
private int mStartX;
|
private int mStartX;
|
||||||
|
@ -251,7 +251,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
private static final int MSG_POPUP_PREVIEW = 1;
|
private static final int MSG_POPUP_PREVIEW = 1;
|
||||||
private static final int MSG_DISMISS_PREVIEW = 2;
|
private static final int MSG_DISMISS_PREVIEW = 2;
|
||||||
private static final int MSG_REPEAT_KEY = 3;
|
private static final int MSG_REPEAT_KEY = 3;
|
||||||
private static final int MSG_LOGPRESS_KEY = 4;
|
private static final int MSG_LONGPRESS_KEY = 4;
|
||||||
|
|
||||||
private boolean mInKeyRepeat;
|
private boolean mInKeyRepeat;
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_POPUP_PREVIEW:
|
case MSG_POPUP_PREVIEW:
|
||||||
showKey(msg.arg1);
|
showKey((Key)msg.obj);
|
||||||
break;
|
break;
|
||||||
case MSG_DISMISS_PREVIEW:
|
case MSG_DISMISS_PREVIEW:
|
||||||
mPreviewText.setVisibility(INVISIBLE);
|
mPreviewText.setVisibility(INVISIBLE);
|
||||||
|
@ -268,15 +268,15 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
repeatKey(msg.arg1);
|
repeatKey(msg.arg1);
|
||||||
startKeyRepeatTimer(REPEAT_INTERVAL, msg.arg1);
|
startKeyRepeatTimer(REPEAT_INTERVAL, msg.arg1);
|
||||||
break;
|
break;
|
||||||
case MSG_LOGPRESS_KEY:
|
case MSG_LONGPRESS_KEY:
|
||||||
openPopupIfRequired(msg.arg1);
|
openPopupIfRequired(msg.arg1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void popupPreview(int keyIndex, long delay) {
|
public void popupPreview(Key key, long delay) {
|
||||||
removeMessages(MSG_POPUP_PREVIEW);
|
removeMessages(MSG_POPUP_PREVIEW);
|
||||||
sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0), delay);
|
sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, key), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelPopupPreview() {
|
public void cancelPopupPreview() {
|
||||||
|
@ -306,12 +306,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startLongPressTimer(int keyIndex, long delay) {
|
public void startLongPressTimer(int keyIndex, long delay) {
|
||||||
removeMessages(MSG_LOGPRESS_KEY);
|
removeMessages(MSG_LONGPRESS_KEY);
|
||||||
sendMessageDelayed(obtainMessage(MSG_LOGPRESS_KEY, keyIndex, 0), delay);
|
sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelLongPressTimer() {
|
public void cancelLongPressTimer() {
|
||||||
removeMessages(MSG_LOGPRESS_KEY);
|
removeMessages(MSG_LONGPRESS_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelKeyTimers() {
|
public void cancelKeyTimers() {
|
||||||
|
@ -326,7 +326,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static class KeyDebouncer {
|
public static class KeyDebouncer {
|
||||||
|
public interface UIProxy {
|
||||||
|
public void invalidateKey(Key key);
|
||||||
|
}
|
||||||
|
private final UIProxy mProxy;
|
||||||
|
|
||||||
private Key[] mKeys;
|
private Key[] mKeys;
|
||||||
private int mKeyDebounceThresholdSquared = -1;
|
private int mKeyDebounceThresholdSquared = -1;
|
||||||
|
|
||||||
|
@ -342,6 +347,15 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
private long mLastMoveTime;
|
private long mLastMoveTime;
|
||||||
private long mCurrentKeyTime;
|
private long mCurrentKeyTime;
|
||||||
|
|
||||||
|
// pressed key
|
||||||
|
private int mPreviousKey;
|
||||||
|
|
||||||
|
public KeyDebouncer(UIProxy proxy) {
|
||||||
|
if (proxy == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
mProxy = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
public void setKeyboard(Key[] keys, float hysteresisPixel) {
|
public void setKeyboard(Key[] keys, float hysteresisPixel) {
|
||||||
if (keys == null || hysteresisPixel < 1.0f)
|
if (keys == null || hysteresisPixel < 1.0f)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
@ -349,6 +363,23 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
mKeyDebounceThresholdSquared = (int)(hysteresisPixel * hysteresisPixel);
|
mKeyDebounceThresholdSquared = (int)(hysteresisPixel * hysteresisPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateKey(int keyIndex) {
|
||||||
|
int oldKeyIndex = mPreviousKey;
|
||||||
|
mPreviousKey = keyIndex;
|
||||||
|
if (keyIndex != oldKeyIndex) {
|
||||||
|
if (oldKeyIndex != NOT_A_KEY && oldKeyIndex < mKeys.length) {
|
||||||
|
// if new key index is not a key, old key was just released inside of the key.
|
||||||
|
final boolean inside = (keyIndex == NOT_A_KEY);
|
||||||
|
mKeys[oldKeyIndex].onReleased(inside);
|
||||||
|
mProxy.invalidateKey(mKeys[oldKeyIndex]);
|
||||||
|
}
|
||||||
|
if (keyIndex != NOT_A_KEY && keyIndex < mKeys.length) {
|
||||||
|
mKeys[keyIndex].onPressed();
|
||||||
|
mProxy.invalidateKey(mKeys[keyIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getLastCodeX() {
|
public int getLastCodeX() {
|
||||||
return mLastCodeX;
|
return mLastCodeX;
|
||||||
}
|
}
|
||||||
|
@ -586,6 +617,14 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
final boolean ignoreMultitouch = true;
|
final boolean ignoreMultitouch = true;
|
||||||
mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
|
mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
|
||||||
mGestureDetector.setIsLongpressEnabled(false);
|
mGestureDetector.setIsLongpressEnabled(false);
|
||||||
|
|
||||||
|
// TODO: This anonymous interface is temporary until KeyDebouncer becomes top-level class.
|
||||||
|
// In the future LatinKeyboardBaseView class will implement UIProxy.
|
||||||
|
mDebouncer = new KeyDebouncer(new KeyDebouncer.UIProxy() {
|
||||||
|
public void invalidateKey(Key key) {
|
||||||
|
LatinKeyboardBaseView.this.invalidateKey(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
|
public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
|
||||||
|
@ -609,7 +648,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
*/
|
*/
|
||||||
public void setKeyboard(Keyboard keyboard) {
|
public void setKeyboard(Keyboard keyboard) {
|
||||||
if (mKeyboard != null) {
|
if (mKeyboard != null) {
|
||||||
showPreview(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
}
|
}
|
||||||
// Remove any pending messages, except dismissing preview
|
// Remove any pending messages, except dismissing preview
|
||||||
mHandler.cancelKeyTimers();
|
mHandler.cancelKeyTimers();
|
||||||
|
@ -952,30 +991,21 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
// Multi-tap
|
// Multi-tap
|
||||||
mPreviewLabel.setLength(0);
|
mPreviewLabel.setLength(0);
|
||||||
mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]);
|
mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]);
|
||||||
return adjustCase(mPreviewLabel);
|
return mPreviewLabel;
|
||||||
} else {
|
} else {
|
||||||
return adjustCase(key.label);
|
return key.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: clean up this when KeyDebouncer class becomes top-level class.
|
||||||
|
private void showKeyPreviewAndUpdateKey(int keyIndex) {
|
||||||
|
mDebouncer.updateKey(keyIndex);
|
||||||
|
showPreview(keyIndex);
|
||||||
|
}
|
||||||
|
|
||||||
private void showPreview(int keyIndex) {
|
private void showPreview(int keyIndex) {
|
||||||
int oldKeyIndex = mOldPreviewKeyIndex;
|
int oldKeyIndex = mOldPreviewKeyIndex;
|
||||||
mOldPreviewKeyIndex = keyIndex;
|
mOldPreviewKeyIndex = keyIndex;
|
||||||
|
|
||||||
// Release the old key and press the new key
|
|
||||||
final Key[] keys = mKeys;
|
|
||||||
if (oldKeyIndex != keyIndex) {
|
|
||||||
if (oldKeyIndex != NOT_A_KEY && keys.length > oldKeyIndex) {
|
|
||||||
// if new key index is not a key, old key was just released inside of the key.
|
|
||||||
final boolean inside = (keyIndex == NOT_A_KEY);
|
|
||||||
keys[oldKeyIndex].onReleased(inside);
|
|
||||||
invalidateKey(oldKeyIndex);
|
|
||||||
}
|
|
||||||
if (keyIndex != NOT_A_KEY && keys.length > keyIndex) {
|
|
||||||
keys[keyIndex].onPressed();
|
|
||||||
invalidateKey(keyIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If key changed and preview is on ...
|
// If key changed and preview is on ...
|
||||||
if (oldKeyIndex != keyIndex && mShowPreview) {
|
if (oldKeyIndex != keyIndex && mShowPreview) {
|
||||||
final PopupWindow previewPopup = mPreviewPopup;
|
final PopupWindow previewPopup = mPreviewPopup;
|
||||||
|
@ -987,26 +1017,23 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
} else {
|
} else {
|
||||||
if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
|
if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
|
||||||
// Show right away, if it's already visible and finger is moving around
|
// Show right away, if it's already visible and finger is moving around
|
||||||
showKey(keyIndex);
|
showKey(mKeys[keyIndex]);
|
||||||
} else {
|
} else {
|
||||||
mHandler.popupPreview(keyIndex, DELAY_BEFORE_PREVIEW);
|
mHandler.popupPreview(mKeys[keyIndex], DELAY_BEFORE_PREVIEW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showKey(final int keyIndex) {
|
private void showKey(final Key key) {
|
||||||
final PopupWindow previewPopup = mPreviewPopup;
|
final PopupWindow previewPopup = mPreviewPopup;
|
||||||
final Key[] keys = mKeys;
|
|
||||||
if (keyIndex < 0 || keyIndex >= mKeys.length) return;
|
|
||||||
Key key = keys[keyIndex];
|
|
||||||
if (key.icon != null) {
|
if (key.icon != null) {
|
||||||
mPreviewText.setCompoundDrawables(null, null, null,
|
mPreviewText.setCompoundDrawables(null, null, null,
|
||||||
key.iconPreview != null ? key.iconPreview : key.icon);
|
key.iconPreview != null ? key.iconPreview : key.icon);
|
||||||
mPreviewText.setText(null);
|
mPreviewText.setText(null);
|
||||||
} else {
|
} else {
|
||||||
mPreviewText.setCompoundDrawables(null, null, null, null);
|
mPreviewText.setCompoundDrawables(null, null, null, null);
|
||||||
mPreviewText.setText(getPreviewText(key));
|
mPreviewText.setText(adjustCase(getPreviewText(key)));
|
||||||
if (key.label.length() > 1 && key.codes.length < 2) {
|
if (key.label.length() > 1 && key.codes.length < 2) {
|
||||||
mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize);
|
mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize);
|
||||||
mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
|
mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
|
||||||
|
@ -1092,12 +1119,9 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
* @param keyIndex the index of the key in the attached {@link Keyboard}.
|
* @param keyIndex the index of the key in the attached {@link Keyboard}.
|
||||||
* @see #invalidateAllKeys
|
* @see #invalidateAllKeys
|
||||||
*/
|
*/
|
||||||
public void invalidateKey(int keyIndex) {
|
public void invalidateKey(Key key) {
|
||||||
if (mKeys == null) return;
|
if (key == null)
|
||||||
if (keyIndex < 0 || keyIndex >= mKeys.length) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
final Key key = mKeys[keyIndex];
|
|
||||||
mInvalidatedKey = key;
|
mInvalidatedKey = key;
|
||||||
mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(),
|
mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(),
|
||||||
key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
|
key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop());
|
||||||
|
@ -1118,7 +1142,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
Key popupKey = mKeys[keyIndex];
|
Key popupKey = mKeys[keyIndex];
|
||||||
boolean result = onLongPress(popupKey);
|
boolean result = onLongPress(popupKey);
|
||||||
if (result) {
|
if (result) {
|
||||||
showPreview(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1258,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
|
|
||||||
// We must disable gesture detector while mini-keyboard is on the screen.
|
// We must disable gesture detector while mini-keyboard is on the screen.
|
||||||
if (!mMiniKeyboardOnScreen && mGestureDetector.onTouchEvent(me)) {
|
if (!mMiniKeyboardOnScreen && mGestureDetector.onTouchEvent(me)) {
|
||||||
showPreview(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
mHandler.cancelKeyTimers();
|
mHandler.cancelKeyTimers();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1341,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
if (keyIndex != NOT_A_KEY) {
|
if (keyIndex != NOT_A_KEY) {
|
||||||
mHandler.startLongPressTimer(keyIndex, LONGPRESS_TIMEOUT);
|
mHandler.startLongPressTimer(keyIndex, LONGPRESS_TIMEOUT);
|
||||||
}
|
}
|
||||||
showPreview(keyIndex);
|
showKeyPreviewAndUpdateKey(keyIndex);
|
||||||
mDebouncer.updateMoveDebouncing(touchX, touchY);
|
mDebouncer.updateMoveDebouncing(touchX, touchY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1346,7 +1370,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
* eventually, the last key should be sent as the result. In such case mCurrentKey
|
* eventually, the last key should be sent as the result. In such case mCurrentKey
|
||||||
* should not be showed as popup preview.
|
* should not be showed as popup preview.
|
||||||
*/
|
*/
|
||||||
showPreview(mDebouncer.isMinorTimeBounce() ? mDebouncer.getLastKey() : mCurrentKey);
|
showKeyPreviewAndUpdateKey(
|
||||||
|
mDebouncer.isMinorTimeBounce() ? mDebouncer.getLastKey() : mCurrentKey);
|
||||||
mDebouncer.updateMoveDebouncing(touchX, touchY);
|
mDebouncer.updateMoveDebouncing(touchX, touchY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,20 +1392,22 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
touchX = mDebouncer.getLastCodeX();
|
touchX = mDebouncer.getLastCodeX();
|
||||||
touchY = mDebouncer.getLastCodeY();
|
touchY = mDebouncer.getLastCodeY();
|
||||||
}
|
}
|
||||||
showPreview(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
// If we're not on a repeating key (which sends on a DOWN event)
|
// If we're not on a repeating key (which sends on a DOWN event)
|
||||||
if (!wasInKeyRepeat && !mMiniKeyboardOnScreen) {
|
if (!wasInKeyRepeat && !mMiniKeyboardOnScreen) {
|
||||||
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
|
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
|
||||||
}
|
}
|
||||||
invalidateKey(keyIndex);
|
if (keyIndex != NOT_A_KEY)
|
||||||
|
invalidateKey(mKeys[keyIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCancelEvent(int touchX, int touchY, long eventTime) {
|
private void onCancelEvent(int touchX, int touchY, long eventTime) {
|
||||||
mHandler.cancelKeyTimers();
|
mHandler.cancelKeyTimers();
|
||||||
mHandler.cancelPopupPreview();
|
mHandler.cancelPopupPreview();
|
||||||
dismissPopupKeyboard();
|
dismissPopupKeyboard();
|
||||||
showPreview(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
invalidateKey(mCurrentKey);
|
if (mCurrentKey != NOT_A_KEY)
|
||||||
|
invalidateKey(mKeys[mCurrentKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void repeatKey(int keyIndex) {
|
private void repeatKey(int keyIndex) {
|
||||||
|
|
Loading…
Reference in New Issue