Refactor LatinKeyboard and LatinKey

This change also moves KeyboardSwitcher and related classes to
com.android.inputmethod.keyboard package.

Multi project change with Ib23017b2

Change-Id: Id7d54b24615fe22ebb540ca847549909e346ee24
main
Tadashi G. Takaoka 2010-12-02 20:54:32 +09:00
parent 26dae3f4e8
commit 571bdb401f
22 changed files with 462 additions and 505 deletions

View File

@ -35,47 +35,47 @@ public class Key {
* All the key codes (unicode or custom code) that this key could generate, zero'th * All the key codes (unicode or custom code) that this key could generate, zero'th
* being the most important. * being the most important.
*/ */
public int[] codes; public int[] mCodes;
/** The unicode that this key generates in manual temporary upper case mode. */ /** The unicode that this key generates in manual temporary upper case mode. */
public int manualTemporaryUpperCaseCode; public int mManualTemporaryUpperCaseCode;
/** Label to display */ /** Label to display */
public CharSequence label; public CharSequence mLabel;
/** Option of the label */ /** Option of the label */
public int labelOption; public int mLabelOption;
/** Icon to display instead of a label. Icon takes precedence over a label */ /** Icon to display instead of a label. Icon takes precedence over a label */
public Drawable icon; public Drawable mIcon;
/** Hint icon to display on the key in conjunction with the label */ /** Hint icon to display on the key in conjunction with the label */
public Drawable hintIcon; public Drawable mHintIcon;
/** Preview version of the icon, for the preview popup */ /** Preview version of the icon, for the preview popup */
/** /**
* The hint icon to display on the key when keyboard is in manual temporary upper case * The hint icon to display on the key when keyboard is in manual temporary upper case
* mode. * mode.
*/ */
public Drawable manualTemporaryUpperCaseHintIcon; public Drawable mManualTemporaryUpperCaseHintIcon;
public Drawable iconPreview; public Drawable mPreviewIcon;
/** Width of the key, not including the gap */ /** Width of the key, not including the gap */
public int width; public int mWidth;
/** Height of the key, not including the gap */ /** Height of the key, not including the gap */
public int height; public int mHeight;
/** The horizontal gap before this key */ /** The horizontal gap before this key */
public int gap; public int mGap;
/** Whether this key is sticky, i.e., a toggle key */ /** Whether this key is sticky, i.e., a toggle key */
public boolean sticky; public boolean mSticky;
/** X coordinate of the key in the keyboard layout */ /** X coordinate of the key in the keyboard layout */
public int x; public int mX;
/** Y coordinate of the key in the keyboard layout */ /** Y coordinate of the key in the keyboard layout */
public int y; public int mY;
/** The current pressed state of this key */ /** The current pressed state of this key */
public boolean pressed; public boolean mPressed;
/** If this is a sticky key, is it on? */ /** If this is a sticky key, is it on? */
public boolean on; public boolean mOn;
/** Text to output when pressed. This can be multiple characters, like ".com" */ /** Text to output when pressed. This can be multiple characters, like ".com" */
public CharSequence text; public CharSequence mOutputText;
/** Popup characters */ /** Popup characters */
public CharSequence popupCharacters; public CharSequence mPopupCharacters;
/** /**
* Flags that specify the anchoring to edges of the keyboard for detecting touch events * Flags that specify the anchoring to edges of the keyboard for detecting touch events
@ -83,18 +83,18 @@ public class Key {
* {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT}, * {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT},
* {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}. * {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}.
*/ */
public int edgeFlags; public int mEdgeFlags;
/** Whether this is a modifier key, such as Shift or Alt */ /** Whether this is a modifier key, such as Shift or Alt */
public boolean modifier; public boolean mModifier;
/** The Keyboard that this key belongs to */ /** The Keyboard that this key belongs to */
protected final Keyboard keyboard; protected final Keyboard mKeyboard;
/** /**
* If this key pops up a mini keyboard, this is the resource id for the XML layout for that * If this key pops up a mini keyboard, this is the resource id for the XML layout for that
* keyboard. * keyboard.
*/ */
public int popupResId; public int mPopupResId;
/** Whether this key repeats itself when held down */ /** Whether this key repeats itself when held down */
public boolean repeatable; public boolean mRepeatable;
private final static int[] KEY_STATE_NORMAL_ON = { private final static int[] KEY_STATE_NORMAL_ON = {
@ -124,13 +124,24 @@ public class Key {
android.R.attr.state_pressed android.R.attr.state_pressed
}; };
// functional normal state (with properties)
private static final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
android.R.attr.state_single
};
// functional pressed state (with properties)
private static final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
android.R.attr.state_single,
android.R.attr.state_pressed
};
/** Create an empty key with no attributes. */ /** Create an empty key with no attributes. */
public Key(Row parent) { public Key(Row parent) {
keyboard = parent.parent; mKeyboard = parent.mParent;
height = parent.defaultHeight; mHeight = parent.mDefaultHeight;
gap = parent.defaultHorizontalGap; mGap = parent.mDefaultHorizontalGap;
width = parent.defaultWidth - gap; mWidth = parent.mDefaultWidth - mGap;
edgeFlags = parent.rowEdgeFlags; mEdgeFlags = parent.mRowEdgeFlags;
} }
/** Create a key with the given top-left coordinate and extract its attributes from /** Create a key with the given top-left coordinate and extract its attributes from
@ -148,15 +159,15 @@ public class Key {
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard); R.styleable.Keyboard);
height = KeyboardParser.getDimensionOrFraction(a, mHeight = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyHeight, R.styleable.Keyboard_keyHeight,
keyboard.mDisplayHeight, parent.defaultHeight); mKeyboard.mDisplayHeight, parent.mDefaultHeight);
gap = KeyboardParser.getDimensionOrFraction(a, mGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_horizontalGap, R.styleable.Keyboard_horizontalGap,
keyboard.mDisplayWidth, parent.defaultHorizontalGap); mKeyboard.mDisplayWidth, parent.mDefaultHorizontalGap);
width = KeyboardParser.getDimensionOrFraction(a, mWidth = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyWidth, R.styleable.Keyboard_keyWidth,
keyboard.mDisplayWidth, parent.defaultWidth) - gap; mKeyboard.mDisplayWidth, parent.mDefaultWidth) - mGap;
a.recycle(); a.recycle();
a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key);
@ -172,42 +183,48 @@ public class Key {
} }
// Horizontal gap is divided equally to both sides of the key. // Horizontal gap is divided equally to both sides of the key.
this.x = x + gap / 2; this.mX = x + mGap / 2;
this.y = y; this.mY = y;
codes = style.getIntArray(a, R.styleable.Keyboard_Key_codes); mCodes = style.getIntArray(a, R.styleable.Keyboard_Key_codes);
iconPreview = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview); mPreviewIcon = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview);
Keyboard.setDefaultBounds(iconPreview); Keyboard.setDefaultBounds(mPreviewIcon);
popupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters); mPopupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters);
popupResId = style.getResourceId(a, R.styleable.Keyboard_Key_popupKeyboard, 0); mPopupResId = style.getResourceId(a, R.styleable.Keyboard_Key_popupKeyboard, 0);
repeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false); mRepeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false);
modifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false); mModifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false);
sticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false); mSticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false);
edgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0); mEdgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0);
edgeFlags |= parent.rowEdgeFlags; mEdgeFlags |= parent.mRowEdgeFlags;
icon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon); mIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon);
Keyboard.setDefaultBounds(icon); Keyboard.setDefaultBounds(mIcon);
hintIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyHintIcon); mHintIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyHintIcon);
Keyboard.setDefaultBounds(hintIcon); Keyboard.setDefaultBounds(mHintIcon);
manualTemporaryUpperCaseHintIcon = style.getDrawable(a, mManualTemporaryUpperCaseHintIcon = style.getDrawable(a,
R.styleable.Keyboard_Key_manualTemporaryUpperCaseHintIcon); R.styleable.Keyboard_Key_manualTemporaryUpperCaseHintIcon);
Keyboard.setDefaultBounds(manualTemporaryUpperCaseHintIcon); Keyboard.setDefaultBounds(mManualTemporaryUpperCaseHintIcon);
label = style.getText(a, R.styleable.Keyboard_Key_keyLabel); mLabel = style.getText(a, R.styleable.Keyboard_Key_keyLabel);
labelOption = style.getFlag(a, R.styleable.Keyboard_Key_keyLabelOption, 0); mLabelOption = style.getFlag(a, R.styleable.Keyboard_Key_keyLabelOption, 0);
manualTemporaryUpperCaseCode = style.getInt(a, mManualTemporaryUpperCaseCode = style.getInt(a,
R.styleable.Keyboard_Key_manualTemporaryUpperCaseCode, 0); R.styleable.Keyboard_Key_manualTemporaryUpperCaseCode, 0);
text = style.getText(a, R.styleable.Keyboard_Key_keyOutputText); mOutputText = style.getText(a, R.styleable.Keyboard_Key_keyOutputText);
final Drawable shiftedIcon = style.getDrawable(a, final Drawable shiftedIcon = style.getDrawable(a,
R.styleable.Keyboard_Key_shiftedIcon); R.styleable.Keyboard_Key_shiftedIcon);
if (shiftedIcon != null)
keyboard.getShiftedIcons().put(this, shiftedIcon);
if (codes == null && !TextUtils.isEmpty(label)) {
codes = new int[] { label.charAt(0) };
}
a.recycle(); a.recycle();
if (shiftedIcon != null)
mKeyboard.getShiftedIcons().put(this, shiftedIcon);
if (mCodes == null && !TextUtils.isEmpty(mLabel)) {
mCodes = new int[] { mLabel.charAt(0) };
}
if (mPopupCharacters == null || mPopupCharacters.length() == 0) {
// If there is a keyboard with no keys specified in popupCharacters
mPopupResId = 0;
}
} }
/** /**
@ -216,7 +233,7 @@ public class Key {
* @see #onReleased(boolean) * @see #onReleased(boolean)
*/ */
public void onPressed() { public void onPressed() {
pressed = !pressed; mPressed = !mPressed;
} }
/** /**
@ -226,10 +243,9 @@ public class Key {
* @see #onPressed() * @see #onPressed()
*/ */
public void onReleased(boolean inside) { public void onReleased(boolean inside) {
pressed = !pressed; mPressed = !mPressed;
if (sticky) { if (mSticky && !mKeyboard.isShiftLockEnabled(this))
on = !on; mOn = !mOn;
}
} }
/** /**
@ -241,14 +257,14 @@ public class Key {
* inside the key. * inside the key.
*/ */
public boolean isInside(int x, int y) { public boolean isInside(int x, int y) {
boolean leftEdge = (edgeFlags & Keyboard.EDGE_LEFT) > 0; boolean leftEdge = (mEdgeFlags & Keyboard.EDGE_LEFT) > 0;
boolean rightEdge = (edgeFlags & Keyboard.EDGE_RIGHT) > 0; boolean rightEdge = (mEdgeFlags & Keyboard.EDGE_RIGHT) > 0;
boolean topEdge = (edgeFlags & Keyboard.EDGE_TOP) > 0; boolean topEdge = (mEdgeFlags & Keyboard.EDGE_TOP) > 0;
boolean bottomEdge = (edgeFlags & Keyboard.EDGE_BOTTOM) > 0; boolean bottomEdge = (mEdgeFlags & Keyboard.EDGE_BOTTOM) > 0;
if ((x >= this.x || (leftEdge && x <= this.x + this.width)) if ((x >= this.mX || (leftEdge && x <= this.mX + this.mWidth))
&& (x < this.x + this.width || (rightEdge && x >= this.x)) && (x < this.mX + this.mWidth || (rightEdge && x >= this.mX))
&& (y >= this.y || (topEdge && y <= this.y + this.height)) && (y >= this.mY || (topEdge && y <= this.mY + this.mHeight))
&& (y < this.y + this.height || (bottomEdge && y >= this.y))) { && (y < this.mY + this.mHeight || (bottomEdge && y >= this.mY))) {
return true; return true;
} else { } else {
return false; return false;
@ -262,10 +278,10 @@ public class Key {
* @return the square of the distance of the point from the nearest edge of the key * @return the square of the distance of the point from the nearest edge of the key
*/ */
public int squaredDistanceToEdge(int x, int y) { public int squaredDistanceToEdge(int x, int y) {
final int left = this.x; final int left = this.mX;
final int right = left + this.width; final int right = left + this.mWidth;
final int top = this.y; final int top = this.mY;
final int bottom = top + this.height; final int bottom = top + this.mHeight;
final int edgeX = x < left ? left : (x > right ? right : x); final int edgeX = x < left ? left : (x > right ? right : x);
final int edgeY = y < top ? top : (y > bottom ? bottom : y); final int edgeY = y < top ? top : (y > bottom ? bottom : y);
final int dx = x - edgeX; final int dx = x - edgeX;
@ -273,29 +289,43 @@ public class Key {
return dx * dx + dy * dy; return dx * dx + dy * dy;
} }
// sticky is used for shift key. If a key is not sticky and is modifier,
// the key will be treated as functional.
private boolean isFunctionalKey() {
return !mSticky && mModifier;
}
/** /**
* Returns the drawable state for the key, based on the current state and type of the key. * Returns the drawable state for the key, based on the current state and type of the key.
* @return the drawable state of the key. * @return the drawable state of the key.
* @see android.graphics.drawable.StateListDrawable#setState(int[]) * @see android.graphics.drawable.StateListDrawable#setState(int[])
*/ */
public int[] getCurrentDrawableState() { public int[] getCurrentDrawableState() {
if (isFunctionalKey()) {
if (mPressed) {
return KEY_STATE_FUNCTIONAL_PRESSED;
} else {
return KEY_STATE_FUNCTIONAL_NORMAL;
}
}
int[] states = KEY_STATE_NORMAL; int[] states = KEY_STATE_NORMAL;
if (on) { if (mOn) {
if (pressed) { if (mPressed) {
states = KEY_STATE_PRESSED_ON; states = KEY_STATE_PRESSED_ON;
} else { } else {
states = KEY_STATE_NORMAL_ON; states = KEY_STATE_NORMAL_ON;
} }
} else { } else {
if (sticky) { if (mSticky) {
if (pressed) { if (mPressed) {
states = KEY_STATE_PRESSED_OFF; states = KEY_STATE_PRESSED_OFF;
} else { } else {
states = KEY_STATE_NORMAL_OFF; states = KEY_STATE_NORMAL_OFF;
} }
} else { } else {
if (pressed) { if (mPressed) {
states = KEY_STATE_PRESSED; states = KEY_STATE_PRESSED;
} }
} }

View File

@ -29,6 +29,7 @@ import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -51,20 +52,32 @@ import java.util.Map;
* </pre> * </pre>
*/ */
public class Keyboard { public class Keyboard {
private static final String TAG = "Keyboard";
static final String TAG = "Keyboard";
public static final int EDGE_LEFT = 0x01; public static final int EDGE_LEFT = 0x01;
public static final int EDGE_RIGHT = 0x02; public static final int EDGE_RIGHT = 0x02;
public static final int EDGE_TOP = 0x04; public static final int EDGE_TOP = 0x04;
public static final int EDGE_BOTTOM = 0x08; public static final int EDGE_BOTTOM = 0x08;
public static final int KEYCODE_SHIFT = -1; public static final int CODE_ENTER = '\n';
public static final int KEYCODE_MODE_CHANGE = -2; public static final int CODE_TAB = '\t';
public static final int KEYCODE_CANCEL = -3; public static final int CODE_SPACE = ' ';
public static final int KEYCODE_DONE = -4; public static final int CODE_PERIOD = '.';
public static final int KEYCODE_DELETE = -5;
public static final int KEYCODE_ALT = -6; public static final int CODE_SHIFT = -1;
public static final int CODE_MODE_CHANGE = -2;
public static final int CODE_CANCEL = -3;
public static final int CODE_DONE = -4;
public static final int CODE_DELETE = -5;
public static final int CODE_ALT = -6;
public static final int CODE_OPTIONS = -100;
public static final int CODE_OPTIONS_LONGPRESS = -101;
public static final int CODE_CAPSLOCK = -103;
public static final int CODE_NEXT_LANGUAGE = -104;
public static final int CODE_PREV_LANGUAGE = -105;
// TODO: remove this once LatinIME stops referring to this.
public static final int CODE_VOICE = -109;
/** Horizontal gap default for all rows */ /** Horizontal gap default for all rows */
int mDefaultHorizontalGap; int mDefaultHorizontalGap;
@ -78,14 +91,17 @@ public class Keyboard {
/** Default gap between rows */ /** Default gap between rows */
int mDefaultVerticalGap; int mDefaultVerticalGap;
/** Is the keyboard in the shifted state */ /** List of shift keys in this keyboard and its icons and state */
private boolean mShifted;
/** List of shift keys in this keyboard */
private final List<Key> mShiftKeys = new ArrayList<Key>(); private final List<Key> mShiftKeys = new ArrayList<Key>();
/** List of shift keys and its shifted state icon */
private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>(); private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
private final HashSet<Key> mShiftLockEnabled = new HashSet<Key>();
private final KeyboardShiftState mShiftState = new KeyboardShiftState();
/** Space key and its icons */
protected Key mSpaceKey;
protected Drawable mSpaceIcon;
protected Drawable mSpacePreviewIcon;
/** Total height of the keyboard, including the padding and keys */ /** Total height of the keyboard, including the padding and keys */
private int mTotalHeight; private int mTotalHeight;
@ -191,11 +207,11 @@ public class Keyboard {
mTotalWidth = 0; mTotalWidth = 0;
Row row = new Row(this); Row row = new Row(this);
row.defaultHeight = mDefaultHeight; row.mDefaultHeight = mDefaultHeight;
row.defaultWidth = mDefaultWidth; row.mDefaultWidth = mDefaultWidth;
row.defaultHorizontalGap = mDefaultHorizontalGap; row.mDefaultHorizontalGap = mDefaultHorizontalGap;
row.verticalGap = mDefaultVerticalGap; row.mVerticalGap = mDefaultVerticalGap;
row.rowEdgeFlags = EDGE_TOP | EDGE_BOTTOM; row.mRowEdgeFlags = EDGE_TOP | EDGE_BOTTOM;
final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns; final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns;
for (int i = 0; i < characters.length(); i++) { for (int i = 0; i < characters.length(); i++) {
char c = characters.charAt(i); char c = characters.charAt(i);
@ -207,12 +223,12 @@ public class Keyboard {
} }
final Key key = new Key(row); final Key key = new Key(row);
// Horizontal gap is divided equally to both sides of the key. // Horizontal gap is divided equally to both sides of the key.
key.x = x + key.gap / 2; key.mX = x + key.mGap / 2;
key.y = y; key.mY = y;
key.label = String.valueOf(c); key.mLabel = String.valueOf(c);
key.codes = new int[] { c }; key.mCodes = new int[] { c };
column++; column++;
x += key.width + key.gap; x += key.mWidth + key.mGap;
mKeys.add(key); mKeys.add(key);
if (x > mTotalWidth) { if (x > mTotalWidth) {
mTotalWidth = x; mTotalWidth = x;
@ -283,21 +299,6 @@ public class Keyboard {
return mDisplayWidth; return mDisplayWidth;
} }
public boolean setShifted(boolean shiftState) {
for (final Key key : mShiftKeys) {
key.on = shiftState;
}
if (mShifted != shiftState) {
mShifted = shiftState;
return true;
}
return false;
}
public boolean isShiftedOrShiftLocked() {
return mShifted;
}
public List<Key> getShiftKeys() { public List<Key> getShiftKeys() {
return mShiftKeys; return mShiftKeys;
} }
@ -306,6 +307,82 @@ public class Keyboard {
return mShiftedIcons; return mShiftedIcons;
} }
public void enableShiftLock() {
for (final Key key : getShiftKeys()) {
mShiftLockEnabled.add(key);
mNormalShiftIcons.put(key, key.mIcon);
}
}
public boolean isShiftLockEnabled(Key key) {
return mShiftLockEnabled.contains(key);
}
public boolean setShiftLocked(boolean newShiftLockState) {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
key.mOn = newShiftLockState;
key.mIcon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key);
}
mShiftState.setShiftLocked(newShiftLockState);
return true;
}
public boolean isShiftLocked() {
return mShiftState.isShiftLocked();
}
public boolean setShifted(boolean newShiftState) {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
if (!newShiftState && !mShiftState.isShiftLocked()) {
key.mIcon = mNormalShiftIcons.get(key);
} else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
key.mIcon = shiftedIcons.get(key);
}
}
return mShiftState.setShifted(newShiftState);
}
public boolean isShiftedOrShiftLocked() {
return mShiftState.isShiftedOrShiftLocked();
}
public void setAutomaticTemporaryUpperCase() {
setShifted(true);
mShiftState.setAutomaticTemporaryUpperCase();
}
public boolean isAutomaticTemporaryUpperCase() {
return isAlphaKeyboard() && mShiftState.isAutomaticTemporaryUpperCase();
}
public boolean isManualTemporaryUpperCase() {
return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
}
public KeyboardShiftState getKeyboardShiftState() {
return mShiftState;
}
public boolean isAlphaKeyboard() {
return mId.isAlphabetKeyboard();
}
public boolean isPhoneKeyboard() {
return mId.isPhoneKeyboard();
}
public boolean isNumberKeyboard() {
return mId.isNumberKeyboard();
}
public void setSpaceKey(Key space) {
mSpaceKey = space;
mSpaceIcon = space.mIcon;
mSpacePreviewIcon = space.mPreviewIcon;
}
private void computeNearestNeighbors() { private void computeNearestNeighbors() {
// Round-up so we don't have any pixels outside the grid // Round-up so we don't have any pixels outside the grid
mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH;

View File

@ -83,10 +83,18 @@ public class KeyboardId {
return mXmlId; return mXmlId;
} }
public boolean isAlphabetMode() { public boolean isAlphabetKeyboard() {
return mXmlId == R.xml.kbd_qwerty; return mXmlId == R.xml.kbd_qwerty;
} }
public boolean isPhoneKeyboard() {
return mMode == MODE_PHONE;
}
public boolean isNumberKeyboard() {
return mMode == MODE_NUMBER;
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
return other instanceof KeyboardId && equals((KeyboardId) other); return other instanceof KeyboardId && equals((KeyboardId) other);

View File

@ -264,8 +264,10 @@ public class KeyboardParser {
mKeyStyles); mKeyStyles);
checkEndTag(TAG_KEY, parser); checkEndTag(TAG_KEY, parser);
keys.add(key); keys.add(key);
if (key.codes[0] == Keyboard.KEYCODE_SHIFT) if (key.mCodes[0] == Keyboard.CODE_SHIFT)
mKeyboard.getShiftKeys().add(key); mKeyboard.getShiftKeys().add(key);
if (key.mCodes[0] == Keyboard.CODE_SPACE)
mKeyboard.setSpaceKey(key);
endKey(key); endKey(key);
} }
} }
@ -492,12 +494,12 @@ public class KeyboardParser {
private void endRow() { private void endRow() {
if (mCurrentRow == null) if (mCurrentRow == null)
throw new InflateException("orphant end row tag"); throw new InflateException("orphant end row tag");
mCurrentY += mCurrentRow.verticalGap + mCurrentRow.defaultHeight; mCurrentY += mCurrentRow.mVerticalGap + mCurrentRow.mDefaultHeight;
mCurrentRow = null; mCurrentRow = null;
} }
private void endKey(Key key) { private void endKey(Key key) {
mCurrentX += key.gap + key.width; mCurrentX += key.mGap + key.mWidth;
if (mCurrentX > mMaxRowWidth) if (mCurrentX > mMaxRowWidth)
mMaxRowWidth = mCurrentX; mMaxRowWidth = mCurrentX;
} }

View File

@ -16,12 +16,10 @@
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard;
import com.android.inputmethod.latin.KeyboardSwitcher;
import android.util.Log; import android.util.Log;
public class LatinKeyboardShiftState { public class KeyboardShiftState {
private static final String TAG = "LatinKeyboardShiftState"; private static final String TAG = "KeyboardShiftState";
private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE; private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
private static final int NORMAL = 0; private static final int NORMAL = 0;

View File

@ -14,12 +14,14 @@
* the License. * the License.
*/ */
package com.android.inputmethod.latin; package com.android.inputmethod.keyboard;
import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.latin.LatinIMESettings;
import com.android.inputmethod.keyboard.LatinKeyboard; import com.android.inputmethod.latin.LatinIMEUtil;
import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -238,7 +240,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} }
public boolean isAlphabetMode() { public boolean isAlphabetMode() {
return mCurrentId != null && mCurrentId.isAlphabetMode(); return mCurrentId != null && mCurrentId.isAlphabetKeyboard();
} }
public boolean isInputViewShown() { public boolean isInputViewShown() {
@ -530,12 +532,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// characters followed by a space/enter // characters followed by a space/enter
switch (mSymbolsModeState) { switch (mSymbolsModeState) {
case SYMBOLS_MODE_STATE_BEGIN: case SYMBOLS_MODE_STATE_BEGIN:
if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) { if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key > 0) {
mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL; mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
} }
break; break;
case SYMBOLS_MODE_STATE_SYMBOL: case SYMBOLS_MODE_STATE_SYMBOL:
if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) { if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
changeKeyboardMode(); changeKeyboardMode();
} }
break; break;

View File

@ -58,8 +58,6 @@ import java.util.WeakHashMap;
* A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key * A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key
* presses and touch movements. * presses and touch movements.
* *
* TODO: References to LatinKeyboard in this class should be replaced with ones to its base class.
*
* @attr ref R.styleable#KeyboardView_keyBackground * @attr ref R.styleable#KeyboardView_keyBackground
* @attr ref R.styleable#KeyboardView_keyPreviewLayout * @attr ref R.styleable#KeyboardView_keyPreviewLayout
* @attr ref R.styleable#KeyboardView_keyPreviewOffset * @attr ref R.styleable#KeyboardView_keyPreviewOffset
@ -592,7 +590,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
int maxCount = 0; int maxCount = 0;
int mostCommonWidth = 0; int mostCommonWidth = 0;
for (Key key : keys) { for (Key key : keys) {
final Integer width = key.width + key.gap; final Integer width = key.mWidth + key.mGap;
Integer count = histogram.get(width); Integer count = histogram.get(width);
if (count == null) if (count == null)
count = 0; count = 0;
@ -648,17 +646,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final int kbdPaddingTop = getPaddingTop(); final int kbdPaddingTop = getPaddingTop();
final Key[] keys = mKeys; final Key[] keys = mKeys;
final Key invalidKey = mInvalidatedKey; final Key invalidKey = mInvalidatedKey;
final boolean isManualTemporaryUpperCase = (mKeyboard instanceof LatinKeyboard final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
&& ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase());
boolean drawSingleKey = false; boolean drawSingleKey = false;
if (invalidKey != null && canvas.getClipBounds(clipRegion)) { if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
// TODO we should use Rect.inset and Rect.contains here. // TODO we should use Rect.inset and Rect.contains here.
// Is clipRegion completely contained within the invalidated key? // Is clipRegion completely contained within the invalidated key?
if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && if (invalidKey.mX + kbdPaddingLeft - 1 <= clipRegion.left &&
invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && invalidKey.mY + kbdPaddingTop - 1 <= clipRegion.top &&
invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right && invalidKey.mX + invalidKey.mWidth + kbdPaddingLeft + 1 >= clipRegion.right &&
invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) { invalidKey.mY + invalidKey.mHeight + kbdPaddingTop + 1 >= clipRegion.bottom) {
drawSingleKey = true; drawSingleKey = true;
} }
} }
@ -673,16 +670,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
keyBackground.setState(drawableState); keyBackground.setState(drawableState);
// Switch the character to uppercase if shift is pressed // Switch the character to uppercase if shift is pressed
String label = key.label == null? null : adjustCase(key.label).toString(); String label = key.mLabel == null? null : adjustCase(key.mLabel).toString();
final Rect bounds = keyBackground.getBounds(); final Rect bounds = keyBackground.getBounds();
if (key.width != bounds.right || key.height != bounds.bottom) { if (key.mWidth != bounds.right || key.mHeight != bounds.bottom) {
keyBackground.setBounds(0, 0, key.width, key.height); keyBackground.setBounds(0, 0, key.mWidth, key.mHeight);
} }
canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop); canvas.translate(key.mX + kbdPaddingLeft, key.mY + kbdPaddingTop);
keyBackground.draw(canvas); keyBackground.draw(canvas);
final int rowHeight = padding.top + key.height; final int rowHeight = padding.top + key.mHeight;
// Draw key label // Draw key label
if (label != null) { if (label != null) {
// For characters, use large font. For labels like "Done", use small font. // For characters, use large font. For labels like "Done", use small font.
@ -691,36 +688,36 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// Vertical label text alignment. // Vertical label text alignment.
final float baseline; final float baseline;
if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) { if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) {
baseline = key.height - baseline = key.mHeight -
+ labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR; + labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR;
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawHorizontalLine(canvas, (int)baseline, key.width, 0xc0008000, drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000,
new Paint()); new Paint());
} else { // Align center } else { // Align center
final float centerY = (key.height + padding.top - padding.bottom) / 2; final float centerY = (key.mHeight + padding.top - padding.bottom) / 2;
baseline = centerY baseline = centerY
+ labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER; + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER;
} }
// Horizontal label text alignment // Horizontal label text alignment
final int positionX; final int positionX;
if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
positionX = mKeyLabelHorizontalPadding + padding.left; positionX = mKeyLabelHorizontalPadding + padding.left;
paint.setTextAlign(Align.LEFT); paint.setTextAlign(Align.LEFT);
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint()); drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint());
} else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
positionX = key.width - mKeyLabelHorizontalPadding - padding.right; positionX = key.mWidth - mKeyLabelHorizontalPadding - padding.right;
paint.setTextAlign(Align.RIGHT); paint.setTextAlign(Align.RIGHT);
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint()); drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint());
} else { } else {
positionX = (key.width + padding.left - padding.right) / 2; positionX = (key.mWidth + padding.left - padding.right) / 2;
paint.setTextAlign(Align.CENTER); paint.setTextAlign(Align.CENTER);
if (DEBUG_SHOW_ALIGN && label.length() > 1) if (DEBUG_SHOW_ALIGN && label.length() > 1)
drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint()); drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
} }
if (key.manualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) { if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
paint.setColor(mKeyTextColorDisabled); paint.setColor(mKeyTextColorDisabled);
} else { } else {
paint.setColor(mKeyTextColor); paint.setColor(mKeyTextColor);
@ -732,47 +729,47 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
paint.setShadowLayer(0, 0, 0, 0); paint.setShadowLayer(0, 0, 0, 0);
} }
// Draw key icon // Draw key icon
if (key.label == null && key.icon != null) { if (key.mLabel == null && key.mIcon != null) {
final int drawableWidth = key.icon.getIntrinsicWidth(); final int drawableWidth = key.mIcon.getIntrinsicWidth();
final int drawableHeight = key.icon.getIntrinsicHeight(); final int drawableHeight = key.mIcon.getIntrinsicHeight();
final int drawableX; final int drawableX;
final int drawableY = ( final int drawableY = (
key.height + padding.top - padding.bottom - drawableHeight) / 2; key.mHeight + padding.top - padding.bottom - drawableHeight) / 2;
if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
drawableX = padding.left + mKeyLabelHorizontalPadding; drawableX = padding.left + mKeyLabelHorizontalPadding;
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint()); drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint());
} else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
drawableX = key.width - padding.right - mKeyLabelHorizontalPadding drawableX = key.mWidth - padding.right - mKeyLabelHorizontalPadding
- drawableWidth; - drawableWidth;
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight, drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight,
0xc0808000, new Paint()); 0xc0808000, new Paint());
} else { // Align center } else { // Align center
drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2; drawableX = (key.mWidth + padding.left - padding.right - drawableWidth) / 2;
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight, drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight,
0xc0008080, new Paint()); 0xc0008080, new Paint());
} }
drawIcon(canvas, key.icon, drawableX, drawableY, drawableWidth, drawableHeight); drawIcon(canvas, key.mIcon, drawableX, drawableY, drawableWidth, drawableHeight);
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
0x80c00000, new Paint()); 0x80c00000, new Paint());
} }
if (key.hintIcon != null) { if (key.mHintIcon != null) {
final int drawableWidth = key.width; final int drawableWidth = key.mWidth;
final int drawableHeight = key.height; final int drawableHeight = key.mHeight;
final int drawableX = 0; final int drawableX = 0;
final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL; final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
Drawable icon = (isManualTemporaryUpperCase Drawable icon = (isManualTemporaryUpperCase
&& key.manualTemporaryUpperCaseHintIcon != null) && key.mManualTemporaryUpperCaseHintIcon != null)
? key.manualTemporaryUpperCaseHintIcon : key.hintIcon; ? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon;
drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight); drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
if (DEBUG_SHOW_ALIGN) if (DEBUG_SHOW_ALIGN)
drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
0x80c0c000, new Paint()); 0x80c0c000, new Paint());
} }
canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop); canvas.translate(-key.mX - kbdPaddingLeft, -key.mY - kbdPaddingTop);
} }
if (DEBUG_KEYBOARD_GRID) { if (DEBUG_KEYBOARD_GRID) {
@ -822,9 +819,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// For characters, use large font. For labels like "Done", use small font. // For characters, use large font. For labels like "Done", use small font.
final int labelSize; final int labelSize;
final Typeface labelStyle; final Typeface labelStyle;
if (label.length() > 1 && key.codes.length < 2) { if (label.length() > 1 && key.mCodes.length < 2) {
labelSize = mLabelTextSize; labelSize = mLabelTextSize;
if ((key.labelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) { if ((key.mLabelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) {
labelStyle = Typeface.DEFAULT; labelStyle = Typeface.DEFAULT;
} else { } else {
labelStyle = Typeface.DEFAULT_BOLD; labelStyle = Typeface.DEFAULT_BOLD;
@ -927,11 +924,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
if (key == null || !mInForeground) if (key == null || !mInForeground)
return; return;
// What we show as preview should match what we show on key top in onBufferDraw(). // What we show as preview should match what we show on key top in onBufferDraw().
if (key.label != null) { if (key.mLabel != null) {
// TODO Should take care of temporaryShiftLabel here. // TODO Should take care of temporaryShiftLabel here.
mPreviewText.setCompoundDrawables(null, null, null, null); mPreviewText.setCompoundDrawables(null, null, null, null);
mPreviewText.setText(adjustCase(tracker.getPreviewText(key))); mPreviewText.setText(adjustCase(tracker.getPreviewText(key)));
if (key.label.length() > 1 && key.codes.length < 2) { if (key.mLabel.length() > 1 && key.mCodes.length < 2) {
mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize); mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
mPreviewText.setTypeface(Typeface.DEFAULT_BOLD); mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
} else { } else {
@ -940,12 +937,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
} else { } else {
mPreviewText.setCompoundDrawables(null, null, null, mPreviewText.setCompoundDrawables(null, null, null,
key.iconPreview != null ? key.iconPreview : key.icon); key.mPreviewIcon != null ? key.mPreviewIcon : key.mIcon);
mPreviewText.setText(null); mPreviewText.setText(null);
} }
mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.mWidth
+ mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
final int popupHeight = mPreviewHeight; final int popupHeight = mPreviewHeight;
LayoutParams lp = mPreviewText.getLayoutParams(); LayoutParams lp = mPreviewText.getLayoutParams();
@ -954,8 +951,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
lp.height = popupHeight; lp.height = popupHeight;
} }
int popupPreviewX = key.x - (popupWidth - key.width) / 2; int popupPreviewX = key.mX - (popupWidth - key.mWidth) / 2;
int popupPreviewY = key.y - popupHeight + mPreviewOffset; int popupPreviewY = key.mY - popupHeight + mPreviewOffset;
mHandler.cancelDismissPreview(); mHandler.cancelDismissPreview();
if (mOffsetInWindow == null) { if (mOffsetInWindow == null) {
@ -969,7 +966,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
// Set the preview background state // Set the preview background state
mPreviewText.getBackground().setState( mPreviewText.getBackground().setState(
key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); key.mPopupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
popupPreviewX += mOffsetInWindow[0]; popupPreviewX += mOffsetInWindow[0];
popupPreviewY += mOffsetInWindow[1]; popupPreviewY += mOffsetInWindow[1];
@ -977,10 +974,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
if (popupPreviewY + mWindowY < 0) { if (popupPreviewY + mWindowY < 0) {
// If the key you're pressing is on the left side of the keyboard, show the popup on // If the key you're pressing is on the left side of the keyboard, show the popup on
// the right, offset by enough to see at least one key to the left/right. // the right, offset by enough to see at least one key to the left/right.
if (key.x + key.width <= getWidth() / 2) { if (key.mX + key.mWidth <= getWidth() / 2) {
popupPreviewX += (int) (key.width * 2.5); popupPreviewX += (int) (key.mWidth * 2.5);
} else { } else {
popupPreviewX -= (int) (key.width * 2.5); popupPreviewX -= (int) (key.mWidth * 2.5);
} }
popupPreviewY += popupHeight; popupPreviewY += popupHeight;
} }
@ -1028,11 +1025,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
return; return;
mInvalidatedKey = key; mInvalidatedKey = key;
// TODO we should clean up this and record key's region to use in onBufferDraw. // TODO we should clean up this and record key's region to use in onBufferDraw.
mDirtyRect.union(key.x + getPaddingLeft(), key.y + getPaddingTop(), mDirtyRect.union(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop()); key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
onBufferDraw(); onBufferDraw();
invalidate(key.x + getPaddingLeft(), key.y + getPaddingTop(), invalidate(key.mX + getPaddingLeft(), key.mY + getPaddingTop(),
key.x + key.width + getPaddingLeft(), key.y + key.height + getPaddingTop()); key.mX + key.mWidth + getPaddingLeft(), key.mY + key.mHeight + getPaddingTop());
} }
private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) { private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
@ -1058,11 +1055,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private void onLongPressShiftKey(PointerTracker tracker) { private void onLongPressShiftKey(PointerTracker tracker) {
tracker.setAlreadyProcessed(); tracker.setAlreadyProcessed();
mPointerQueue.remove(tracker); mPointerQueue.remove(tracker);
mKeyboardActionListener.onKey(LatinKeyboard.KEYCODE_CAPSLOCK, null, 0, 0); mKeyboardActionListener.onKey(Keyboard.CODE_CAPSLOCK, null, 0, 0);
} }
private View inflateMiniKeyboardContainer(Key popupKey) { private View inflateMiniKeyboardContainer(Key popupKey) {
int popupKeyboardId = popupKey.popupResId; int popupKeyboardId = popupKey.mPopupResId;
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService( LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE); Context.LAYOUT_INFLATER_SERVICE);
View container = inflater.inflate(mPopupLayout, null); View container = inflater.inflate(mPopupLayout, null);
@ -1116,8 +1113,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
miniKeyboard.mGestureDetector = null; miniKeyboard.mGestureDetector = null;
Keyboard keyboard; Keyboard keyboard;
if (popupKey.popupCharacters != null) { if (popupKey.mPopupCharacters != null) {
keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.popupCharacters, keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.mPopupCharacters,
-1, getPaddingLeft() + getPaddingRight()); -1, getPaddingLeft() + getPaddingRight());
} else { } else {
keyboard = new Keyboard(getContext(), popupKeyboardId); keyboard = new Keyboard(getContext(), popupKeyboardId);
@ -1133,7 +1130,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private static boolean isOneRowKeys(List<Key> keys) { private static boolean isOneRowKeys(List<Key> keys) {
if (keys.size() == 0) return false; if (keys.size() == 0) return false;
final int edgeFlags = keys.get(0).edgeFlags; final int edgeFlags = keys.get(0).mEdgeFlags;
// HACK: The first key of mini keyboard which was inflated from xml and has multiple rows, // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows,
// does not have both top and bottom edge flags on at the same time. On the other hand, // does not have both top and bottom edge flags on at the same time. On the other hand,
// the first key of mini keyboard that was created with popupCharacters must have both top // the first key of mini keyboard that was created with popupCharacters must have both top
@ -1155,7 +1152,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// TODO if popupKey.popupCharacters has only one letter, send it as key without opening // TODO if popupKey.popupCharacters has only one letter, send it as key without opening
// mini keyboard. // mini keyboard.
if (popupKey.popupResId == 0) if (popupKey.mPopupResId == 0)
return false; return false;
View container = mMiniKeyboardCache.get(popupKey); View container = mMiniKeyboardCache.get(popupKey);
@ -1177,22 +1174,22 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// b) When we have the rightmost key in popup keyboard directly above the pressed key // b) When we have the rightmost key in popup keyboard directly above the pressed key
// Left edges of both keys should be aligned for consistent default selection // Left edges of both keys should be aligned for consistent default selection
final List<Key> miniKeys = mMiniKeyboard.getKeyboard().getKeys(); final List<Key> miniKeys = mMiniKeyboard.getKeyboard().getKeys();
final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).width : 0; final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).mWidth : 0;
// HACK: Have the leftmost number in the popup characters right above the key // HACK: Have the leftmost number in the popup characters right above the key
boolean isNumberAtLeftmost = boolean isNumberAtLeftmost =
hasMultiplePopupChars(popupKey) && isNumberAtLeftmostPopupChar(popupKey); hasMultiplePopupChars(popupKey) && isNumberAtLeftmostPopupChar(popupKey);
int popupX = popupKey.x + mWindowOffset[0]; int popupX = popupKey.mX + mWindowOffset[0];
popupX += getPaddingLeft(); popupX += getPaddingLeft();
if (isNumberAtLeftmost) { if (isNumberAtLeftmost) {
popupX += popupKey.width - miniKeyWidth; // adjustment for a) described above popupX += popupKey.mWidth - miniKeyWidth; // adjustment for a) described above
popupX -= container.getPaddingLeft(); popupX -= container.getPaddingLeft();
} else { } else {
popupX += miniKeyWidth; // adjustment for b) described above popupX += miniKeyWidth; // adjustment for b) described above
popupX -= container.getMeasuredWidth(); popupX -= container.getMeasuredWidth();
popupX += container.getPaddingRight(); popupX += container.getPaddingRight();
} }
int popupY = popupKey.y + mWindowOffset[1]; int popupY = popupKey.mY + mWindowOffset[1];
popupY += getPaddingTop(); popupY += getPaddingTop();
popupY -= container.getMeasuredHeight(); popupY -= container.getMeasuredHeight();
popupY += container.getPaddingBottom(); popupY += container.getPaddingBottom();
@ -1208,7 +1205,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0]; mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0];
mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1]; mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1];
mMiniKeyboard.setPopupOffset(adjustedX, y); mMiniKeyboard.setPopupOffset(adjustedX, y);
// TODO: change the below line to use getLatinKeyboard() instead of getKeyboard()
Keyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard(); Keyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard();
if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null
? false : mKeyboard.isShiftedOrShiftLocked())) { ? false : mKeyboard.isShiftedOrShiftLocked())) {
@ -1224,8 +1220,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// Inject down event on the key to mini keyboard. // Inject down event on the key to mini keyboard.
long eventTime = SystemClock.uptimeMillis(); long eventTime = SystemClock.uptimeMillis();
mMiniKeyboardPopupTime = eventTime; mMiniKeyboardPopupTime = eventTime;
MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.x MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.mX
+ popupKey.width / 2, popupKey.y + popupKey.height / 2, eventTime); + popupKey.mWidth / 2, popupKey.mY + popupKey.mHeight / 2, eventTime);
mMiniKeyboard.onTouchEvent(downEvent); mMiniKeyboard.onTouchEvent(downEvent);
downEvent.recycle(); downEvent.recycle();
@ -1234,15 +1230,15 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
private static boolean hasMultiplePopupChars(Key key) { private static boolean hasMultiplePopupChars(Key key) {
if (key.popupCharacters != null && key.popupCharacters.length() > 1) { if (key.mPopupCharacters != null && key.mPopupCharacters.length() > 1) {
return true; return true;
} }
return false; return false;
} }
private static boolean isNumberAtLeftmostPopupChar(Key key) { private static boolean isNumberAtLeftmostPopupChar(Key key) {
if (key.popupCharacters != null && key.popupCharacters.length() > 0 if (key.mPopupCharacters != null && key.mPopupCharacters.length() > 0
&& isAsciiDigit(key.popupCharacters.charAt(0))) { && isAsciiDigit(key.mPopupCharacters.charAt(0))) {
return true; return true;
} }
return false; return false;

View File

@ -19,47 +19,11 @@ package com.android.inputmethod.keyboard;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.XmlResourceParser; import android.content.res.XmlResourceParser;
// TODO: We should remove this class
public class LatinKey extends Key { public class LatinKey extends Key {
// functional normal state (with properties)
private final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
android.R.attr.state_single
};
// functional pressed state (with properties)
private final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
android.R.attr.state_single,
android.R.attr.state_pressed
};
private boolean mShiftLockEnabled;
public LatinKey(Resources res, Row parent, int x, int y, public LatinKey(Resources res, Row parent, int x, int y,
XmlResourceParser parser, KeyStyles keyStyles) { XmlResourceParser parser, KeyStyles keyStyles) {
super(res, parent, x, y, parser, keyStyles); super(res, parent, x, y, parser, keyStyles);
if (popupCharacters != null && popupCharacters.length() == 0) {
// If there is a keyboard with no keys specified in popupCharacters
popupResId = 0;
}
}
void enableShiftLock() {
mShiftLockEnabled = true;
}
// sticky is used for shift key. If a key is not sticky and is modifier,
// the key will be treated as functional.
private boolean isFunctionalKey() {
return !sticky && modifier;
}
@Override
public void onReleased(boolean inside) {
if (!mShiftLockEnabled) {
super.onReleased(inside);
} else {
pressed = !pressed;
}
} }
/** /**
@ -67,24 +31,12 @@ public class LatinKey extends Key {
*/ */
@Override @Override
public boolean isInside(int x, int y) { public boolean isInside(int x, int y) {
boolean result = (keyboard instanceof LatinKeyboard) boolean result = (mKeyboard instanceof LatinKeyboard)
&& ((LatinKeyboard)keyboard).isInside(this, x, y); && ((LatinKeyboard)mKeyboard).isInside(this, x, y);
return result; return result;
} }
boolean isInsideSuper(int x, int y) { boolean isInsideSuper(int x, int y) {
return super.isInside(x, y); return super.isInside(x, y);
} }
@Override
public int[] getCurrentDrawableState() {
if (isFunctionalKey()) {
if (pressed) {
return KEY_STATE_FUNCTIONAL_PRESSED;
} else {
return KEY_STATE_FUNCTIONAL_NORMAL;
}
}
return super.getCurrentDrawableState();
}
} }

View File

@ -16,7 +16,6 @@
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher;
@ -34,36 +33,23 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.util.Log; import android.util.Log;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
// TODO: We should remove this class
public class LatinKeyboard extends Keyboard { public class LatinKeyboard extends Keyboard {
private static final boolean DEBUG_PREFERRED_LETTER = false; private static final boolean DEBUG_PREFERRED_LETTER = false;
private static final String TAG = "LatinKeyboard"; private static final String TAG = "LatinKeyboard";
public static final int KEYCODE_OPTIONS = -100; public static final int OPACITY_FULLY_OPAQUE = 255;
public static final int KEYCODE_OPTIONS_LONGPRESS = -101;
// TODO: remove this once LatinIME stops referring to this.
public static final int KEYCODE_VOICE = -102;
public static final int KEYCODE_NEXT_LANGUAGE = -104;
public static final int KEYCODE_PREV_LANGUAGE = -105;
public static final int KEYCODE_CAPSLOCK = -106;
static final int OPACITY_FULLY_OPAQUE = 255;
private static final int SPACE_LED_LENGTH_PERCENT = 80; private static final int SPACE_LED_LENGTH_PERCENT = 80;
private Drawable mShiftLockPreviewIcon; private Drawable mShiftLockPreviewIcon;
private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
private Drawable mSpaceIcon;
private Drawable mSpaceAutoCompletionIndicator; private Drawable mSpaceAutoCompletionIndicator;
private Drawable mSpacePreviewIcon;
private final Drawable mButtonArrowLeftIcon; private final Drawable mButtonArrowLeftIcon;
private final Drawable mButtonArrowRightIcon; private final Drawable mButtonArrowRightIcon;
private final int mSpaceBarTextShadowColor; private final int mSpaceBarTextShadowColor;
private Key mSpaceKey;
private int mSpaceKeyIndex = -1; private int mSpaceKeyIndex = -1;
private int mSpaceDragStartX; private int mSpaceDragStartX;
private int mSpaceDragLastDiff; private int mSpaceDragLastDiff;
@ -77,8 +63,6 @@ public class LatinKeyboard extends Keyboard {
private int mPrefLetterY; private int mPrefLetterY;
private int mPrefDistance; private int mPrefDistance;
private LatinKeyboardShiftState mShiftState = new LatinKeyboardShiftState();
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f; private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f; private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
@ -111,99 +95,13 @@ public class LatinKeyboard extends Keyboard {
mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right); mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right);
sSpacebarVerticalCorrection = res.getDimensionPixelOffset( sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
R.dimen.spacebar_vertical_correction); R.dimen.spacebar_vertical_correction);
mSpaceKeyIndex = indexOf(LatinIME.KEYCODE_SPACE); mSpaceKeyIndex = indexOf(CODE_SPACE);
} }
@Override @Override
protected Key createKeyFromXml(Resources res, Row parent, int x, int y, protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
XmlResourceParser parser, KeyStyles keyStyles) { XmlResourceParser parser, KeyStyles keyStyles) {
Key key = new LatinKey(res, parent, x, y, parser, keyStyles); return new LatinKey(res, parent, x, y, parser, keyStyles);
switch (key.codes[0]) {
case LatinIME.KEYCODE_SPACE:
mSpaceKey = key;
mSpaceIcon = key.icon;
mSpacePreviewIcon = key.iconPreview;
break;
}
return key;
}
public void enableShiftLock() {
for (final Key key : getShiftKeys()) {
if (key instanceof LatinKey) {
((LatinKey)key).enableShiftLock();
}
mNormalShiftIcons.put(key, key.icon);
}
}
public boolean setShiftLocked(boolean newShiftLockState) {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
key.on = newShiftLockState;
key.icon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key);
}
mShiftState.setShiftLocked(newShiftLockState);
return true;
}
public boolean isShiftLocked() {
return mShiftState.isShiftLocked();
}
@Override
public boolean setShifted(boolean newShiftState) {
if (getShiftKeys().size() == 0)
return super.setShifted(newShiftState);
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
if (!newShiftState && !mShiftState.isShiftLocked()) {
key.icon = mNormalShiftIcons.get(key);
} else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
key.icon = shiftedIcons.get(key);
}
}
return mShiftState.setShifted(newShiftState);
}
@Override
public boolean isShiftedOrShiftLocked() {
if (getShiftKeys().size() > 0) {
return mShiftState.isShiftedOrShiftLocked();
} else {
return super.isShiftedOrShiftLocked();
}
}
public void setAutomaticTemporaryUpperCase() {
setShifted(true);
mShiftState.setAutomaticTemporaryUpperCase();
}
public boolean isAutomaticTemporaryUpperCase() {
return isAlphaKeyboard() && mShiftState.isAutomaticTemporaryUpperCase();
}
public boolean isManualTemporaryUpperCase() {
return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
}
public LatinKeyboardShiftState getKeyboardShiftState() {
return mShiftState;
}
public boolean isAlphaKeyboard() {
return mId.getXmlId() == R.xml.kbd_qwerty;
}
public boolean isPhoneKeyboard() {
return mId.mMode == KeyboardId.MODE_PHONE;
}
public boolean isNumberKeyboard() {
return mId.mMode == KeyboardId.MODE_NUMBER;
} }
/** /**
@ -218,15 +116,15 @@ public class LatinKeyboard extends Keyboard {
final Resources res = mRes; final Resources res = mRes;
// If application locales are explicitly selected. // If application locales are explicitly selected.
if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) { if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
mSpaceKey.icon = new BitmapDrawable(res, mSpaceKey.mIcon = new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion)); drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
} else { } else {
// sym_keyboard_space_led can be shared with Black and White symbol themes. // sym_keyboard_space_led can be shared with Black and White symbol themes.
if (isAutoCompletion) { if (isAutoCompletion) {
mSpaceKey.icon = new BitmapDrawable(res, mSpaceKey.mIcon = new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion)); drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
} else { } else {
mSpaceKey.icon = mSpaceIcon; mSpaceKey.mIcon = mSpaceIcon;
} }
} }
} }
@ -283,7 +181,7 @@ public class LatinKeyboard extends Keyboard {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion) { private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion) {
final int width = mSpaceKey.width; final int width = mSpaceKey.mWidth;
final int height = mSpaceIcon.getIntrinsicHeight(); final int height = mSpaceIcon.getIntrinsicHeight();
final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(buffer); final Canvas canvas = new Canvas(buffer);
@ -341,26 +239,26 @@ public class LatinKeyboard extends Keyboard {
private void updateLocaleDrag(int diff) { private void updateLocaleDrag(int diff) {
if (mSlidingLocaleIcon == null) { if (mSlidingLocaleIcon == null) {
final int width = Math.max(mSpaceKey.width, final int width = Math.max(mSpaceKey.mWidth,
(int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)); (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
final int height = mSpacePreviewIcon.getIntrinsicHeight(); final int height = mSpacePreviewIcon.getIntrinsicHeight();
mSlidingLocaleIcon = mSlidingLocaleIcon =
new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height); new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height);
mSlidingLocaleIcon.setBounds(0, 0, width, height); mSlidingLocaleIcon.setBounds(0, 0, width, height);
mSpaceKey.iconPreview = mSlidingLocaleIcon; mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
} }
mSlidingLocaleIcon.setDiff(diff); mSlidingLocaleIcon.setDiff(diff);
if (Math.abs(diff) == Integer.MAX_VALUE) { if (Math.abs(diff) == Integer.MAX_VALUE) {
mSpaceKey.iconPreview = mSpacePreviewIcon; mSpaceKey.mPreviewIcon = mSpacePreviewIcon;
} else { } else {
mSpaceKey.iconPreview = mSlidingLocaleIcon; mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
} }
mSpaceKey.iconPreview.invalidateSelf(); mSpaceKey.mPreviewIcon.invalidateSelf();
} }
public int getLanguageChangeDirection() { public int getLanguageChangeDirection() {
if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1 if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1
|| Math.abs(mSpaceDragLastDiff) < mSpaceKey.width * SPACEBAR_DRAG_THRESHOLD) { || Math.abs(mSpaceDragLastDiff) < mSpaceKey.mWidth * SPACEBAR_DRAG_THRESHOLD) {
return 0; // No change return 0; // No change
} }
return mSpaceDragLastDiff > 0 ? 1 : -1; return mSpaceDragLastDiff > 0 ? 1 : -1;
@ -393,12 +291,12 @@ public class LatinKeyboard extends Keyboard {
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public boolean isInside(LatinKey key, int x, int y) { public boolean isInside(LatinKey key, int x, int y) {
final int code = key.codes[0]; final int code = key.mCodes[0];
if (code == KEYCODE_SHIFT || code == KEYCODE_DELETE) { if (code == CODE_SHIFT || code == CODE_DELETE) {
y -= key.height / 10; y -= key.mHeight / 10;
if (code == KEYCODE_SHIFT) x += key.width / 6; if (code == CODE_SHIFT) x += key.mWidth / 6;
if (code == KEYCODE_DELETE) x -= key.width / 6; if (code == CODE_DELETE) x -= key.mWidth / 6;
} else if (code == LatinIME.KEYCODE_SPACE) { } else if (code == CODE_SPACE) {
y += LatinKeyboard.sSpacebarVerticalCorrection; y += LatinKeyboard.sSpacebarVerticalCorrection;
if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER
&& SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) { && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) {
@ -447,11 +345,11 @@ public class LatinKeyboard extends Keyboard {
mPrefLetterY = y; mPrefLetterY = y;
for (int i = 0; i < nearby.length; i++) { for (int i = 0; i < nearby.length; i++) {
Key k = nearbyKeys.get(nearby[i]); Key k = nearbyKeys.get(nearby[i]);
if (k != key && inPrefList(k.codes[0], pref)) { if (k != key && inPrefList(k.mCodes[0], pref)) {
final int dist = distanceFrom(k, x, y); final int dist = distanceFrom(k, x, y);
if (dist < (int) (k.width * OVERLAP_PERCENTAGE_LOW_PROB) && if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_LOW_PROB) &&
(pref[k.codes[0]] > pref[mPrefLetter] * 3)) { (pref[k.mCodes[0]] > pref[mPrefLetter] * 3)) {
mPrefLetter = k.codes[0]; mPrefLetter = k.mCodes[0];
mPrefDistance = dist; mPrefDistance = dist;
if (DEBUG_PREFERRED_LETTER) { if (DEBUG_PREFERRED_LETTER) {
Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!"); Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!");
@ -475,11 +373,11 @@ public class LatinKeyboard extends Keyboard {
for (int i = 0; i < nearby.length; i++) { for (int i = 0; i < nearby.length; i++) {
Key k = nearbyKeys.get(nearby[i]); Key k = nearbyKeys.get(nearby[i]);
if (inPrefList(k.codes[0], pref)) { if (inPrefList(k.mCodes[0], pref)) {
final int dist = distanceFrom(k, x, y); final int dist = distanceFrom(k, x, y);
if (dist < (int) (k.width * OVERLAP_PERCENTAGE_HIGH_PROB) if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_HIGH_PROB)
&& dist < mPrefDistance) { && dist < mPrefDistance) {
mPrefLetter = k.codes[0]; mPrefLetter = k.mCodes[0];
mPrefLetterX = x; mPrefLetterX = x;
mPrefLetterY = y; mPrefLetterY = y;
mPrefDistance = dist; mPrefDistance = dist;
@ -507,8 +405,8 @@ public class LatinKeyboard extends Keyboard {
} }
private int distanceFrom(Key k, int x, int y) { private int distanceFrom(Key k, int x, int y) {
if (y > k.y && y < k.y + k.height) { if (y > k.mY && y < k.mY + k.mHeight) {
return Math.abs(k.x + k.width / 2 - x); return Math.abs(k.mX + k.mWidth / 2 - x);
} else { } else {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
@ -529,7 +427,7 @@ public class LatinKeyboard extends Keyboard {
List<Key> keys = getKeys(); List<Key> keys = getKeys();
int count = keys.size(); int count = keys.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (keys.get(i).codes[0] == code) return i; if (keys.get(i).mCodes[0] == code) return i;
} }
return -1; return -1;
} }

View File

@ -31,6 +31,7 @@ import android.view.MotionEvent;
import java.util.List; import java.util.List;
// TODO: We should remove this class
public class LatinKeyboardView extends KeyboardView { public class LatinKeyboardView extends KeyboardView {
/** Whether we've started dropping move events because we found a big jump */ /** Whether we've started dropping move events because we found a big jump */
@ -86,9 +87,9 @@ public class LatinKeyboardView extends KeyboardView {
@Override @Override
protected boolean onLongPress(Key key) { protected boolean onLongPress(Key key) {
int primaryCode = key.codes[0]; int primaryCode = key.mCodes[0];
if (primaryCode == LatinKeyboard.KEYCODE_OPTIONS) { if (primaryCode == Keyboard.CODE_OPTIONS) {
return invokeOnKey(LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS); return invokeOnKey(Keyboard.CODE_OPTIONS_LONGPRESS);
} else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) { } else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
// Long pressing on 0 in phone number keypad gives you a '+'. // Long pressing on 0 in phone number keypad gives you a '+'.
return invokeOnKey('+'); return invokeOnKey('+');
@ -216,7 +217,7 @@ public class LatinKeyboardView extends KeyboardView {
if (languageDirection != 0) { if (languageDirection != 0) {
getOnKeyboardActionListener().onKey( getOnKeyboardActionListener().onKey(
languageDirection == 1 languageDirection == 1
? LatinKeyboard.KEYCODE_NEXT_LANGUAGE : LatinKeyboard.KEYCODE_PREV_LANGUAGE, ? Keyboard.CODE_NEXT_LANGUAGE : Keyboard.CODE_PREV_LANGUAGE,
null, mLastX, mLastY); null, mLastX, mLastY);
me.setAction(MotionEvent.ACTION_CANCEL); me.setAction(MotionEvent.ACTION_CANCEL);
keyboard.keyReleased(); keyboard.keyReleased();
@ -271,8 +272,8 @@ public class LatinKeyboardView extends KeyboardView {
} }
c = mStringToPlay.charAt(mStringIndex); c = mStringToPlay.charAt(mStringIndex);
} }
int x = mAsciiKeys[c].x + 10; int x = mAsciiKeys[c].mX + 10;
int y = mAsciiKeys[c].y + 26; int y = mAsciiKeys[c].mY + 26;
MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(), MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN, x, y, 0); MotionEvent.ACTION_DOWN, x, y, 0);
@ -284,8 +285,8 @@ public class LatinKeyboardView extends KeyboardView {
break; break;
case MSG_TOUCH_UP: case MSG_TOUCH_UP:
char cUp = mStringToPlay.charAt(mStringIndex); char cUp = mStringToPlay.charAt(mStringIndex);
int x2 = mAsciiKeys[cUp].x + 10; int x2 = mAsciiKeys[cUp].mX + 10;
int y2 = mAsciiKeys[cUp].y + 26; int y2 = mAsciiKeys[cUp].mY + 26;
mStringIndex++; mStringIndex++;
MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(), MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
@ -309,7 +310,7 @@ public class LatinKeyboardView extends KeyboardView {
List<Key> keys = getLatinKeyboard().getKeys(); List<Key> keys = getLatinKeyboard().getKeys();
// Get the keys on this keyboard // Get the keys on this keyboard
for (int i = 0; i < keys.size(); i++) { for (int i = 0; i < keys.size(); i++) {
int code = keys.get(i).codes[0]; int code = keys.get(i).mCodes[0];
if (code >= 0 && code <= 255) { if (code >= 0 && code <= 255) {
mAsciiKeys[code] = keys.get(i); mAsciiKeys[code] = keys.get(i);
} }

View File

@ -52,7 +52,7 @@ public class MiniKeyboardKeyDetector extends KeyDetector {
} }
if (allKeys != null && closestKeyIndex != NOT_A_KEY) if (allKeys != null && closestKeyIndex != NOT_A_KEY)
allKeys[0] = keys[closestKeyIndex].codes[0]; allKeys[0] = keys[closestKeyIndex].mCodes[0];
return closestKeyIndex; return closestKeyIndex;
} }
} }

View File

@ -14,7 +14,7 @@
* the License. * the License.
*/ */
package com.android.inputmethod.latin; package com.android.inputmethod.keyboard;
import android.util.Log; import android.util.Log;

View File

@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard;
import com.android.inputmethod.keyboard.KeyboardView.UIHandler; import com.android.inputmethod.keyboard.KeyboardView.UIHandler;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import android.content.res.Resources; import android.content.res.Resources;
@ -45,7 +44,7 @@ public class PointerTracker {
// Miscellaneous constants // Miscellaneous constants
private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY; private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY;
private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE }; private static final int[] KEY_DELETE = { Keyboard.CODE_DELETE };
private final UIProxy mProxy; private final UIProxy mProxy;
private final UIHandler mHandler; private final UIHandler mHandler;
@ -207,9 +206,9 @@ public class PointerTracker {
Key key = getKey(keyIndex); Key key = getKey(keyIndex);
if (key == null) if (key == null)
return false; return false;
int primaryCode = key.codes[0]; int primaryCode = key.mCodes[0];
return primaryCode == Keyboard.KEYCODE_SHIFT return primaryCode == Keyboard.CODE_SHIFT
|| primaryCode == Keyboard.KEYCODE_MODE_CHANGE; || primaryCode == Keyboard.CODE_MODE_CHANGE;
} }
public boolean isModifier() { public boolean isModifier() {
@ -222,7 +221,7 @@ public class PointerTracker {
public boolean isSpaceKey(int keyIndex) { public boolean isSpaceKey(int keyIndex) {
Key key = getKey(keyIndex); Key key = getKey(keyIndex);
return key != null && key.codes[0] == LatinIME.KEYCODE_SPACE; return key != null && key.mCodes[0] == Keyboard.CODE_SPACE;
} }
public void releaseKey() { public void releaseKey() {
@ -278,14 +277,14 @@ public class PointerTracker {
checkMultiTap(eventTime, keyIndex); checkMultiTap(eventTime, keyIndex);
if (mListener != null) { if (mListener != null) {
if (isValidKeyIndex(keyIndex)) { if (isValidKeyIndex(keyIndex)) {
mListener.onPress(mKeys[keyIndex].codes[0]); mListener.onPress(mKeys[keyIndex].mCodes[0]);
// This onPress call may have changed keyboard layout and have updated mKeyIndex. // This onPress call may have changed keyboard layout and have updated mKeyIndex.
// If that's the case, mKeyIndex has been updated in setKeyboard(). // If that's the case, mKeyIndex has been updated in setKeyboard().
keyIndex = mKeyState.getKeyIndex(); keyIndex = mKeyState.getKeyIndex();
} }
} }
if (isValidKeyIndex(keyIndex)) { if (isValidKeyIndex(keyIndex)) {
if (mKeys[keyIndex].repeatable) { if (mKeys[keyIndex].mRepeatable) {
repeatKey(keyIndex); repeatKey(keyIndex);
mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this); mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
mIsRepeatableKey = true; mIsRepeatableKey = true;
@ -309,7 +308,7 @@ public class PointerTracker {
startLongPressTimer(keyIndex); startLongPressTimer(keyIndex);
} else if (!isMinorMoveBounce(x, y, keyIndex)) { } else if (!isMinorMoveBounce(x, y, keyIndex)) {
if (mListener != null) if (mListener != null)
mListener.onRelease(oldKey.codes[0]); mListener.onRelease(oldKey.mCodes[0]);
resetMultiTap(); resetMultiTap();
keyState.onMoveToNewKey(keyIndex, x, y); keyState.onMoveToNewKey(keyIndex, x, y);
startLongPressTimer(keyIndex); startLongPressTimer(keyIndex);
@ -317,7 +316,7 @@ public class PointerTracker {
} else { } else {
if (oldKey != null) { if (oldKey != null) {
if (mListener != null) if (mListener != null)
mListener.onRelease(oldKey.codes[0]); mListener.onRelease(oldKey.mCodes[0]);
keyState.onMoveToNewKey(keyIndex, x ,y); keyState.onMoveToNewKey(keyIndex, x ,y);
mHandler.cancelLongPressTimers(); mHandler.cancelLongPressTimers();
} else if (!isMinorMoveBounce(x, y, keyIndex)) { } else if (!isMinorMoveBounce(x, y, keyIndex)) {
@ -368,7 +367,7 @@ public class PointerTracker {
if (key != null) { if (key != null) {
// While key is repeating, because there is no need to handle multi-tap key, we can // While key is repeating, because there is no need to handle multi-tap key, we can
// pass -1 as eventTime argument. // pass -1 as eventTime argument.
detectAndSendKey(keyIndex, key.x, key.y, -1); detectAndSendKey(keyIndex, key.mX, key.mY, -1);
} }
} }
@ -420,18 +419,13 @@ public class PointerTracker {
private void startLongPressTimer(int keyIndex) { private void startLongPressTimer(int keyIndex) {
Key key = getKey(keyIndex); Key key = getKey(keyIndex);
if (key.codes[0] == Keyboard.KEYCODE_SHIFT) { if (key.mCodes[0] == Keyboard.CODE_SHIFT) {
mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this); mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
} else { } else {
mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
} }
} }
private boolean isManualTemporaryUpperCase() {
return mKeyboard instanceof LatinKeyboard
&& ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase();
}
private void detectAndSendKey(int index, int x, int y, long eventTime) { private void detectAndSendKey(int index, int x, int y, long eventTime) {
final KeyboardActionListener listener = mListener; final KeyboardActionListener listener = mListener;
final Key key = getKey(index); final Key key = getKey(index);
@ -440,30 +434,31 @@ public class PointerTracker {
if (listener != null) if (listener != null)
listener.onCancel(); listener.onCancel();
} else { } else {
if (key.text != null) { if (key.mOutputText != null) {
if (listener != null) { if (listener != null) {
listener.onText(key.text); listener.onText(key.mOutputText);
listener.onRelease(NOT_A_KEY); listener.onRelease(NOT_A_KEY);
} }
} else { } else {
int code = key.codes[0]; int code = key.mCodes[0];
//TextEntryState.keyPressedAt(key, x, y); //TextEntryState.keyPressedAt(key, x, y);
int[] codes = mKeyDetector.newCodeArray(); int[] codes = mKeyDetector.newCodeArray();
mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes); mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
// Multi-tap // Multi-tap
if (mInMultiTap) { if (mInMultiTap) {
if (mTapCount != -1) { if (mTapCount != -1) {
mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y); mListener.onKey(Keyboard.CODE_DELETE, KEY_DELETE, x, y);
} else { } else {
mTapCount = 0; mTapCount = 0;
} }
code = key.codes[mTapCount]; code = key.mCodes[mTapCount];
} }
// If keyboard is in manual temporary upper case state and key has manual temporary // If keyboard is in manual temporary upper case state and key has manual temporary
// shift code, alternate character code should be sent. // shift code, alternate character code should be sent.
if (isManualTemporaryUpperCase() && key.manualTemporaryUpperCaseCode != 0) { if (mKeyboard.isManualTemporaryUpperCase()
code = key.manualTemporaryUpperCaseCode; && key.mManualTemporaryUpperCaseCode != 0) {
code = key.mManualTemporaryUpperCaseCode;
codes[0] = code; codes[0] = code;
} }
@ -493,10 +488,10 @@ public class PointerTracker {
if (mInMultiTap) { if (mInMultiTap) {
// Multi-tap // Multi-tap
mPreviewLabel.setLength(0); mPreviewLabel.setLength(0);
mPreviewLabel.append((char) key.codes[mTapCount < 0 ? 0 : mTapCount]); mPreviewLabel.append((char) key.mCodes[mTapCount < 0 ? 0 : mTapCount]);
return mPreviewLabel; return mPreviewLabel;
} else { } else {
return key.label; return key.mLabel;
} }
} }
@ -514,10 +509,10 @@ public class PointerTracker {
final boolean isMultiTap = final boolean isMultiTap =
(eventTime < mLastTapTime + mMultiTapKeyTimeout && keyIndex == mLastSentIndex); (eventTime < mLastTapTime + mMultiTapKeyTimeout && keyIndex == mLastSentIndex);
if (key.codes.length > 1) { if (key.mCodes.length > 1) {
mInMultiTap = true; mInMultiTap = true;
if (isMultiTap) { if (isMultiTap) {
mTapCount = (mTapCount + 1) % key.codes.length; mTapCount = (mTapCount + 1) % key.mCodes.length;
return; return;
} else { } else {
mTapCount = -1; mTapCount = -1;
@ -536,7 +531,7 @@ public class PointerTracker {
if (key == null) { if (key == null) {
code = "----"; code = "----";
} else { } else {
int primaryCode = key.codes[0]; int primaryCode = key.mCodes[0];
code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode); code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
} }
Log.d(TAG, String.format("%s%s[%d] %3d,%3d %3d(%s) %s", title, Log.d(TAG, String.format("%s%s[%d] %3d,%3d %3d(%s) %s", title,

View File

@ -53,7 +53,7 @@ public class ProximityKeyDetector extends KeyDetector {
} }
if (allKeys == null) continue; if (allKeys == null) continue;
final int nCodes = key.codes.length; final int nCodes = key.mCodes.length;
// Find insertion point // Find insertion point
for (int j = 0; j < distances.length; j++) { for (int j = 0; j < distances.length; j++) {
if (distances[j] > dist) { if (distances[j] > dist) {
@ -62,7 +62,7 @@ public class ProximityKeyDetector extends KeyDetector {
distances.length - (j + nCodes)); distances.length - (j + nCodes));
System.arraycopy(allKeys, j, allKeys, j + nCodes, System.arraycopy(allKeys, j, allKeys, j + nCodes,
allKeys.length - (j + nCodes)); allKeys.length - (j + nCodes));
System.arraycopy(key.codes, 0, allKeys, j, nCodes); System.arraycopy(key.mCodes, 0, allKeys, j, nCodes);
Arrays.fill(distances, j, j + nCodes, dist); Arrays.fill(distances, j, j + nCodes, dist);
break; break;
} }

View File

@ -30,44 +30,44 @@ import android.util.Xml;
*/ */
public class Row { public class Row {
/** Default width of a key in this row. */ /** Default width of a key in this row. */
public int defaultWidth; public int mDefaultWidth;
/** Default height of a key in this row. */ /** Default height of a key in this row. */
public int defaultHeight; public int mDefaultHeight;
/** Default horizontal gap between keys in this row. */ /** Default horizontal gap between keys in this row. */
public int defaultHorizontalGap; public int mDefaultHorizontalGap;
/** Vertical gap following this row. */ /** Vertical gap following this row. */
public int verticalGap; public int mVerticalGap;
/** /**
* Edge flags for this row of keys. Possible values that can be assigned are * Edge flags for this row of keys. Possible values that can be assigned are
* {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM} * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM}
*/ */
public int rowEdgeFlags; public int mRowEdgeFlags;
final Keyboard parent; /* package */ final Keyboard mParent;
Row(Keyboard parent) { /* package */ Row(Keyboard parent) {
this.parent = parent; this.mParent = parent;
} }
public Row(Resources res, Keyboard parent, XmlResourceParser parser) { public Row(Resources res, Keyboard parent, XmlResourceParser parser) {
this.parent = parent; this.mParent = parent;
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard); R.styleable.Keyboard);
defaultWidth = KeyboardParser.getDimensionOrFraction(a, mDefaultWidth = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyWidth, R.styleable.Keyboard_keyWidth,
parent.mDisplayWidth, parent.mDefaultWidth); parent.mDisplayWidth, parent.mDefaultWidth);
defaultHeight = KeyboardParser.getDimensionOrFraction(a, mDefaultHeight = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyHeight, R.styleable.Keyboard_keyHeight,
parent.mDisplayHeight, parent.mDefaultHeight); parent.mDisplayHeight, parent.mDefaultHeight);
defaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a, mDefaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_horizontalGap, R.styleable.Keyboard_horizontalGap,
parent.mDisplayWidth, parent.mDefaultHorizontalGap); parent.mDisplayWidth, parent.mDefaultHorizontalGap);
verticalGap = KeyboardParser.getDimensionOrFraction(a, mVerticalGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_verticalGap, R.styleable.Keyboard_verticalGap,
parent.mDisplayHeight, parent.mDefaultVerticalGap); parent.mDisplayHeight, parent.mDefaultVerticalGap);
a.recycle(); a.recycle();
a = res.obtainAttributes(Xml.asAttributeSet(parser), a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard_Row); R.styleable.Keyboard_Row);
rowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0); mRowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0);
} }
} }

View File

@ -14,7 +14,7 @@
* the License. * the License.
*/ */
package com.android.inputmethod.latin; package com.android.inputmethod.keyboard;
import android.util.Log; import android.util.Log;

View File

@ -19,8 +19,8 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.KeyboardView;
import com.android.inputmethod.keyboard.LatinKeyboard;
import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.keyboard.LatinKeyboardView;
import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer; import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer;
import com.android.inputmethod.voice.VoiceIMEConnector; import com.android.inputmethod.voice.VoiceIMEConnector;
@ -109,11 +109,6 @@ public class LatinIME extends InputMethodService
// Key events coming any faster than this are long-presses. // Key events coming any faster than this are long-presses.
private static final int QUICK_PRESS = 200; private static final int QUICK_PRESS = 200;
public static final int KEYCODE_ENTER = '\n';
public static final int KEYCODE_TAB = '\t';
public static final int KEYCODE_SPACE = ' ';
public static final int KEYCODE_PERIOD = '.';
// Contextual menu positions // Contextual menu positions
private static final int POS_METHOD = 0; private static final int POS_METHOD = 0;
private static final int POS_SETTINGS = 1; private static final int POS_SETTINGS = 1;
@ -255,7 +250,7 @@ public class LatinIME extends InputMethodService
} }
} }
/* package */ final UIHandler mHandler = new UIHandler(); public final UIHandler mHandler = new UIHandler();
public class UIHandler extends Handler { public class UIHandler extends Handler {
private static final int MSG_UPDATE_SUGGESTIONS = 0; private static final int MSG_UPDATE_SUGGESTIONS = 0;
@ -968,7 +963,8 @@ public class LatinIME extends InputMethodService
if (ic == null) return; if (ic == null) return;
CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
if (lastTwo != null && lastTwo.length() == 2 if (lastTwo != null && lastTwo.length() == 2
&& lastTwo.charAt(0) == KEYCODE_SPACE && isSentenceSeparator(lastTwo.charAt(1))) { && lastTwo.charAt(0) == Keyboard.CODE_SPACE
&& isSentenceSeparator(lastTwo.charAt(1))) {
ic.beginBatchEdit(); ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0); ic.deleteSurroundingText(2, 0);
ic.commitText(lastTwo.charAt(1) + " ", 1); ic.commitText(lastTwo.charAt(1) + " ", 1);
@ -983,9 +979,9 @@ public class LatinIME extends InputMethodService
if (ic == null) return; if (ic == null) return;
CharSequence lastThree = ic.getTextBeforeCursor(3, 0); CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3 if (lastThree != null && lastThree.length() == 3
&& lastThree.charAt(0) == KEYCODE_PERIOD && lastThree.charAt(0) == Keyboard.CODE_PERIOD
&& lastThree.charAt(1) == KEYCODE_SPACE && lastThree.charAt(1) == Keyboard.CODE_SPACE
&& lastThree.charAt(2) == KEYCODE_PERIOD) { && lastThree.charAt(2) == Keyboard.CODE_PERIOD) {
ic.beginBatchEdit(); ic.beginBatchEdit();
ic.deleteSurroundingText(3, 0); ic.deleteSurroundingText(3, 0);
ic.commitText(" ..", 1); ic.commitText(" ..", 1);
@ -1002,7 +998,8 @@ public class LatinIME extends InputMethodService
CharSequence lastThree = ic.getTextBeforeCursor(3, 0); CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3 if (lastThree != null && lastThree.length() == 3
&& Character.isLetterOrDigit(lastThree.charAt(0)) && Character.isLetterOrDigit(lastThree.charAt(0))
&& lastThree.charAt(1) == KEYCODE_SPACE && lastThree.charAt(2) == KEYCODE_SPACE) { && lastThree.charAt(1) == Keyboard.CODE_SPACE
&& lastThree.charAt(2) == Keyboard.CODE_SPACE) {
ic.beginBatchEdit(); ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0); ic.deleteSurroundingText(2, 0);
ic.commitText(". ", 1); ic.commitText(". ", 1);
@ -1020,8 +1017,8 @@ public class LatinIME extends InputMethodService
// if there is one. // if there is one.
CharSequence lastOne = ic.getTextBeforeCursor(1, 0); CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1 if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == KEYCODE_PERIOD && lastOne.charAt(0) == Keyboard.CODE_PERIOD
&& text.charAt(0) == KEYCODE_PERIOD) { && text.charAt(0) == Keyboard.CODE_PERIOD) {
ic.deleteSurroundingText(1, 0); ic.deleteSurroundingText(1, 0);
} }
} }
@ -1032,7 +1029,7 @@ public class LatinIME extends InputMethodService
CharSequence lastOne = ic.getTextBeforeCursor(1, 0); CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1 if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == KEYCODE_SPACE) { && lastOne.charAt(0) == Keyboard.CODE_SPACE) {
ic.deleteSurroundingText(1, 0); ic.deleteSurroundingText(1, 0);
} }
} }
@ -1082,57 +1079,57 @@ public class LatinIME extends InputMethodService
@Override @Override
public void onKey(int primaryCode, int[] keyCodes, int x, int y) { public void onKey(int primaryCode, int[] keyCodes, int x, int y) {
long when = SystemClock.uptimeMillis(); long when = SystemClock.uptimeMillis();
if (primaryCode != Keyboard.KEYCODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0; mDeleteCount = 0;
} }
mLastKeyTime = when; mLastKeyTime = when;
KeyboardSwitcher switcher = mKeyboardSwitcher; KeyboardSwitcher switcher = mKeyboardSwitcher;
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
switch (primaryCode) { switch (primaryCode) {
case Keyboard.KEYCODE_DELETE: case Keyboard.CODE_DELETE:
handleBackspace(); handleBackspace();
mDeleteCount++; mDeleteCount++;
LatinImeLogger.logOnDelete(); LatinImeLogger.logOnDelete();
break; break;
case Keyboard.KEYCODE_SHIFT: case Keyboard.CODE_SHIFT:
// Shift key is handled in onPress() when device has distinct multi-touch panel. // Shift key is handled in onPress() when device has distinct multi-touch panel.
if (!distinctMultiTouch) if (!distinctMultiTouch)
switcher.toggleShift(); switcher.toggleShift();
break; break;
case Keyboard.KEYCODE_MODE_CHANGE: case Keyboard.CODE_MODE_CHANGE:
// Symbol key is handled in onPress() when device has distinct multi-touch panel. // Symbol key is handled in onPress() when device has distinct multi-touch panel.
if (!distinctMultiTouch) if (!distinctMultiTouch)
switcher.changeKeyboardMode(); switcher.changeKeyboardMode();
break; break;
case Keyboard.KEYCODE_CANCEL: case Keyboard.CODE_CANCEL:
if (!isShowingOptionDialog()) { if (!isShowingOptionDialog()) {
handleClose(); handleClose();
} }
break; break;
case LatinKeyboard.KEYCODE_OPTIONS: case Keyboard.CODE_OPTIONS:
onOptionKeyPressed(); onOptionKeyPressed();
break; break;
case LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS: case Keyboard.CODE_OPTIONS_LONGPRESS:
onOptionKeyLongPressed(); onOptionKeyLongPressed();
break; break;
case LatinKeyboard.KEYCODE_NEXT_LANGUAGE: case Keyboard.CODE_NEXT_LANGUAGE:
toggleLanguage(false, true); toggleLanguage(false, true);
break; break;
case LatinKeyboard.KEYCODE_PREV_LANGUAGE: case Keyboard.CODE_PREV_LANGUAGE:
toggleLanguage(false, false); toggleLanguage(false, false);
break; break;
case LatinKeyboard.KEYCODE_CAPSLOCK: case Keyboard.CODE_CAPSLOCK:
switcher.toggleCapsLock(); switcher.toggleCapsLock();
break; break;
case LatinKeyboard.KEYCODE_VOICE: /* was a button press, was not a swipe */ case Keyboard.CODE_VOICE: /* was a button press, was not a swipe */
mVoiceConnector.startListening(false, mVoiceConnector.startListening(false,
mKeyboardSwitcher.getInputView().getWindowToken(), mConfigurationChanging); mKeyboardSwitcher.getInputView().getWindowToken(), mConfigurationChanging);
break; break;
case KEYCODE_TAB: case Keyboard.CODE_TAB:
handleTab(); handleTab();
break; break;
default: default:
if (primaryCode != KEYCODE_ENTER) { if (primaryCode != Keyboard.CODE_ENTER) {
mJustAddedAutoSpace = false; mJustAddedAutoSpace = false;
} }
RingCharBuffer.getInstance().push((char)primaryCode, x, y); RingCharBuffer.getInstance().push((char)primaryCode, x, y);
@ -1344,14 +1341,14 @@ public class LatinIME extends InputMethodService
pickedDefault = pickDefaultSuggestion(); pickedDefault = pickDefaultSuggestion();
// Picked the suggestion by the space key. We consider this // Picked the suggestion by the space key. We consider this
// as "added an auto space". // as "added an auto space".
if (primaryCode == KEYCODE_SPACE) { if (primaryCode == Keyboard.CODE_SPACE) {
mJustAddedAutoSpace = true; mJustAddedAutoSpace = true;
} }
} else { } else {
commitTyped(ic); commitTyped(ic);
} }
} }
if (mJustAddedAutoSpace && primaryCode == KEYCODE_ENTER) { if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) {
removeTrailingSpace(); removeTrailingSpace();
mJustAddedAutoSpace = false; mJustAddedAutoSpace = false;
} }
@ -1360,15 +1357,15 @@ public class LatinIME extends InputMethodService
// Handle the case of ". ." -> " .." with auto-space if necessary // Handle the case of ". ." -> " .." with auto-space if necessary
// before changing the TextEntryState. // before changing the TextEntryState.
if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
&& primaryCode == KEYCODE_PERIOD) { && primaryCode == Keyboard.CODE_PERIOD) {
reswapPeriodAndSpace(); reswapPeriodAndSpace();
} }
TextEntryState.typedCharacter((char) primaryCode, true); TextEntryState.typedCharacter((char) primaryCode, true);
if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
&& primaryCode != KEYCODE_ENTER) { && primaryCode != Keyboard.CODE_ENTER) {
swapPunctuationAndSpace(); swapPunctuationAndSpace();
} else if (isPredictionOn() && primaryCode == KEYCODE_SPACE) { } else if (isPredictionOn() && primaryCode == Keyboard.CODE_SPACE) {
doubleSpace(); doubleSpace();
} }
if (pickedDefault) { if (pickedDefault) {
@ -1629,7 +1626,7 @@ public class LatinIME extends InputMethodService
// Fool the state watcher so that a subsequent backspace will not do a revert, unless // Fool the state watcher so that a subsequent backspace will not do a revert, unless
// we just did a correction, in which case we need to stay in // we just did a correction, in which case we need to stay in
// TextEntryState.State.PICKED_SUGGESTION state. // TextEntryState.State.PICKED_SUGGESTION state.
TextEntryState.typedCharacter((char) KEYCODE_SPACE, true); TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true);
setPunctuationSuggestions(); setPunctuationSuggestions();
} else if (!showingAddToDictionaryHint) { } else if (!showingAddToDictionaryHint) {
// If we're not showing the "Touch again to save", then show corrections again. // If we're not showing the "Touch again to save", then show corrections again.
@ -1857,7 +1854,7 @@ public class LatinIME extends InputMethodService
} }
private void sendSpace() { private void sendSpace() {
sendKeyChar((char)KEYCODE_SPACE); sendKeyChar((char)Keyboard.CODE_SPACE);
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();
//onKey(KEY_SPACE[0], KEY_SPACE); //onKey(KEY_SPACE[0], KEY_SPACE);
} }
@ -1930,9 +1927,9 @@ public class LatinIME extends InputMethodService
playKeyClick(primaryCode); playKeyClick(primaryCode);
KeyboardSwitcher switcher = mKeyboardSwitcher; KeyboardSwitcher switcher = mKeyboardSwitcher;
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
switcher.onPressShift(); switcher.onPressShift();
} else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_MODE_CHANGE) {
switcher.onPressSymbol(); switcher.onPressSymbol();
} else { } else {
switcher.onOtherKeyPressed(); switcher.onOtherKeyPressed();
@ -1945,9 +1942,9 @@ public class LatinIME extends InputMethodService
// Reset any drag flags in the keyboard // Reset any drag flags in the keyboard
switcher.keyReleased(); switcher.keyReleased();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
switcher.onReleaseShift(); switcher.onReleaseShift();
} else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_MODE_CHANGE) {
switcher.onReleaseSymbol(); switcher.onReleaseSymbol();
} }
} }
@ -1984,13 +1981,13 @@ public class LatinIME extends InputMethodService
// FIXME: These should be triggered after auto-repeat logic // FIXME: These should be triggered after auto-repeat logic
int sound = AudioManager.FX_KEYPRESS_STANDARD; int sound = AudioManager.FX_KEYPRESS_STANDARD;
switch (primaryCode) { switch (primaryCode) {
case Keyboard.KEYCODE_DELETE: case Keyboard.CODE_DELETE:
sound = AudioManager.FX_KEYPRESS_DELETE; sound = AudioManager.FX_KEYPRESS_DELETE;
break; break;
case KEYCODE_ENTER: case Keyboard.CODE_ENTER:
sound = AudioManager.FX_KEYPRESS_RETURN; sound = AudioManager.FX_KEYPRESS_RETURN;
break; break;
case KEYCODE_SPACE: case Keyboard.CODE_SPACE:
sound = AudioManager.FX_KEYPRESS_SPACEBAR; sound = AudioManager.FX_KEYPRESS_SPACEBAR;
break; break;
} }

View File

@ -48,7 +48,7 @@ public class LatinIMESettings extends PreferenceActivity
private static final String VOICE_SETTINGS_KEY = "voice_mode"; private static final String VOICE_SETTINGS_KEY = "voice_mode";
private static final String PREF_AUTO_COMPLETION_THRESHOLD = "auto_completion_threshold"; private static final String PREF_AUTO_COMPLETION_THRESHOLD = "auto_completion_threshold";
private static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion"; private static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
/* package */ static final String PREF_SETTINGS_KEY = "settings_key"; public static final String PREF_SETTINGS_KEY = "settings_key";
/* package */ static final String PREF_VIBRATE_ON = "vibrate_on"; /* package */ static final String PREF_VIBRATE_ON = "vibrate_on";
private static final String TAG = "LatinIMESettings"; private static final String TAG = "LatinIMESettings";

View File

@ -16,7 +16,7 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.LatinKeyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.voice.SettingsUtil; import com.android.inputmethod.voice.SettingsUtil;
import com.android.inputmethod.voice.VoiceIMEConnector; import com.android.inputmethod.voice.VoiceIMEConnector;
import com.android.inputmethod.voice.VoiceInput; import com.android.inputmethod.voice.VoiceInput;
@ -198,7 +198,7 @@ public class SubtypeSwitcher {
|| VoiceIMEConnector.getInstance().needsToShowWarningDialog()) { || VoiceIMEConnector.getInstance().needsToShowWarningDialog()) {
if (mVoiceInput != null) { if (mVoiceInput != null) {
// TODO: Call proper function to trigger VoiceIME // TODO: Call proper function to trigger VoiceIME
mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0); mService.onKey(Keyboard.CODE_VOICE, null, 0, 0);
} }
} }
} else { } else {
@ -351,7 +351,7 @@ public class SubtypeSwitcher {
if (DBG) { if (DBG) {
Log.d(TAG, "Set and call voice input."); Log.d(TAG, "Set and call voice input.");
} }
mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0); mService.onKey(Keyboard.CODE_VOICE, null, 0, 0);
return true; return true;
} }
} }

View File

@ -261,13 +261,13 @@ public class TextEntryState {
} }
public static void keyPressedAt(Key key, int x, int y) { public static void keyPressedAt(Key key, int x, int y) {
if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) { if (LOGGING && sKeyLocationFile != null && key.mCodes[0] >= 32) {
String out = String out =
"KEY: " + (char) key.codes[0] "KEY: " + (char) key.mCodes[0]
+ " X: " + x + " X: " + x
+ " Y: " + y + " Y: " + y
+ " MX: " + (key.x + key.width / 2) + " MX: " + (key.mX + key.mWidth / 2)
+ " MY: " + (key.y + key.height / 2) + " MY: " + (key.mY + key.mHeight / 2)
+ "\n"; + "\n";
try { try {
sKeyLocationFile.write(out.getBytes()); sKeyLocationFile.write(out.getBytes());

View File

@ -16,6 +16,7 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.keyboard.LatinKeyboardView;
import android.content.Context; import android.content.Context;

View File

@ -16,8 +16,8 @@
package com.android.inputmethod.voice; package com.android.inputmethod.voice;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.EditingUtil; import com.android.inputmethod.latin.EditingUtil;
import com.android.inputmethod.latin.KeyboardSwitcher;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinIME.UIHandler; import com.android.inputmethod.latin.LatinIME.UIHandler;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;