From eb68036798f53763768e4ab37c7bfab9a2f36025 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" <takaoka@google.com> Date: Mon, 13 Sep 2010 19:26:23 +0900 Subject: [PATCH] Add keyHysteresisDistance xml attribute This change also introduces MiniKeyboardKeyDetector and mini_keyboad_slide_allowance parameter to tune the key detection behavior. Bug: 2993769 Change-Id: I1932b0a382e172cb77b9e098ae182049c834dfe0 --- java/res/layout/keyboard_popup.xml | 2 + java/res/values-land/dimens.xml | 5 +- java/res/values/attrs.xml | 6 +- java/res/values/dimens.xml | 4 +- java/res/values/styles.xml | 2 +- .../latin/LatinKeyboardBaseView.java | 25 ++++---- .../latin/MiniKeyboardKeyDetector.java | 59 +++++++++++++++++++ .../inputmethod/latin/PointerTracker.java | 13 ++-- 8 files changed, 89 insertions(+), 27 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java diff --git a/java/res/layout/keyboard_popup.xml b/java/res/layout/keyboard_popup.xml index 1005e7e11a..9a52e2cbd4 100644 --- a/java/res/layout/keyboard_popup.xml +++ b/java/res/layout/keyboard_popup.xml @@ -33,5 +33,7 @@ android:background="@drawable/keyboard_dark_background" latin:keyBackground="@drawable/btn_keyboard_key_gingerbread_popup" + latin:keyHysteresisDistance="0dip" + latin:verticalCorrection="-20dip" /> </LinearLayout> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index 43951552e5..4f87b79d27 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -22,4 +22,7 @@ <dimen name="key_height">47dip</dimen> <dimen name="candidate_strip_height">38dip</dimen> <dimen name="spacebar_vertical_correction">2dip</dimen> -</resources> \ No newline at end of file + <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> + <!-- key_height * 1.7 --> + <dimen name="mini_keyboard_slide_allowance">79.9dip</dimen> +</resources> diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index a8eaab9a34..995373e845 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -43,12 +43,12 @@ <!-- Height of the key press feedback popup. --> <attr name="keyPreviewHeight" format="dimension" /> + <!-- Hysteresis distance for key debouncing --> + <attr name="keyHysteresisDistance" format="dimension" /> + <!-- Amount to offset the touch Y coordinate by, for bias correction. --> <attr name="verticalCorrection" format="dimension" /> - <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> - <attr name="miniKeyboardSlideAllowance" format="dimension" /> - <!-- Layout resource for popup keyboards. --> <attr name="popupLayout" format="reference" /> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 39dce9db0e..af8b381105 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -27,5 +27,7 @@ will not go into extract (fullscreen) mode. --> <dimen name="max_height_for_fullscreen">2.5in</dimen> <dimen name="key_text_size">22sp</dimen> - <dimen name="key_debounce_hysteresis_distance">0.05in</dimen> + <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> + <!-- key_height * 1.7 --> + <dimen name="mini_keyboard_slide_allowance">91.8dip</dimen> </resources> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 48f0d5e542..258082eb66 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -26,8 +26,8 @@ <item name="keyPreviewHeight">80dip</item> <item name="labelTextSize">14sp</item> <item name="popupLayout">@layout/keyboard_popup</item> + <item name="keyHysteresisDistance">0.05in</item> <item name="verticalCorrection">-10dip</item> - <item name="miniKeyboardSlideAllowance">40dip</item> <item name="shadowColor">#BB000000</item> <item name="shadowRadius">2.75</item> <item name="backgroundDimAmount">0.5</item> diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java index 610d954233..a78e2b8691 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java @@ -170,6 +170,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx private float mShadowRadius; private Drawable mKeyBackground; private float mBackgroundDimAmount; + private float mKeyHysteresisDistance; private float mVerticalCorrection; private int mPreviewOffset; private int mPreviewHeight; @@ -200,14 +201,13 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx private int mMiniKeyboardOriginY; private long mMiniKeyboardPopupTime; private int[] mWindowOffset; - private float mMiniKeyboardSlideAllowance; + private final float mMiniKeyboardSlideAllowance; /** Listener for {@link OnKeyboardActionListener}. */ private OnKeyboardActionListener mKeyboardActionListener; private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>(); private final PointerQueue mPointerQueue = new PointerQueue(); - private final float mDebounceHysteresis; private final boolean mHasDistinctMultitouch; private int mOldPointerCount = 1; @@ -386,12 +386,12 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx case R.styleable.LatinKeyboardBaseView_keyBackground: mKeyBackground = a.getDrawable(attr); break; + case R.styleable.LatinKeyboardBaseView_keyHysteresisDistance: + mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0); + break; case R.styleable.LatinKeyboardBaseView_verticalCorrection: mVerticalCorrection = a.getDimensionPixelOffset(attr, 0); break; - case R.styleable.LatinKeyboardBaseView_miniKeyboardSlideAllowance: - mMiniKeyboardSlideAllowance = a.getDimensionPixelOffset(attr, 0); - break; case R.styleable.LatinKeyboardBaseView_keyPreviewLayout: previewLayout = a.getResourceId(attr, 0); break; @@ -473,7 +473,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density); // TODO: Refer frameworks/base/core/res/res/values/config.xml mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation); - mDebounceHysteresis = res.getDimension(R.dimen.key_debounce_hysteresis_distance); + mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance); GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @@ -556,7 +556,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); for (PointerTracker tracker : mPointerTrackers) { - tracker.setKeyboard(mKeys, mDebounceHysteresis); + tracker.setKeyboard(mKeys, mKeyHysteresisDistance); } requestLayout(); // Hint to reallocate the buffer if the size changed @@ -1025,6 +1025,8 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx mKeyboardActionListener.onRelease(primaryCode); } }); + // Override default ProximityKeyDetector. + miniKeyboard.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance); Keyboard keyboard; if (popupKey.popupCharacters != null) { @@ -1120,12 +1122,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) { return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action, - x - mMiniKeyboardOriginX, - // TODO: Currently just taking care of "below" of the keys in a mini popup keyboard - // for key detection by sliding finger. Need to take care of left, right, and - // upper of "edge" keys. - y - mMiniKeyboardOriginY - (int)mMiniKeyboardSlideAllowance, - 0); + x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0); } private PointerTracker getPointerTracker(final int id) { @@ -1138,7 +1135,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx final PointerTracker tracker = new PointerTracker(i, mHandler, mKeyDetector, this, mHasDistinctMultitouch); if (keys != null) - tracker.setKeyboard(keys, mDebounceHysteresis); + tracker.setKeyboard(keys, mKeyHysteresisDistance); if (listener != null) tracker.setOnKeyboardActionListener(listener); pointers.add(tracker); diff --git a/java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java new file mode 100644 index 0000000000..709d082bed --- /dev/null +++ b/java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.latin; + +import android.inputmethodservice.Keyboard.Key; + +class MiniKeyboardKeyDetector extends KeyDetector { + private static final int MAX_NEARBY_KEYS = 1; + + private final int mSlideAllowanceSquare; + private final int mSlideAllowanceSquareTop; + + public MiniKeyboardKeyDetector(float slideAllowance) { + super(); + mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance); + // Top slide allowance is slightly longer (sqrt(2) times) than other edges. + mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2; + } + + @Override + protected int getMaxNearbyKeys() { + return MAX_NEARBY_KEYS; + } + + @Override + public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) { + final Key[] keys = getKeys(); + final int touchX = getTouchX(x); + final int touchY = getTouchY(y); + int closestKey = LatinKeyboardBaseView.NOT_A_KEY; + int closestKeyDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare; + final int keyCount = keys.length; + for (int i = 0; i < keyCount; i++) { + final Key key = keys[i]; + int dist = key.squaredDistanceFrom(touchX, touchY); + if (dist < closestKeyDist) { + closestKey = i; + closestKeyDist = dist; + } + } + if (allKeys != null && closestKey != LatinKeyboardBaseView.NOT_A_KEY) + allKeys[0] = closestKey; + return closestKey; + } +} diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java index e10c9b8623..958e57618d 100644 --- a/java/src/com/android/inputmethod/latin/PointerTracker.java +++ b/java/src/com/android/inputmethod/latin/PointerTracker.java @@ -55,7 +55,7 @@ public class PointerTracker { private final boolean mHasDistinctMultitouch; private Key[] mKeys; - private int mKeyDebounceThresholdSquared = -1; + private int mKeyHysteresisDistanceSquared = -1; private int mCurrentKey = NOT_A_KEY; private int mStartX; @@ -106,11 +106,11 @@ public class PointerTracker { mListener = listener; } - public void setKeyboard(Key[] keys, float hysteresisPixel) { - if (keys == null || hysteresisPixel < 1.0f) + public void setKeyboard(Key[] keys, float keyHysteresisDistance) { + if (keys == null || keyHysteresisDistance < 0) throw new IllegalArgumentException(); mKeys = keys; - mKeyDebounceThresholdSquared = (int)(hysteresisPixel * hysteresisPixel); + mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); // Update current key index because keyboard layout has been changed. mCurrentKey = mKeyDetector.getKeyIndexAndNearbyCodes(mStartX, mStartY, null); } @@ -335,13 +335,12 @@ public class PointerTracker { } private boolean isMinorMoveBounce(int x, int y, int newKey, int curKey) { - if (mKeys == null || mKeyDebounceThresholdSquared < 0) + if (mKeys == null || mKeyHysteresisDistanceSquared < 0) throw new IllegalStateException("keyboard and/or hysteresis not set"); if (newKey == curKey) { return true; } else if (isValidKeyIndex(curKey)) { - return getSquareDistanceToKeyEdge(x, y, mKeys[curKey]) - < mKeyDebounceThresholdSquared; + return getSquareDistanceToKeyEdge(x, y, mKeys[curKey]) < mKeyHysteresisDistanceSquared; } else { return false; } -- GitLab