Make Keyboard object immutable except shift state
This is the first step to implement suggestions pane as mini keyboard. Bug: 5023981 Change-Id: I90ffbde0fda19b4be68add449310997b56bf6904main
parent
8d7782bf3c
commit
8da9a13760
|
@ -30,3 +30,7 @@
|
||||||
-keep class com.android.inputmethod.latin.SettingsActivity {
|
-keep class com.android.inputmethod.latin.SettingsActivity {
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-keep class com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder$MiniKeyboardLayoutParams {
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.util.Xml;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyStyles;
|
import com.android.inputmethod.keyboard.internal.KeyStyles;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
|
import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardParser;
|
import com.android.inputmethod.keyboard.internal.KeyboardParser;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardParser.ParseException;
|
import com.android.inputmethod.keyboard.internal.KeyboardParser.ParseException;
|
||||||
import com.android.inputmethod.keyboard.internal.PopupCharactersParser;
|
import com.android.inputmethod.keyboard.internal.PopupCharactersParser;
|
||||||
|
@ -190,11 +191,11 @@ public class Key {
|
||||||
/**
|
/**
|
||||||
* This constructor is being used only for key in popup mini keyboard.
|
* This constructor is being used only for key in popup mini keyboard.
|
||||||
*/
|
*/
|
||||||
public Key(Resources res, Keyboard keyboard, CharSequence popupCharacter, int x, int y,
|
public Key(Resources res, KeyboardParams params, CharSequence popupCharacter, int x, int y,
|
||||||
int width, int height, int edgeFlags) {
|
int width, int height, int edgeFlags) {
|
||||||
mHeight = height - keyboard.getVerticalGap();
|
mHeight = height - params.mVerticalGap;
|
||||||
mHorizontalGap = keyboard.getHorizontalGap();
|
mHorizontalGap = params.mHorizontalGap;
|
||||||
mVerticalGap = keyboard.getVerticalGap();
|
mVerticalGap = params.mVerticalGap;
|
||||||
mVisualInsetsLeft = mVisualInsetsRight = 0;
|
mVisualInsetsLeft = mVisualInsetsRight = 0;
|
||||||
mWidth = width - mHorizontalGap;
|
mWidth = width - mHorizontalGap;
|
||||||
mEdgeFlags = edgeFlags;
|
mEdgeFlags = edgeFlags;
|
||||||
|
@ -209,8 +210,8 @@ public class Key {
|
||||||
mLabel = PopupCharactersParser.getLabel(popupSpecification);
|
mLabel = PopupCharactersParser.getLabel(popupSpecification);
|
||||||
mOutputText = PopupCharactersParser.getOutputText(popupSpecification);
|
mOutputText = PopupCharactersParser.getOutputText(popupSpecification);
|
||||||
final int code = PopupCharactersParser.getCode(res, popupSpecification);
|
final int code = PopupCharactersParser.getCode(res, popupSpecification);
|
||||||
mCode = keyboard.isRtlKeyboard() ? getRtlParenthesisCode(code) : code;
|
mCode = params.mIsRtlKeyboard ? getRtlParenthesisCode(code) : code;
|
||||||
mIcon = keyboard.mIconsSet.getIcon(PopupCharactersParser.getIconId(popupSpecification));
|
mIcon = params.mIconsSet.getIcon(PopupCharactersParser.getIconId(popupSpecification));
|
||||||
// Horizontal gap is divided equally to both sides of the key.
|
// Horizontal gap is divided equally to both sides of the key.
|
||||||
mX = x + mHorizontalGap / 2;
|
mX = x + mHorizontalGap / 2;
|
||||||
mY = y;
|
mY = y;
|
||||||
|
@ -220,16 +221,15 @@ public class Key {
|
||||||
* Create a key with the given top-left coordinate and extract its attributes from the XML
|
* Create a key with the given top-left coordinate and extract its attributes from the XML
|
||||||
* parser.
|
* parser.
|
||||||
* @param res resources associated with the caller's context
|
* @param res resources associated with the caller's context
|
||||||
* @param row the row that this key belongs to. The row must already be attached to
|
* @param params the keyboard building parameters.
|
||||||
* a {@link Keyboard}.
|
* @param row the row that this key belongs to.
|
||||||
* @param x the x coordinate of the top-left
|
* @param x the x coordinate of the top-left
|
||||||
* @param y the y coordinate of the top-left
|
* @param y the y coordinate of the top-left
|
||||||
* @param parser the XML parser containing the attributes for this key
|
* @param parser the XML parser containing the attributes for this key
|
||||||
* @param keyStyles active key styles set
|
* @param keyStyles active key styles set
|
||||||
*/
|
*/
|
||||||
public Key(Resources res, Row row, int x, int y, XmlResourceParser parser,
|
public Key(Resources res, KeyboardParams params, Row row, int x, int y,
|
||||||
KeyStyles keyStyles) {
|
XmlResourceParser parser, KeyStyles keyStyles) {
|
||||||
final Keyboard keyboard = row.getKeyboard();
|
|
||||||
|
|
||||||
final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
|
final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
R.styleable.Keyboard);
|
R.styleable.Keyboard);
|
||||||
|
@ -237,14 +237,14 @@ public class Key {
|
||||||
try {
|
try {
|
||||||
mHeight = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
mHeight = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_rowHeight,
|
R.styleable.Keyboard_rowHeight,
|
||||||
keyboard.getKeyboardHeight(), row.mDefaultHeight) - keyboard.getVerticalGap();
|
params.mHeight, row.mRowHeight) - params.mVerticalGap;
|
||||||
mHorizontalGap = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
mHorizontalGap = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_horizontalGap,
|
R.styleable.Keyboard_horizontalGap,
|
||||||
keyboard.getDisplayWidth(), keyboard.getHorizontalGap());
|
params.mWidth, params.mHorizontalGap);
|
||||||
mVerticalGap = keyboard.getVerticalGap();
|
mVerticalGap = params.mVerticalGap;
|
||||||
keyWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
keyWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_keyWidth,
|
R.styleable.Keyboard_keyWidth,
|
||||||
keyboard.getDisplayWidth(), row.mDefaultWidth);
|
params.mWidth, row.mDefaultKeyWidth);
|
||||||
} finally {
|
} finally {
|
||||||
keyboardAttr.recycle();
|
keyboardAttr.recycle();
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ public class Key {
|
||||||
style = keyStyles.getEmptyKeyStyle();
|
style = keyStyles.getEmptyKeyStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
final int keyboardWidth = keyboard.getDisplayWidth();
|
final int keyboardWidth = params.mOccupiedWidth;
|
||||||
int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
|
int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
|
||||||
R.styleable.Keyboard_Key_keyXPos, keyboardWidth, x);
|
R.styleable.Keyboard_Key_keyXPos, keyboardWidth, x);
|
||||||
if (keyXPos < 0) {
|
if (keyXPos < 0) {
|
||||||
|
@ -293,13 +293,13 @@ public class Key {
|
||||||
|
|
||||||
CharSequence[] popupCharacters = style.getTextArray(
|
CharSequence[] popupCharacters = style.getTextArray(
|
||||||
keyAttr, R.styleable.Keyboard_Key_popupCharacters);
|
keyAttr, R.styleable.Keyboard_Key_popupCharacters);
|
||||||
if (keyboard.mId.mPasswordInput) {
|
if (params.mId.mPasswordInput) {
|
||||||
popupCharacters = PopupCharactersParser.filterOut(
|
popupCharacters = PopupCharactersParser.filterOut(
|
||||||
res, popupCharacters, PopupCharactersParser.NON_ASCII_FILTER);
|
res, popupCharacters, PopupCharactersParser.NON_ASCII_FILTER);
|
||||||
}
|
}
|
||||||
// In Arabic symbol layouts, we'd like to keep digits in popup characters regardless of
|
// In Arabic symbol layouts, we'd like to keep digits in popup characters regardless of
|
||||||
// config_digit_popup_characters_enabled.
|
// config_digit_popup_characters_enabled.
|
||||||
if (keyboard.mId.isAlphabetKeyboard() && !res.getBoolean(
|
if (params.mId.isAlphabetKeyboard() && !res.getBoolean(
|
||||||
R.bool.config_digit_popup_characters_enabled)) {
|
R.bool.config_digit_popup_characters_enabled)) {
|
||||||
mPopupCharacters = PopupCharactersParser.filterOut(
|
mPopupCharacters = PopupCharactersParser.filterOut(
|
||||||
res, popupCharacters, PopupCharactersParser.DIGIT_FILTER);
|
res, popupCharacters, PopupCharactersParser.DIGIT_FILTER);
|
||||||
|
@ -308,7 +308,7 @@ public class Key {
|
||||||
}
|
}
|
||||||
mMaxPopupColumn = style.getInt(keyboardAttr,
|
mMaxPopupColumn = style.getInt(keyboardAttr,
|
||||||
R.styleable.Keyboard_Key_maxPopupKeyboardColumn,
|
R.styleable.Keyboard_Key_maxPopupKeyboardColumn,
|
||||||
keyboard.getMaxPopupKeyboardColumn());
|
params.mMaxPopupColumn);
|
||||||
|
|
||||||
mRepeatable = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable, false);
|
mRepeatable = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable, false);
|
||||||
mFunctional = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional, false);
|
mFunctional = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional, false);
|
||||||
|
@ -316,7 +316,7 @@ public class Key {
|
||||||
mEnabled = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_enabled, true);
|
mEnabled = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_enabled, true);
|
||||||
mEdgeFlags = 0;
|
mEdgeFlags = 0;
|
||||||
|
|
||||||
final KeyboardIconsSet iconsSet = keyboard.mIconsSet;
|
final KeyboardIconsSet iconsSet = params.mIconsSet;
|
||||||
mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr,
|
mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr,
|
||||||
R.styleable.Keyboard_Key_visualInsetsLeft, keyboardWidth, 0);
|
R.styleable.Keyboard_Key_visualInsetsLeft, keyboardWidth, 0);
|
||||||
mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr,
|
mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr,
|
||||||
|
@ -331,7 +331,7 @@ public class Key {
|
||||||
KeyboardIconsSet.ICON_UNDEFINED);
|
KeyboardIconsSet.ICON_UNDEFINED);
|
||||||
if (shiftedIconId != KeyboardIconsSet.ICON_UNDEFINED) {
|
if (shiftedIconId != KeyboardIconsSet.ICON_UNDEFINED) {
|
||||||
final Drawable shiftedIcon = iconsSet.getIcon(shiftedIconId);
|
final Drawable shiftedIcon = iconsSet.getIcon(shiftedIconId);
|
||||||
keyboard.addShiftedIcon(this, shiftedIcon);
|
params.addShiftedIcon(this, shiftedIcon);
|
||||||
}
|
}
|
||||||
mHintLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
|
mHintLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
|
||||||
|
|
||||||
|
@ -344,15 +344,12 @@ public class Key {
|
||||||
Keyboard.CODE_UNSPECIFIED);
|
Keyboard.CODE_UNSPECIFIED);
|
||||||
if (code == Keyboard.CODE_UNSPECIFIED && !TextUtils.isEmpty(mLabel)) {
|
if (code == Keyboard.CODE_UNSPECIFIED && !TextUtils.isEmpty(mLabel)) {
|
||||||
final int firstChar = mLabel.charAt(0);
|
final int firstChar = mLabel.charAt(0);
|
||||||
mCode = keyboard.isRtlKeyboard() ? getRtlParenthesisCode(firstChar) : firstChar;
|
mCode = params.mIsRtlKeyboard ? getRtlParenthesisCode(firstChar) : firstChar;
|
||||||
} else if (code != Keyboard.CODE_UNSPECIFIED) {
|
} else if (code != Keyboard.CODE_UNSPECIFIED) {
|
||||||
mCode = code;
|
mCode = code;
|
||||||
} else {
|
} else {
|
||||||
mCode = Keyboard.CODE_DUMMY;
|
mCode = Keyboard.CODE_DUMMY;
|
||||||
}
|
}
|
||||||
if (mCode == Keyboard.CODE_SHIFT) {
|
|
||||||
keyboard.addShiftKey(this);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
keyAttr.recycle();
|
keyAttr.recycle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class KeyDetector {
|
||||||
mCorrectionX = (int)correctionX;
|
mCorrectionX = (int)correctionX;
|
||||||
mCorrectionY = (int)correctionY;
|
mCorrectionY = (int)correctionY;
|
||||||
mKeyboard = keyboard;
|
mKeyboard = keyboard;
|
||||||
final int threshold = keyboard.getMostCommonKeyWidth();
|
final int threshold = keyboard.mMostCommonKeyWidth;
|
||||||
mProximityThresholdSquare = threshold * threshold;
|
mProximityThresholdSquare = threshold * threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,23 +16,14 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard;
|
package com.android.inputmethod.keyboard;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardParser;
|
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
||||||
import com.android.inputmethod.keyboard.internal.KeyboardShiftState;
|
import com.android.inputmethod.keyboard.internal.KeyboardShiftState;
|
||||||
import com.android.inputmethod.latin.R;
|
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import java.util.Collections;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -56,8 +47,6 @@ import java.util.Set;
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class Keyboard {
|
public class Keyboard {
|
||||||
private static final String TAG = Keyboard.class.getSimpleName();
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -98,209 +87,77 @@ public class Keyboard {
|
||||||
public final KeyboardId mId;
|
public final KeyboardId mId;
|
||||||
|
|
||||||
/** Total height of the keyboard, including the padding and keys */
|
/** Total height of the keyboard, including the padding and keys */
|
||||||
private int mTotalHeight;
|
public final int mOccupiedHeight;
|
||||||
|
/** Total width of the keyboard, including the padding and keys */
|
||||||
|
public final int mOccupiedWidth;
|
||||||
|
|
||||||
/**
|
public final int mHeight;
|
||||||
* Total width (minimum width) of the keyboard, including left side gaps and keys, but not any
|
public final int mWidth;
|
||||||
* gaps on the right side.
|
|
||||||
*/
|
|
||||||
private int mMinWidth;
|
|
||||||
|
|
||||||
/** Horizontal gap default for all rows */
|
|
||||||
private int mHorizontalGap;
|
|
||||||
|
|
||||||
/** Default key width */
|
|
||||||
private int mDefaultKeyWidth;
|
|
||||||
|
|
||||||
/** Default row height */
|
/** Default row height */
|
||||||
private int mDefaultRowHeight;
|
public final int mDefaultRowHeight;
|
||||||
|
|
||||||
/** Default gap between rows */
|
/** Default gap between rows */
|
||||||
private int mVerticalGap;
|
public final int mVerticalGap;
|
||||||
|
|
||||||
|
public final int mMostCommonKeyWidth;
|
||||||
|
|
||||||
/** Popup keyboard template */
|
/** Popup keyboard template */
|
||||||
private int mPopupKeyboardResId;
|
public final int mPopupKeyboardResId;
|
||||||
|
|
||||||
/** Maximum column for popup keyboard */
|
/** Maximum column for popup keyboard */
|
||||||
private int mMaxPopupColumn;
|
public final int mMaxPopupColumn;
|
||||||
|
|
||||||
/** True if Right-To-Left keyboard */
|
/** True if Right-To-Left keyboard */
|
||||||
private boolean mIsRtlKeyboard;
|
public final boolean mIsRtlKeyboard;
|
||||||
|
|
||||||
/** List of keys in this keyboard */
|
/** List of keys and icons in this keyboard */
|
||||||
private final List<Key> mKeys = new ArrayList<Key>();
|
public final List<Key> mKeys;
|
||||||
/** List of shift keys in this keyboard and its icons and state */
|
public final List<Key> mShiftKeys;
|
||||||
private final List<Key> mShiftKeys = new ArrayList<Key>();
|
public final Set<Key> mShiftLockKeys;
|
||||||
private final Map<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
|
public final Map<Key, Drawable> mShiftedIcons;
|
||||||
private final Map<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
|
public final Map<Key, Drawable> mUnshiftedIcons;
|
||||||
private final Set<Key> mShiftLockKeys = new HashSet<Key>();
|
public final KeyboardIconsSet mIconsSet;
|
||||||
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
|
||||||
|
|
||||||
|
|
||||||
/** Width of the screen available to fit the keyboard */
|
|
||||||
private final int mDisplayWidth;
|
|
||||||
|
|
||||||
/** Height of the screen */
|
|
||||||
private final int mDisplayHeight;
|
|
||||||
|
|
||||||
/** Height of keyboard */
|
|
||||||
private int mKeyboardHeight;
|
|
||||||
|
|
||||||
private int mMostCommonKeyWidth = 0;
|
|
||||||
|
|
||||||
private final KeyboardShiftState mShiftState = new KeyboardShiftState();
|
private final KeyboardShiftState mShiftState = new KeyboardShiftState();
|
||||||
|
|
||||||
// Variables for pre-computing nearest keys.
|
|
||||||
|
|
||||||
// TODO: Change GRID_WIDTH and GRID_HEIGHT to private.
|
|
||||||
public final int GRID_WIDTH;
|
|
||||||
public final int GRID_HEIGHT;
|
|
||||||
|
|
||||||
private final ProximityInfo mProximityInfo;
|
private final ProximityInfo mProximityInfo;
|
||||||
|
|
||||||
/**
|
public Keyboard(KeyboardParams params) {
|
||||||
* Creates a keyboard from the given xml key layout file.
|
mId = params.mId;
|
||||||
* @param context the application or service context
|
mOccupiedHeight = params.mOccupiedHeight;
|
||||||
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
|
mOccupiedWidth = params.mOccupiedWidth;
|
||||||
* @param id keyboard identifier
|
mHeight = params.mHeight;
|
||||||
* @param width keyboard width
|
mWidth = params.mWidth;
|
||||||
*/
|
mMostCommonKeyWidth = params.mMostCommonKeyWidth;
|
||||||
|
mIsRtlKeyboard = params.mIsRtlKeyboard;
|
||||||
|
mPopupKeyboardResId = params.mPopupKeyboardResId;
|
||||||
|
mMaxPopupColumn = params.mMaxPopupColumn;
|
||||||
|
|
||||||
public Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width) {
|
mDefaultRowHeight = params.mDefaultRowHeight;
|
||||||
final Resources res = context.getResources();
|
mVerticalGap = params.mVerticalGap;
|
||||||
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
|
||||||
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
|
||||||
|
|
||||||
final int horizontalEdgesPadding = (int)res.getDimension(
|
mKeys = Collections.unmodifiableList(params.mKeys);
|
||||||
R.dimen.keyboard_horizontal_edges_padding);
|
mShiftKeys = Collections.unmodifiableList(params.mShiftKeys);
|
||||||
mDisplayWidth = width - horizontalEdgesPadding * 2;
|
mShiftLockKeys = Collections.unmodifiableSet(params.mShiftLockKeys);
|
||||||
// TODO: Adjust the height by referring to the height of area available for drawing as well.
|
mShiftedIcons = Collections.unmodifiableMap(params.mShiftedIcons);
|
||||||
mDisplayHeight = res.getDisplayMetrics().heightPixels;
|
mUnshiftedIcons = Collections.unmodifiableMap(params.mUnshiftedIcons);
|
||||||
|
mIconsSet = params.mIconsSet;
|
||||||
|
|
||||||
mHorizontalGap = 0;
|
|
||||||
setKeyWidth(mDisplayWidth / 10);
|
|
||||||
mVerticalGap = 0;
|
|
||||||
mDefaultRowHeight = mDefaultKeyWidth;
|
|
||||||
mId = id;
|
|
||||||
loadKeyboard(context, xmlLayoutResId);
|
|
||||||
mProximityInfo = new ProximityInfo(
|
mProximityInfo = new ProximityInfo(
|
||||||
GRID_WIDTH, GRID_HEIGHT, getMinWidth(), getHeight(), getKeyWidth(), mKeys);
|
params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
|
||||||
|
mMostCommonKeyWidth, mKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProximityInfo() {
|
public int getProximityInfo() {
|
||||||
return mProximityInfo.getNativeProximityInfo();
|
return mProximityInfo.getNativeProximityInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Access mKeys directly
|
||||||
public List<Key> getKeys() {
|
public List<Key> getKeys() {
|
||||||
return mKeys;
|
return mKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHorizontalGap() {
|
|
||||||
return mHorizontalGap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHorizontalGap(int gap) {
|
|
||||||
mHorizontalGap = gap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVerticalGap() {
|
|
||||||
return mVerticalGap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVerticalGap(int gap) {
|
|
||||||
mVerticalGap = gap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRowHeight() {
|
|
||||||
return mDefaultRowHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRowHeight(int height) {
|
|
||||||
mDefaultRowHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyWidth() {
|
|
||||||
return mDefaultKeyWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyWidth(int width) {
|
|
||||||
mDefaultKeyWidth = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the total height of the keyboard
|
|
||||||
* @return the total height of the keyboard
|
|
||||||
*/
|
|
||||||
public int getHeight() {
|
|
||||||
return mTotalHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeight(int height) {
|
|
||||||
mTotalHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinWidth() {
|
|
||||||
return mMinWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinWidth(int minWidth) {
|
|
||||||
mMinWidth = minWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDisplayHeight() {
|
|
||||||
return mDisplayHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDisplayWidth() {
|
|
||||||
return mDisplayWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyboardHeight() {
|
|
||||||
return mKeyboardHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyboardHeight(int height) {
|
|
||||||
mKeyboardHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRtlKeyboard() {
|
|
||||||
return mIsRtlKeyboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRtlKeyboard(boolean isRtl) {
|
|
||||||
mIsRtlKeyboard = isRtl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPopupKeyboardResId() {
|
|
||||||
return mPopupKeyboardResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPopupKeyboardResId(int resId) {
|
|
||||||
mPopupKeyboardResId = resId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxPopupKeyboardColumn() {
|
|
||||||
return mMaxPopupColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxPopupKeyboardColumn(int column) {
|
|
||||||
mMaxPopupColumn = column;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addShiftKey(Key key) {
|
|
||||||
if (key == null) return;
|
|
||||||
mShiftKeys.add(key);
|
|
||||||
if (key.mSticky) {
|
|
||||||
mShiftLockKeys.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addShiftedIcon(Key key, Drawable icon) {
|
|
||||||
if (key == null) return;
|
|
||||||
mUnshiftedIcons.put(key, key.getIcon());
|
|
||||||
mShiftedIcons.put(key, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasShiftLockKey() {
|
public boolean hasShiftLockKey() {
|
||||||
return !mShiftLockKeys.isEmpty();
|
return !mShiftLockKeys.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -391,46 +248,4 @@ public class Keyboard {
|
||||||
public int[] getNearestKeys(int x, int y) {
|
public int[] getNearestKeys(int x, int y) {
|
||||||
return mProximityInfo.getNearestKeys(x, y);
|
return mProximityInfo.getNearestKeys(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the most common key width in order to use it as proximity key detection threshold.
|
|
||||||
*
|
|
||||||
* @return The most common key width in the keyboard
|
|
||||||
*/
|
|
||||||
public int getMostCommonKeyWidth() {
|
|
||||||
if (mMostCommonKeyWidth == 0) {
|
|
||||||
final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
|
|
||||||
int maxCount = 0;
|
|
||||||
int mostCommonWidth = 0;
|
|
||||||
for (final Key key : mKeys) {
|
|
||||||
final Integer width = key.mWidth + key.mHorizontalGap;
|
|
||||||
Integer count = histogram.get(width);
|
|
||||||
if (count == null)
|
|
||||||
count = 0;
|
|
||||||
histogram.put(width, ++count);
|
|
||||||
if (count > maxCount) {
|
|
||||||
maxCount = count;
|
|
||||||
mostCommonWidth = width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mMostCommonKeyWidth = mostCommonWidth;
|
|
||||||
}
|
|
||||||
return mMostCommonKeyWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadKeyboard(Context context, int xmlLayoutResId) {
|
|
||||||
try {
|
|
||||||
KeyboardParser parser = new KeyboardParser(this, context);
|
|
||||||
parser.parseKeyboard(xmlLayoutResId);
|
|
||||||
// mMinWidth is the width of this keyboard which is maximum width of row.
|
|
||||||
mMinWidth = parser.getMaxRowWidth();
|
|
||||||
mTotalHeight = parser.getTotalHeight();
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
Log.w(TAG, "keyboard XML parse error: " + e);
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(TAG, "keyboard XML parse error: " + e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,6 @@ public class KeyboardId {
|
||||||
public static final int F2KEY_MODE_SHORTCUT_IME = 2;
|
public static final int F2KEY_MODE_SHORTCUT_IME = 2;
|
||||||
public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
|
public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
|
||||||
|
|
||||||
private static final int MINI_KEYBOARD_ID_MARKER = -1;
|
|
||||||
|
|
||||||
public final Locale mLocale;
|
public final Locale mLocale;
|
||||||
public final int mOrientation;
|
public final int mOrientation;
|
||||||
public final int mWidth;
|
public final int mWidth;
|
||||||
|
@ -110,9 +108,9 @@ public class KeyboardId {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardId cloneAsMiniKeyboard() {
|
public KeyboardId cloneWithNewXml(String xmlName, int xmlId) {
|
||||||
return new KeyboardId("mini popup keyboard", MINI_KEYBOARD_ID_MARKER, mLocale, mOrientation,
|
return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute,
|
||||||
mWidth, mMode, mAttribute, false, F2KEY_MODE_NONE, false, false, false);
|
false, F2KEY_MODE_NONE, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardId cloneWithNewGeometry(int orientation, int width) {
|
public KeyboardId cloneWithNewGeometry(int orientation, int width) {
|
||||||
|
@ -127,10 +125,6 @@ public class KeyboardId {
|
||||||
return mXmlId;
|
return mXmlId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMiniKeyboard() {
|
|
||||||
return mXmlId == MINI_KEYBOARD_ID_MARKER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlphabetKeyboard() {
|
public boolean isAlphabetKeyboard() {
|
||||||
return mXmlId == R.xml.kbd_qwerty;
|
return mXmlId == R.xml.kbd_qwerty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import android.view.View;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
|
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
|
||||||
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
|
|
||||||
import com.android.inputmethod.keyboard.internal.ModifierKeyState;
|
import com.android.inputmethod.keyboard.internal.ModifierKeyState;
|
||||||
import com.android.inputmethod.keyboard.internal.ShiftKeyState;
|
import com.android.inputmethod.keyboard.internal.ShiftKeyState;
|
||||||
import com.android.inputmethod.latin.LatinIME;
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
|
@ -270,14 +269,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
if (keyboard == null) {
|
if (keyboard == null) {
|
||||||
final Locale savedLocale = Utils.setSystemLocale(
|
final Locale savedLocale = Utils.setSystemLocale(
|
||||||
mResources, mSubtypeSwitcher.getInputLocale());
|
mResources, mSubtypeSwitcher.getInputLocale());
|
||||||
|
try {
|
||||||
keyboard = new LatinKeyboard(mThemeContext, id, id.mWidth);
|
keyboard = new LatinKeyboard.Builder(mThemeContext).load(id).build();
|
||||||
|
} finally {
|
||||||
|
Utils.setSystemLocale(mResources, savedLocale);
|
||||||
|
}
|
||||||
mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
|
mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
|
||||||
if (DEBUG_CACHE)
|
|
||||||
|
if (DEBUG_CACHE) {
|
||||||
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
|
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
|
||||||
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
|
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
|
||||||
|
}
|
||||||
Utils.setSystemLocale(mResources, savedLocale);
|
|
||||||
} else if (DEBUG_CACHE) {
|
} else if (DEBUG_CACHE) {
|
||||||
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
|
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,7 +357,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
mDirtyRect.set(0, 0, getWidth(), getHeight());
|
mDirtyRect.set(0, 0, getWidth(), getHeight());
|
||||||
mBufferNeedsUpdate = true;
|
mBufferNeedsUpdate = true;
|
||||||
invalidateAllKeys();
|
invalidateAllKeys();
|
||||||
final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
|
final int keyHeight = keyboard.mDefaultRowHeight - keyboard.mVerticalGap;
|
||||||
mKeyDrawParams.updateKeyHeight(keyHeight);
|
mKeyDrawParams.updateKeyHeight(keyHeight);
|
||||||
mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
|
mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
if (mKeyboard != null) {
|
if (mKeyboard != null) {
|
||||||
// The main keyboard expands to the display width.
|
// The main keyboard expands to the display width.
|
||||||
final int height = mKeyboard.getKeyboardHeight() + getPaddingTop() + getPaddingBottom();
|
final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
|
||||||
setMeasuredDimension(widthMeasureSpec, height);
|
setMeasuredDimension(widthMeasureSpec, height);
|
||||||
} else {
|
} else {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
|
|
@ -31,13 +31,14 @@ import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardParser;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.SubtypeSwitcher;
|
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||||
|
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
// TODO: We should remove this class
|
// TODO: We should remove this class
|
||||||
|
@ -73,32 +74,16 @@ public class LatinKeyboard extends Keyboard {
|
||||||
private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
|
private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
|
||||||
private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
|
private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
|
||||||
|
|
||||||
public LatinKeyboard(Context context, KeyboardId id, int width) {
|
private LatinKeyboard(Context context, LatinKeyboardParams params) {
|
||||||
super(context, id.getXmlId(), id, width);
|
super(params);
|
||||||
mRes = context.getResources();
|
mRes = context.getResources();
|
||||||
mTheme = context.getTheme();
|
mTheme = context.getTheme();
|
||||||
|
|
||||||
final List<Key> keys = getKeys();
|
|
||||||
int spaceKeyIndex = -1;
|
|
||||||
int shortcutKeyIndex = -1;
|
|
||||||
final int keyCount = keys.size();
|
|
||||||
for (int index = 0; index < keyCount; index++) {
|
|
||||||
// For now, assuming there are up to one space key and one shortcut key respectively.
|
|
||||||
switch (keys.get(index).mCode) {
|
|
||||||
case CODE_SPACE:
|
|
||||||
spaceKeyIndex = index;
|
|
||||||
break;
|
|
||||||
case CODE_SHORTCUT:
|
|
||||||
shortcutKeyIndex = index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The index of space key is available only after Keyboard constructor has finished.
|
// The index of space key is available only after Keyboard constructor has finished.
|
||||||
mSpaceKey = (spaceKeyIndex >= 0) ? keys.get(spaceKeyIndex) : null;
|
mSpaceKey = params.mSpaceKey;
|
||||||
mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null;
|
mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null;
|
||||||
|
|
||||||
mShortcutKey = (shortcutKeyIndex >= 0) ? keys.get(shortcutKeyIndex) : null;
|
mShortcutKey = params.mShortcutKey;
|
||||||
mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null;
|
mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null;
|
||||||
|
|
||||||
final TypedArray a = context.obtainStyledAttributes(
|
final TypedArray a = context.obtainStyledAttributes(
|
||||||
|
@ -114,6 +99,42 @@ public class LatinKeyboard extends Keyboard {
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class LatinKeyboardParams extends KeyboardParams {
|
||||||
|
public Key mSpaceKey = null;
|
||||||
|
public Key mShortcutKey = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddKey(Key key) {
|
||||||
|
super.onAddKey(key);
|
||||||
|
|
||||||
|
switch (key.mCode) {
|
||||||
|
case Keyboard.CODE_SPACE:
|
||||||
|
mSpaceKey = key;
|
||||||
|
break;
|
||||||
|
case Keyboard.CODE_SHORTCUT:
|
||||||
|
mShortcutKey = key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends KeyboardParser<LatinKeyboardParams> {
|
||||||
|
public Builder(Context context) {
|
||||||
|
super(context, new LatinKeyboardParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder load(KeyboardId id) {
|
||||||
|
super.load(id);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LatinKeyboard build() {
|
||||||
|
return new LatinKeyboard(mContext, mParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
|
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
|
||||||
mSpacebarTextFadeFactor = fadeFactor;
|
mSpacebarTextFadeFactor = fadeFactor;
|
||||||
updateSpacebarForLocale(false);
|
updateSpacebarForLocale(false);
|
||||||
|
@ -294,8 +315,8 @@ public class LatinKeyboard extends Keyboard {
|
||||||
@Override
|
@Override
|
||||||
public int[] getNearestKeys(int x, int y) {
|
public int[] getNearestKeys(int x, int y) {
|
||||||
// Avoid dead pixels at edges of the keyboard
|
// Avoid dead pixels at edges of the keyboard
|
||||||
return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)),
|
return super.getNearestKeys(Math.max(0, Math.min(x, mOccupiedWidth - 1)),
|
||||||
Math.max(0, Math.min(y, getHeight() - 1)));
|
Math.max(0, Math.min(y, mOccupiedHeight - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
|
public static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
|
||||||
|
|
|
@ -289,7 +289,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
|
||||||
super.setKeyboard(keyboard);
|
super.setKeyboard(keyboard);
|
||||||
mKeyDetector.setKeyboard(
|
mKeyDetector.setKeyboard(
|
||||||
keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
|
keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
|
||||||
mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
|
mKeyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth);
|
||||||
PointerTracker.setKeyDetector(mKeyDetector);
|
PointerTracker.setKeyDetector(mKeyDetector);
|
||||||
mPopupPanelCache.clear();
|
mPopupPanelCache.clear();
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
|
||||||
(PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
|
(PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
|
||||||
final Keyboard parentKeyboard = getKeyboard();
|
final Keyboard parentKeyboard = getKeyboard();
|
||||||
final Keyboard miniKeyboard = new MiniKeyboardBuilder(
|
final Keyboard miniKeyboard = new MiniKeyboardBuilder(
|
||||||
this, parentKeyboard.getPopupKeyboardResId(), parentKey, parentKeyboard).build();
|
this, parentKeyboard.mPopupKeyboardResId, parentKey, parentKeyboard).build();
|
||||||
miniKeyboardView.setKeyboard(miniKeyboard);
|
miniKeyboardView.setKeyboard(miniKeyboard);
|
||||||
|
|
||||||
container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
|
container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class LatinKeyboardView extends LatinKeyboardBaseView {
|
||||||
public void setKeyboard(Keyboard newKeyboard) {
|
public void setKeyboard(Keyboard newKeyboard) {
|
||||||
super.setKeyboard(newKeyboard);
|
super.setKeyboard(newKeyboard);
|
||||||
// One-seventh of the keyboard width seems like a reasonable threshold
|
// One-seventh of the keyboard width seems like a reasonable threshold
|
||||||
final int jumpThreshold = newKeyboard.getMinWidth() / 7;
|
final int jumpThreshold = newKeyboard.mOccupiedWidth / 7;
|
||||||
mJumpThresholdSquare = jumpThreshold * jumpThreshold;
|
mJumpThresholdSquare = jumpThreshold * jumpThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,30 +16,14 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard;
|
package com.android.inputmethod.keyboard;
|
||||||
|
|
||||||
import android.content.Context;
|
import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder.MiniKeyboardLayoutParams;
|
||||||
|
|
||||||
public class MiniKeyboard extends Keyboard {
|
public class MiniKeyboard extends Keyboard {
|
||||||
private int mDefaultKeyCoordX;
|
private final int mDefaultKeyCoordX;
|
||||||
|
|
||||||
public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) {
|
public MiniKeyboard(MiniKeyboardLayoutParams params) {
|
||||||
super(context, xmlLayoutResId, parentKeyboard.mId.cloneAsMiniKeyboard(),
|
super(params);
|
||||||
parentKeyboard.getMinWidth());
|
mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2;
|
||||||
// HACK: Current mini keyboard design totally relies on the 9-patch padding about horizontal
|
|
||||||
// and vertical key spacing. To keep the visual of mini keyboard as is, these hacks are
|
|
||||||
// needed to keep having the same horizontal and vertical key spacing.
|
|
||||||
setHorizontalGap(0);
|
|
||||||
setVerticalGap(parentKeyboard.getVerticalGap() / 2);
|
|
||||||
|
|
||||||
// TODO: When we have correctly padded key background 9-patch drawables for mini keyboard,
|
|
||||||
// revert the above hacks and uncomment the following lines.
|
|
||||||
//setHorizontalGap(parentKeyboard.getHorizontalGap());
|
|
||||||
//setVerticalGap(parentKeyboard.getVerticalGap());
|
|
||||||
|
|
||||||
setRtlKeyboard(parentKeyboard.isRtlKeyboard());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultCoordX(int pos) {
|
|
||||||
mDefaultKeyCoordX = pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDefaultCoordX() {
|
public int getDefaultCoordX() {
|
||||||
|
|
|
@ -286,7 +286,7 @@ public class PointerTracker {
|
||||||
mKeyDetector = keyDetector;
|
mKeyDetector = keyDetector;
|
||||||
mKeyboard = keyDetector.getKeyboard();
|
mKeyboard = keyDetector.getKeyboard();
|
||||||
mKeys = mKeyboard.getKeys();
|
mKeys = mKeyboard.getKeys();
|
||||||
final int keyQuarterWidth = mKeyboard.getKeyWidth() / 4;
|
final int keyQuarterWidth = mKeyboard.mMostCommonKeyWidth / 4;
|
||||||
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
|
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,8 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
final Keyboard keyboard = getKeyboard();
|
final Keyboard keyboard = getKeyboard();
|
||||||
if (keyboard != null) {
|
if (keyboard != null) {
|
||||||
final int width = keyboard.getMinWidth() + getPaddingLeft() + getPaddingRight();
|
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
|
||||||
final int height = keyboard.getKeyboardHeight() + getPaddingTop() + getPaddingBottom();
|
final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
|
||||||
setMeasuredDimension(width, height);
|
setMeasuredDimension(width, height);
|
||||||
} else {
|
} else {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
@ -170,9 +170,9 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
|
||||||
final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
|
final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
|
||||||
+ parentKeyboardView.getPaddingLeft();
|
+ parentKeyboardView.getPaddingLeft();
|
||||||
final int x = Math.max(0, Math.min(miniKeyboardLeft,
|
final int x = Math.max(0, Math.min(miniKeyboardLeft,
|
||||||
parentKeyboardView.getWidth() - miniKeyboard.getMinWidth()))
|
parentKeyboardView.getWidth() - miniKeyboard.mOccupiedWidth))
|
||||||
- container.getPaddingLeft() + mCoordinates[0];
|
- container.getPaddingLeft() + mCoordinates[0];
|
||||||
final int y = pointY - parentKeyboard.getVerticalGap()
|
final int y = pointY - parentKeyboard.mVerticalGap
|
||||||
- (container.getMeasuredHeight() - container.getPaddingBottom())
|
- (container.getMeasuredHeight() - container.getPaddingBottom())
|
||||||
+ parentKeyboardView.getPaddingTop() + mCoordinates[1];
|
+ parentKeyboardView.getPaddingTop() + mCoordinates[1];
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard.internal;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -31,8 +32,8 @@ import java.util.Set;
|
||||||
public class KeyboardParams {
|
public class KeyboardParams {
|
||||||
public KeyboardId mId;
|
public KeyboardId mId;
|
||||||
|
|
||||||
public int mTotalHeight;
|
public int mOccupiedHeight;
|
||||||
public int mTotalWidth;
|
public int mOccupiedWidth;
|
||||||
|
|
||||||
public int mHeight;
|
public int mHeight;
|
||||||
public int mWidth;
|
public int mWidth;
|
||||||
|
@ -61,40 +62,34 @@ public class KeyboardParams {
|
||||||
public final Map<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
|
public final Map<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
|
||||||
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
||||||
|
|
||||||
public void addShiftKey(Key key) {
|
public int mMostCommonKeyWidth = 0;
|
||||||
if (key == null) return;
|
|
||||||
mShiftKeys.add(key);
|
public void onAddKey(Key key) {
|
||||||
if (key.mSticky) {
|
mKeys.add(key);
|
||||||
mShiftLockKeys.add(key);
|
updateHistogram(key);
|
||||||
|
if (key.mCode == Keyboard.CODE_SHIFT) {
|
||||||
|
mShiftKeys.add(key);
|
||||||
|
if (key.mSticky) {
|
||||||
|
mShiftLockKeys.add(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addShiftedIcon(Key key, Drawable icon) {
|
public void addShiftedIcon(Key key, Drawable icon) {
|
||||||
if (key == null) return;
|
|
||||||
mUnshiftedIcons.put(key, key.getIcon());
|
mUnshiftedIcons.put(key, key.getIcon());
|
||||||
mShiftedIcons.put(key, icon);
|
mShiftedIcons.put(key, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private int mMaxCount = 0;
|
||||||
* Compute the most common key width in order to use it as proximity key detection threshold.
|
private final Map<Integer, Integer> mHistogram = new HashMap<Integer, Integer>();
|
||||||
*
|
|
||||||
* @return The most common key width in the keyboard
|
private void updateHistogram(Key key) {
|
||||||
*/
|
final Integer width = key.mWidth + key.mHorizontalGap;
|
||||||
public int getMostCommonKeyWidth() {
|
final int count = (mHistogram.containsKey(width) ? mHistogram.get(width) : 0) + 1;
|
||||||
final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
|
mHistogram.put(width, count);
|
||||||
int maxCount = 0;
|
if (count > mMaxCount) {
|
||||||
int mostCommonWidth = 0;
|
mMaxCount = count;
|
||||||
for (final Key key : mKeys) {
|
mMostCommonKeyWidth = width;
|
||||||
final Integer width = key.mWidth + key.mHorizontalGap;
|
|
||||||
Integer count = histogram.get(width);
|
|
||||||
if (count == null)
|
|
||||||
count = 0;
|
|
||||||
histogram.put(width, ++count);
|
|
||||||
if (count > maxCount) {
|
|
||||||
maxCount = count;
|
|
||||||
mostCommonWidth = width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return mostCommonWidth;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
@ -107,7 +108,7 @@ import java.util.List;
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class KeyboardParser {
|
public class KeyboardParser<KP extends KeyboardParams> {
|
||||||
private static final String TAG = KeyboardParser.class.getSimpleName();
|
private static final String TAG = KeyboardParser.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
@ -123,40 +124,52 @@ public class KeyboardParser {
|
||||||
private static final String TAG_DEFAULT = "default";
|
private static final String TAG_DEFAULT = "default";
|
||||||
public static final String TAG_KEY_STYLE = "key-style";
|
public static final String TAG_KEY_STYLE = "key-style";
|
||||||
|
|
||||||
private final Keyboard mKeyboard;
|
protected final KP mParams;
|
||||||
private final Context mContext;
|
protected final Context mContext;
|
||||||
private final Resources mResources;
|
protected final Resources mResources;
|
||||||
|
private final DisplayMetrics mDisplayMetrics;
|
||||||
|
|
||||||
private int mKeyboardTopPadding;
|
|
||||||
private int mKeyboardBottomPadding;
|
|
||||||
private int mHorizontalEdgesPadding;
|
|
||||||
private int mCurrentX = 0;
|
private int mCurrentX = 0;
|
||||||
private int mCurrentY = 0;
|
private int mCurrentY = 0;
|
||||||
private int mMaxRowWidth = 0;
|
|
||||||
private int mTotalHeight = 0;
|
|
||||||
private Row mCurrentRow = null;
|
private Row mCurrentRow = null;
|
||||||
private boolean mLeftEdge;
|
private boolean mLeftEdge;
|
||||||
private Key mRightEdgeKey = null;
|
private Key mRightEdgeKey = null;
|
||||||
private final KeyStyles mKeyStyles = new KeyStyles();
|
private final KeyStyles mKeyStyles = new KeyStyles();
|
||||||
|
|
||||||
public KeyboardParser(Keyboard keyboard, Context context) {
|
public KeyboardParser(Context context, KP params) {
|
||||||
mKeyboard = keyboard;
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
mResources = res;
|
mResources = res;
|
||||||
mHorizontalEdgesPadding = (int)res.getDimension(R.dimen.keyboard_horizontal_edges_padding);
|
mDisplayMetrics = res.getDisplayMetrics();
|
||||||
|
|
||||||
|
mParams = params;
|
||||||
|
mParams.mHorizontalEdgesPadding = (int)res.getDimension(
|
||||||
|
R.dimen.keyboard_horizontal_edges_padding);
|
||||||
|
|
||||||
|
mParams.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
||||||
|
mParams.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxRowWidth() {
|
public KeyboardParser<KP> load(KeyboardId id) {
|
||||||
return mMaxRowWidth;
|
mParams.mId = id;
|
||||||
|
try {
|
||||||
|
parseKeyboard(id.getXmlId());
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
Log.w(TAG, "keyboard XML parse error: " + e);
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, "keyboard XML parse error: " + e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTotalHeight() {
|
public Keyboard build() {
|
||||||
return mTotalHeight;
|
return new Keyboard(mParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseKeyboard(int resId) throws XmlPullParserException, IOException {
|
private void parseKeyboard(int resId) throws XmlPullParserException, IOException {
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_KEYBOARD, mKeyboard.mId));
|
if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_KEYBOARD, mParams.mId));
|
||||||
final XmlResourceParser parser = mResources.getXml(resId);
|
final XmlResourceParser parser = mResources.getXml(resId);
|
||||||
int event;
|
int event;
|
||||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
@ -165,7 +178,7 @@ public class KeyboardParser {
|
||||||
if (TAG_KEYBOARD.equals(tag)) {
|
if (TAG_KEYBOARD.equals(tag)) {
|
||||||
parseKeyboardAttributes(parser);
|
parseKeyboardAttributes(parser);
|
||||||
startKeyboard();
|
startKeyboard();
|
||||||
parseKeyboardContent(parser, mKeyboard.getKeys());
|
parseKeyboardContent(parser, false);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStartTag(parser, TAG_KEYBOARD);
|
throw new IllegalStartTag(parser, TAG_KEYBOARD);
|
||||||
|
@ -196,15 +209,14 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseKeyboardAttributes(XmlResourceParser parser) {
|
private void parseKeyboardAttributes(XmlResourceParser parser) {
|
||||||
final Keyboard keyboard = mKeyboard;
|
final int displayWidth = mDisplayMetrics.widthPixels;
|
||||||
final int displayWidth = keyboard.getDisplayWidth();
|
|
||||||
final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
|
final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
|
||||||
Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
|
Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
|
||||||
R.style.Keyboard);
|
R.style.Keyboard);
|
||||||
final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
R.styleable.Keyboard_Key);
|
R.styleable.Keyboard_Key);
|
||||||
try {
|
try {
|
||||||
final int displayHeight = keyboard.getDisplayHeight();
|
final int displayHeight = mDisplayMetrics.heightPixels;
|
||||||
final int keyboardHeight = (int)keyboardAttr.getDimension(
|
final int keyboardHeight = (int)keyboardAttr.getDimension(
|
||||||
R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
|
R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
|
||||||
final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
|
final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
|
||||||
|
@ -219,37 +231,41 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
// Keyboard height will not exceed maxKeyboardHeight and will not be less than
|
// Keyboard height will not exceed maxKeyboardHeight and will not be less than
|
||||||
// minKeyboardHeight.
|
// minKeyboardHeight.
|
||||||
final int height = Math.max(
|
mParams.mOccupiedHeight = Math.max(
|
||||||
Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
|
Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
|
||||||
|
mParams.mOccupiedWidth = mParams.mId.mWidth;
|
||||||
|
mParams.mTopPadding = getDimensionOrFraction(keyboardAttr,
|
||||||
|
R.styleable.Keyboard_keyboardTopPadding, mParams.mOccupiedHeight, 0);
|
||||||
|
mParams.mBottomPadding = getDimensionOrFraction(keyboardAttr,
|
||||||
|
R.styleable.Keyboard_keyboardBottomPadding, mParams.mOccupiedHeight, 0);
|
||||||
|
|
||||||
keyboard.setKeyboardHeight(height);
|
final int height = mParams.mOccupiedHeight;
|
||||||
keyboard.setRtlKeyboard(keyboardAttr.getBoolean(
|
final int width = mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding * 2
|
||||||
R.styleable.Keyboard_isRtlKeyboard, false));
|
- mParams.mHorizontalCenterPadding;
|
||||||
keyboard.setKeyWidth(getDimensionOrFraction(keyboardAttr,
|
mParams.mHeight = height;
|
||||||
R.styleable.Keyboard_keyWidth, displayWidth, displayWidth / 10));
|
mParams.mWidth = width;
|
||||||
keyboard.setRowHeight(getDimensionOrFraction(keyboardAttr,
|
mParams.mDefaultKeyWidth = getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_rowHeight, height, 50));
|
R.styleable.Keyboard_keyWidth, width, width / 10);
|
||||||
keyboard.setHorizontalGap(getDimensionOrFraction(keyboardAttr,
|
mParams.mDefaultRowHeight = getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_horizontalGap, displayWidth, 0));
|
R.styleable.Keyboard_rowHeight, height, height / 4);
|
||||||
keyboard.setVerticalGap(getDimensionOrFraction(keyboardAttr,
|
mParams.mHorizontalGap = getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_verticalGap, height, 0));
|
R.styleable.Keyboard_horizontalGap, width, 0);
|
||||||
keyboard.setPopupKeyboardResId(keyboardAttr.getResourceId(
|
mParams.mVerticalGap = getDimensionOrFraction(keyboardAttr,
|
||||||
R.styleable.Keyboard_popupKeyboardTemplate, 0));
|
R.styleable.Keyboard_verticalGap, height, 0);
|
||||||
keyboard.setMaxPopupKeyboardColumn(keyAttr.getInt(
|
|
||||||
R.styleable.Keyboard_Key_maxPopupKeyboardColumn, 5));
|
|
||||||
|
|
||||||
mKeyboard.mIconsSet.loadIcons(keyboardAttr);
|
mParams.mIsRtlKeyboard = keyboardAttr.getBoolean(R.styleable.Keyboard_isRtlKeyboard, false);
|
||||||
mKeyboardTopPadding = getDimensionOrFraction(keyboardAttr,
|
mParams.mPopupKeyboardResId = keyboardAttr.getResourceId(
|
||||||
R.styleable.Keyboard_keyboardTopPadding, height, 0);
|
R.styleable.Keyboard_popupKeyboardTemplate, 0);
|
||||||
mKeyboardBottomPadding = getDimensionOrFraction(keyboardAttr,
|
mParams.mMaxPopupColumn = keyAttr.getInt(R.styleable.Keyboard_Key_maxPopupKeyboardColumn, 5);
|
||||||
R.styleable.Keyboard_keyboardBottomPadding, height, 0);
|
|
||||||
|
mParams.mIconsSet.loadIcons(keyboardAttr);
|
||||||
} finally {
|
} finally {
|
||||||
keyAttr.recycle();
|
keyAttr.recycle();
|
||||||
keyboardAttr.recycle();
|
keyboardAttr.recycle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseKeyboardContent(XmlResourceParser parser, List<Key> keys)
|
private void parseKeyboardContent(XmlResourceParser parser, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
int event;
|
int event;
|
||||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
@ -258,22 +274,22 @@ public class KeyboardParser {
|
||||||
if (TAG_ROW.equals(tag)) {
|
if (TAG_ROW.equals(tag)) {
|
||||||
Row row = parseRowAttributes(parser);
|
Row row = parseRowAttributes(parser);
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_ROW));
|
if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_ROW));
|
||||||
if (keys != null)
|
if (!skip)
|
||||||
startRow(row);
|
startRow(row);
|
||||||
parseRowContent(parser, row, keys);
|
parseRowContent(parser, row, skip);
|
||||||
} else if (TAG_INCLUDE.equals(tag)) {
|
} else if (TAG_INCLUDE.equals(tag)) {
|
||||||
parseIncludeKeyboardContent(parser, keys);
|
parseIncludeKeyboardContent(parser, skip);
|
||||||
} else if (TAG_SWITCH.equals(tag)) {
|
} else if (TAG_SWITCH.equals(tag)) {
|
||||||
parseSwitchKeyboardContent(parser, keys);
|
parseSwitchKeyboardContent(parser, skip);
|
||||||
} else if (TAG_KEY_STYLE.equals(tag)) {
|
} else if (TAG_KEY_STYLE.equals(tag)) {
|
||||||
parseKeyStyle(parser, keys);
|
parseKeyStyle(parser, skip);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStartTag(parser, TAG_ROW);
|
throw new IllegalStartTag(parser, TAG_ROW);
|
||||||
}
|
}
|
||||||
} else if (event == XmlPullParser.END_TAG) {
|
} else if (event == XmlPullParser.END_TAG) {
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (TAG_KEYBOARD.equals(tag)) {
|
if (TAG_KEYBOARD.equals(tag)) {
|
||||||
endKeyboard(mKeyboard.getVerticalGap());
|
endKeyboard();
|
||||||
break;
|
break;
|
||||||
} else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
|
} else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
|
||||||
|| TAG_MERGE.equals(tag)) {
|
|| TAG_MERGE.equals(tag)) {
|
||||||
|
@ -296,28 +312,28 @@ public class KeyboardParser {
|
||||||
throw new IllegalAttribute(parser, "horizontalGap");
|
throw new IllegalAttribute(parser, "horizontalGap");
|
||||||
if (a.hasValue(R.styleable.Keyboard_verticalGap))
|
if (a.hasValue(R.styleable.Keyboard_verticalGap))
|
||||||
throw new IllegalAttribute(parser, "verticalGap");
|
throw new IllegalAttribute(parser, "verticalGap");
|
||||||
return new Row(mResources, mKeyboard, parser);
|
return new Row(mResources, mParams, parser);
|
||||||
} finally {
|
} finally {
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRowContent(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseRowContent(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
int event;
|
int event;
|
||||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
if (event == XmlPullParser.START_TAG) {
|
if (event == XmlPullParser.START_TAG) {
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (TAG_KEY.equals(tag)) {
|
if (TAG_KEY.equals(tag)) {
|
||||||
parseKey(parser, row, keys);
|
parseKey(parser, row, skip);
|
||||||
} else if (TAG_SPACER.equals(tag)) {
|
} else if (TAG_SPACER.equals(tag)) {
|
||||||
parseSpacer(parser, row, keys);
|
parseSpacer(parser, row, skip);
|
||||||
} else if (TAG_INCLUDE.equals(tag)) {
|
} else if (TAG_INCLUDE.equals(tag)) {
|
||||||
parseIncludeRowContent(parser, row, keys);
|
parseIncludeRowContent(parser, row, skip);
|
||||||
} else if (TAG_SWITCH.equals(tag)) {
|
} else if (TAG_SWITCH.equals(tag)) {
|
||||||
parseSwitchRowContent(parser, row, keys);
|
parseSwitchRowContent(parser, row, skip);
|
||||||
} else if (TAG_KEY_STYLE.equals(tag)) {
|
} else if (TAG_KEY_STYLE.equals(tag)) {
|
||||||
parseKeyStyle(parser, keys);
|
parseKeyStyle(parser, skip);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStartTag(parser, TAG_KEY);
|
throw new IllegalStartTag(parser, TAG_KEY);
|
||||||
}
|
}
|
||||||
|
@ -325,7 +341,7 @@ public class KeyboardParser {
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (TAG_ROW.equals(tag)) {
|
if (TAG_ROW.equals(tag)) {
|
||||||
if (DEBUG) Log.d(TAG, String.format("</%s>", TAG_ROW));
|
if (DEBUG) Log.d(TAG, String.format("</%s>", TAG_ROW));
|
||||||
if (keys != null)
|
if (!skip)
|
||||||
endRow();
|
endRow();
|
||||||
break;
|
break;
|
||||||
} else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
|
} else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
|
||||||
|
@ -341,24 +357,24 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseKey(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseKey(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
if (keys == null) {
|
if (skip) {
|
||||||
checkEndTag(TAG_KEY, parser);
|
checkEndTag(TAG_KEY, parser);
|
||||||
} else {
|
} else {
|
||||||
Key key = new Key(mResources, row, mCurrentX, mCurrentY, parser, mKeyStyles);
|
Key key = new Key(mResources, mParams, row, mCurrentX, mCurrentY, parser, mKeyStyles);
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s%s keyLabel=%s code=%d popupCharacters=%s />",
|
if (DEBUG) Log.d(TAG, String.format("<%s%s keyLabel=%s code=%d popupCharacters=%s />",
|
||||||
TAG_KEY, (key.isEnabled() ? "" : " disabled"), key.mLabel, key.mCode,
|
TAG_KEY, (key.isEnabled() ? "" : " disabled"), key.mLabel, key.mCode,
|
||||||
Arrays.toString(key.mPopupCharacters)));
|
Arrays.toString(key.mPopupCharacters)));
|
||||||
checkEndTag(TAG_KEY, parser);
|
checkEndTag(TAG_KEY, parser);
|
||||||
keys.add(key);
|
mParams.onAddKey(key);
|
||||||
endKey(key);
|
endKey(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSpacer(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseSpacer(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
if (keys == null) {
|
if (skip) {
|
||||||
checkEndTag(TAG_SPACER, parser);
|
checkEndTag(TAG_SPACER, parser);
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER));
|
if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER));
|
||||||
|
@ -366,9 +382,9 @@ public class KeyboardParser {
|
||||||
R.styleable.Keyboard);
|
R.styleable.Keyboard);
|
||||||
if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
|
if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
|
||||||
throw new IllegalAttribute(parser, "horizontalGap");
|
throw new IllegalAttribute(parser, "horizontalGap");
|
||||||
final int keyboardWidth = mKeyboard.getDisplayWidth();
|
final int keyboardWidth = mParams.mWidth;
|
||||||
final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
|
final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
|
||||||
keyboardWidth, row.mDefaultWidth);
|
keyboardWidth, row.mDefaultKeyWidth);
|
||||||
keyboardAttr.recycle();
|
keyboardAttr.recycle();
|
||||||
|
|
||||||
final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
|
@ -385,19 +401,19 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIncludeKeyboardContent(XmlResourceParser parser, List<Key> keys)
|
private void parseIncludeKeyboardContent(XmlResourceParser parser, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
parseIncludeInternal(parser, null, keys);
|
parseIncludeInternal(parser, null, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIncludeRowContent(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseIncludeRowContent(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
parseIncludeInternal(parser, row, keys);
|
parseIncludeInternal(parser, row, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIncludeInternal(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseIncludeInternal(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
if (keys == null) {
|
if (skip) {
|
||||||
checkEndTag(TAG_INCLUDE, parser);
|
checkEndTag(TAG_INCLUDE, parser);
|
||||||
} else {
|
} else {
|
||||||
final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
|
@ -411,11 +427,11 @@ public class KeyboardParser {
|
||||||
throw new ParseException("No keyboardLayout attribute in <include/>", parser);
|
throw new ParseException("No keyboardLayout attribute in <include/>", parser);
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s keyboardLayout=%s />",
|
if (DEBUG) Log.d(TAG, String.format("<%s keyboardLayout=%s />",
|
||||||
TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout)));
|
TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout)));
|
||||||
parseMerge(mResources.getLayout(keyboardLayout), row, keys);
|
parseMerge(mResources.getLayout(keyboardLayout), row, skip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseMerge(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseMerge(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
int event;
|
int event;
|
||||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
@ -423,9 +439,9 @@ public class KeyboardParser {
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (TAG_MERGE.equals(tag)) {
|
if (TAG_MERGE.equals(tag)) {
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
parseKeyboardContent(parser, keys);
|
parseKeyboardContent(parser, skip);
|
||||||
} else {
|
} else {
|
||||||
parseRowContent(parser, row, keys);
|
parseRowContent(parser, row, skip);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -436,28 +452,28 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSwitchKeyboardContent(XmlResourceParser parser, List<Key> keys)
|
private void parseSwitchKeyboardContent(XmlResourceParser parser, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
parseSwitchInternal(parser, null, keys);
|
parseSwitchInternal(parser, null, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSwitchRowContent(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseSwitchRowContent(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
parseSwitchInternal(parser, row, keys);
|
parseSwitchInternal(parser, row, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSwitchInternal(XmlResourceParser parser, Row row, List<Key> keys)
|
private void parseSwitchInternal(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_SWITCH, mKeyboard.mId));
|
if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_SWITCH, mParams.mId));
|
||||||
boolean selected = false;
|
boolean selected = false;
|
||||||
int event;
|
int event;
|
||||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
if (event == XmlPullParser.START_TAG) {
|
if (event == XmlPullParser.START_TAG) {
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (TAG_CASE.equals(tag)) {
|
if (TAG_CASE.equals(tag)) {
|
||||||
selected |= parseCase(parser, row, selected ? null : keys);
|
selected |= parseCase(parser, row, selected ? true : skip);
|
||||||
} else if (TAG_DEFAULT.equals(tag)) {
|
} else if (TAG_DEFAULT.equals(tag)) {
|
||||||
selected |= parseDefault(parser, row, selected ? null : keys);
|
selected |= parseDefault(parser, row, selected ? true : skip);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStartTag(parser, TAG_KEY);
|
throw new IllegalStartTag(parser, TAG_KEY);
|
||||||
}
|
}
|
||||||
|
@ -473,21 +489,21 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseCase(XmlResourceParser parser, Row row, List<Key> keys)
|
private boolean parseCase(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
final boolean selected = parseCaseCondition(parser);
|
final boolean selected = parseCaseCondition(parser);
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
// Processing Rows.
|
// Processing Rows.
|
||||||
parseKeyboardContent(parser, selected ? keys : null);
|
parseKeyboardContent(parser, selected ? skip : true);
|
||||||
} else {
|
} else {
|
||||||
// Processing Keys.
|
// Processing Keys.
|
||||||
parseRowContent(parser, row, selected ? keys : null);
|
parseRowContent(parser, row, selected ? skip : true);
|
||||||
}
|
}
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseCaseCondition(XmlResourceParser parser) {
|
private boolean parseCaseCondition(XmlResourceParser parser) {
|
||||||
final KeyboardId id = mKeyboard.mId;
|
final KeyboardId id = mParams.mId;
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -596,18 +612,18 @@ public class KeyboardParser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseDefault(XmlResourceParser parser, Row row, List<Key> keys)
|
private boolean parseDefault(XmlResourceParser parser, Row row, boolean skip)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_DEFAULT));
|
if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_DEFAULT));
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
parseKeyboardContent(parser, keys);
|
parseKeyboardContent(parser, skip);
|
||||||
} else {
|
} else {
|
||||||
parseRowContent(parser, row, keys);
|
parseRowContent(parser, row, skip);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseKeyStyle(XmlResourceParser parser, List<Key> keys) {
|
private void parseKeyStyle(XmlResourceParser parser, boolean skip) {
|
||||||
TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
R.styleable.Keyboard_KeyStyle);
|
R.styleable.Keyboard_KeyStyle);
|
||||||
TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
|
@ -616,7 +632,7 @@ public class KeyboardParser {
|
||||||
if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName))
|
if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName))
|
||||||
throw new ParseException("<" + TAG_KEY_STYLE
|
throw new ParseException("<" + TAG_KEY_STYLE
|
||||||
+ "/> needs styleName attribute", parser);
|
+ "/> needs styleName attribute", parser);
|
||||||
if (keys != null)
|
if (!skip)
|
||||||
mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
|
mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
|
||||||
} finally {
|
} finally {
|
||||||
keyStyleAttr.recycle();
|
keyStyleAttr.recycle();
|
||||||
|
@ -632,12 +648,12 @@ public class KeyboardParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startKeyboard() {
|
private void startKeyboard() {
|
||||||
mCurrentY += mKeyboardTopPadding;
|
mCurrentY += mParams.mTopPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRow(Row row) {
|
private void startRow(Row row) {
|
||||||
mCurrentX = 0;
|
mCurrentX = 0;
|
||||||
setSpacer(mCurrentX, mHorizontalEdgesPadding);
|
setSpacer(mCurrentX, mParams.mHorizontalEdgesPadding);
|
||||||
mCurrentRow = row;
|
mCurrentRow = row;
|
||||||
mLeftEdge = true;
|
mLeftEdge = true;
|
||||||
mRightEdgeKey = null;
|
mRightEdgeKey = null;
|
||||||
|
@ -650,10 +666,8 @@ public class KeyboardParser {
|
||||||
mRightEdgeKey.addEdgeFlags(Keyboard.EDGE_RIGHT);
|
mRightEdgeKey.addEdgeFlags(Keyboard.EDGE_RIGHT);
|
||||||
mRightEdgeKey = null;
|
mRightEdgeKey = null;
|
||||||
}
|
}
|
||||||
setSpacer(mCurrentX, mHorizontalEdgesPadding);
|
setSpacer(mCurrentX, mParams.mHorizontalEdgesPadding);
|
||||||
if (mCurrentX > mMaxRowWidth)
|
mCurrentY += mCurrentRow.mRowHeight;
|
||||||
mMaxRowWidth = mCurrentX;
|
|
||||||
mCurrentY += mCurrentRow.mDefaultHeight;
|
|
||||||
mCurrentRow = null;
|
mCurrentRow = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,9 +680,7 @@ public class KeyboardParser {
|
||||||
mRightEdgeKey = key;
|
mRightEdgeKey = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void endKeyboard(int defaultVerticalGap) {
|
private void endKeyboard() {
|
||||||
mCurrentY += mKeyboardBottomPadding;
|
|
||||||
mTotalHeight = mCurrentY - defaultVerticalGap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSpacer(int keyXPos, int width) {
|
private void setSpacer(int keyXPos, int width) {
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard.internal;
|
package com.android.inputmethod.keyboard.internal;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
@ -27,26 +25,30 @@ import com.android.inputmethod.keyboard.KeyboardView;
|
||||||
import com.android.inputmethod.keyboard.MiniKeyboard;
|
import com.android.inputmethod.keyboard.MiniKeyboard;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
import java.util.List;
|
public class MiniKeyboardBuilder extends
|
||||||
|
KeyboardParser<MiniKeyboardBuilder.MiniKeyboardLayoutParams> {
|
||||||
public class MiniKeyboardBuilder {
|
|
||||||
private final Resources mRes;
|
|
||||||
private final MiniKeyboard mKeyboard;
|
|
||||||
private final CharSequence[] mPopupCharacters;
|
private final CharSequence[] mPopupCharacters;
|
||||||
private final MiniKeyboardLayoutParams mParams;
|
|
||||||
|
|
||||||
/* package */ static class MiniKeyboardLayoutParams {
|
public static class MiniKeyboardLayoutParams extends KeyboardParams {
|
||||||
public final int mKeyWidth;
|
/* package */ int mTopRowAdjustment;
|
||||||
public final int mRowHeight;
|
public int mNumRows;
|
||||||
/* package */ final int mTopRowAdjustment;
|
public int mNumColumns;
|
||||||
public final int mNumRows;
|
public int mLeftKeys;
|
||||||
public final int mNumColumns;
|
public int mRightKeys; // includes default key.
|
||||||
public final int mLeftKeys;
|
|
||||||
public final int mRightKeys; // includes default key.
|
public MiniKeyboardLayoutParams() {
|
||||||
public int mTopPadding;
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package for test */ MiniKeyboardLayoutParams(int numKeys, int maxColumns, int keyWidth,
|
||||||
|
int rowHeight, int coordXInParent, int parentKeyboardWidth) {
|
||||||
|
super();
|
||||||
|
setParameters(
|
||||||
|
numKeys, maxColumns, keyWidth, rowHeight, coordXInParent, parentKeyboardWidth);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object holding mini keyboard layout parameters.
|
* Set keyboard parameters of mini keyboard.
|
||||||
*
|
*
|
||||||
* @param numKeys number of keys in this mini keyboard.
|
* @param numKeys number of keys in this mini keyboard.
|
||||||
* @param maxColumns number of maximum columns of this mini keyboard.
|
* @param maxColumns number of maximum columns of this mini keyboard.
|
||||||
|
@ -54,15 +56,15 @@ public class MiniKeyboardBuilder {
|
||||||
* @param rowHeight mini keyboard row height in pixel, including vertical gap.
|
* @param rowHeight mini keyboard row height in pixel, including vertical gap.
|
||||||
* @param coordXInParent coordinate x of the popup key in parent keyboard.
|
* @param coordXInParent coordinate x of the popup key in parent keyboard.
|
||||||
* @param parentKeyboardWidth parent keyboard width in pixel.
|
* @param parentKeyboardWidth parent keyboard width in pixel.
|
||||||
* parent keyboard.
|
|
||||||
*/
|
*/
|
||||||
public MiniKeyboardLayoutParams(int numKeys, int maxColumns, int keyWidth, int rowHeight,
|
public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
|
||||||
int coordXInParent, int parentKeyboardWidth) {
|
int coordXInParent, int parentKeyboardWidth) {
|
||||||
if (parentKeyboardWidth / keyWidth < maxColumns)
|
if (parentKeyboardWidth / keyWidth < maxColumns) {
|
||||||
throw new IllegalArgumentException("Keyboard is too small to hold mini keyboard: "
|
throw new IllegalArgumentException("Keyboard is too small to hold mini keyboard: "
|
||||||
+ parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
|
+ parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
|
||||||
mKeyWidth = keyWidth;
|
}
|
||||||
mRowHeight = rowHeight;
|
mDefaultKeyWidth = keyWidth;
|
||||||
|
mDefaultRowHeight = rowHeight;
|
||||||
|
|
||||||
final int numRows = (numKeys + maxColumns - 1) / maxColumns;
|
final int numRows = (numKeys + maxColumns - 1) / maxColumns;
|
||||||
mNumRows = numRows;
|
mNumRows = numRows;
|
||||||
|
@ -108,6 +110,9 @@ public class MiniKeyboardBuilder {
|
||||||
} else {
|
} else {
|
||||||
mTopRowAdjustment = -1;
|
mTopRowAdjustment = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth;
|
||||||
|
mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return key position according to column count (0 is default).
|
// Return key position according to column count (0 is default).
|
||||||
|
@ -160,19 +165,19 @@ public class MiniKeyboardBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDefaultKeyCoordX() {
|
public int getDefaultKeyCoordX() {
|
||||||
return mLeftKeys * mKeyWidth;
|
return mLeftKeys * mDefaultKeyWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX(int n, int row) {
|
public int getX(int n, int row) {
|
||||||
final int x = getColumnPos(n) * mKeyWidth + getDefaultKeyCoordX();
|
final int x = getColumnPos(n) * mDefaultKeyWidth + getDefaultKeyCoordX();
|
||||||
if (isTopRow(row)) {
|
if (isTopRow(row)) {
|
||||||
return x + mTopRowAdjustment * (mKeyWidth / 2);
|
return x + mTopRowAdjustment * (mDefaultKeyWidth / 2);
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getY(int row) {
|
public int getY(int row) {
|
||||||
return (mNumRows - 1 - row) * mRowHeight + mTopPadding;
|
return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRowFlags(int row) {
|
public int getRowFlags(int row) {
|
||||||
|
@ -185,42 +190,32 @@ public class MiniKeyboardBuilder {
|
||||||
private boolean isTopRow(int rowCount) {
|
private boolean isTopRow(int rowCount) {
|
||||||
return rowCount == mNumRows - 1;
|
return rowCount == mNumRows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTopPadding (int topPadding) {
|
|
||||||
mTopPadding = topPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyboardHeight() {
|
|
||||||
return mNumRows * mRowHeight + mTopPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyboardWidth() {
|
|
||||||
return mNumColumns * mKeyWidth;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey,
|
public MiniKeyboardBuilder(KeyboardView view, int xmlId, Key parentKey,
|
||||||
Keyboard parentKeyboard) {
|
Keyboard parentKeyboard) {
|
||||||
final Context context = view.getContext();
|
super(view.getContext(), new MiniKeyboardLayoutParams());
|
||||||
mRes = context.getResources();
|
load(parentKeyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
|
||||||
final MiniKeyboard keyboard = new MiniKeyboard(
|
|
||||||
context, layoutTemplateResId, parentKeyboard);
|
// HACK: Current mini keyboard design totally relies on the 9-patch padding about horizontal
|
||||||
mKeyboard = keyboard;
|
// and vertical key spacing. To keep the visual of mini keyboard as is, these hacks are
|
||||||
|
// needed to keep having the same horizontal and vertical key spacing.
|
||||||
|
mParams.mHorizontalGap = 0;
|
||||||
|
mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
|
||||||
|
// TODO: When we have correctly padded key background 9-patch drawables for mini keyboard,
|
||||||
|
// revert the above hacks and uncomment the following lines.
|
||||||
|
//mParams.mHorizontalGap = parentKeyboard.mHorizontalGap;
|
||||||
|
//mParams.mVerticalGap = parentKeyboard.mVerticalGap;
|
||||||
|
|
||||||
|
mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
|
||||||
mPopupCharacters = parentKey.mPopupCharacters;
|
mPopupCharacters = parentKey.mPopupCharacters;
|
||||||
|
|
||||||
final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, keyboard.getKeyWidth());
|
final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, mParams.mDefaultKeyWidth);
|
||||||
final MiniKeyboardLayoutParams params = new MiniKeyboardLayoutParams(
|
mParams.setParameters(
|
||||||
mPopupCharacters.length, parentKey.mMaxPopupColumn,
|
mPopupCharacters.length, parentKey.mMaxPopupColumn,
|
||||||
keyWidth, parentKeyboard.getRowHeight(),
|
keyWidth, parentKeyboard.mDefaultRowHeight,
|
||||||
parentKey.mX + (parentKey.mWidth + parentKey.mHorizontalGap) / 2 - keyWidth / 2,
|
parentKey.mX + (mParams.mDefaultKeyWidth - keyWidth) / 2,
|
||||||
view.getMeasuredWidth());
|
view.getMeasuredWidth());
|
||||||
params.setTopPadding(keyboard.getVerticalGap());
|
|
||||||
mParams = params;
|
|
||||||
|
|
||||||
keyboard.setRowHeight(params.mRowHeight);
|
|
||||||
keyboard.setKeyboardHeight(params.getKeyboardHeight());
|
|
||||||
keyboard.setMinWidth(params.getKeyboardWidth());
|
|
||||||
keyboard.setDefaultCoordX(params.getDefaultKeyCoordX() + params.mKeyWidth / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getMaxKeyWidth(KeyboardView view, CharSequence[] popupCharacters,
|
private static int getMaxKeyWidth(KeyboardView view, CharSequence[] popupCharacters,
|
||||||
|
@ -249,17 +244,16 @@ public class MiniKeyboardBuilder {
|
||||||
return Math.max(minKeyWidth, maxWidth + horizontalPadding);
|
return Math.max(minKeyWidth, maxWidth + horizontalPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public MiniKeyboard build() {
|
public MiniKeyboard build() {
|
||||||
final MiniKeyboard keyboard = mKeyboard;
|
|
||||||
final List<Key> keys = keyboard.getKeys();
|
|
||||||
final MiniKeyboardLayoutParams params = mParams;
|
final MiniKeyboardLayoutParams params = mParams;
|
||||||
for (int n = 0; n < mPopupCharacters.length; n++) {
|
for (int n = 0; n < mPopupCharacters.length; n++) {
|
||||||
final CharSequence label = mPopupCharacters[n];
|
final CharSequence label = mPopupCharacters[n];
|
||||||
final int row = n / params.mNumColumns;
|
final int row = n / params.mNumColumns;
|
||||||
final Key key = new Key(mRes, keyboard, label, params.getX(n, row), params.getY(row),
|
final Key key = new Key(mResources, params, label, params.getX(n, row), params.getY(row),
|
||||||
params.mKeyWidth, params.mRowHeight, params.getRowFlags(row));
|
params.mDefaultKeyWidth, params.mDefaultRowHeight, params.getRowFlags(row));
|
||||||
keys.add(key);
|
params.onAddKey(key);
|
||||||
}
|
}
|
||||||
return keyboard;
|
return new MiniKeyboard(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,26 +31,19 @@ import com.android.inputmethod.latin.R;
|
||||||
*/
|
*/
|
||||||
public class Row {
|
public class Row {
|
||||||
/** Default width of a key in this row. */
|
/** Default width of a key in this row. */
|
||||||
public final int mDefaultWidth;
|
public final int mDefaultKeyWidth;
|
||||||
/** Default height of a key in this row. */
|
/** Default height of a key in this row. */
|
||||||
public final int mDefaultHeight;
|
public final int mRowHeight;
|
||||||
|
|
||||||
private final Keyboard mKeyboard;
|
public Row(Resources res, KeyboardParams params, XmlResourceParser parser) {
|
||||||
|
final int keyboardWidth = params.mWidth;
|
||||||
public Row(Resources res, Keyboard keyboard, XmlResourceParser parser) {
|
final int keyboardHeight = params.mHeight;
|
||||||
this.mKeyboard = keyboard;
|
|
||||||
final int keyboardWidth = keyboard.getDisplayWidth();
|
|
||||||
final int keyboardHeight = keyboard.getKeyboardHeight();
|
|
||||||
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
|
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
|
||||||
R.styleable.Keyboard);
|
R.styleable.Keyboard);
|
||||||
mDefaultWidth = KeyboardParser.getDimensionOrFraction(a,
|
mDefaultKeyWidth = KeyboardParser.getDimensionOrFraction(a,
|
||||||
R.styleable.Keyboard_keyWidth, keyboardWidth, keyboard.getKeyWidth());
|
R.styleable.Keyboard_keyWidth, keyboardWidth, params.mDefaultKeyWidth);
|
||||||
mDefaultHeight = KeyboardParser.getDimensionOrFraction(a,
|
mRowHeight = KeyboardParser.getDimensionOrFraction(a,
|
||||||
R.styleable.Keyboard_rowHeight, keyboardHeight, keyboard.getRowHeight());
|
R.styleable.Keyboard_rowHeight, keyboardHeight, params.mDefaultRowHeight);
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Keyboard getKeyboard() {
|
|
||||||
return mKeyboard;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1685,7 +1685,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
final int rawPrimaryCode = suggestion.charAt(0);
|
final int rawPrimaryCode = suggestion.charAt(0);
|
||||||
// Maybe apply the "bidi mirrored" conversions for parentheses
|
// Maybe apply the "bidi mirrored" conversions for parentheses
|
||||||
final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
|
final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
|
||||||
final int primaryCode = keyboard.isRtlKeyboard()
|
final int primaryCode = keyboard.mIsRtlKeyboard
|
||||||
? Key.getRtlParenthesisCode(rawPrimaryCode) : rawPrimaryCode;
|
? Key.getRtlParenthesisCode(rawPrimaryCode) : rawPrimaryCode;
|
||||||
|
|
||||||
final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : "";
|
final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : "";
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class SuggestHelper {
|
||||||
// Use null as the locale for Suggest so as to force it to use the internal dictionary
|
// Use null as the locale for Suggest so as to force it to use the internal dictionary
|
||||||
// (and not try to find a dictionary provider for a specified locale)
|
// (and not try to find a dictionary provider for a specified locale)
|
||||||
mSuggest = new Suggest(context, dictionaryId, null);
|
mSuggest = new Suggest(context, dictionaryId, null);
|
||||||
mKeyboard = new LatinKeyboard(context, keyboardId, keyboardId.mWidth);
|
mKeyboard = new LatinKeyboard.Builder(context).load(keyboardId).build();
|
||||||
mKeyDetector = new KeyDetector(0);
|
mKeyDetector = new KeyDetector(0);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class SuggestHelper {
|
||||||
protected SuggestHelper(Context context, File dictionaryPath, long startOffset, long length,
|
protected SuggestHelper(Context context, File dictionaryPath, long startOffset, long length,
|
||||||
KeyboardId keyboardId) {
|
KeyboardId keyboardId) {
|
||||||
mSuggest = new Suggest(context, dictionaryPath, startOffset, length, null);
|
mSuggest = new Suggest(context, dictionaryPath, startOffset, length, null);
|
||||||
mKeyboard = new LatinKeyboard(context, keyboardId, keyboardId.mWidth);
|
mKeyboard = new LatinKeyboard.Builder(context).load(keyboardId).build();
|
||||||
mKeyDetector = new KeyDetector(0);
|
mKeyDetector = new KeyDetector(0);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class SuggestHelper {
|
||||||
mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL);
|
mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL);
|
||||||
mKeyDetector.setKeyboard(mKeyboard, 0, 0);
|
mKeyDetector.setKeyboard(mKeyboard, 0, 0);
|
||||||
mKeyDetector.setProximityCorrectionEnabled(true);
|
mKeyDetector.setProximityCorrectionEnabled(true);
|
||||||
mKeyDetector.setProximityThreshold(mKeyboard.getMostCommonKeyWidth());
|
mKeyDetector.setProximityThreshold(mKeyboard.mMostCommonKeyWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCorrectionMode(int correctionMode) {
|
public void setCorrectionMode(int correctionMode) {
|
||||||
|
|
Loading…
Reference in New Issue