Merge "Create proximity info just after parsing keyboard layouts"
This commit is contained in:
commit
8275fb0a1a
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.
|
// TODO: Change GRID_WIDTH and GRID_HEIGHT to private.
|
||||||
public final int GRID_WIDTH;
|
public final int GRID_WIDTH;
|
||||||
public final int GRID_HEIGHT;
|
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;
|
private final ProximityInfo mProximityInfo;
|
||||||
|
|
||||||
|
@ -164,7 +156,6 @@ public class Keyboard {
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
||||||
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
||||||
GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
|
|
||||||
|
|
||||||
final int horizontalEdgesPadding = (int)res.getDimension(
|
final int horizontalEdgesPadding = (int)res.getDimension(
|
||||||
R.dimen.keyboard_horizontal_edges_padding);
|
R.dimen.keyboard_horizontal_edges_padding);
|
||||||
|
@ -177,12 +168,13 @@ public class Keyboard {
|
||||||
mDefaultVerticalGap = 0;
|
mDefaultVerticalGap = 0;
|
||||||
mDefaultHeight = mDefaultWidth;
|
mDefaultHeight = mDefaultWidth;
|
||||||
mId = id;
|
mId = id;
|
||||||
mProximityInfo = new ProximityInfo(GRID_WIDTH, GRID_HEIGHT);
|
|
||||||
loadKeyboard(context, xmlLayoutResId);
|
loadKeyboard(context, xmlLayoutResId);
|
||||||
|
mProximityInfo = new ProximityInfo(
|
||||||
|
GRID_WIDTH, GRID_HEIGHT, getMinWidth(), getHeight(), getKeyWidth(), mKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProximityInfo() {
|
public int getProximityInfo() {
|
||||||
return mProximityInfo.getNativeProximityInfo(this);
|
return mProximityInfo.getNativeProximityInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Key> getKeys() {
|
public List<Key> getKeys() {
|
||||||
|
@ -219,8 +211,6 @@ public class Keyboard {
|
||||||
|
|
||||||
public void setKeyWidth(int width) {
|
public void setKeyWidth(int width) {
|
||||||
mDefaultWidth = width;
|
mDefaultWidth = width;
|
||||||
final int threshold = (int) (width * SEARCH_DISTANCE);
|
|
||||||
mProximityThreshold = threshold * threshold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -365,34 +355,6 @@ public class Keyboard {
|
||||||
return label;
|
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.
|
* Returns the indices of the keys that are closest to the given point.
|
||||||
* @param x the x-coordinate of the 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.
|
* point is out of range, then an array of size zero is returned.
|
||||||
*/
|
*/
|
||||||
public int[] getNearestKeys(int x, int y) {
|
public int[] getNearestKeys(int x, int y) {
|
||||||
if (mGridNeighbors == null) computeNearestNeighbors();
|
return mProximityInfo.getNearestKeys(x, y);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,15 +23,35 @@ import java.util.List;
|
||||||
|
|
||||||
public class ProximityInfo {
|
public class ProximityInfo {
|
||||||
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
|
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 mGridWidth;
|
||||||
private final int mGridHeight;
|
private final int mGridHeight;
|
||||||
private final int mGridSize;
|
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;
|
mGridWidth = gridWidth;
|
||||||
mGridHeight = gridHeight;
|
mGridHeight = gridHeight;
|
||||||
mGridSize = mGridWidth * mGridHeight;
|
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;
|
private int mNativeProximityInfo;
|
||||||
|
@ -42,7 +62,7 @@ public class ProximityInfo {
|
||||||
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray);
|
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray);
|
||||||
private native void releaseProximityInfoNative(int nativeProximityInfo);
|
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 keyboardHeight, List<Key> keys) {
|
||||||
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
|
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
|
||||||
|
@ -57,12 +77,7 @@ public class ProximityInfo {
|
||||||
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray);
|
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get rid of this function's input (keyboard).
|
public int getNativeProximityInfo() {
|
||||||
public int getNativeProximityInfo(Keyboard keyboard) {
|
|
||||||
if (mNativeProximityInfo == 0) {
|
|
||||||
// TODO: Move this function to ProximityInfo and make this private.
|
|
||||||
keyboard.computeNearestNeighbors();
|
|
||||||
}
|
|
||||||
return mNativeProximityInfo;
|
return mNativeProximityInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,4 +92,42 @@ public class ProximityInfo {
|
||||||
super.finalize();
|
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