Create proximity info just after parsing keyboard layouts
Bug: 4807069 Change-Id: Ic18b2fc526efec58510841884a949a1a0201e7f5
This commit is contained in:
parent
08eea95650
commit
0d5494c66a
2 changed files with 65 additions and 57 deletions
|
@ -141,14 +141,6 @@ public class Keyboard {
|
|||
// TODO: Change GRID_WIDTH and GRID_HEIGHT to private.
|
||||
public final int GRID_WIDTH;
|
||||
public final int GRID_HEIGHT;
|
||||
private final int GRID_SIZE;
|
||||
private int mCellWidth;
|
||||
private int mCellHeight;
|
||||
private int[][] mGridNeighbors;
|
||||
private int mProximityThreshold;
|
||||
private static int[] EMPTY_INT_ARRAY = new int[0];
|
||||
/** Number of key widths from current touch point to search for nearest keys. */
|
||||
private static float SEARCH_DISTANCE = 1.2f;
|
||||
|
||||
private final ProximityInfo mProximityInfo;
|
||||
|
||||
|
@ -164,7 +156,6 @@ public class Keyboard {
|
|||
final Resources res = context.getResources();
|
||||
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
||||
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
||||
GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
|
||||
|
||||
final int horizontalEdgesPadding = (int)res.getDimension(
|
||||
R.dimen.keyboard_horizontal_edges_padding);
|
||||
|
@ -177,12 +168,13 @@ public class Keyboard {
|
|||
mDefaultVerticalGap = 0;
|
||||
mDefaultHeight = mDefaultWidth;
|
||||
mId = id;
|
||||
mProximityInfo = new ProximityInfo(GRID_WIDTH, GRID_HEIGHT);
|
||||
loadKeyboard(context, xmlLayoutResId);
|
||||
mProximityInfo = new ProximityInfo(
|
||||
GRID_WIDTH, GRID_HEIGHT, getMinWidth(), getHeight(), getKeyWidth(), mKeys);
|
||||
}
|
||||
|
||||
public int getProximityInfo() {
|
||||
return mProximityInfo.getNativeProximityInfo(this);
|
||||
return mProximityInfo.getNativeProximityInfo();
|
||||
}
|
||||
|
||||
public List<Key> getKeys() {
|
||||
|
@ -219,8 +211,6 @@ public class Keyboard {
|
|||
|
||||
public void setKeyWidth(int width) {
|
||||
mDefaultWidth = width;
|
||||
final int threshold = (int) (width * SEARCH_DISTANCE);
|
||||
mProximityThreshold = threshold * threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -365,34 +355,6 @@ public class Keyboard {
|
|||
return label;
|
||||
}
|
||||
|
||||
// TODO: Move this function to ProximityInfo and make this private.
|
||||
public void computeNearestNeighbors() {
|
||||
// Round-up so we don't have any pixels outside the grid
|
||||
mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH;
|
||||
mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT;
|
||||
mGridNeighbors = new int[GRID_SIZE][];
|
||||
final int[] indices = new int[mKeys.size()];
|
||||
final int gridWidth = GRID_WIDTH * mCellWidth;
|
||||
final int gridHeight = GRID_HEIGHT * mCellHeight;
|
||||
final int threshold = mProximityThreshold;
|
||||
for (int x = 0; x < gridWidth; x += mCellWidth) {
|
||||
for (int y = 0; y < gridHeight; y += mCellHeight) {
|
||||
final int centerX = x + mCellWidth / 2;
|
||||
final int centerY = y + mCellHeight / 2;
|
||||
int count = 0;
|
||||
for (int i = 0; i < mKeys.size(); i++) {
|
||||
final Key key = mKeys.get(i);
|
||||
if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
|
||||
indices[count++] = i;
|
||||
}
|
||||
final int[] cell = new int[count];
|
||||
System.arraycopy(indices, 0, cell, 0, count);
|
||||
mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell;
|
||||
}
|
||||
}
|
||||
mProximityInfo.setProximityInfo(mGridNeighbors, getMinWidth(), getHeight(), mKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the indices of the keys that are closest to the given point.
|
||||
* @param x the x-coordinate of the point
|
||||
|
@ -401,14 +363,7 @@ public class Keyboard {
|
|||
* point is out of range, then an array of size zero is returned.
|
||||
*/
|
||||
public int[] getNearestKeys(int x, int y) {
|
||||
if (mGridNeighbors == null) computeNearestNeighbors();
|
||||
if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) {
|
||||
int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth);
|
||||
if (index < GRID_SIZE) {
|
||||
return mGridNeighbors[index];
|
||||
}
|
||||
}
|
||||
return EMPTY_INT_ARRAY;
|
||||
return mProximityInfo.getNearestKeys(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,15 +23,35 @@ import java.util.List;
|
|||
|
||||
public class ProximityInfo {
|
||||
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
|
||||
/** Number of key widths from current touch point to search for nearest keys. */
|
||||
private static float SEARCH_DISTANCE = 1.2f;
|
||||
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||
|
||||
private final int mGridWidth;
|
||||
private final int mGridHeight;
|
||||
private final int mGridSize;
|
||||
private final int mCellWidth;
|
||||
private final int mCellHeight;
|
||||
// TODO: Find a proper name for mKeyboardMinWidth
|
||||
private final int mKeyboardMinWidth;
|
||||
private final int mKeyboardHeight;
|
||||
private final int[][] mGridNeighbors;
|
||||
|
||||
ProximityInfo(int gridWidth, int gridHeight) {
|
||||
ProximityInfo(
|
||||
int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, List<Key> keys) {
|
||||
mGridWidth = gridWidth;
|
||||
mGridHeight = gridHeight;
|
||||
mGridSize = mGridWidth * mGridHeight;
|
||||
mCellWidth = (minWidth + mGridWidth - 1) / mGridWidth;
|
||||
mCellHeight = (height + mGridHeight - 1) / mGridHeight;
|
||||
mKeyboardMinWidth = minWidth;
|
||||
mKeyboardHeight = height;
|
||||
mGridNeighbors = new int[mGridSize][];
|
||||
if (minWidth == 0 || height == 0) {
|
||||
// No proximity required. Keyboard might be mini keyboard.
|
||||
return;
|
||||
}
|
||||
computeNearestNeighbors(keyWidth, keys);
|
||||
}
|
||||
|
||||
private int mNativeProximityInfo;
|
||||
|
@ -42,7 +62,7 @@ public class ProximityInfo {
|
|||
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray);
|
||||
private native void releaseProximityInfoNative(int nativeProximityInfo);
|
||||
|
||||
public final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
|
||||
private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
|
||||
int keyboardHeight, List<Key> keys) {
|
||||
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
|
||||
|
@ -57,12 +77,7 @@ public class ProximityInfo {
|
|||
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray);
|
||||
}
|
||||
|
||||
// TODO: Get rid of this function's input (keyboard).
|
||||
public int getNativeProximityInfo(Keyboard keyboard) {
|
||||
if (mNativeProximityInfo == 0) {
|
||||
// TODO: Move this function to ProximityInfo and make this private.
|
||||
keyboard.computeNearestNeighbors();
|
||||
}
|
||||
public int getNativeProximityInfo() {
|
||||
return mNativeProximityInfo;
|
||||
}
|
||||
|
||||
|
@ -77,4 +92,42 @@ public class ProximityInfo {
|
|||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
private void computeNearestNeighbors(int defaultWidth, List<Key> keys) {
|
||||
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
|
||||
final int threshold = thresholdBase * thresholdBase;
|
||||
// Round-up so we don't have any pixels outside the grid
|
||||
final int[] indices = new int[keys.size()];
|
||||
final int gridWidth = mGridWidth * mCellWidth;
|
||||
final int gridHeight = mGridHeight * mCellHeight;
|
||||
for (int x = 0; x < gridWidth; x += mCellWidth) {
|
||||
for (int y = 0; y < gridHeight; y += mCellHeight) {
|
||||
final int centerX = x + mCellWidth / 2;
|
||||
final int centerY = y + mCellHeight / 2;
|
||||
int count = 0;
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
final Key key = keys.get(i);
|
||||
if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
|
||||
indices[count++] = i;
|
||||
}
|
||||
final int[] cell = new int[count];
|
||||
System.arraycopy(indices, 0, cell, 0, count);
|
||||
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
|
||||
}
|
||||
}
|
||||
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys);
|
||||
}
|
||||
|
||||
public int[] getNearestKeys(int x, int y) {
|
||||
if (mGridNeighbors == null) {
|
||||
return EMPTY_INT_ARRAY;
|
||||
}
|
||||
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
|
||||
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
|
||||
if (index < mGridSize) {
|
||||
return mGridNeighbors[index];
|
||||
}
|
||||
}
|
||||
return EMPTY_INT_ARRAY;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue