From c13c1adfa72227b0006add5f13f555fbb9c9eb4e Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 21 Apr 2014 14:41:57 -0700 Subject: [PATCH] Sort keys from top-left to bottom-right order Change-Id: I228748824de62e9e46fa43db200d23f41eb6d2ce --- .../AccessibilityEntityProvider.java | 4 +-- .../keyboard/EmojiPalettesView.java | 5 ++-- .../inputmethod/keyboard/Keyboard.java | 26 ++++++++++------ .../inputmethod/keyboard/KeyboardView.java | 2 +- .../keyboard/MoreKeysDetector.java | 2 +- .../inputmethod/keyboard/ProximityInfo.java | 22 +++++++------- .../internal/DynamicGridKeyboard.java | 6 ++-- .../keyboard/internal/KeyboardParams.java | 21 +++++++++++-- .../inputmethod/research/ResearchLogger.java | 2 +- .../expected/ActualKeyboardBuilder.java | 30 +++++-------------- .../layout/tests/LayoutTestsBase.java | 3 +- 11 files changed, 66 insertions(+), 57 deletions(-) diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java index ae826fe25..063f2113d 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java @@ -159,7 +159,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider // Add the virtual children of the root View. final Keyboard keyboard = mKeyboardView.getKeyboard(); - for (final Key key : keyboard.getKeys()) { + for (final Key key : keyboard.getSortedKeys()) { final int childVirtualViewId = generateVirtualViewIdForKey(key); rootInfo.addChild(mKeyboardView, childVirtualViewId); } @@ -307,7 +307,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider } mVirtualViewIdToKey.clear(); - for (final Key key : keyboard.getKeys()) { + for (final Key key : keyboard.getSortedKeys()) { final int virtualViewId = generateVirtualViewIdForKey(key); mVirtualViewIdToKey.put(virtualViewId, key); } diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java index 3c50401fe..d8b5758a6 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java @@ -298,7 +298,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange private int getCategoryPageCount(final int categoryId) { final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); - return (keyboard.getKeys().size() - 1) / mMaxPageKeyCount + 1; + return (keyboard.getSortedKeys().size() - 1) / mMaxPageKeyCount + 1; } // Returns a pair of the category id and the category page id from the view pager's page @@ -347,7 +347,8 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange } final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); - final Key[][] sortedKeys = sortKeysIntoPages(keyboard.getKeys(), mMaxPageKeyCount); + final Key[][] sortedKeys = sortKeysIntoPages( + keyboard.getSortedKeys(), mMaxPageKeyCount); for (int pageId = 0; pageId < sortedKeys.length; ++pageId) { final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs, mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 516277035..801e32528 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -78,7 +78,7 @@ public class Keyboard { public final int mMaxMoreKeysKeyboardColumn; /** List of keys in this keyboard */ - private final List mKeys; + private final List mSortedKeys; public final List mShiftKeys; public final List mAltCodeKeysWhileTyping; public final KeyboardIconsSet mIconsSet; @@ -103,14 +103,16 @@ public class Keyboard { mTopPadding = params.mTopPadding; mVerticalGap = params.mVerticalGap; - mKeys = Collections.unmodifiableList(CollectionUtils.newArrayList(params.mKeys)); + mSortedKeys = Collections.unmodifiableList( + CollectionUtils.newArrayList(params.mSortedKeys)); mShiftKeys = Collections.unmodifiableList(params.mShiftKeys); mAltCodeKeysWhileTyping = Collections.unmodifiableList(params.mAltCodeKeysWhileTyping); mIconsSet = params.mIconsSet; mProximityInfo = new ProximityInfo(params.mId.mLocale.toString(), params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight, - mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection); + mMostCommonKeyWidth, mMostCommonKeyHeight, mSortedKeys, + params.mTouchPositionCorrection); mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled; } @@ -129,7 +131,7 @@ public class Keyboard { mTopPadding = keyboard.mTopPadding; mVerticalGap = keyboard.mVerticalGap; - mKeys = keyboard.mKeys; + mSortedKeys = keyboard.mSortedKeys; mShiftKeys = keyboard.mShiftKeys; mAltCodeKeysWhileTyping = keyboard.mAltCodeKeysWhileTyping; mIconsSet = keyboard.mIconsSet; @@ -154,12 +156,18 @@ public class Keyboard { return mProximityInfo; } - public List getKeys() { - return mKeys; + /** + * Return the sorted list of keys of this keyboard. + * The keys are sorted from top-left to bottom-right order. + * The list may contain {@link Spacer} object as well. + * @return the sorted unmodifiable list of {@link Key}s of this keyboard. + */ + public List getSortedKeys() { + return mSortedKeys; } public Key getKeyFromOutputText(final String outputText) { - for (final Key key : getKeys()) { + for (final Key key : getSortedKeys()) { if (outputText.equals(key.getOutputText())) { return key; } @@ -177,7 +185,7 @@ public class Keyboard { return mKeyCache.valueAt(index); } - for (final Key key : getKeys()) { + for (final Key key : getSortedKeys()) { if (key.getCode() == code) { mKeyCache.put(code, key); return key; @@ -193,7 +201,7 @@ public class Keyboard { return true; } - for (final Key key : getKeys()) { + for (final Key key : getSortedKeys()) { if (key == aKey) { mKeyCache.put(key.getCode(), key); return true; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 18e51d392..8ca00b005 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -289,7 +289,7 @@ public class KeyboardView extends View { // TODO: Confirm if it's really required to draw all keys when hardware acceleration is on. if (drawAllKeys || isHardwareAccelerated) { // Draw all keys. - for (final Key key : mKeyboard.getKeys()) { + for (final Key key : mKeyboard.getSortedKeys()) { onDrawKey(key, canvas, paint); } } else { diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java index abff202b7..5a9d4755f 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java @@ -43,7 +43,7 @@ public final class MoreKeysDetector extends KeyDetector { Key nearestKey = null; int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare; - for (final Key key : keyboard.getKeys()) { + for (final Key key : keyboard.getSortedKeys()) { final int dist = key.squaredDistanceToEdge(touchX, touchY); if (dist < nearestDist) { nearestKey = key; diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index fdb20f8fa..3746d5b79 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -51,13 +51,13 @@ public class ProximityInfo { private final int mKeyboardHeight; private final int mMostCommonKeyWidth; private final int mMostCommonKeyHeight; - private final List mKeys; + private final List mSortedKeys; private final List[] mGridNeighbors; private final String mLocaleStr; ProximityInfo(final String localeStr, final int gridWidth, final int gridHeight, final int minWidth, final int height, final int mostCommonKeyWidth, - final int mostCommonKeyHeight, final List keys, + final int mostCommonKeyHeight, final List sortedKeys, final TouchPositionCorrection touchPositionCorrection) { if (TextUtils.isEmpty(localeStr)) { mLocaleStr = ""; @@ -73,7 +73,7 @@ public class ProximityInfo { mKeyboardHeight = height; mMostCommonKeyHeight = mostCommonKeyHeight; mMostCommonKeyWidth = mostCommonKeyWidth; - mKeys = keys; + mSortedKeys = sortedKeys; mGridNeighbors = new List[mGridSize]; if (minWidth == 0 || height == 0) { // No proximity required. Keyboard might be more keys keyboard. @@ -146,8 +146,8 @@ public class ProximityInfo { } } - final List keys = mKeys; - final int keyCount = getProximityInfoKeysCount(keys); + final List sortedKeys = mSortedKeys; + final int keyCount = getProximityInfoKeysCount(sortedKeys); final int[] keyXCoordinates = new int[keyCount]; final int[] keyYCoordinates = new int[keyCount]; final int[] keyWidths = new int[keyCount]; @@ -157,8 +157,8 @@ public class ProximityInfo { final float[] sweetSpotCenterYs; final float[] sweetSpotRadii; - for (int infoIndex = 0, keyIndex = 0; keyIndex < keys.size(); keyIndex++) { - final Key key = keys.get(keyIndex); + for (int infoIndex = 0, keyIndex = 0; keyIndex < sortedKeys.size(); keyIndex++) { + final Key key = sortedKeys.get(keyIndex); // Excluding from key coordinate arrays if (!needsProximityInfo(key)) { continue; @@ -181,8 +181,8 @@ public class ProximityInfo { final int rows = touchPositionCorrection.getRows(); final float defaultRadius = DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS * (float)Math.hypot(mMostCommonKeyWidth, mMostCommonKeyHeight); - for (int infoIndex = 0, keyIndex = 0; keyIndex < keys.size(); keyIndex++) { - final Key key = keys.get(keyIndex); + for (int infoIndex = 0, keyIndex = 0; keyIndex < sortedKeys.size(); keyIndex++) { + final Key key = sortedKeys.get(keyIndex); // Excluding from touch position correction arrays if (!needsProximityInfo(key)) { continue; @@ -244,7 +244,7 @@ public class ProximityInfo { private void computeNearestNeighbors() { final int defaultWidth = mMostCommonKeyWidth; - final int keyCount = mKeys.size(); + final int keyCount = mSortedKeys.size(); final int gridSize = mGridNeighbors.length; final int threshold = (int) (defaultWidth * SEARCH_DISTANCE); final int thresholdSquared = threshold * threshold; @@ -263,7 +263,7 @@ public class ProximityInfo { final int[] neighborCountPerCell = new int[gridSize]; final int halfCellWidth = mCellWidth / 2; final int halfCellHeight = mCellHeight / 2; - for (final Key key : mKeys) { + for (final Key key : mSortedKeys) { if (key.isSpacer()) continue; /* HOW WE PRE-SELECT THE CELLS (iterate over only the relevant cells, instead of all of them) diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java index dd5ec1def..bf76ca455 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java @@ -68,7 +68,7 @@ public class DynamicGridKeyboard extends Keyboard { } private Key getTemplateKey(final int code) { - for (final Key key : super.getKeys()) { + for (final Key key : super.getSortedKeys()) { if (key.getCode() == code) { return key; } @@ -207,7 +207,7 @@ public class DynamicGridKeyboard extends Keyboard { } @Override - public List getKeys() { + public List getSortedKeys() { synchronized (mLock) { if (mCachedGridKeys != null) { return mCachedGridKeys; @@ -222,7 +222,7 @@ public class DynamicGridKeyboard extends Keyboard { @Override public List getNearestKeys(final int x, final int y) { // TODO: Calculate the nearest key index in mGridKeys from x and y. - return getKeys(); + return getSortedKeys(); } static final class GridKey extends Key { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java index 153391eed..a61a79b85 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java @@ -24,6 +24,8 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; +import java.util.Comparator; +import java.util.SortedSet; import java.util.TreeSet; public class KeyboardParams { @@ -58,7 +60,8 @@ public class KeyboardParams { public int GRID_WIDTH; public int GRID_HEIGHT; - public final TreeSet mKeys = CollectionUtils.newTreeSet(); // ordered set + // Keys are sorted from top-left to bottom-right order. + public final SortedSet mSortedKeys = new TreeSet(ROW_COLUMN_COMPARATOR); public final ArrayList mShiftKeys = CollectionUtils.newArrayList(); public final ArrayList mAltCodeKeysWhileTyping = CollectionUtils.newArrayList(); public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet(); @@ -75,8 +78,20 @@ public class KeyboardParams { public final TouchPositionCorrection mTouchPositionCorrection = new TouchPositionCorrection(); + // Comparator to sort {@link Key}s from top-left to bottom-right order. + private static final Comparator ROW_COLUMN_COMPARATOR = new Comparator() { + @Override + public int compare(final Key lhs, final Key rhs) { + if (lhs.getY() < rhs.getY()) return -1; + if (lhs.getY() > rhs.getY()) return 1; + if (lhs.getX() < rhs.getX()) return -1; + if (lhs.getX() > rhs.getX()) return 1; + return 0; + } + }; + protected void clearKeys() { - mKeys.clear(); + mSortedKeys.clear(); mShiftKeys.clear(); clearHistogram(); } @@ -88,7 +103,7 @@ public class KeyboardParams { // Ignore zero width {@link Spacer}. return; } - mKeys.add(key); + mSortedKeys.add(key); if (isSpacer) { return; } diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index b1f54c0b4..d907dd1b0 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -1362,7 +1362,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang kid.navigateNext(), kid.navigatePrevious(), kid.mClobberSettingsKey, isPasswordView, kid.mSupportsSwitchingToShortcutIme, kid.mHasShortcutKey, kid.mLanguageSwitchKeyEnabled, kid.isMultiLine(), keyboard.mOccupiedWidth, - keyboard.mOccupiedHeight, keyboard.getKeys()); + keyboard.mOccupiedHeight, keyboard.getSortedKeys()); } /** diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java index b0cd4df5c..26d2e2ad2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java @@ -24,27 +24,13 @@ import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; /** * This class builds an actual keyboard for unit test. */ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder { - // Comparator to sort {@link Key}s from top-left to bottom-right order. - private static final Comparator ROW_COLUMN_COMPARATOR = new Comparator() { - @Override - public int compare(final Key lhs, final Key rhs) { - if (lhs.getY() < rhs.getY()) return -1; - if (lhs.getY() > rhs.getY()) return 1; - if (lhs.getX() < rhs.getX()) return -1; - if (lhs.getX() > rhs.getX()) return 1; - return 0; - } - }; - - private static ArrayList filterOutSpacerAndSortKeys(final List keys) { + private static ArrayList filterOutSpacer(final List keys) { final ArrayList filteredKeys = CollectionUtils.newArrayList(); for (final Key key : keys) { if (key.isSpacer()) { @@ -52,25 +38,23 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder { } filteredKeys.add(key); } - Collections.sort(filteredKeys, ROW_COLUMN_COMPARATOR); return filteredKeys; } /** * Create the keyboard that consists of the array of rows of the actual keyboard's keys. - * @param keys the list of keys of the actual keyboard. + * @param sortedKeys the sorted list of keys of the actual keyboard. * @return the actual keyboard grouped with rows. */ - public static Key[][] buildKeyboard(final List keys) { - // Filter out spacer and sort keys from top-left to bottom-right order to prepare to - // create rows. - final ArrayList sortedKeys = filterOutSpacerAndSortKeys(keys); + public static Key[][] buildKeyboard(final List sortedKeys) { + // Filter out spacer to prepare to create rows. + final ArrayList filteredSortedKeys = filterOutSpacer(sortedKeys); // Grouping keys into rows. final ArrayList> rows = CollectionUtils.newArrayList(); ArrayList elements = CollectionUtils.newArrayList(); - int lastY = sortedKeys.get(0).getY(); - for (final Key key : sortedKeys) { + int lastY = filteredSortedKeys.get(0).getY(); + for (final Key key : filteredSortedKeys) { if (lastY != key.getY()) { // A new row is starting. lastY = key.getY(); diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java index 555ec8971..4002c49c2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java @@ -150,7 +150,8 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase { // Create actual keyboard object. final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(elementId); // Create actual keyboard to be compared with the expected keyboard. - final Key[][] actualKeyboard = ActualKeyboardBuilder.buildKeyboard(keyboard.getKeys()); + final Key[][] actualKeyboard = ActualKeyboardBuilder.buildKeyboard( + keyboard.getSortedKeys()); // Dump human readable definition of expected/actual keyboards. Log.d(tag, "expected=\n" + ExpectedKeyboardBuilder.toString(expectedKeyboard));