Add separate key hysteresis distance for sliding modifier input

Bug: 7294402
Change-Id: I78c8be9e1a7b2d49d86bfe1e3a46d1785bfe5d48
main
Tadashi G. Takaoka 2012-10-06 23:22:36 +09:00
parent 448e732272
commit f731eb1760
6 changed files with 48 additions and 22 deletions

View File

@ -109,6 +109,8 @@
<attr name="altCodeKeyWhileTypingFadeinAnimator" format="reference" />
<!-- Key detection hysteresis distance. -->
<attr name="keyHysteresisDistance" format="dimension" />
<!-- Key detection hysteresis distance for shift/symbols sliding input. -->
<attr name="keyHysteresisDistanceForSlidingModifier" format="dimension" />
<!-- Touch noise threshold time in millisecond -->
<attr name="touchNoiseThresholdTime" format="integer" />
<!-- Touch noise threshold distance in millimeter -->

View File

@ -57,6 +57,7 @@
Configuration for MainKeyboardView
-->
<dimen name="config_key_hysteresis_distance">8.0dp</dimen>
<dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
<integer name="config_touch_noise_threshold_time">40</integer>
<dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
<bool name="config_sliding_key_input_enabled">true</bool>

View File

@ -81,6 +81,7 @@
<item name="gesturePreviewTrailEndWidth">@dimen/gesture_preview_trail_end_width</item>
<!-- Common attributes of MainKeyboardView -->
<item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
<item name="keyHysteresisDistanceForSlidingModifier">@dimen/config_key_hysteresis_distance_for_sliding_modifier</item>
<item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
<item name="touchNoiseThresholdDistance">@dimen/config_touch_noise_threshold_distance</item>
<item name="slidingKeyInputEnable">@bool/config_sliding_key_input_enabled</item>

View File

@ -21,6 +21,7 @@ import com.android.inputmethod.latin.Constants;
public class KeyDetector {
private final int mKeyHysteresisDistanceSquared;
private final int mKeyHysteresisDistanceForSlidingModifierSquared;
private Keyboard mKeyboard;
private int mCorrectionX;
@ -30,10 +31,24 @@ public class KeyDetector {
* This class handles key detection.
*
* @param keyHysteresisDistance if the pointer movement distance is smaller than this, the
* movement will not been handled as meaningful movement. The unit is pixel.
* movement will not be handled as meaningful movement. The unit is pixel.
*/
public KeyDetector(float keyHysteresisDistance) {
this(keyHysteresisDistance, keyHysteresisDistance);
}
/**
* This class handles key detection.
*
* @param keyHysteresisDistance if the pointer movement distance is smaller than this, the
* movement will not be handled as meaningful movement. The unit is pixel.
* @param keyHysteresisDistanceForSlidingModifier the same parameter for sliding input that
* starts from a modifier key such as shift and symbols key.
*/
public KeyDetector(float keyHysteresisDistance, float keyHysteresisDistanceForSlidingModifier) {
mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
mKeyHysteresisDistanceForSlidingModifierSquared = (int)(
keyHysteresisDistanceForSlidingModifier * keyHysteresisDistanceForSlidingModifier);
}
public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
@ -45,8 +60,9 @@ public class KeyDetector {
mKeyboard = keyboard;
}
public int getKeyHysteresisDistanceSquared() {
return mKeyHysteresisDistanceSquared;
public int getKeyHysteresisDistanceSquared(boolean isSlidingFromModifier) {
return isSlidingFromModifier
? mKeyHysteresisDistanceForSlidingModifierSquared : mKeyHysteresisDistanceSquared;
}
public int getTouchX(int x) {

View File

@ -389,7 +389,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final float keyHysteresisDistance = a.getDimension(
R.styleable.MainKeyboardView_keyHysteresisDistance, 0);
mKeyDetector = new KeyDetector(keyHysteresisDistance);
final float keyHysteresisDistanceForSlidingModifier = a.getDimension(
R.styleable.MainKeyboardView_keyHysteresisDistanceForSlidingModifier, 0);
mKeyDetector = new KeyDetector(
keyHysteresisDistance, keyHysteresisDistanceForSlidingModifier);
mKeyTimerHandler = new KeyTimerHandler(this, a);
mConfigShowMoreKeysKeyboardAtTouchedPoint = a.getBoolean(
R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false);

View File

@ -268,15 +268,15 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if this pointer has been long-pressed and is showing a more keys panel.
private boolean mIsShowingMoreKeysPanel;
// true if this pointer is in sliding key input
// true if this pointer is in a sliding key input.
boolean mIsInSlidingKeyInput;
// true if this pointer is in a sliding key input from a modifier key,
// so that further modifier keys should be ignored.
boolean mIsInSlidingKeyInputFromModifier;
// true if sliding key is allowed.
// true if a sliding key input is allowed.
private boolean mIsAllowedSlidingKeyInput;
// ignore modifier key if true
private boolean mIgnoreModifierKey;
// Empty {@link KeyboardActionListener}
private static final KeyboardActionListener EMPTY_LISTENER =
new KeyboardActionListener.Adapter();
@ -383,7 +383,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (sInGesture) {
return false;
}
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
final boolean ignoreModifierKey = mIsInSlidingKeyInputFromModifier && key.isModifier();
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onPress : %s%s%s", mPointerId,
KeyDetector.printableCode(key),
@ -407,7 +407,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// primaryCode is different from {@link Key#mCode}.
private void callListenerOnCodeInput(final Key key, final int primaryCode, final int x,
final int y, final long eventTime) {
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
final boolean ignoreModifierKey = mIsInSlidingKeyInputFromModifier && key.isModifier();
final boolean altersCode = key.altCodeWhileTyping() && mTimerProxy.isTypingState();
final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) {
@ -435,14 +435,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
}
// Note that we need primaryCode argument because the keyboard may in shifted state and the
// Note that we need primaryCode argument because the keyboard may be in shifted state and the
// primaryCode is different from {@link Key#mCode}.
private void callListenerOnRelease(final Key key, final int primaryCode,
final boolean withSliding) {
if (sInGesture) {
return;
}
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
final boolean ignoreModifierKey = mIsInSlidingKeyInputFromModifier && key.isModifier();
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onRelease : %s%s%s%s", mPointerId,
Keyboard.printableCode(primaryCode),
@ -778,8 +778,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|| mKeyDetector.alwaysAllowsSlidingInput();
mKeyboardLayoutHasBeenChanged = false;
mKeyAlreadyProcessed = false;
mIsInSlidingKeyInput = false;
mIgnoreModifierKey = false;
resetSlidingKeyInput();
if (key != null) {
// This onPress call may have changed keyboard layout. Those cases are detected at
// {@link #setKeyboard}. In those cases, we should update key according to the new
@ -796,11 +795,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void startSlidingKeyInput(final Key key) {
if (!mIsInSlidingKeyInput) {
mIgnoreModifierKey = key.isModifier();
mIsInSlidingKeyInputFromModifier = key.isModifier();
}
mIsInSlidingKeyInput = true;
}
private void resetSlidingKeyInput() {
mIsInSlidingKeyInput = false;
mIsInSlidingKeyInputFromModifier = false;
}
private void onGestureMoveEvent(final int x, final int y, final long eventTime,
final boolean isMajorEvent, final Key key) {
final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
@ -847,9 +851,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Register move event on gesture tracker.
onGestureMoveEvent(x, y, eventTime, true /* isMajorEvent */, key);
if (sInGesture) {
mIgnoreModifierKey = true;
mTimerProxy.cancelLongPressTimer();
mIsInSlidingKeyInput = true;
mCurrentKey = null;
setReleasedKeyGraphics(oldKey);
return;
@ -983,7 +985,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void onUpEventInternal(final long eventTime) {
mTimerProxy.cancelKeyTimers();
mIsInSlidingKeyInput = false;
resetSlidingKeyInput();
mIsDetectingGesture = false;
final Key currentKey = mCurrentKey;
mCurrentKey = null;
@ -1041,7 +1043,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void onCancelEventInternal() {
mTimerProxy.cancelKeyTimers();
setReleasedKeyGraphics(mCurrentKey);
mIsInSlidingKeyInput = false;
resetSlidingKeyInput();
if (mIsShowingMoreKeysPanel) {
mDrawingProxy.dismissMoreKeysPanel();
mIsShowingMoreKeysPanel = false;
@ -1070,8 +1072,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (newKey == curKey) {
return false;
} else if (curKey != null) {
return curKey.squaredDistanceToEdge(x, y)
>= mKeyDetector.getKeyHysteresisDistanceSquared();
final int keyHysteresisDistanceSquared = mKeyDetector.getKeyHysteresisDistanceSquared(
mIsInSlidingKeyInputFromModifier);
return curKey.squaredDistanceToEdge(x, y) >= keyHysteresisDistanceSquared;
} else {
return true;
}